using EgwCoreLib.Lux.Core.Generic; using EgwCoreLib.Razor; using Newtonsoft.Json; using static Lux.UI.Components.Compo.Order.OrderRowMan; namespace Lux.UI.Components.Compo.Planner { public partial class BalanceProgGroup { #region Public Properties [Parameter] public List AllRecords { get; set; } = null!; [Parameter] public List ListOrderRow { get; set; } = null!; [Parameter] public DtUtils.Periodo Periodo { get; set; } = null!; [Parameter] public EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS CurrEnvir { get; set; } = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.NULL; [Parameter] public EventCallback EC_RemBalance { get; set; } [Parameter] public EventCallback EC_ReqCreateBatch { get; set; } #endregion Public Properties #region Public Methods /// /// Richiede rimozione da balance dell' OrderRow UID selezionato /// /// /// public async Task RemOrder(string OrdRowUID) { // recupero riga dict if (DictGrouped.ContainsKey(OrdRowUID)) { // prendo orderRowId da primo elemento... var listBal = DictGrouped[OrdRowUID]; if (listBal != null && listBal.Count > 0) { int ordId = listBal.FirstOrDefault()?.OrderRowID ?? 0; if (ordId > 0) { await EC_RemBalance.InvokeAsync(ordId); } } } } /// /// Struttura ritorno x creazione Batch e ODL /// public class BatchCreateInfo { /// /// Info batch da creare /// public ProductionBatchModel NewBatch { get; set; } = null!; /// /// Dettaglio macchine x cui creare ODL /// public List GroupDetail { get; set; } = null!; /// /// Record di partenza x esecuzione creazione ODL /// public List AllRecords { get; set; } = null!; } #endregion Public Methods #region Protected Properties protected decimal BalancedTotalTime { get => AllRecords?.Where(x=>x.BarQty > 0).Sum(x => x.TotalEstimTime) ?? 0; } [Inject] protected IJSRuntime JSRuntime { get; set; } = null!; #endregion Protected Properties #region Protected Methods protected override void OnParametersSet() { if (AllRecords != null) { // Supponendo che 'listaOriginale' sia la tua List DictGrouped = AllRecords .GroupBy(x => x.OrderRowNav.OrderRowUID) .ToDictionary( g => g.Key, // La chiave del dizionario � l'OrderRowNav.OrderRowUID g => g.ToList() // Il valore � la lista di oggetti raggruppati ); ListBalancedDet = AllRecords? .SelectMany(pg => pg.WorkGroupList) // appiattisce tutti i dizionari .GroupBy(kvp => kvp.Key) // raggruppa per la chiave del dizionario .Select(g => { // Materializziamo i tag separatamente per sicurezza List tags = g.SelectMany(x => x.Value.TagList ?? new List()).ToList(); // genero oggetto DTO in return return new GroupDetailDTO { MachineName = g.Key, TagList = tags, TotalBarQty = g.Sum(x => x.Value.BarQty), TotalNumPart = g.Sum(x => x.Value.NumParts), TotalTime = g.Sum(x => x.Value.Time) }; }) .ToList(); } } protected override async Task OnParametersSetAsync() { isLoading = true; OrderList = await OrdService.GetFiltAsync(Periodo.Inizio, Periodo.Fine); isLoading = false; } #endregion Protected Methods #region Private Fields [Inject] private IProdService PService { get; set; } = null!; [Inject] private ICalcRuidService CRService { get; set; } = null!; [Inject] private IOrderService OrdService { get; set; } = null!; [Inject] private IProductionItemService PIService { get; set; } = null!; private Dictionary> DictGrouped = new(); private ProductionBatchModel? newBatch = null; private bool ShowCreateBatch = false; private BootstrapModal Modal = new(); private string mTitle = ""; private string mMessage = ""; private BootstrapModal.ModalMode mMode = BootstrapModal.ModalMode.ND; private Dictionary modalOpt = new Dictionary(); private bool bOpenEstim = false; private MergedOrderRow currMergeOrderRow = new(); private WorkLoadDetailDTO? WorkLoadRecord = null; private OrderModel currOrder = new(); private List OrderList = new(); private bool isLoading = false; #endregion Private Fields #region Private Properties private string CssToggleBatch { get => ShowCreateBatch ? "btn-warning" : "btn-success"; } private List? ListBalancedDet { get; set; } = new(); #endregion Private Properties #region Private Methods private void ToggleCreaBatch() { ShowCreateBatch = !ShowCreateBatch; if (ShowCreateBatch) { newBatch = new ProductionBatchModel() { Envir = CurrEnvir, Description = $"Nuova Commessa {DateTime.Now:yyyy-MM-dd_HH:mm:ss}", DueDate = DateTime.Today.AddMonths(3), }; } else { newBatch = null; } } private string FormatEstTime(decimal totSeconds) { var tSpan = TimeSpan.FromSeconds((double)totSeconds); string answ = DateTimeUtils.FormatDateTime(tSpan); return answ; } private async Task CreateAllComm(MouseEventArgs args) { if (ListBalancedDet != null && newBatch != null && AllRecords != null) { var numMacc = ListBalancedDet.Count; var totBars = ListBalancedDet.Sum(x => x.TotalBarQty); var totNumPart = ListBalancedDet.Sum(x => x.TotalNumPart); mTitle = "Attenzione"; mMessage = $"Sicuro di voler creare la commessa su ogni impianto?\nL'impegno totale � per:\n " + $"- macchine: {numMacc}\n" + $"- parti: {totNumPart}\n" + $"- barre: {totBars}\n" + $"- tempo lavorazioni: {FormatEstTime(BalancedTotalTime)}"; mMode = BootstrapModal.ModalMode.Confirm; modalOpt = new(); modalOpt.Add(true, "Si"); modalOpt.Add(false, "No"); if (!await Modal!.ShowAsync()) return; BatchCreateInfo newData = new BatchCreateInfo() { AllRecords = AllRecords, NewBatch = newBatch, GroupDetail = ListBalancedDet }; ToggleCreaBatch(); // invia info x richiesta creazione batch. await EC_ReqCreateBatch.InvokeAsync(newData); } } private string TypePart(ProductionGroupModel group) { string ans = "Ko"; if (group.PlantList.Count > 1) { ans = "Ovunque"; } else if (group.PlantList.Count == 1 && group.PlantListJoin.Count() > 2) { ans = "Vinc"; } return ans; } private void OpenTimeEstim(string sRow, List prodGroups) { bOpenEstim = true; var orderRow = ListOrderRow.Where(x => x.OrderRowCode.Equals(sRow)).FirstOrDefault() ?? new(); currOrder = OrderList.Where(x=>x.OrderID == orderRow.OrderID).FirstOrDefault() ?? new(); var wld = !string.IsNullOrEmpty(orderRow.ProdEstimate) ? new WorkLoadDetailDTO(orderRow.OrderRowUID, orderRow.ProdEstimate) : null; currMergeOrderRow = new MergedOrderRow { Original = orderRow, WorkLoad = wld, CurrProdGroup = prodGroups }; WorkLoadRecord = wld; } /// /// Rimette da coda running in waiting il Job del WLD corrente /// /// private async Task ReRunJob() { if (WorkLoadRecord != null && currMergeOrderRow.Original != null) { mTitle = "Attenzione"; mMessage = "Sicuro di voler rimettere in coda il calcolo?"; mMode = BootstrapModal.ModalMode.Confirm; modalOpt = new(); modalOpt.Add(true, "Si"); modalOpt.Add(false, "No"); if (!await Modal!.ShowAsync()) return; string JobCode = $"ORDER:ESTIMATE:{WorkLoadRecord.UID}"; await PService.ReRunJobAsync(currMergeOrderRow.Original.Envir, JobCode); } } private void ClosePopup() { bOpenEstim = false; } /// /// Invio richiesta balance ordine /// /// /// private async Task ReqBalance(BalanceReqDto balData) { if (WorkLoadRecord != null && balData != null && balData.TagList.Count > 0) { mTitle = "Attenzione"; mMessage = $"Confermi richiesta bilanciamento carico per {balData.TagList.Count} articoli?"; mMode = BootstrapModal.ModalMode.Confirm; modalOpt = new(); modalOpt.Add(true, "Si"); modalOpt.Add(false, "No"); if (!await Modal!.ShowAsync()) return; // verifico parametri da conf envir... Egw.Window.Data.Enums.QuestionModes cMode = Egw.Window.Data.Enums.QuestionModes.ORDER; Egw.Window.Data.Enums.QuestionOrderSubModes cSubMode = Egw.Window.Data.Enums.QuestionOrderSubModes.BALANCE; string reqKey = ""; // preparo la richiesta di bilanciamento CalcRequestDTO calcReq = new CalcRequestDTO(); // elenco tags ricevuto... List TagList = balData.TagList; string serTagList = string.Join(",", TagList); // preparo richiesta serializzata e la accodo (viene inviata richiesta calcolo) Dictionary dictArgs = new Dictionary(); // creo registrazione richiesta... var ruid = await CRService.AddRequestAsync($"{currOrder.Envir}", $"{(int)cMode}-{(int)cSubMode}", WorkLoadRecord.UID); dictArgs.Add("UID", WorkLoadRecord.UID); dictArgs.Add("Group", $"{balData.GroupIdx}"); // aggiungo RUID effettivo dictArgs.Add("RUID", ruid); dictArgs.Add("OrderUID", currOrder.OrderCode); dictArgs.Add("Mode", $"{(int)cMode}"); dictArgs.Add("SubMode", $"{(int)cSubMode}"); dictArgs.Add("TagList", serTagList); // serializzo la richiesta di bilanciamento... string reqBalance = JsonConvert.SerializeObject(balData.MachineBalance); dictArgs.Add("ReqBalance", reqBalance); dictArgs.Add("BarLenght", $"{balData.BarLenght}"); calcReq = new CalcRequestDTO() { DictExec = dictArgs, EnvType = currOrder.Envir }; // chiave: composta da cMode, submode, UID riga... reqKey = $"{cMode}:{cSubMode}:{WorkLoadRecord.UID}"; // invio richiesta await PService.EnqueueRequestAsync("Balance", reqKey, calcReq); // parto dalla history attuale var currHist = currOrder.LogHistory; // aggiungo evento... currHist.Add(new TaskHistDTO() { DtEvent = DateTime.Now, UserName = "Default User", Message = $"{reqKey}", IconCss = "fa-solid fa-hourglass-start" }); currOrder.LogHistory = currHist; await OrdService.UpsertAsync(currOrder); } } /// /// Esegue assegnazione diretta valori ricevuti /// /// /// private async Task DirectAssign(DirectAssignReqDto updInfo) { if (updInfo != null) { int numDone = await PIService.BulkAssignProdGroupAsync(updInfo.OrderRowID, updInfo.ProdAssignID, updInfo.DictPartAssign); } } /// /// Esegue reset assegnazioni /// /// /// private Task ResetAssign(int OrderRowID) { return PIService.ResetAssignAsync(OrderRowID); } private string GetOrderByOrderRow(string orderRowCode) { string ans = ""; OrderModel order = OrderList.Where(x=>x.OrderRowNav.Any(x => x.OrderRowCode == orderRowCode)).FirstOrDefault() ?? new(); if(order != null) { ans = order.OrderCode; } return ans; } #endregion Private Methods } }