393 lines
14 KiB
C#
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
|
|
}
|
|
} |