306 lines
13 KiB
C#
306 lines
13 KiB
C#
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
|
|
|
|
/// <summary>
|
|
/// Controllo status Alive
|
|
/// GET: api/Resources/alive
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("alive")]
|
|
public string alive()
|
|
{
|
|
//Log.Debug("Chiamata alive");
|
|
return $"OK";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="id">token comunicazione</param>
|
|
/// <returns>
|
|
/// 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)
|
|
/// </returns>
|
|
[HttpPost("check/{id}")]
|
|
public async Task<string> 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<ResourceModel> 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<int, int> list2check = projectData.ResourceList.ToDictionary(x => x.RawItemCloudId, x => x.Qty);
|
|
Dictionary<int, int> 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<List<ResourceModel>> Get()
|
|
{
|
|
// se non ho chiave --> vuoto!
|
|
List<ResourceModel> ListRecords = new List<ResourceModel>();
|
|
await Task.Delay(100);
|
|
return ListRecords;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco Macchine dato RestToken
|
|
/// </summary>
|
|
/// <param name="id">Rest Token cliente</param>
|
|
/// <param name="projDbId">ID progetto</param>
|
|
/// <param name="isEstim">true = ultima stima attiva / false = consumi effettivi</param>
|
|
/// <returns></returns>
|
|
// GET api/Resources/2cba60c7-7be4-40b1-aa0d-52e7c71fc1a7
|
|
[HttpGet("{id}")]
|
|
public async Task<List<ResourceExpDTO>> Get(string id, int projDbId, bool isEstim)
|
|
{
|
|
List<ResourceExpDTO> ListRecords = new List<ResourceExpDTO>();
|
|
// 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="id">token comunicazione</param>
|
|
/// <returns></returns>
|
|
[HttpPost("track/{id}")]
|
|
public async Task<string> 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<ResourceModel> 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;
|
|
|
|
/// <summary>
|
|
/// Classe per logging
|
|
/// </summary>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Utility method comparatore dizionari
|
|
/// </summary>
|
|
/// <param name="dict1"></param>
|
|
/// <param name="dict2"></param>
|
|
/// <returns></returns>
|
|
private bool DictComparer(Dictionary<int, int> dict1, Dictionary<int, int> 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
|
|
}
|
|
} |