using EgwCoreLib.Lux.Core.RestPayload; using EgwCoreLib.Lux.Data.DbModel.Config; using EgwCoreLib.Lux.Data.DbModel.Cost; using EgwCoreLib.Lux.Data.DbModel.Items; using EgwCoreLib.Lux.Data.DbModel.Production; using EgwCoreLib.Lux.Data.DbModel.Sales; using EgwCoreLib.Lux.Data.DbModel.Task; using EgwCoreLib.Lux.Data.DbModel.Utils; 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 { internal class LuxController { // manca costruttore parametrico contoller... #region Internal Methods internal async Task> ConfEnvirParamGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetEnvirPar .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ConfEnvirParamGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Esegue eliminazione /// /// /// internal async Task ConfGlassDeleteAsync(GlassModel rec2del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = dbCtx .DbSetConfGlass .Where(x => x.GlassID == rec2del.GlassID) .FirstOrDefault(); // se trovato --> elimino e sposto i rimanenti... if (dbResult != null) { // elimino dbCtx.DbSetConfGlass.Remove(dbResult); // salvo tutto await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante ConfGlassDeleteAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco completo Config Glass /// /// internal async Task> ConfGlassGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetConfGlass .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ConfGlassGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Upsert record ConfGlass /// /// /// internal async Task ConfGlassUpsertAsync(GlassModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetConfGlass .Where(x => upsRec.GlassID > 0 && x.GlassID == upsRec.GlassID) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { currRec.Code = string.IsNullOrEmpty(upsRec.Code) ? $"{upsRec.GlassID:0000}" : upsRec.Code; currRec.Description = upsRec.Description; currRec.Thickness = upsRec.Thickness; dbCtx.Entry(currRec).State = EntityState.Modified; } // se mancasse --> aggiungo else { dbCtx.DbSetConfGlass.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante ConfGlassUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Esegue eliminazione /// /// /// internal async Task ConfProfileDeleteAsync(ProfileModel rec2del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = dbCtx .DbSetConfProfile .Where(x => x.ProfileID == rec2del.ProfileID) .FirstOrDefault(); // se trovato --> elimino e sposto i rimanenti... if (dbResult != null) { // elimino dbCtx.DbSetConfProfile.Remove(dbResult); // salvo tutto await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante ConfProfileDeleteAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco completo Config Profile /// /// internal async Task> ConfProfileGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetConfProfile .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ConfProfileGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Upsert record ConfProfile /// /// /// internal async Task ConfProfileUpsertAsync(ProfileModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetConfProfile .Where(x => upsRec.ProfileID > 0 && x.ProfileID == upsRec.ProfileID) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { currRec.Code = string.IsNullOrEmpty(upsRec.Code) ? $"{upsRec.ProfileID:0000}" : upsRec.Code; currRec.Description = upsRec.Description; currRec.Thickness = upsRec.Thickness; dbCtx.Entry(currRec).State = EntityState.Modified; } // se mancasse --> aggiungo else { dbCtx.DbSetConfProfile.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante ConfProfileUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Esegue eliminazione /// /// /// internal async Task ConfWoodDeleteAsync(WoodModel rec2del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = dbCtx .DbSetConfWood .Where(x => x.WoodID == rec2del.WoodID) .FirstOrDefault(); // se trovato --> elimino e sposto i rimanenti... if (dbResult != null) { // elimino dbCtx.DbSetConfWood.Remove(dbResult); // salvo tutto await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante ConfWoodDeleteAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco completo Config Wood /// /// internal async Task> ConfWoodGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetConfWood .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ConfWoodGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Upsert record ConfWood /// /// /// internal async Task ConfWoodUpsertAsync(WoodModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetConfWood .Where(x => upsRec.WoodID > 0 && x.WoodID == upsRec.WoodID) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { currRec.Code = string.IsNullOrEmpty(upsRec.Code) ? $"{upsRec.WoodID:0000}" : upsRec.Code; currRec.Description = upsRec.Description; currRec.Type = upsRec.Type; dbCtx.Entry(currRec).State = EntityState.Modified; } // se mancasse --> aggiungo else { dbCtx.DbSetConfWood.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante ConfWoodUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco CostDrivers /// /// internal async Task> CostDriverGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetCostDriver .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante CostDriverGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco completo Customers da DB /// /// internal List CustomersGetAll() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetCustomer .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante CustomersGetAll{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco completo Dealers da DB /// /// internal List DealersGetAll() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetDealer .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante DealersGetAll{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Esegue eliminazione /// /// /// internal async Task GenClassDeleteAsync(GenClassModel rec2del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = dbCtx .DbSetGenClass .Where(x => x.ClassCod == rec2del.ClassCod) .FirstOrDefault(); var numChild = dbCtx .DbSetGenVal .Count(x => x.ClassCod == rec2del.ClassCod); // se trovato e NON HA record child --> elimino if (dbResult != null && numChild == 0) { dbCtx.DbSetGenClass.Remove(dbResult); await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante GenClassDeleteAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco completo GenClass /// /// internal async Task> GenClassGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetGenClass .Include(o => o.GenValNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante GenClassGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Upsert record GenClass /// /// /// internal async Task GenClassUpsertAsync(GenClassModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetGenClass .Where(x => x.ClassCod == upsRec.ClassCod) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { currRec.Description = upsRec.Description; dbCtx.Entry(currRec).State = EntityState.Modified; } // se mancasse --> aggiungo else { dbCtx.DbSetGenClass.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante GenClassUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Esegue eliminazione /// /// /// internal async Task GenValDeleteAsync(GenValueModel rec2del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = dbCtx .DbSetGenVal .Where(x => x.GenValID == rec2del.GenValID) .FirstOrDefault(); // se trovato --> elimino e sposto i rimanenti... if (dbResult != null) { // modifico record successivi... var list2Move = dbCtx .DbSetGenVal .Where(x => x.ClassCod == rec2del.ClassCod && x.Index > dbResult.Index) .ToList(); foreach (var item in list2Move) { item.Index--; dbCtx.Entry(item).State = EntityState.Modified; } // elimino dbCtx.DbSetGenVal.Remove(dbResult); // salvo tutto await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante GenValDeleteAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco valori x classe richiesta /// /// /// internal async Task> GenValGetFiltAsync(string codClass) { List dbResult = new List(); if (!string.IsNullOrEmpty(codClass)) { //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetGenVal .Where(x => x.ClassCod == codClass) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante GenValGetFiltAsync{Environment.NewLine}{exc}"); } } } return dbResult; } /// /// Esegue spostamento nell'ordinamento relativo alla classe /// NB: verifica spostamento sia ammissibile: se primo rec non "sale", se ultimo non "scende"... /// /// /// /// internal async Task GenValMoveAsync(GenValueModel selRec, bool moveUp) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetGenVal .Where(x => x.GenValID == selRec.GenValID) .FirstOrDefault(); if (currRec != null) { // recupero info del num rec del suo gruppo int numRec = dbCtx .DbSetGenVal .Count(x => x.ClassCod == selRec.ClassCod); // verifico NON sia primo/ultimo... bool canMove = false; int newPos = moveUp ? currRec.Index - 1 : currRec.Index + 1; if (moveUp) { canMove = newPos > 0; } else { canMove = newPos <= numRec; } // se abilitato --> aggiorno i 2 record... if (canMove) { var otherRec = dbCtx .DbSetGenVal .Where(x => x.ClassCod == selRec.ClassCod && x.Index == newPos) .FirstOrDefault(); if (otherRec != null) { otherRec.Index = currRec.Index; dbCtx.Entry(otherRec).State = EntityState.Modified; currRec.Index = newPos; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } } } catch (Exception exc) { Log.Error($"Eccezione durante GenValMoveAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Esegue Upsert del record ricevuto /// /// /// internal async Task GenValUpsertAsync(GenValueModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetGenVal .Where(x => x.GenValID == upsRec.GenValID) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { currRec.ValString = upsRec.ValString; dbCtx.Entry(currRec).State = EntityState.Modified; } // se mancasse --> aggiungo else { dbCtx.DbSetGenVal.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante GenValUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Eliminazione record item /// /// /// internal async Task ItemDeleteAsync(ItemModel rec2del) { bool result = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = await dbCtx .DbSetItem .Where(x => x.ItemID == rec2del.ItemID) .FirstOrDefaultAsync(); if (dbResult != null) { dbCtx.DbSetItem.Remove(dbResult); await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante ItemDeleteAsync{Environment.NewLine}{exc}"); } } return result; } /// /// Elenco completo Items /// /// internal List ItemGetAll() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetItem .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetAll{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco item alternativi da ID di un record (per sostituzione) /// /// ID item corrente (valido quindi >0) /// internal List ItemGetAlt(int ItemId) { List dbResult = new List(); if (ItemId > 0) { //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // cerco singolo record x partire... var currRec = dbCtx .DbSetItem .Where(x => x.ItemID == ItemId) .FirstOrDefault(); if ((currRec != null)) { // se è un record che ha parentId > 0 --> cerco da quello record analoghi + parent if (currRec.ItemIDParent > 0) { dbResult = dbCtx .DbSetItem .Where(x => x.ItemID == currRec.ItemIDParent || x.ItemIDParent == currRec.ItemIDParent) .ToList(); } // altrimenti cerco child collegati else { dbResult = dbCtx .DbSetItem .Where(x => x.ItemID == currRec.ItemID || x.ItemIDParent == currRec.ItemID) .ToList(); } } } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetAlt{Environment.NewLine}{exc}"); } } } return dbResult; } /// /// Elenco item da ricerca filtro x gruppo/tipo /// /// /// /// internal List ItemGetFilt(string CodGroup, ItemClassType ItemType) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetItem .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) && (ItemType == ItemClassType.ND || x.ItemType == ItemType)) .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetFilt{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco item da ricerca completa /// /// /// /// /// internal List ItemGetFilt(string CodGroup, ItemClassType ItemType, string SearchVal) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetItem .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) && (ItemType == ItemClassType.ND || x.ItemType == ItemType) && (string.IsNullOrEmpty(SearchVal) || x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) ) .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetFilt{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco item da ricerca filtro x gruppo/tipo Async /// /// /// /// /// internal async Task> ItemGetFiltAsync(string CodGroup, ItemClassType ItemType) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetItem .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) && (ItemType == ItemClassType.ND || x.ItemType == ItemType)) .Include(g => g.ItemGroupNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetFiltAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco item da ricerca completa Async /// /// /// /// /// internal async Task> ItemGetFiltAsync(string CodGroup, ItemClassType ItemType, string SearchVal) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetItem .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) && (ItemType == ItemClassType.ND || x.ItemType == ItemType) && (string.IsNullOrEmpty(SearchVal) || x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) ) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetFiltAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco item da ricerca /// /// /// internal List ItemGetSearch(string SearchVal) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetItem .Where(x => x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetSearch{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco item da ricerca async /// /// /// internal async Task> ItemGetSearchAsync(string SearchVal) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetItem .Where(x => x.Description.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.ExtItemCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.SupplCode.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetSearchAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco completo ItemGroup gestiti /// /// internal List ItemGroupGetAll() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetItemGroup .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGroupGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco completo ItemGroup gestiti async /// /// internal async Task> ItemGroupGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetItemGroup .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGroupGetAllAsync{Environment.NewLine}{exc}"); } } 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; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetItem .Where(x => x.ItemID == newRec.ItemID) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { currRec.Description = newRec.Description; currRec.SupplCode = newRec.SupplCode; currRec.ItemCode = newRec.ItemCode; currRec.Cost = newRec.Cost; currRec.Description = newRec.Description; currRec.IsService = newRec.IsService; currRec.Margin = newRec.Margin; dbCtx.Entry(currRec).State = EntityState.Modified; } // se mancasse --> aggiungo else { dbCtx.DbSetItem.Add(newRec); } // salvo... dbCtx.SaveChanges(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemGetSearch{Environment.NewLine}{exc}"); } } return answ; } /// /// Inserisce o aggiorna il record /// /// /// internal async Task ItemUpsertAsync(ItemModel currRec) { bool result = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = await dbCtx .DbSetItem .Where(x => x.ItemID == currRec.ItemID) .FirstOrDefaultAsync(); if (dbResult != null) { //dbCtx.DbSetItem.Remove(dbResult); dbResult.CodGroup = currRec.CodGroup; dbResult.ItemType = currRec.ItemType; dbResult.IsService = currRec.IsService; dbResult.ItemCode = currRec.ItemCode; dbResult.ExtItemCode = currRec.ExtItemCode; dbResult.Cost = currRec.Cost; dbResult.Margin = currRec.Margin; dbResult.Description = currRec.Description; dbResult.QtyMin = currRec.QtyMin; dbResult.QtyMax = currRec.QtyMax; dbResult.UM = currRec.UM; dbCtx.Entry(dbResult).State = EntityState.Modified; } else { dbCtx.DbSetItem.Add(currRec); } await dbCtx.SaveChangesAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemUpsertAsync{Environment.NewLine}{exc}"); } } return result; } /// /// Upsert item ricevuti da BOM calcolata /// /// /// internal bool ItemUpsertFromBom(List bomList) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { 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(); // ciclo x ogni elemento della BOM, cercando x gruppo e ExtItemCode foreach (var item in item2save) { var currRec = dbCtx .DbSetItem .Where(x => x.CodGroup == item.ClassCode && x.ExtItemCode == item.ItemCode) .FirstOrDefault(); // se nullo --> verifico x inserire!!! if (currRec == null) { // 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() { CodGroup = item.ClassCode, ItemType = Core.Enums.ItemClassType.Bom, IsService = false, // da calcolare meglio x gruppo ItemCode = 0, ExtItemCode = item.ItemCode, SupplCode = "BOM ITEM", Description = $"BOM | {item.ClassCode} | {item.ItemCode}", Cost = 0, Margin = 0, QtyMin = 0, QtyMax = 0, UM = "#" }; dbCtx.DbSetItem.Add(newRec); listInserted.Add(newRec); } } } // salvo... dbCtx.SaveChanges(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemUpsertFromBom{Environment.NewLine}{exc}"); } } return answ; } /// /// Eliminazione record richiesto /// /// /// internal async Task JobStepDeleteAsync(JobStepModel rec2del) { bool result = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = await dbCtx .DbSetJobStep .Where(x => x.JobStepID == rec2del.JobStepID) .FirstOrDefaultAsync(); if (dbResult != null) { // cerco righe successive var list2move = dbCtx .DbSetJobStep .Where(x => x.JobID == rec2del.JobID && x.Index > dbResult.Index) .ToList(); // se ci sono aggiorno! if (list2move != null && list2move.Count > 0) { foreach (var item in list2move) { item.Index--; dbCtx.Entry(item).State = EntityState.Modified; } } // elimino record dbCtx.DbSetJobStep.Remove(dbResult); await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante JobStepDeleteAsync{Environment.NewLine}{exc}"); } } return result; } /// /// Elenco JobStep dato JobID parent /// /// /// internal async Task> JobStepGetAsync(int jobID) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetJobStep .Where(x => x.JobID == jobID) .Include(c => c.JobNav) .Include(c => c.PhaseNav) .Include(c => c.ResourceNav) .Include(c => c.TagNav) .Include(c => c.ResourceNav.DriverNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante JobStepGetAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Esegue spostamento nell'ordinamento /// NB: verifica spostamento sia ammissibile: se primo rec non "sale", se ultimo non "scende"... /// /// /// /// internal async Task JobStepMoveAsync(JobStepModel selRec, bool moveUp) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetJobStep .Where(x => x.JobStepID == selRec.JobStepID) .FirstOrDefault(); if (currRec != null) { // recupero info del num rec del suo gruppo int numRec = dbCtx .DbSetJobStep .Where(x => x.JobID == selRec.JobID) .Count(); // verifico NON sia primo/ultimo... bool canMove = false; int newPos = moveUp ? currRec.Index - 1 : currRec.Index + 1; if (moveUp) { canMove = newPos > 0; } else { canMove = newPos <= numRec; } // se abilitato --> aggiorno i 2 record... if (canMove) { var otherRec = dbCtx .DbSetJobStep .Where(x => x.Index == newPos) .FirstOrDefault(); if (otherRec != null) { otherRec.Index = currRec.Index; dbCtx.Entry(otherRec).State = EntityState.Modified; currRec.Index = newPos; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } } } catch (Exception exc) { Log.Error($"Eccezione durante JobStepMoveAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert record /// /// /// internal async Task JobStepUpsertAsync(JobStepModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetJobStep .Where(x => x.JobStepID == upsRec.JobStepID && upsRec.JobStepID > 0) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { dbCtx.Entry(currRec).CurrentValues.SetValues(upsRec); } // se mancasse --> aggiungo else { dbCtx.DbSetJobStep.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante JobStepUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert dell'elenco dei tags associati /// /// ID Job richiesto /// Elenco Tags richiesto /// internal async Task JobTask2TagsUpsertAsync(int JobID, List reqTagList) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetJobTask .Where(x => x.JobID == JobID) .Include(t => t.TagNav) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { var currentTags = currRec.TagNav.Select(t => t.CodTag).ToList(); // calcolo modifiche var toAdd = reqTagList.Except(currentTags).ToList(); var toRemove = currentTags.Except(reqTagList).ToList(); // aggiunte foreach (var tag in toAdd) { currRec.TagNav.Add(new JobTaskTagModel { JobID = JobID, CodTag = tag }); } // rimozioni foreach (var tag in toRemove) { var entity = currRec.TagNav.FirstOrDefault(t => t.CodTag == tag); if (entity != null) dbCtx.Remove(entity); } dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante JobTask2TagsUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Eliminazione record richiesto /// /// /// internal async Task JobTaskDeleteAsync(JobTaskModel rec2del) { bool result = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var dbResult = await dbCtx .DbSetJobTask .Where(x => x.JobID == rec2del.JobID) .FirstOrDefaultAsync(); if (dbResult != null) { // cerco righe successive var list2move = dbCtx .DbSetJobTask .Where(x => x.Index > dbResult.Index) .ToList(); // se ci sono aggiorno! if (list2move != null && list2move.Count > 0) { foreach (var item in list2move) { item.Index--; dbCtx.Entry(item).State = EntityState.Modified; } } dbCtx.DbSetJobTask.Remove(dbResult); await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante JobTaskDeleteAsync{Environment.NewLine}{exc}"); } } return result; } /// /// Recupera elenco Jobs (conf) da DB /// /// internal async Task> JobTaskGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetJobTask .Include(c => c.TagNav) .Include(c => c.JobStepNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante JobTaskGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Esegue spostamento nell'ordinamento /// NB: verifica spostamento sia ammissibile: se primo rec non "sale", se ultimo non "scende"... /// /// /// /// internal async Task JobTaskMoveAsync(JobTaskModel selRec, bool moveUp) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetJobTask .Where(x => x.JobID == selRec.JobID) .FirstOrDefault(); if (currRec != null) { // recupero info del num rec del suo gruppo int numRec = dbCtx .DbSetJobTask .Count(); // verifico NON sia primo/ultimo... bool canMove = false; int newPos = moveUp ? currRec.Index - 1 : currRec.Index + 1; if (moveUp) { canMove = newPos > 0; } else { canMove = newPos <= numRec; } // se abilitato --> aggiorno i 2 record... if (canMove) { var otherRec = dbCtx .DbSetJobTask .Where(x => x.Index == newPos) .FirstOrDefault(); if (otherRec != null) { otherRec.Index = currRec.Index; dbCtx.Entry(otherRec).State = EntityState.Modified; currRec.Index = newPos; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } } } catch (Exception exc) { Log.Error($"Eccezione durante JobTaskMoveAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert record /// /// /// internal async Task JobTaskUpsertAsync(JobTaskModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetJobTask .Where(x => x.JobID == upsRec.JobID) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { dbCtx.Entry(currRec).CurrentValues.SetValues(upsRec); } // se mancasse --> aggiungo else { dbCtx.DbSetJobTask.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante JobTaskUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Esegue il cloning completo di un offerta e di TUTTE le relative righe di offerta... /// /// /// internal async Task OfferClone(OfferModel rec2clone) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { DateTime adesso = DateTime.Now; // recupero offerta... var currRec = dbCtx .DbSetOffer .Where(x => x.OfferID == rec2clone.OfferID) .Include(x => x.OfferRowNav) .FirstOrDefault(); // ultimo record OFFERTA x calcolo refNum var lastRec = dbCtx .DbSetOffer .Where(x => x.RefYear == adesso.Year) .OrderByDescending(x => x.RefNum) .FirstOrDefault(); int newRefNum = lastRec != null ? lastRec.RefNum + 1 : 1; // se trovo --> duplico! if (currRec != null) { // recupero ultimo num offerta dell'anno corrente... OfferModel newRec = new OfferModel() { ConsNote = rec2clone.ConsNote, CustomerID = rec2clone.CustomerID, DealerID = rec2clone.DealerID, Description = rec2clone.Description, DictPresel = rec2clone.DictPresel, Discount = rec2clone.Discount, DueDateProm = rec2clone.DueDateProm, DueDateReq = rec2clone.DueDateReq, Envir = rec2clone.Envir, Inserted = adesso, Modified = adesso, OffertState = OfferStates.Open, RefNum = newRefNum, RefRev = 1, RefYear = adesso.Year, ValidUntil = currRec.ValidUntil }; // sistemo child... newRec.OfferRowNav = currRec.OfferRowNav .Select(c => new OfferRowModel() { AwaitBom = c.AwaitBom, AwaitPrice = c.AwaitPrice, BomCost = c.BomCost, BomOk = c.BomOk, BomPrice = c.BomPrice, Envir = c.Envir, FileName = c.FileName, FileResource = c.FileResource, FileSize = c.FileSize, Inserted = adesso, ItemBOM = c.ItemBOM, ItemJCD = c.ItemJCD, ItemOk = c.ItemOk, ItemSteps = c.ItemSteps, ItemTags = c.ItemTags, JobID = c.JobID, Modified = c.Modified, Note = c.Note, ProdItemQty = c.ProdItemQty, Qty = c.Qty, RowNum = c.RowNum, SellingItemID = c.SellingItemID, SerStruct = c.SerStruct, StepCost = c.StepCost, StepFlowTime = c.StepFlowTime, StepLeadTime = c.StepLeadTime, StepPrice = c.StepPrice, //OrderID = dbRec.OrderID, OfferRowUID = c.OfferRowDtx }) .ToList(); // infine aggiungo riga ordine e relativi child dbCtx.DbSetOffer.Add(newRec); } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OfferClone{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco completo offerte da DB /// /// internal async Task> OfferGetAll() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetOffer .Include(c => c.CustomerNav) .Include(d => d.DealerNav) .Include(o => o.OfferRowNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante OfferGetAll{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco offerte da DB filtrate x periodo e stato /// /// /// /// internal async Task> OfferGetFilt(DateTime inizio, DateTime fine) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetOffer .Where(x => x.Inserted >= inizio && x.Inserted <= fine) .Include(c => c.CustomerNav) .Include(d => d.DealerNav) .Include(o => o.OfferRowNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante OfferGetFilt{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco righe offerta specificata /// /// /// internal List OfferRowGetByOffer(int OfferID) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetOfferRow .Where(x => x.OfferID == OfferID) .Include(s => s.SellingItemNav) //.Include(d => d.DealerNav) .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante OfferRowGetByOffer{Environment.NewLine}{exc}"); } } return dbResult; } internal async Task OffersCheckExpired() { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { DateTime adesso = DateTime.Now; // recupero offerta... var listExpired = dbCtx .DbSetOffer .Where(x => x.ValidUntil < adesso && x.OffertState == OfferStates.Open) .ToList(); // se trovo le aggiorno come stato if (listExpired != null) { foreach (var item in listExpired) { item.OffertState = OfferStates.Expired; dbCtx.Entry(item).State = EntityState.Modified; } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } } catch (Exception exc) { Log.Error($"Eccezione durante OffersCheckExpired{Environment.NewLine}{exc}"); } } return answ; } /// Elimina riga e sposta eventuali righe successive... /// /// /// internal async Task OffertRowDelete(OfferRowModel rec2Del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero offerta... var currRec = dbCtx .DbSetOfferRow .Where(x => x.OfferRowID == rec2Del.OfferRowID) .FirstOrDefault(); // se non trovo aggiungo if (currRec != null) { // recupero indice attuale... int currRowNum = rec2Del.RowNum; // cerco righe successive var list2move = dbCtx .DbSetOfferRow .Where(x => x.OfferID == rec2Del.OfferID && x.RowNum > currRowNum) .ToList(); // se ci sono aggiorno! if (list2move != null && list2move.Count > 0) { foreach (var item in list2move) { item.RowNum--; dbCtx.Entry(item).State = EntityState.Modified; } } // infine rimuovo riga dbCtx.DbSetOfferRow.Remove(currRec); } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertRowDelete{Environment.NewLine}{exc}"); } } return answ; } /// /// Aggiornamento valore UID non calcolato + ritorno elenco UID da aggiornare /// /// /// internal List OffertRowFixUid(int offertID) { List answ = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currList = dbCtx .DbSetOfferRow .Where(x => x.OfferID == offertID) .ToList(); // se trovato --> verifico valori differenti, aggiorno e restituisco da calcolare if (currList != null) { var list2fix = currList.Where(x => string.IsNullOrEmpty(x.OfferRowUID) || x.OfferRowUID != x.OfferRowDtx).ToList(); if (list2fix != null && list2fix.Count > 0) { // salvo elenco answ = list2fix.Select(x => x.OfferRowDtx).ToList(); // sistemo UID foreach (var item in list2fix) { item.OfferRowUID = item.OfferRowDtx; dbCtx.Entry(item).State = EntityState.Modified; } // salvo... var result = dbCtx.SaveChanges(); } } } catch (Exception exc) { Log.Error($"Eccezione durante OffertRowFixUid{Environment.NewLine}{exc}"); } } return answ; } /// /// Effettua update dei costi di tutte le righe dell'offerta indicata /// /// ID riga offerta da aggiornare /// Bom aggiornata da salvare /// internal async Task OffertRowUpdateBom(int OfferRowID, List newBomList) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero riga offerta da aggiornare... var currRec = dbCtx .DbSetOfferRow .Where(x => x.OfferRowID == OfferRowID) .FirstOrDefault(); // se è valida --> procedo! if (currRec != null) { // recupero l'elenco degli itemGroup gestiti var itemGroupList = dbCtx .DbSetItemGroup .ToList(); // recupero il subset item da BOM / BomAlt... var bomGenList = dbCtx .DbSetItem .Where(x => (x.ItemType == Core.Enums.ItemClassType.Bom || x.ItemType == Core.Enums.ItemClassType.BomAlt)) .ToList(); // calcolo il NUOVO costo e lo aggiorno... double totCost = 0; double totPrice = 0; int totItemQty = 0; int numGroupOk = 0; int numItemOk = 0; int numElems = newBomList.Count; // validazione e completamento BOM validateBom(itemGroupList, bomGenList, ref newBomList, null, ref totCost, ref totPrice, ref totItemQty, ref numGroupOk, ref numItemOk); // salvo BOM... string itemBom = JsonConvert.SerializeObject(newBomList); currRec.ItemBOM = itemBom; // salvo arrotondato alla 3° decimale currRec.BomCost = Math.Round(totCost, 3); currRec.BomPrice = Math.Round(totPrice, 3); currRec.BomOk = numElems == numGroupOk; currRec.ItemOk = numElems == numItemOk; currRec.ProdItemQty = totItemQty; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo modifiche... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertRowUpdateBom{Environment.NewLine}{exc}"); } } return answ; } /// /// Aggiorno sul DB i dati del file associato /// /// /// internal async Task OffertRowUpdateFileData(OfferRowModel updRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero righe offerta... var currRec = dbCtx .DbSetOfferRow .Where(x => x.OfferRowID == updRec.OfferRowID) .FirstOrDefault(); // aggiorno parametri (se inviati) if (currRec != null) { currRec.FileName = updRec.FileName; currRec.FileResource = updRec.FileResource; currRec.FileSize = updRec.FileSize; currRec.SerStruct = updRec.SerStruct; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertRowUpdateFileData{Environment.NewLine}{exc}"); } } return answ; } /// /// Effettua update serStruct per l'offerta indicata /// /// ID singola riga offerta /// Valore serializzatoe /// internal async Task OffertRowUpdateSerStruct(int offerRowID, string serStruct) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero righe offerta... var currRec = dbCtx .DbSetOfferRow .Where(x => x.OfferRowID == offerRowID) .FirstOrDefault(); // aggiorno parametri (se inviati) if (currRec != null) { currRec.SerStruct = serStruct; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertRowUpdateSerStruct{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert record riga offerta /// /// /// internal async Task OffertRowUpsert(OfferRowModel updRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero offerta... var currRec = dbCtx .DbSetOfferRow .Where(x => x.OfferRowID == updRec.OfferRowID) .FirstOrDefault(); // se non trovo aggiungo if (currRec == null) { dbCtx.DbSetOfferRow.Add(updRec); // se ci sono record successivi li devo spostare... var list2move = dbCtx .DbSetOfferRow .Where(x => x.OfferID == updRec.OfferID && x.RowNum >= updRec.RowNum) .ToList(); if (list2move != null && list2move.Count > 0) { foreach (var item2move in list2move) { item2move.RowNum++; dbCtx.Entry(item2move).State = EntityState.Modified; } } } // altrimenti aggiorno else { dbCtx.Entry(currRec).CurrentValues.SetValues(updRec); } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertRowUpsert{Environment.NewLine}{exc}"); } } return answ; } /// /// Effettua update stato await BOM/PRICE per l'offerta indicata /// /// ID singola riga offerta /// Se non nullo è il nuovo stato await BOM /// Se non nullo è stato await Price /// internal async Task OffertUpdateAwaitState(int offerRowID, bool? awaitBom, bool? awaitPrice) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero righe offerta... var currRec = dbCtx .DbSetOfferRow .Where(x => x.OfferRowID == offerRowID) .FirstOrDefault(); // aggiorno parametri (se inviati) if (currRec != null) { currRec.AwaitBom = awaitBom ?? currRec.AwaitBom; currRec.AwaitPrice = awaitPrice ?? currRec.AwaitPrice; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertUpdateAwaitState{Environment.NewLine}{exc}"); } } return answ; } /// /// Effettua update dei costi di tutte le righe dell'offerta indicata /// /// /// internal async Task OffertUpdateCost(int OfferID) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero righe offerta... var offRowList = dbCtx .DbSetOfferRow .Where(x => x.OfferID == OfferID) .ToList(); // recupero l'elenco degli itemGroup gestiti var itemGroupList = dbCtx .DbSetItemGroup .ToList(); // recupero il subset item da BOM / BomAlt... var bomGenList = dbCtx .DbSetItem .Where(x => (x.ItemType == Core.Enums.ItemClassType.Bom || x.ItemType == Core.Enums.ItemClassType.BomAlt)) .ToList(); // ciclo! foreach (var currRec in offRowList) { // se contiene qualcosa x BOM... if (!string.IsNullOrEmpty(currRec.ItemBOM) && currRec.ItemBOM.Length > 2) { // deserializzo var bomList = JsonConvert.DeserializeObject>(currRec.ItemBOM); // se ho trovato elementi... if (bomList != null) { // calcolo il NUOVO costo e lo aggiorno... double totCost = 0; double totPrice = 0; int totItemQty = 0; int numGroupOk = 0; int numItemOk = 0; int numElems = bomList.Count; // validazione e completamento BOM validateBom(itemGroupList, bomGenList, ref bomList, null, ref totCost, ref totPrice, ref totItemQty, ref numGroupOk, ref numItemOk); // salvo BOM... string itemBom = JsonConvert.SerializeObject(bomList); currRec.ItemBOM = itemBom; // salvo arrotondato alla 3° decimale currRec.BomCost = Math.Round(totCost, 3); currRec.BomPrice = Math.Round(totPrice, 3); currRec.BomOk = numElems == numGroupOk; currRec.ItemOk = numElems == numItemOk; currRec.ProdItemQty = totItemQty; dbCtx.Entry(currRec).State = EntityState.Modified; } } } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertUpdateCost{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert record offerta /// /// /// internal async Task OffertUpsert(OfferModel updRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero offerta... var currRec = dbCtx .DbSetOffer .Where(x => x.OfferID == updRec.OfferID) .FirstOrDefault(); // se non trovo aggiungo if (currRec == null) { dbCtx.DbSetOffer.Add(updRec); } // altrimenti aggiorno else { dbCtx.Entry(currRec).CurrentValues.SetValues(updRec); } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OffertUpsert{Environment.NewLine}{exc}"); } } return answ; } /// /// Esegue upsert del record offerta data la BOM ricevuta /// /// /// internal bool OfferUpsertFromBom(string uID, List bomList) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetOfferRow .Where(x => x.OfferRowUID == uID) .FirstOrDefault(); // se trovato --> salvo BOM e calcolo costi if (currRec != null) { // recupero l'elenco degli itemGroup gestiti var itemGroupList = dbCtx .DbSetItemGroup .ToList(); // recupero il subset item da BOM... var bomGenList = dbCtx .DbSetItem //.Where(x => x.ItemType == Core.Enums.ItemClassType.Bom) .Where(x => (x.ItemType == Core.Enums.ItemClassType.Bom || x.ItemType == Core.Enums.ItemClassType.BomAlt)) .ToList(); // recupero la BOM list precedente var bomListPrev = JsonConvert.DeserializeObject>(currRec.ItemBOM); // calcolo il NUOVO costo e lo aggiorno... double totCost = 0; double totPrice = 0; int totItemQty = 0; int numGroupOk = 0; int numItemOk = 0; int numElems = bomList.Count; // validazione e completamento BOM validateBom(itemGroupList, bomGenList, ref bomList, bomListPrev, ref totCost, ref totPrice, ref totItemQty, ref numGroupOk, ref numItemOk); // salvo BOM... string itemBom = JsonConvert.SerializeObject(bomList); currRec.ItemBOM = itemBom; // salvo arrotondato alla 3° decimale currRec.BomCost = Math.Round(totCost, 3); currRec.BomPrice = Math.Round(totPrice, 3); currRec.BomOk = numElems == numGroupOk; currRec.ItemOk = numElems == numItemOk; // setto ok await di BOM e Price currRec.AwaitBom = false; currRec.AwaitPrice = false; currRec.ProdItemQty = totItemQty; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo... var result = dbCtx.SaveChanges(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OfferUpsertFromBom{Environment.NewLine}{exc}"); } } return answ; } /// /// Restituisce record ordine + righe Ordine dato ID /// /// /// internal async Task OrderById(int orderId) { OrderModel? dbRec = null; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { DateTime adesso = DateTime.Now; // recupero offerta... var currRec = dbCtx .DbSetOrder .Where(x => x.OrderID == orderId) .Include(x => x.OrderRowNav) .FirstOrDefault(); } catch (Exception exc) { Log.Error($"Eccezione durante OrderById{Environment.NewLine}{exc}"); } } return dbRec; } /// /// Genera un nuovo record ordine come cloning completo di un offerta e di TUTTE le relative righe di offerta + rif offerta /// /// /// internal async Task OrderFromOffer(OfferModel rec2clone) { int orderId = 0; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { OrderModel? newRec = null; try { DateTime adesso = DateTime.Now; // recupero offerta... var currRec = dbCtx .DbSetOffer .Where(x => x.OfferID == rec2clone.OfferID) .Include(x => x.OfferRowNav) .FirstOrDefault(); // ultimo record ORDINE x calcolo refNum var lastRec = dbCtx .DbSetOrder .Where(x => x.RefYear == adesso.Year) .OrderByDescending(x => x.RefNum) .FirstOrDefault(); int newRefNum = lastRec != null ? lastRec.RefNum + 1 : 1; // se trovo --> duplico! if (currRec != null) { // recupero ultimo num offerta dell'anno corrente... newRec = new OrderModel() { ConsNote = rec2clone.ConsNote, CustomerID = rec2clone.CustomerID, DealerID = rec2clone.DealerID, Description = rec2clone.Description, DictPresel = rec2clone.DictPresel, Discount = rec2clone.Discount, DueDateProm = rec2clone.DueDateProm, DueDateReq = rec2clone.DueDateReq, Envir = rec2clone.Envir, Inserted = adesso, Modified = adesso, OfferID = rec2clone.OfferID, OrderState = OrderStates.Created, RefNum = newRefNum, RefRev = 1, RefYear = adesso.Year, ValidUntil = currRec.ValidUntil }; // sistemo child offer... newRec.OrderRowNav = currRec.OfferRowNav .Select(c => new OrderRowModel() { AwaitBom = c.AwaitBom, AwaitPrice = c.AwaitPrice, BomCost = c.BomCost, BomOk = c.BomOk, BomPrice = c.BomPrice, Envir = c.Envir, FileName = c.FileName, FileResource = c.FileResource, FileSize = c.FileSize, Inserted = adesso, ItemBOM = c.ItemBOM, ItemJCD = c.ItemJCD, ItemOk = c.ItemOk, ItemSteps = c.ItemSteps, ItemTags = c.ItemTags, JobID = c.JobID, Modified = c.Modified, Note = c.Note, ProdItemQty = c.ProdItemQty, Qty = c.Qty, RowNum = c.RowNum, SellingItemID = c.SellingItemID, SerStruct = c.SerStruct, StepCost = c.StepCost, StepFlowTime = c.StepFlowTime, StepLeadTime = c.StepLeadTime, StepPrice = c.StepPrice }) .ToList(); // infine aggiungo riga ordine e relativi child dbCtx.DbSetOrder.Add(newRec); } // salvo TUTTI i cambiamenti... var numSave = await dbCtx.SaveChangesAsync(); // se ok sistemo UID... if (numSave > 0 && newRec != null) { orderId = newRec.OrderID; // sistemo UID... foreach (var item in newRec.OrderRowNav) { item.OrderRowUID = item.OrderRowCode; // alternativa da valutare.. if (false) { // genero tanti record collegati alla riga d'ordine... for (int i = 0; i < item.ProdItemQtyTot; i++) { var child = new ProductionItemModel { OrderRowID = item.OrderRowID, //OrderRowNav = item, ItemCode = i + 1, ExtItemCode = $"{item.OrderRowCode}-{i + 1:000}", ProductionBatchID = null }; // aggiungo record item.ProdItemNav.Add(child); } } else { item.ProdItemNav = Enumerable.Range(1, (int)item.ProdItemQtyTot) .Select(i => new ProductionItemModel { //OrderRowID = item.OrderRowID, OrderRowNav = item, ItemCode = i, ExtItemCode = $"{item.OrderRowCode}-{i:000}", ProductionBatchID = null }) .ToList(); } dbCtx.Entry(item).State = EntityState.Modified; } // salvo ulteriori variazioni await dbCtx.SaveChangesAsync(); } } catch (Exception exc) { Log.Error($"Eccezione durante OrderFromOffer{Environment.NewLine}{exc}"); } } return orderId; } /// /// Ordini da DB filtrati x periodo /// /// /// /// internal async Task> OrderGetFilt(DateTime inizio, DateTime fine) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetOrder .Where(x => x.Inserted >= inizio && x.Inserted <= fine) .Include(c => c.CustomerNav) .Include(d => d.DealerNav) .Include(o => o.OrderRowNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante OrderGetFilt{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elimina riga e sposta eventuali righe successive... /// /// /// internal async Task OrderRowDelete(OrderRowModel rec2Del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero offerta... var currRec = dbCtx .DbSetOrderRow .Where(x => x.OrderRowID == rec2Del.OrderRowID) .FirstOrDefault(); // se trovo procedo if (currRec != null) { // recupero indice attuale... int currRowNum = rec2Del.RowNum; // cerco righe successive var list2move = dbCtx .DbSetOrderRow .Where(x => x.OrderID == rec2Del.OrderID && x.RowNum > currRowNum) .ToList(); // se ci sono aggiorno! if (list2move != null && list2move.Count > 0) { foreach (var item in list2move) { item.RowNum--; dbCtx.Entry(item).State = EntityState.Modified; } } // infine rimuovo riga dbCtx.DbSetOrderRow.Remove(currRec); } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowDelete{Environment.NewLine}{exc}"); } } return answ; } /// /// Aggiornamento valore UID non calcolato + ritorno elenco UID da aggiornare /// /// /// internal List OrderRowFixUid(int orderID) { List answ = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currList = dbCtx .DbSetOrderRow .Where(x => x.OrderID == orderID) .ToList(); // se trovato --> verifico valori differenti, aggiorno e restituisco da calcolare if (currList != null) { var list2fix = currList.Where(x => string.IsNullOrEmpty(x.OrderRowUID) || x.OrderRowUID != x.OrderRowCode).ToList(); if (list2fix != null && list2fix.Count > 0) { // salvo elenco answ = list2fix.Select(x => x.OrderRowCode).ToList(); // sistemo UID foreach (var item in list2fix) { item.OrderRowUID = item.OrderRowCode; dbCtx.Entry(item).State = EntityState.Modified; } // salvo... var result = dbCtx.SaveChanges(); } } } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowFixUid{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco righe Ordine specificato /// /// /// internal List OrderRowGetByOffer(int OrderID) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = dbCtx .DbSetOrderRow .Where(x => x.OrderID == OrderID) .Include(s => s.SellingItemNav) //.Include(d => d.DealerNav) .ToList(); } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowGetByOffer{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Effettua update stato await BOM/PRICE per l'Ordine indicato /// /// ID singola riga ordine /// Se non nullo è il nuovo stato await BOM /// Se non nullo è stato await Price /// internal async Task OrderRowUpdateAwaitState(int orderRowID, bool? awaitBom, bool? awaitPrice) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero righe ordine... var currRec = dbCtx .DbSetOrderRow .Where(x => x.OrderRowID == orderRowID) .FirstOrDefault(); // aggiorno parametri (se inviati) if (currRec != null) { currRec.AwaitBom = awaitBom ?? currRec.AwaitBom; currRec.AwaitPrice = awaitPrice ?? currRec.AwaitPrice; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowUpdateAwaitState{Environment.NewLine}{exc}"); } } return answ; } /// /// Aggiorno sul DB i dati del file associato /// /// /// internal async Task OrderRowUpdateFileData(OrderRowModel updRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero righe offerta... var currRec = dbCtx .DbSetOrderRow .Where(x => x.OrderRowID == updRec.OrderRowID) .FirstOrDefault(); // aggiorno parametri (se inviati) if (currRec != null) { currRec.FileName = updRec.FileName; currRec.FileResource = updRec.FileResource; currRec.FileSize = updRec.FileSize; currRec.SerStruct = updRec.SerStruct; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowUpdateFileData{Environment.NewLine}{exc}"); } } return answ; } /// /// Effettua update serStruct per l'Ordine indicato /// /// ID singola riga Ordine /// Valore serializzatoe /// internal async Task OrderRowUpdateSerStruct(int orderRowID, string serStruct) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero righe offerta... var currRec = dbCtx .DbSetOrderRow .Where(x => x.OrderRowID == orderRowID) .FirstOrDefault(); // aggiorno parametri (se inviati) if (currRec != null) { currRec.SerStruct = serStruct; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowUpdateSerStruct{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert riga ordine /// /// /// internal async Task OrderRowUpsert(OrderRowModel updRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero offerta... var currRec = dbCtx .DbSetOrderRow .Where(x => x.OrderRowID == updRec.OrderRowID) .FirstOrDefault(); // se non trovo aggiungo if (currRec == null) { dbCtx.DbSetOrderRow.Add(updRec); // se ci sono record successivi li devo spostare... var list2move = dbCtx .DbSetOrderRow .Where(x => x.OrderID == updRec.OrderID && x.RowNum >= updRec.RowNum) .ToList(); if (list2move != null && list2move.Count > 0) { foreach (var item2move in list2move) { item2move.RowNum++; dbCtx.Entry(item2move).State = EntityState.Modified; } } } // altrimenti aggiorno else { dbCtx.Entry(currRec).CurrentValues.SetValues(updRec); } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowUpsert{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert record del solo ProdEstimate /// /// /// internal async Task OrderRowUpsertProdEst(string uID, string prodEstim) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero offerta... var currRec = dbCtx .DbSetOrderRow .Where(x => x.OrderRowUID == uID) .FirstOrDefault(); // se non trovo aggiungo if (currRec != null) { currRec.ProdEstimate = prodEstim; dbCtx.Entry(currRec).State = EntityState.Modified; } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OrderRowUpsertProdEst{Environment.NewLine}{exc}"); } } return answ; } /// /// Upsert record /// /// /// internal async Task OrderUpsert(OrderModel updRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { // recupero offerta... var currRec = dbCtx .DbSetOrder .Where(x => x.OrderID == updRec.OrderID) .FirstOrDefault(); // se non trovo aggiungo if (currRec == null) { dbCtx.DbSetOrder.Add(updRec); } // altrimenti aggiorno else { dbCtx.Entry(currRec).CurrentValues.SetValues(updRec); } // salvo TUTTI i cambiamenti... var result = await dbCtx.SaveChangesAsync(); answ = result > 0; } catch (Exception exc) { Log.Error($"Eccezione durante OrderUpsert{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco record Fasi da DB /// /// internal async Task> PhasesGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetPhase .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante PhasesGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco ProdItem dato OrderRow /// /// /// internal async Task> ProdItemByOrderRow(int orderRowId) { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetProdItem .Where(x => x.OrderRowID == orderRowId) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ProdItemByOrderRow{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Eliminazione record /// /// /// internal async Task ResourcesDeleteAsync(ResourceModel rec2del) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetResource .Where(x => rec2del.ResourceID > 0 && x.ResourceID == rec2del.ResourceID) .FirstOrDefault(); // se trovato --> elimino if (currRec != null) { dbCtx.DbSetResource.Remove(rec2del); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante ResourcesDeleteAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Elenco record risorse da DB /// /// internal async Task> ResourcesGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetResource .Include(d => d.DriverNav) .Include(j => j.JobStepNav) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante ResourcesGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Upsert record /// /// /// internal async Task ResourcesUpsertAsync(ResourceModel upsRec) { bool answ = false; //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { var currRec = dbCtx .DbSetResource .Where(x => upsRec.ResourceID > 0 && x.ResourceID == upsRec.ResourceID) .FirstOrDefault(); // se trovato --> aggiorno if (currRec != null) { dbCtx.Entry(currRec).CurrentValues.SetValues(upsRec); } // se mancasse --> aggiungo else { dbCtx.DbSetResource.Add(upsRec); } // salvo... int numAct = await dbCtx.SaveChangesAsync(); answ = numAct > 0; } catch (Exception exc) { Log.Error($"Eccezione durante ResourcesUpsertAsync{Environment.NewLine}{exc}"); } } return answ; } /// /// Restituisce elenco SellingItem dato envir /// /// /// internal async Task> SellingItemsByEnvir(EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS envir) { List dbRec = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { DateTime adesso = DateTime.Now; // recupero offerta... dbRec = await dbCtx .DbSetSellItem .Where(x => x.Envir == envir) .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante SellingItemsByEnvir{Environment.NewLine}{exc}"); } } return dbRec; } #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 /// /// Elenco completo Tags /// /// internal async Task> TagsGetAllAsync() { List dbResult = new List(); //using (DataLayerContext dbCtx = new DataLayerContext(_config)) using (DataLayerContext dbCtx = new DataLayerContext()) { try { dbResult = await dbCtx .DbSetTags .ToListAsync(); } catch (Exception exc) { Log.Error($"Eccezione durante TagsGetAllAsync{Environment.NewLine}{exc}"); } } return dbResult; } 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; private static Logger Log = LogManager.GetCurrentClassLogger(); #endregion Private Fields #region Private Methods /// /// Esegue completamento e la validazione dei dati BOM da lista articoli + gruppi, /// validando i dati stessi /// /// Elenco ItemGroup da considerare /// Item di tipo BOM/BomAlt AMMESSI /// Lista BOM ricevuta da validare /// Lista BOM precedente da confrontare x scelta alternativi /// Costo netto componenti BOM calcolato /// Prezzo complessivo calcolato (con aggiunta marginalità) /// Numero toale di item dello step BOM /// 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 totItemQty, ref int numGroupOk, ref int numItemOk) { double margin = 0; // ciclo x ogni elemento della BOM, cercando x gruppo e ExtItemCode foreach (var item in bomList) { // init del margine margin = 0; // verifico item group esistente... if (itemGroupList.Where(x => x.CodGroup == item.ClassCode).Count() > 0) { numGroupOk++; } // 2025.09.16: se il prezzo arriva dalla BOM calcolata uso quello... if (item.Price > 0) { // resetto ItemID ma NON il prezzo item.ItemID = 0; // conto l'item numItemOk++; item.PriceEff = item.Price; // dovrei recuperare margine da BOM... da rivedere, x ora cablato 20%... margin = 0.2; } else { /************************************************* * Ricerca costo item: * - se ho un itemID --> cerco record ESATTO e sostituisco descrizioni & co... * - se non ho itemID --> cerco dati di selezione + qtyRange *************************************************/ ItemModel? recCost = null; bool selExact = item.ItemID > 0; if (selExact) { recCost = bomGenList .Where(x => x.ItemID == item.ItemID) .FirstOrDefault(); } else { recCost = bomGenList .Where(x => x.CodGroup == item.ClassCode && x.ItemIDParent == 0 // voglio NON sia un record CHILD && x.ExtItemCode == item.ItemCode && item.Qty >= x.QtyMin && item.Qty < x.QtyMax) .OrderByDescending(x => x.Cost) .FirstOrDefault(); // 2025.09.24: se ho un elenco item della BOM precedente if (bomListPrev != null && bomListPrev.Count > 0 && recCost != null) { // ...cerco item trovato come PARENT di altri item var listAlt = bomGenList.Where(x => x.ItemIDParent == recCost.ItemID).ToList(); // che cerco nella nella BOM precedente... var result = listAlt .Join( bomListPrev, l1 => l1.ItemID, l2 => l2.ItemID, (l1, l2) => l1) .ToList(); // nel caso ne trovassi solo 1 uso quello al posto del recCost... if (result.Count == 1) { recCost = result.FirstOrDefault(); } } } // se trovato valorizzo! if (recCost != null) { numItemOk++; item.ItemID = recCost.ItemID; //item.PriceEff = recCost.BomCost * (1 + recCost.Margin); item.PriceEff = recCost.Cost; // se selezione esatta sovrascrivo altri valori if (selExact) { item.ItemCode = recCost.ExtItemCode; //item.DescriptionCode = recCost.Name; } margin = recCost.Margin; } else { item.ItemID = 0; item.PriceEff = 0; } } // ...e aggiorno totale totCost += item.TotalCost; // e prezzo totale compreso margine totPrice += item.TotalCost * (1 + margin); totItemQty += item.ItemQty; } } #endregion Private Methods } }