namespace EgwCoreLib.Lux.Core.RestPayload { /// /// Classe per definizione WorkLoad in dettaglio x un dato task (POR tipicamente) /// public class WorkLoadDetailDTO { #region Public Constructors /// /// Init classe partendo dal valore serializzato di una stima di lavorabilità di un item d'ordine minimo (POR) /// /// /// public WorkLoadDetailDTO(string UID, string rawData) { uID = UID; // deserializzo risultati calcolo machineCalcResults = JsonConvert.DeserializeObject>(rawData) ?? new List(); if (!string.IsNullOrEmpty(rawData) && rawData.Count() > 2) { // calcolo "esito sinteitco" della lavorabilità (NESSUNA part UnHealthy su ogni macchina) workable = machineCalcResults.Sum(x => x.NumPartsKo) == 0; // cerco la prima macchina (in caso multi macchina), da valutare se fosse suddiviso var firstMachine = machineCalcResults.FirstOrDefault(); if (firstMachine != null) { // lista completa... listComplete = firstMachine.PartList.Select(x => x.Tag).ToList(); // pezzi lavorabili listWorkable = MachineCalc.Utils.IntersectTags(machineCalcResults, p => p.CalcResult == Enums.PartVerificationResult.MACHINABLE).ToList(); // cerco l'insieme dei pezzi NON lavorabili listUnWorkable = MachineCalc.Utils.IntersectTags(machineCalcResults, p => p.CalcResult != Enums.PartVerificationResult.MACHINABLE).ToList(); listVincolated = listComplete .Except(listWorkable) .Except(ListUnWorkable) .ToList(); numKo = listUnWorkable.Count(); numOk = listWorkable.Count(); numOkVin = listVincolated.Count(); time = firstMachine.Time; // se non ok verifico SE ci siano part unhealty su OGNI macchina (altrimenti è cmq lavorabile if (!workable) { workable = !listUnWorkable.Any(); } } } LoadDetail = MachineCalc.Utils.CalculateIntersections(machineCalcResults); } #endregion Public Constructors #region Public Properties /// /// Elenco effettivo macchine /// public List ListMachines { get => machineCalcResults.Select(x => x.Name).OrderBy(x => x).ToList(); } /// /// Elenco Macchine in formato stringa join /// public string ListMachinesJoin { get => string.Join(", ", machineCalcResults.Select(x => x.Name).OrderBy(x => x).ToList()); } /// /// Elenco delle etichette parts non OK /// public List ListUnWorkable { get => listUnWorkable ?? new List(); } /// /// Elenco parts vincolate (=non ogni impianto) /// public List ListVincolated { get => listVincolated ?? new List(); } /// /// Elenco etichette parts OK /// public List ListWorkable { get => listWorkable ?? new List(); } /// /// Dettaglio combinazioni carico di lavoro /// public List LoadDetail { get; set; } = new List(); public List MachineCalcResults { get => machineCalcResults; } /// /// Numero di parts non lavorabili /// public int NumKo { get => numKo; } /// /// Num Macchine /// public int NumMachines { get => machineCalcResults.Count(); } /// /// Numero di parts lavorabili su OGNI macchina /// public int NumOk { get => numOk; } /// /// Numero pezzi vincolati (su una SOLA macchina) /// public int NumOkVin { get => numOkVin; } public int NumParts { get => listComplete?.Count() ?? 0; } /// /// Tempo massimo complessivo in ORE /// public decimal TotMaxTime { get { decimal ans = 0; // eventualmente decisione sul tipo di timing con una variabile esplicita (bool)? if (time > 0) { ans = time; } else { if (LoadDetail != null) ans = LoadDetail.Max(x => x.MaxTime); else ans = 0; } return ans; } } /// /// Tempo minimo complessivo in ORE /// public decimal TotMinTime { //get => TimeSpan.FromSeconds((double)LoadDetail.Min(x => x.MinTime)); get => LoadDetail.Min(x => x.MinTime); } public string UID { get => uID; } public bool Workable { get => workable; } #endregion Public Properties #region Private Fields private List? listComplete = null; private List? listUnWorkable = null; private List? listVincolated = null; private List? listWorkable = null; private List machineCalcResults = new List(); private int numKo = 0; private int numOk = 0; private int numOkVin = 0; private decimal time = 0; private string uID = ""; private bool workable = false; #endregion Private Fields } }