Files
lux/Lux.UI/Components/Compo/Planner/BalanceProgGroup.razor.cs
T

393 lines
14 KiB
C#

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<ProductionGroupModel>? AllRecords { get; set; } = null;
[Parameter]
public List<OrderRowModel> 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<int> EC_RemBalance { get; set; }
[Parameter]
public EventCallback<BatchCreateInfo> EC_ReqCreateBatch { get; set; }
#endregion Public Properties
#region Public Methods
/// <summary>
/// Richiede rimozione da balance dell' OrderRow UID selezionato
/// </summary>
/// <param name="OrdRowUID"></param>
/// <returns></returns>
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);
}
}
}
}
/// <summary>
/// Struttura ritorno x creazione Batch e ODL
/// </summary>
public class BatchCreateInfo
{
/// <summary>
/// Info batch da creare
/// </summary>
public ProductionBatchModel NewBatch { get; set; } = null!;
/// <summary>
/// Dettaglio macchine x cui creare ODL
/// </summary>
public List<GroupDetailDTO> GroupDetail { get; set; } = null!;
/// <summary>
/// Record di partenza x esecuzione creazione ODL
/// </summary>
public List<ProductionGroupModel> 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 string FormatEstTime(decimal totSeconds)
{
var tSpan = TimeSpan.FromSeconds((double)totSeconds);
string answ = DateTimeUtils.FormatDateTime(tSpan);
return answ;
}
protected override void OnParametersSet()
{
if (AllRecords != null)
{
// Supponendo che 'listaOriginale' sia la tua List<ProductionGroupModel>
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<string> tags = g.SelectMany(x => x.Value.TagList ?? new List<string>()).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()
{
OrderList = await OrdService.GetFiltAsync(Periodo.Inizio, Periodo.Fine);
}
protected 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;
}
}
#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<string, List<ProductionGroupModel>> 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<bool, string> modalOpt = new Dictionary<bool, string>();
private bool bOpenEstim = false;
private MergedOrderRow currMergeOrderRow = new();
private WorkLoadDetailDTO? WorkLoadRecord = null;
private OrderModel currOrder = new();
private List<OrderModel> OrderList = new();
#endregion Private Fields
#region Private Properties
private string CssToggleBatch
{
get => ShowCreateBatch ? "btn-warning" : "btn-success";
}
private List<GroupDetailDTO>? ListBalancedDet { get; set; } = new();
#endregion Private Properties
#region Private Methods
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<bool>())
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 = "Ok";
}
else if (group.PlantList.Count == 1 && group.PlantListJoin.Count() > 2)
{
ans = "Vinc";
}
return ans;
}
private void OpenTimeEstim(string sRow, List<ProductionGroupModel> 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;
}
/// <summary>
/// Rimette da coda running in waiting il Job del WLD corrente
/// </summary>
/// <returns></returns>
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<bool>())
return;
string JobCode = $"ORDER:ESTIMATE:{WorkLoadRecord.UID}";
await PService.ReRunJobAsync(currMergeOrderRow.Original.Envir, JobCode);
}
}
private void ClosePopup()
{
bOpenEstim = false;
}
/// <summary>
/// Invio richiesta balance ordine
/// </summary>
/// <param name="balData"></param>
/// <returns></returns>
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<bool>())
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<string> TagList = balData.TagList;
string serTagList = string.Join(",", TagList);
// preparo richiesta serializzata e la accodo (viene inviata richiesta calcolo)
Dictionary<string, string> dictArgs = new Dictionary<string, string>();
// 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);
}
}
/// <summary>
/// Esegue assegnazione diretta valori ricevuti
/// </summary>
/// <param name="updInfo"></param>
/// <returns></returns>
private async Task DirectAssign(DirectAssignReqDto updInfo)
{
if (updInfo != null)
{
int numDone = await PIService.BulkAssignProdGroupAsync(updInfo.OrderRowID, updInfo.ProdAssignID, updInfo.DictPartAssign);
}
}
/// <summary>
/// Esegue reset assegnazioni
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
private Task ResetAssign(int OrderRowID)
{
return PIService.ResetAssignAsync(OrderRowID);
}
#endregion Private Methods
}
}