From 2075cfa0bd20e17c601261d755ac3f4e5aee0879 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 7 Nov 2025 17:14:43 +0100 Subject: [PATCH] Update forzato in massa importi BOM BEAM --- .../Controllers/LuxController.cs | 293 ++++++++++++++---- .../Services/DataLayerServices.cs | 62 +++- Lux.API/Lux.API.csproj | 2 +- Lux.API/Services/ExternalMessageProcessor.cs | 50 --- Lux.UI/Components/Compo/EditBom.razor | 219 ++++++++----- Lux.UI/Components/Compo/EditBom.razor.cs | 178 +++++++++-- Lux.UI/Components/Compo/OfferRowMan.razor | 8 +- Lux.UI/Components/Compo/OfferRowMan.razor.cs | 148 +++++---- Lux.UI/Lux.UI.csproj | 2 +- Resources/ChangeLog.html | 2 +- Resources/VersNum.txt | 2 +- Resources/manifest.xml | 2 +- 12 files changed, 687 insertions(+), 281 deletions(-) diff --git a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs index b4dae47d..1f9dd2e2 100644 --- a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs +++ b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs @@ -9,6 +9,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using NLog; +using System.Globalization; using static EgwCoreLib.Lux.Core.Enums; namespace EgwCoreLib.Lux.Data.Controllers @@ -1026,6 +1027,134 @@ namespace EgwCoreLib.Lux.Data.Controllers return dbResult; } + /// + /// Esegue un mass update dei valori di margine, qtyMax, costo di un set di dati ricevuto + /// + /// Elenco items da aggiornare + /// Costo standard (al volume m3) + /// Margine da impostare per tutti + /// Valore qty max da impostare per tutti + /// Valore UM da impostare per tutti + /// Valore di arrotondamento richiesto (0 = non arrotondo) + /// Valore di scala da unità in ingresso x unità di costo (mm x mm x m --> m3) + /// + /// + internal async Task ItemMassUpdate(List list2upd, double setCost, double defMargin, double defQtyMax, string defUM, int roundVal, double scaleFactor) + { + bool answ = false; + if (list2upd == null || !list2upd.Any()) + return answ; + + //using (DataLayerContext dbCtx = new DataLayerContext(_config)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + // Validate input + if (setCost <= 0) + throw new ArgumentException("setCost must be greater than 0."); + + // Step 1: Extract width and height from ExtItemCode + var itemUpdates = new List(); + + foreach (var item in list2upd) + { + if (string.IsNullOrWhiteSpace(item.ItemCode)) + continue; + + // Try to parse ExtItemCode: "Pine-200.0x360.0" + if (!item.ItemCode.Contains("-") || !item.ItemCode.Contains("x")) + { + // Skip invalid format + continue; + } + + // Split by "-" to get prefix and number part + var parts = item.ItemCode.Split('-', 2); + if (parts.Length < 2) + { + continue; + } + + string numberPart = parts[1]; // e.g. "200.0x360.0" + + // Split by "x" to get width and height + var widthHeight = numberPart.Split('x', 2); + if (widthHeight.Length < 2) + { + continue; + } + + if (!double.TryParse(widthHeight[0], NumberStyles.Any, CultureInfo.InvariantCulture, out double width) || + !double.TryParse(widthHeight[1], NumberStyles.Any, CultureInfo.InvariantCulture, out double height)) + { + continue; + } + + // Step 2: Calculate Cost using formula: + // Cost = setCost / 1,000,000 * width * height + double calculatedCost = (setCost / scaleFactor) * width * height; + // if requested do round ceiling + if (roundVal > 0) + { + calculatedCost = Math.Ceiling(calculatedCost / roundVal) * roundVal; + } + + // Optional: you can also apply margin to cost if needed, but you said "Cost = ..." + // So we're just computing it based on width/height + + // Step 4: Create a new ItemModel with updated values + var updatedItem = new ItemModel + { + ItemID = item.ItemID, + ExtItemCode = item.ItemCode, // keep original + Cost = calculatedCost, + Margin = defMargin, + QtyMax = defQtyMax, + UM = defUM + }; + + itemUpdates.Add(updatedItem); + } + + // Step 5: Update database using EF Core (EF Core doesn't support "update" on entire list directly) + // We'll use .UpdateRange() or a raw update via .Where() and .SetProperty() + + // ✅ Use EF Core's Update method (for bulk update) + if (itemUpdates.Any()) + { + // Update only the ones that exist in the DB + var existingItems = await dbCtx.DbSetItem + .Where(i => itemUpdates.Select(ui => ui.ItemID).Contains(i.ItemID)) + .ToListAsync(); + + if (existingItems.Any()) + { + // Update existing records using EF Core's Update method + foreach (var updatedItem in itemUpdates) + { + var existing = existingItems.FirstOrDefault(i => i.ItemID == updatedItem.ItemID); + if (existing != null) + { + // Update only the fields we're setting + existing.Cost = updatedItem.Cost; + existing.Margin = updatedItem.Margin; + existing.QtyMax = updatedItem.QtyMax; + } + } + + await dbCtx.SaveChangesAsync(); + } + } + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ItemMassUpdate{Environment.NewLine}{exc}"); + } + } + return answ; + } + internal bool ItemUpsert(ItemModel newRec) { bool answ = false; @@ -1113,17 +1242,6 @@ namespace EgwCoreLib.Lux.Data.Controllers return result; } - - internal bool UpdateCodGroup(List bomList) - { - bool answ = false; - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - } - return answ; - } - /// /// Upsert item ricevuti da BOM calcolata /// @@ -1137,30 +1255,15 @@ namespace EgwCoreLib.Lux.Data.Controllers { try { + // Controllo ed inserisco eventuali gruppi mancanti + UpdateCodGroup(bomList); + // prendo solo elementi a prezzo 0 da salvare sul DB var item2save = bomList .Where(x => x.Price == 0) .ToList(); List listInserted = new List(); -#if false - // in primis calcolo ii distinct dei CodGroup x eventuale insert preventivo - List distCodGroups = bomList - .Select(i => i.ClassCode) - .Distinct() - .Where(c => !string.IsNullOrWhiteSpace(c)) - .ToList(); - - // recupero l'elenco degli itemGroup gestiti - var itemGroupList = dbCtx - .DbSetItemGroup - .ToList(); - // elenco da inserire... - var codGroupsToInsert = distCodGroups - .Where(cg => !itemGroupList.Where(x => x.CodGroup == cg)) - .ToList(); -#endif - // ciclo x ogni elemento della BOM, cercando x gruppo e ExtItemCode foreach (var item in item2save) { @@ -1172,7 +1275,7 @@ namespace EgwCoreLib.Lux.Data.Controllers // se nullo --> verifico x inserire!!! if (currRec == null) { - // verifico NON sia tra gli items già in fase di inserimento + // verifico NON sia tra gli list2upd già in fase di inserimento if (!listInserted.Any(x => x.CodGroup == item.ClassCode && x.ExtItemCode == item.ItemCode)) { ItemModel newRec = new ItemModel() @@ -1527,37 +1630,6 @@ namespace EgwCoreLib.Lux.Data.Controllers return answ; } -#if false - /// - /// Elenco item Child da ID Parent (per sostituzione) - /// - /// ID parent (valido quindi >0) - /// - internal List ItemGetChild(int ItemIdParent) - { - List dbResult = new List(); - if (ItemIdParent > 0) - { - //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - try - { - dbResult = dbCtx - .DbSetItem - .Where(x => x.ItemID == ItemIdParent || x.ItemIDParent == ItemIdParent) - .ToList(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ItemGetChild{Environment.NewLine}{exc}"); - } - } - } - return dbResult; - } -#endif - /// /// Upsert record /// @@ -1652,6 +1724,35 @@ namespace EgwCoreLib.Lux.Data.Controllers return dbResult; } +#if false + /// + /// Ritorna direttamente 1 riga offerta + /// + /// + /// + internal OfferRowModel? OfferRowGetByOfferRowID(int offerRowID) + { + OfferRowModel? dbResult = null; + //using (DataLayerContext dbCtx = new DataLayerContext(_config)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + dbResult = dbCtx + .DbSetOfferRow + .Where(x => x.OfferRowID == offerRowID) + .Include(s => s.SellingItemNav) + .FirstOrDefault(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante OfferRowGetByOfferRowID{Environment.NewLine}{exc}"); + } + } + return dbResult; + } +#endif + /// /// Elimina riga e sposta eventuali righe successive... /// @@ -2263,8 +2364,74 @@ namespace EgwCoreLib.Lux.Data.Controllers return answ; } + internal bool UpdateCodGroup(List bomList) + { + bool answ = false; + //using (DataLayerContext dbCtx = new DataLayerContext(_config)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + // in primis calcolo i distinct dei CodGroup x eventuale insert preventivo + List distCodGroups = bomList + .Select(i => i.ClassCode) + .Distinct() + .Where(c => !string.IsNullOrWhiteSpace(c)) + .ToList(); + + // recupero l'elenco degli itemGroup gestiti + var itemGroupList = dbCtx + .DbSetItemGroup + .ToList(); + // elenco da inserire... + var codGroupsToInsert = distCodGroups + .Where(x => !itemGroupList.Any(i => i.CodGroup == x)) + .Select(x => new ItemGroupModel() { CodGroup = x, Description = x }) + .ToList(); + // se ci sono inserisco! + if (codGroupsToInsert != null && codGroupsToInsert.Count > 0) + { + dbCtx + .DbSetItemGroup + .AddRange(codGroupsToInsert); + // salvo... + dbCtx.SaveChanges(); + } + } + return answ; + } + #endregion Internal Methods +#if false + /// + /// Elenco item Child da ID Parent (per sostituzione) + /// + /// ID parent (valido quindi >0) + /// + internal List ItemGetChild(int ItemIdParent) + { + List dbResult = new List(); + if (ItemIdParent > 0) + { + //using (DataLayerContext dbCtx = new DataLayerContext(configuration)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + dbResult = dbCtx + .DbSetItem + .Where(x => x.ItemID == ItemIdParent || x.ItemIDParent == ItemIdParent) + .ToList(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ItemGetChild{Environment.NewLine}{exc}"); + } + } + } + return dbResult; + } +#endif + #region Private Fields private static IConfiguration _configuration; @@ -2285,8 +2452,8 @@ namespace EgwCoreLib.Lux.Data.Controllers /// Lista BOM precedente da confrontare x scelta alternativi /// Costo netto componenti BOM calcolato /// Prezzo complessivo calcolato (con aggiunta marginalità) - /// Controllo coerenza calcoli sui gruppi items - /// Controllo coerenza calcoli su num items + /// Controllo coerenza calcoli sui gruppi list2upd + /// Controllo coerenza calcoli su num list2upd private static void validateBom(List itemGroupList, List bomGenList, ref List bomList, List? bomListPrev, ref double totCost, ref double totPrice, ref int numGroupOk, ref int numItemOk) { double margin = 0; diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs index b378a63b..3e4b7923 100644 --- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs +++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs @@ -17,6 +17,7 @@ using System.ComponentModel.Design; using System.Diagnostics; using System.Linq; using System.Resources; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using static EgwCoreLib.Lux.Core.Enums; @@ -50,6 +51,28 @@ namespace EgwCoreLib.Lux.Data.Services #region Public Methods + /// + /// Sistema gli item che mancassero di ItemID leggendo da DB + /// + /// + /// + public List BomFixItemId(List listOrg) + { + List listFix = listOrg; + // sistemo ItemID per gli item della BOM... + var listItemDB = dbController.ItemGetFilt("", ItemClassType.Bom); + // cerco i record da sistemare ed 1:1 li fixo... + foreach (var item in listFix.Where(x => x.ItemID == 0)) + { + var dbRec = listItemDB.FirstOrDefault(x => x.ExtItemCode == item.ItemCode); + if ((dbRec != null)) + { + item.ItemID = dbRec.ItemID; + } + } + return listFix; + } + /// /// Elenco completo Config Envir /// @@ -608,7 +631,6 @@ namespace EgwCoreLib.Lux.Data.Services /// /// Elenco item da ricerca completa Async /// - /// /// /// /// @@ -713,6 +735,24 @@ namespace EgwCoreLib.Lux.Data.Services return result; } + /// + /// Esecuzione mass update di un set di item cui manca pezzo/quantità max + /// + /// + /// + /// + /// + /// Valore UM da impostare per tutti + /// + /// Valore di scala da unità in ingresso x unità di costo (mm x mm x m --> m3) + /// + public async Task ItemMassUpdate(List list2upd, double setCost, double defMargin, double defQtyMax, string defUM, int roundVal = 0, double scaleFactor = 1_000_000.0) + { + bool result = await dbController.ItemMassUpdate(list2upd, setCost, defMargin, defQtyMax, defUM, roundVal, scaleFactor); + await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Item:*"); + return result; + } + /// /// Update / Insert record item /// @@ -931,6 +971,26 @@ namespace EgwCoreLib.Lux.Data.Services return result; } +#if false + /// + /// Recupero nuovo record BOM diretto dal DB + /// + /// + /// + /// + public OfferRowModel? OfferRowGetByOfferRowID(int offerRowID) + { + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + OfferRowModel? result = null; + result = dbController.OfferRowGetByOfferRowID(offerRowID); + sw.Stop(); + Log.Debug($"OfferRowGetByOfferRowID | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } +#endif + /// /// Converte il campo raw della BOM in lista oggetti da gestire /// diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj index 496890e2..6a6262b5 100644 --- a/Lux.API/Lux.API.csproj +++ b/Lux.API/Lux.API.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 0.9.2511.0618 + 0.9.2511.0717 diff --git a/Lux.API/Services/ExternalMessageProcessor.cs b/Lux.API/Services/ExternalMessageProcessor.cs index 6f8b2469..4321948b 100644 --- a/Lux.API/Services/ExternalMessageProcessor.cs +++ b/Lux.API/Services/ExternalMessageProcessor.cs @@ -159,55 +159,5 @@ namespace Lux.API.Services #endregion Private Fields -#if false - /// - /// Restituisce una risposta all'esecuzione - /// - /// - private void ProcessMan_m_AnswerReceived(ProcessArgsResult result) - { - // verifico che sia la mia richiesta con id immagine... FARE!!! - // salvo il risultato... - if (result.Args != null && result.Args.Count > 0) - { - if (result.Args.ContainsKey("Svg")) - { - // salvo SVG - string newSvg = result.Args["Svg"]; - // salvo nel dizionario - lastSvg = newSvg; - // salvo su redis - _imgService.SaveSvg("123456", lastSvg); - } - } - } - - /// - /// Salva risultato calcolo da broadcast channel REDIS - /// - /// - /// - private void SaveCalcData(RedisChannel channel, RedisValue message) - { - string rawData = $"{message}"; - if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2) - { - // provo a deserializzare - try - { - var retData = JsonConvert.DeserializeObject(rawData); - if (retData != null) - { - // verifico nId di risposta x salvare correttamente - ProcessMan_m_AnswerReceived(retData); - } - } - catch (Exception exc) - { - _logger.LogError($"Errore in fase decodifica messaggio da REDIS Channel{Environment.NewLine}{exc}"); - } - } - } -#endif } } \ No newline at end of file diff --git a/Lux.UI/Components/Compo/EditBom.razor b/Lux.UI/Components/Compo/EditBom.razor index dc0c1fff..bd4e0884 100644 --- a/Lux.UI/Components/Compo/EditBom.razor +++ b/Lux.UI/Components/Compo/EditBom.razor @@ -1,83 +1,156 @@ - - - - - - - - - @* *@ - @if (ShowVolume) - { - - } - - - - - - - @foreach (var item in bomDict) - { - @if (EditRecord != null && item.Key == currIdx) - { - - -
#ClassDescrizioneCodVolQtyUnitPriceImporto
@(item.Key + 1) -
- - - +@if (isLoading) +{ + +} +else +{ + @if (MassEdit) + { +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ @if (showMassEditSave) + { + + } + else + { + + } +
+
+ } + + + + + - @if (ShowVolume) - { - } - - - - - } - else + + + + + @* *@ + @if (ShowVolume) + { + + } + + + + + + + @foreach (var item in bomPaged) { - - - + + + @if (ShowVolume) { - + } - - - - @* *@ + + + + + } + else + { + + + + + + @* *@ + @if (ShowVolume) + { + + } + + + + + } + } + + + @{ + int numCol = ShowVolume ? 8 : 7; + + @if (ShowVolume) { - + } - - - + + + + + + } - } - - - - - @if (ShowVolume) - { - - } - - - - - -
+ @if (MassEdit) + { +
+
-
@($"{item.Value.Volume:N3}")@($"{item.Value.Qty:N3}")@($"{item.Value.PriceEff:C2}")@($"{item.Value.TotalCost:C2}")
ClassDescrizioneCodVolQtyUnitPriceImporto
@(item.Key + 1) - @if (item.Value.Price == 0) + @if (EditRecord != null && item.numRow == EditRecord.numRow) + { +
@(item.numRow) +
+ + + +
+
@($"{item.Volume:N3}")@item.Value.ClassCode@item.Value.ItemCode@item.Value.DescriptionCode@($"{item.Qty:N3}")@($"{item.PriceEff:C2}")@($"{item.TotalCost:C2}")
+ @(item.numRow) + @if (MassEdit) + { + + } + + @if (item.Price == 0) + { + + } + @item.ClassCode@item.ItemCode@item.Value.DescriptionCode@($"{item.Volume:N3}")@($"{item.Qty:N3}")@($"{item.PriceEff:C2}")@($"{item.TotalCost:C2}")
@BomList.Count materiali@($"{item.Value.Volume:N3}")@($"{VolTotale:N3}")@($"{item.Value.Qty:N3}")@($"{item.Value.PriceEff:C2}")@($"{item.Value.TotalCost:C2}")@($"{QtyTotale:N3}")tot:@($"{ImportoTotale:C2}")
+ +
@BomList.Count materiali@($"{VolTotale:N3}")@($"{QtyTotale:N3}")tot:@($"{ImportoTotale:C2}")
\ No newline at end of file + +
+} \ No newline at end of file diff --git a/Lux.UI/Components/Compo/EditBom.razor.cs b/Lux.UI/Components/Compo/EditBom.razor.cs index 401d0acb..44be553c 100644 --- a/Lux.UI/Components/Compo/EditBom.razor.cs +++ b/Lux.UI/Components/Compo/EditBom.razor.cs @@ -4,6 +4,8 @@ using EgwCoreLib.Lux.Data.DbModel.Sales; using EgwCoreLib.Lux.Data.Services; using EgwMultiEngineManager.Data; using Microsoft.AspNetCore.Components; +using RestSharp.Serializers.Xml; +using System.Collections.Generic; using System.Threading.Tasks; namespace Lux.UI.Components.Compo @@ -21,6 +23,9 @@ namespace Lux.UI.Components.Compo [Parameter] public EventCallback> EC_Updated { get; set; } + [Parameter] + public bool MassEdit { get; set; } = false; + #endregion Public Properties #region Protected Properties @@ -35,7 +40,7 @@ namespace Lux.UI.Components.Compo double valTot = 0; if (bomDict != null) { - valTot = bomDict.Sum(x => x.Value.TotalCost); + valTot = bomDict.Sum(x => x.TotalCost); } return valTot; } @@ -48,12 +53,28 @@ namespace Lux.UI.Components.Compo double valTot = 0; if (bomDict != null) { - valTot = bomDict.Sum(x => x.Value.Qty); + valTot = bomDict.Sum(x => x.Qty); } return valTot; } } + protected bool SelAll + { + get => selAll; + set + { + if (selAll != value) + { + selAll = value; + foreach (var item in bomDict) + { + item.isSelected = selAll; + } + } + } + } + protected double VolTotale { get @@ -61,7 +82,7 @@ namespace Lux.UI.Components.Compo double valTot = 0; if (bomDict != null) { - valTot = bomDict.Sum(x => x.Value.Volume); + valTot = bomDict.Sum(x => x.Volume); } return valTot; } @@ -69,21 +90,15 @@ namespace Lux.UI.Components.Compo #endregion Protected Properties - - private bool ShowVolume - { - get => CurrRowRec.Envir == Constants.EXECENVIRONMENTS.BEAM || CurrRowRec.Envir == Constants.EXECENVIRONMENTS.WALL; - } - #region Protected Methods protected void DoCancel() { EditRecord = null; - currIdx = -1; + isLoading = false; } - protected void DoEdit(int key, BomItemDTO editRec) + protected void DoEdit(BomDtoSel editRec) { if (editRec.ItemID > 0) { @@ -99,7 +114,6 @@ namespace Lux.UI.Components.Compo { ListItemAlt = new List(); } - currIdx = key; EditRecord = editRec; } @@ -108,13 +122,46 @@ namespace Lux.UI.Components.Compo /// protected override void OnParametersSet() { - if (BomList != null) + if (BomList != null && BomList.Count > 0) { + int idx = 0; // Convert List to Dictionary with index as key bomDict = BomList - .Select((item, index) => new { index, item }) - .ToDictionary(x => x.index, x => x.item); + .Select(x => new BomDtoSel() + { + isSelected = false, + numRow = idx++, + ClassCode = x.ClassCode, + DescriptionCode = x.DescriptionCode, + ItemCode = x.ItemCode, + ItemID = x.ItemID, + ItemQty = x.ItemQty, + Price = x.Price, + PriceEff = x.PriceEff, + Qty = x.Qty, + Volume = x.Volume + }) + .ToList(); + totalCount = BomList.Count(); + UpdateTable(); + isLoading = false; } + else + { + isLoading = true; + } + } + + protected void SaveNumRec(int newNum) + { + numRecord = newNum; + UpdateTable(); + } + + protected void SavePage(int newNum) + { + currPage = newNum; + UpdateTable(); } #endregion Protected Methods @@ -124,14 +171,76 @@ namespace Lux.UI.Components.Compo /// /// Dizionario interno oggetti x editare con indice /// - private Dictionary bomDict = new Dictionary(); + private List bomDict = new List(); + + private List bomPaged = new List(); + + private int currPage = 1; + + private decimal defMargin = 0.2M; + + private double defQtyMax = 999; + + private int defRound = 5; + + private string defUM = "m"; + + private BomDtoSel? EditRecord = null; + + private bool isLoading = false; - private int currIdx = -1; - private BomItemDTO? EditRecord = null; private List ListItemAlt = new List(); + private int numRecord = 10; + + private bool selAll = false; + + private int totalCount = 0; + + private double totCost = 100; + #endregion Private Fields + protected async Task ForceItemPrice() + { + isLoading = true; + // chiamo metodo update x i soli valori selezionati... + var list2upd = bomDict.Where(x => x.isSelected).Cast().ToList(); + await DLService.ItemMassUpdate(list2upd, totCost, (double)defMargin, defQtyMax, defUM, defRound); + // ...e passo al controller parent LINQ projection to base type + List baseList = bomDict.Cast().ToList(); + await EC_Updated.InvokeAsync(baseList); + SelAll = false; + } + + protected bool showMassEditSave + { + get => bomDict != null && bomDict.Any(x => x.isSelected); + } + + #region Protected Classes + + protected class BomDtoSel : BomItemDTO + { + #region Public Properties + + public bool isSelected { get; set; } = false; + public int numRow { get; set; } = 0; + + #endregion Public Properties + } + + #endregion Protected Classes + + #region Private Properties + + private bool ShowVolume + { + get => CurrRowRec.Envir == Constants.EXECENVIRONMENTS.BEAM || CurrRowRec.Envir == Constants.EXECENVIRONMENTS.WALL; + } + + #endregion Private Properties + #region Private Methods /// @@ -139,21 +248,18 @@ namespace Lux.UI.Components.Compo /// private async Task DoSave() { + isLoading = true; // aggiorno l'oggetto nel mio dizionario if (EditRecord != null) { // modifico il valore ID con quello selezionato nel selettore x l'oggetto - UpdateItem(currIdx, EditRecord); + UpdateItem(EditRecord); } - // converto il dizionario in lista - var updList = bomDict - .OrderBy(kvp => kvp.Key) - .Select(kvp => kvp.Value) - .ToList(); // deseleziono... DoCancel(); - // ...e passo al controller parent - await EC_Updated.InvokeAsync(updList); + // ...e passo al controller parent LINQ projection to base type + List baseList = bomDict.Cast().ToList(); + await EC_Updated.InvokeAsync(baseList); } /// @@ -161,14 +267,28 @@ namespace Lux.UI.Components.Compo /// /// /// - private void UpdateItem(int key, BomItemDTO updatedItem) + private void UpdateItem(BomDtoSel updatedItem) { - if (bomDict.ContainsKey(key)) + int index = bomDict.FindIndex(x => x.numRow == updatedItem.numRow); + if (index >= 0) { - bomDict[key] = updatedItem; + bomDict[index] = updatedItem; } } + /// + /// Filtro e paginazione + /// + private void UpdateTable() + { + // fix paginazione + bomPaged = bomDict + .Skip(numRecord * (currPage - 1)) + .Take(numRecord) + .ToList(); + isLoading = false; + } + #endregion Private Methods } } \ No newline at end of file diff --git a/Lux.UI/Components/Compo/OfferRowMan.razor b/Lux.UI/Components/Compo/OfferRowMan.razor index 6cf868ab..409b3828 100644 --- a/Lux.UI/Components/Compo/OfferRowMan.razor +++ b/Lux.UI/Components/Compo/OfferRowMan.razor @@ -304,17 +304,21 @@ else
Materiali (BOM)
-
+
@EditRecord.Note
@EditRecord.OfferRowUID
+
+ + +
diff --git a/Lux.UI/Components/Compo/OfferRowMan.razor.cs b/Lux.UI/Components/Compo/OfferRowMan.razor.cs index 689a931f..a14f7aa4 100644 --- a/Lux.UI/Components/Compo/OfferRowMan.razor.cs +++ b/Lux.UI/Components/Compo/OfferRowMan.razor.cs @@ -381,25 +381,23 @@ namespace Lux.UI.Components.Compo } /// - /// Imposta modalit� edit ciclo di lavoro + /// Imposta modalita edit ciclo di lavoro /// /// protected void DoSwapJobCycle(OfferRowModel currRow) { CurrEditMode = EditMode.JobCycle; - EditRecord = currRow; - CurrBomList = DLService.OffertGetBomList(EditRecord); + selectBom(currRow); } /// - /// Imposta modalit� ad edit BOM + /// Imposta modalita ad edit BOM /// /// protected void DoSwapMat(OfferRowModel currRow) { CurrEditMode = EditMode.BOM; - EditRecord = currRow; - CurrBomList = DLService.OffertGetBomList(EditRecord); + selectBom(currRow); } /// @@ -590,6 +588,7 @@ namespace Lux.UI.Components.Compo #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); + private List AllColors = new(); private List AllConfEnvir = new(); @@ -623,6 +622,31 @@ namespace Lux.UI.Components.Compo private string calcTag = "calc"; + /// + /// Channel update HwOptions + /// + private string chHwOpt = ""; + + /// + /// Channel update PNG + /// + private string chPng = ""; + + /// + /// Channel update Profile List + /// + private string chProfList = ""; + + /// + /// Channel update Shape + /// + private string chShape = ""; + + /// + /// Channel update SVG + /// + private string chSvg = ""; + private List? CurrBomList = null; /// @@ -637,6 +661,7 @@ namespace Lux.UI.Components.Compo private int currPage = 1; private string currPng = ""; + private List currProfList = new List(); private string currSvg = ""; @@ -646,12 +671,12 @@ namespace Lux.UI.Components.Compo /// private OfferRowModel? EditRecord = null; - private string genericBasePath = ""; - /// - /// Channel update HwOptions + /// Abilita edit massivo record ITEM /// - private string chHwOpt = ""; + private bool enableMassEdit = false; + + private string genericBasePath = ""; private string imgBasePath = ""; @@ -671,36 +696,16 @@ namespace Lux.UI.Components.Compo /// private string origJwd = ""; - /// - /// Channel update PNG - /// - private string chPng = ""; - /// /// Versione precedente JWD x test e confronto /// private string prevJwd = ""; - /// - /// Channel update Profile List - /// - private string chProfList = ""; - /// /// Dizionario richieste /// private Dictionary reqDict = new Dictionary(); - /// - /// Channel update Shape - /// - private string chShape = ""; - - /// - /// Channel update SVG - /// - private string chSvg = ""; - private int totalCount = 0; #endregion Private Fields @@ -804,6 +809,34 @@ namespace Lux.UI.Components.Compo isLoading = false; } + /// + /// Restituisce il contenuto del file salvato + /// + /// + /// + /// + private string loadFileContent(string folderPath, string secureName) + { + string answ = ""; + if (!string.IsNullOrEmpty(folderPath)) + { + try + { + // calcolo path file... + string filePath = Path.Combine(basePath, folderPath, secureName); + if (File.Exists(filePath)) + { + answ = File.ReadAllText(filePath); + } + } + catch (Exception exc) + { + Log.Error($"Exception on loadFileContent{Environment.NewLine}{exc}"); + } + } + return answ; + } + /// /// Ricevuto HwOpt, processo /// @@ -1119,6 +1152,7 @@ namespace Lux.UI.Components.Compo case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW: DictExec.Add(serKey, currRec.SerStruct); break; + case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.BEAM: case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WALL: case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.CABINET: @@ -1128,6 +1162,7 @@ namespace Lux.UI.Components.Compo DictExec.Add(serKey, rawData); DictExec.Add("FileName", currRec.FileName); break; + case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.NULL: default: break; @@ -1212,34 +1247,6 @@ namespace Lux.UI.Components.Compo return answ; } - /// - /// Restituisce il contenuto del file salvato - /// - /// - /// - /// - private string loadFileContent(string folderPath, string secureName) - { - string answ = ""; - if (!string.IsNullOrEmpty(folderPath)) - { - try - { - // calcolo path file... - string filePath = Path.Combine(basePath, folderPath, secureName); - if (File.Exists(filePath)) - { - answ = File.ReadAllText(filePath); - } - } - catch (Exception exc) - { - Log.Error($"Exception on loadFileContent{Environment.NewLine}{exc}"); - } - } - return answ; - } - /// /// Salvataggio del JWD aggiornato nella mia riga di offerta /// @@ -1280,6 +1287,21 @@ namespace Lux.UI.Components.Compo } } + /// + /// Selezione e fix dati BOM + /// + /// + /// + private void selectBom(OfferRowModel currRow) + { + EditRecord = currRow; + CurrBomList = DLService.OffertGetBomList(EditRecord); + if (CurrBomList.Any(x => x.ItemID == 0)) + { + CurrBomList = DLService.BomFixItemId(CurrBomList); + } + } + private async Task setAwaitPrice(bool awaitPrice, bool flushCache) { foreach (var item in AllRecords) @@ -1355,6 +1377,16 @@ namespace Lux.UI.Components.Compo // ricalcolo offerta completa await ReloadData(); UpdateTable(); + // rilegge il record da elenco appena rinfrescato... + int offerRowId = EditRecord.OfferRowID; + var updRec = AllRecords.FirstOrDefault(x => x.OfferRowID == offerRowId); + if (updRec != null) + { + CurrBomList = new List(); + // fa refresh dei dati della BOM visualizzata + selectBom(updRec); + await InvokeAsync(StateHasChanged); + } } } diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj index 698fe88b..c7a4515a 100644 --- a/Lux.UI/Lux.UI.csproj +++ b/Lux.UI/Lux.UI.csproj @@ -5,7 +5,7 @@ enable enable aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50 - 0.9.2511.0618 + 0.9.2511.0717 diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index 4510fb8c..e01634c7 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ LUX - Web Windows MES -

Versione: 0.9.2511.0618

+

Versione: 0.9.2511.0717


Note di rilascio:
  • diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index 20e7993e..d27cf9fe 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -0.9.2511.0618 +0.9.2511.0717 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index 2fb0cacd..ef2f082d 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 0.9.2511.0618 + 0.9.2511.0717 http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html false