using EgwCoreLib.Lux.Core.RestPayload; using EgwCoreLib.Lux.Data.DbModel.Config; using EgwCoreLib.Lux.Data.DbModel.Items; using EgwCoreLib.Lux.Data.DbModel.Sales; using EgwCoreLib.Lux.Data.DbModel.Utils; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using NLog; 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 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.Ordinal > dbResult.Ordinal) .ToList(); foreach (var item in list2Move) { item.Ordinal--; 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.Ordinal - 1 : currRec.Ordinal + 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.Ordinal == newPos) .FirstOrDefault(); if (otherRec != null) { otherRec.Ordinal = currRec.Ordinal; dbCtx.Entry(otherRec).State = EntityState.Modified; currRec.Ordinal = 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; } #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 /// /// 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; } 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 { // prendo solo elementi a prezzo 0 da salvare sul DB var item2save = bomList .Where(x => x.Price == 0) .ToList(); // 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 --> lo devo inserire!!! if (currRec == null) { 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); } } // salvo... dbCtx.SaveChanges(); } catch (Exception exc) { Log.Error($"Eccezione durante ItemUpsertFromBom{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 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; } /// /// 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 numGroupOk = 0; int numItemOk = 0; int numElems = newBomList.Count; // validazione e completamento BOM validateBom(itemGroupList, bomGenList, ref newBomList, null, ref totCost, ref totPrice, 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; 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; 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 /// Se non nullo è il nuovo stato await BOM /// Se non nullo è stato await Price /// 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); } // 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 OffertUpdateAwait{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 numGroupOk = 0; int numItemOk = 0; int numElems = bomList.Count; // validazione e completamento BOM validateBom(itemGroupList, bomGenList, ref bomList, null, ref totCost, ref totPrice, 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; 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 numGroupOk = 0; int numItemOk = 0; int numElems = bomList.Count; // validazione e completamento BOM validateBom(itemGroupList, bomGenList, ref bomList, bomListPrev, ref totCost, ref totPrice, 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; 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; } #endregion Internal Methods #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à) /// Controllo coerenza calcoli sui gruppi items /// Controllo coerenza calcoli su num items 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; // 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); } } #endregion Private Methods } }