using k8s.Models;
using MagMan.Core;
using MagMan.Core.DTO;
using MagMan.Core.Services;
using MagMan.Data.Admin.DbModels;
using MagMan.Data.Admin.Services;
using MagMan.Data.Tenant.DbModels;
using MagMan.Data.Tenant.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NLog;
using System.Linq;
namespace MagMan.UI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ResourcesController : ControllerBase
{
#region Public Constructors
public ResourcesController(MTAdminService MTDataService, TenantService TDataService, MessageService messageService)
{
MTAdmService = MTDataService;
TService = TDataService;
MService = messageService;
// json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/
JSSettings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
Log.Info("Avviata classe ResourcesController");
}
#endregion Public Constructors
#region Public Methods
///
/// Controllo status Alive
/// GET: api/Resources/alive
///
///
[HttpGet("alive")]
public string alive()
{
//Log.Debug("Chiamata alive");
return $"OK";
}
///
/// Processa una chiamata POST per la verifica di un oggetto di TRACKING risorse progetto (RestPayload.Resources)
/// PUT: api/Resources/check/00000000-0000-0000-0000-000000000000
///
/// token comunicazione
///
/// restituisce diversi valori secondo esito: ND/EQUAL/CHANGED, dove | ND = non definito /
/// non calcolato | EQUAL = il set inviato èidentico all'ultimo registrato (in termini di
/// numero barre impiegate complessivo e per singolo tipo, check da CloudId barre) | CHANGED
/// = il set inviato è differente (per tipo/numero/mix di barre)
///
[HttpPost("check/{id}")]
public async Task check(string id, [FromBody] RestPayload.Resources projectData)
{
string answ = "ND";
bool isEqual = false;
// verifico ci sia valore
if (!string.IsNullOrEmpty(id) && projectData != null)
{
// in primis recupero codice chiave da token...
int nKey = await MTAdmService.MainKeyByToken(id);
if (nKey > 0)
{
// nel projData ho le info x gestire aggiornamento PER INTERO
int ProjCloudId = projectData.ProjCloudId;
// proseguo solo se ho un Id valido
if (ProjCloudId > 0)
{
// inizio dal num risorse DTO... se vuoto è sempre FALSE
int numResDTO = 0;
if (projectData.ResourceList == null || projectData.ResourceList.Count == 0)
{
// confermo che NON corrisponde
isEqual = false;
}
else
{
numResDTO = projectData.ResourceList.Count;
// recupero ultimo set ricevuto...
var lastRecPlan = TService.ReqPlanGetLast(nKey, ProjCloudId, Enums.ProjResState.Estimated);
// se non corrisponde ProjId --> false
if (lastRecPlan == null || lastRecPlan.ProjDbId != ProjCloudId)
{
// confermo che NON corrisponde
isEqual = false;
}
// altrimenti verifico contenuto come barre
else
{
// ora recupero risorse associate alla registrazione ricevuta...
var lastResList = await TService.ResourcesGetByProject(nKey, ProjCloudId, true, false);
// se lista vuota
if (lastResList == null || lastResList.Count == 0)
{
// confermo che NON corrisponde
isEqual = false;
}
else
{
//...o se num tot != numResDto --> false
if (lastResList.Count != numResDTO)
{
// confermo che NON corrisponde
isEqual = false;
}
else
{
// altrimenti check CloudId barre + quantità x equality...
// inizio convertendo
List listRes = projectData.ResourceList.Select(x => TService.ResourceFromDto(x, lastRecPlan.RequestId)).ToList();
// dato x scontato che ho stesso numero di barre -->
// confronto 1-1 per quantità... genero i 2 set
Dictionary list2check = projectData.ResourceList.ToDictionary(x => x.RawItemCloudId, x => x.Qty);
Dictionary listSaved = lastResList.ToDictionary(x => x.RawItemId, x => x.Qty);
// comparazione finale!
isEqual = DictComparer(list2check, listSaved);
//isEqual= list2check.Count == listSaved.Count && !list2check.Except(listSaved).Any();
}
}
}
}
}
}
answ = isEqual ? "EQUAL" : "CHANGED";
}
return answ;
}
// GET api/Resources/5
[HttpGet]
public async Task> Get()
{
// se non ho chiave --> vuoto!
List ListRecords = new List();
await Task.Delay(100);
return ListRecords;
}
///
/// Elenco Macchine dato RestToken
///
/// Rest Token cliente
/// ID progetto
/// true = ultima stima attiva / false = consumi effettivi
///
// GET api/Resources/2cba60c7-7be4-40b1-aa0d-52e7c71fc1a7
[HttpGet("{id}")]
public async Task> Get(string id, int projDbId, bool isEstim)
{
List ListRecords = new List();
// verifico ci sia valore
if (!string.IsNullOrEmpty(id))
{
// in primis recupero codice chiave da token...
int nKey = await MTAdmService.MainKeyByToken(id);
//ListRecords = await TService.ResourcesGetByProject(nKey, projDbId, isEstim, false);
ListRecords = await TService.ResourcesExpGetByProject(nKey, projDbId, isEstim, false);
}
return ListRecords;
}
///
/// Processa una chiamata POST per l'invio di un oggetto di TRACKING risorse progetto (RestPayload.Resources)
/// PUT: api/Resources/track/00000000-0000-0000-0000-000000000000
///
/// token comunicazione
///
[HttpPost("track/{id}")]
public async Task track(string id, [FromBody] RestPayload.Resources projectData)
{
string answ = "ND";
bool fatto = false;
// verifico ci sia valore
if (!string.IsNullOrEmpty(id) && projectData != null)
{
// in primis recupero codice chiave da token...
int nKey = await MTAdmService.MainKeyByToken(id);
if (nKey > 0)
{
// nel projData ho le info x gestire aggiornamento PER INTERO
int ProjCloudId = projectData.ProjCloudId;
// proseguo solo se ho un Id valido
if (ProjCloudId > 0)
{
// recupero info del progetto con cui registrare le note
var projRec = await TService.ProjectGetById(nKey, ProjCloudId);
// in primis registro il record RequestPlan...
var recPlan = new RequestPlanModel()
{
DtRequest = projectData.DtReq,
IsActive = true,
ReqState = projectData.ReqState,
ProjDbId = ProjCloudId
};
// registro richiesta prima dei movimenti...
int RequestPlanId = await TService.ReqPlanUpdate(nKey, recPlan);
// per ogni riga risorsa registro le info relative...
if (projectData.ResourceList != null)
{
List listRes = projectData.ResourceList.Select(x => TService.ResourceFromDto(x, RequestPlanId)).ToList();
try
{
string prDesc = $"K{nKey}";
if (projRec != null)
{
prDesc += $" | P.{ProjCloudId} | {projRec.ProjDescription} ({projRec.Machine})";
}
// rivedere SIA consumi che gestione stime...
await TService.ResourceUpdate(nKey, RequestPlanId, projectData.ResourceList, projectData.ReqState, prDesc);
fatto = true;
}
catch (Exception exc)
{
Log.Error($"ResourceController.upsert | Errore in fase salvataggio ResourceDto{Environment.NewLine}{exc}");
fatto = false;
}
}
// resetto cache redis
await MTAdmService.FlushRedisCache();
// broadcast update via redis, indico nKey + projCloudIdx update puntuale
MService.QueUpdRes.sendMessage($"{nKey}|{ProjCloudId}");
// broadcast update via redis, indico nKey x update puntuale
MService.QueUpdProj.sendMessage($"{nKey}");
}
}
}
answ = fatto ? "OK" : "NO";
return answ;
}
#endregion Public Methods
#region Private Fields
private static JsonSerializerSettings? JSSettings;
///
/// Classe per logging
///
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Properties
private MessageService MService { get; set; } = null!;
private MTAdminService MTAdmService { get; set; } = null!;
private TenantService TService { get; set; } = null!;
#endregion Private Properties
#region Private Methods
///
/// Utility method comparatore dizionari
///
///
///
///
private bool DictComparer(Dictionary dict1, Dictionary dict2)
{
// Test for equality.
bool isEqual = false;
if (dict1.Count == dict2.Count) // Require isEqual count.
{
isEqual = true;
foreach (var pair in dict1)
{
int value;
if (dict2.TryGetValue(pair.Key, out value))
{
// Require value be isEqual.
if (value != pair.Value)
{
isEqual = false;
break;
}
}
else
{
// Require key be present.
isEqual = false;
break;
}
}
}
return isEqual;
}
#endregion Private Methods
}
}