646 lines
27 KiB
C#
646 lines
27 KiB
C#
using EgwCoreLib.Lux.Core.RestPayload;
|
|
using EgwCoreLib.Lux.Data.DbModel.Items;
|
|
using EgwCoreLib.Lux.Data.DbModel.Job;
|
|
using EgwCoreLib.Lux.Data.DbModel.Production;
|
|
using EgwCoreLib.Lux.Data.DbModel.Stats;
|
|
using EgwCoreLib.Lux.Data.Domains;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Newtonsoft.Json;
|
|
using NLog;
|
|
using StackExchange.Redis;
|
|
using System.Data;
|
|
using static EgwCoreLib.Lux.Core.Enums;
|
|
|
|
namespace EgwCoreLib.Lux.Data.Controllers
|
|
{
|
|
internal class LuxController
|
|
{
|
|
// manca costruttore parametrico contoller...
|
|
|
|
#region Internal Methods
|
|
|
|
/// <summary>
|
|
/// Add item ricevuti da BOM calcolata
|
|
/// </summary>
|
|
/// <param name="bomList"></param>
|
|
/// <returns></returns>
|
|
internal bool ItemUpsertFromBom(List<BomItemDTO> bomList)
|
|
{
|
|
bool answ = false;
|
|
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
// 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<ItemModel> listInserted = new List<ItemModel>();
|
|
|
|
// 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();
|
|
|
|
}
|
|
return answ;
|
|
}
|
|
/// <summary>
|
|
/// Elenco item da ricerca filtro x gruppo/tipo
|
|
/// </summary>
|
|
/// <param name="CodGroup"></param>
|
|
/// <param name="ItemType"></param>
|
|
/// <returns></returns>
|
|
internal List<ItemModel> ItemGetFilt(string CodGroup, ItemClassType ItemType)
|
|
{
|
|
List<ItemModel> dbResult = new List<ItemModel>();
|
|
//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;
|
|
}
|
|
|
|
internal async Task<bool> 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;
|
|
}
|
|
|
|
#if true
|
|
/// <summary>
|
|
/// Esegue upsert del record offerta data la BOM ricevuta
|
|
/// </summary>
|
|
/// <param name="uID"></param>
|
|
/// <param name="bomList"></param>
|
|
internal bool OfferUpsertFromBom(string uID, List<BomItemDTO> 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.sourceType == 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<List<BomItemDTO>>(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
|
|
BomCalculator.Validate(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;
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Elenco record Fasi da DB
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
internal async Task<List<PhaseModel>> PhasesGetAllAsync()
|
|
{
|
|
List<PhaseModel> dbResult = new List<PhaseModel>();
|
|
//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;
|
|
}
|
|
|
|
#if false
|
|
/// <summary>
|
|
/// Add record di un singolo ProdGroup da fase Balance
|
|
/// </summary>
|
|
/// <param name="uID">UID dell'item offerta di cui si è ricevuto l'oggetto Balance'</param>
|
|
/// <param name="rGroup">Prod Group di riferimento</param>
|
|
/// <param name="rawBalance"></param>
|
|
internal async Task<bool> ProdGroupUpsertBalance(string uID, string rGroup, string rawBalance)
|
|
{
|
|
bool answ = false;
|
|
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
try
|
|
{
|
|
// Tentativo di deserializzazione
|
|
var data = JsonConvert.DeserializeObject<Dictionary<string, ProdMachineDetailDto>>(rawBalance);
|
|
// proseguo solo se è valida la deserializzazione...
|
|
if (data != null)
|
|
{
|
|
// Togliamo la 'G' e convertiamo in int (gestisce automaticamente "01" -> 1)
|
|
int grpIdx = int.Parse(rGroup.TrimStart('G'));
|
|
// recupero ord row (parent)...
|
|
var ordRowRec = dbCtx
|
|
.DbSetOrderRow
|
|
.Where(x => x.OrderRowUID == uID)
|
|
.FirstOrDefault();
|
|
if (ordRowRec != null)
|
|
{
|
|
// recupero record specifico
|
|
var currRec = dbCtx
|
|
.DbSetProdGroup
|
|
.Where(x => x.OrderRowID == ordRowRec.OrderRowID && x.GrpIdx == grpIdx)
|
|
.FirstOrDefault();
|
|
|
|
// se trovato aggiorno
|
|
if (currRec != null)
|
|
{
|
|
currRec.WorkGroupListRaw = rawBalance;
|
|
dbCtx.Entry(currRec).State = EntityState.Modified;
|
|
}
|
|
// altrimenti aggiungo
|
|
else
|
|
{
|
|
ProductionGroupModel newRec = new ProductionGroupModel()
|
|
{
|
|
OrderRowID = ordRowRec.OrderRowID,
|
|
GrpIdx = grpIdx,
|
|
WorkGroupListRaw = rawBalance
|
|
};
|
|
dbCtx
|
|
.DbSetProdGroup
|
|
.Add(newRec);
|
|
}
|
|
|
|
// segno ordine come Assigned se non lo fosse...
|
|
if (ordRowRec.OrderRowState != OrderStates.Assigned)
|
|
{
|
|
ordRowRec.OrderRowState = OrderStates.Assigned;
|
|
dbCtx.Entry(ordRowRec).State = EntityState.Modified;
|
|
}
|
|
|
|
// salvo TUTTI i cambiamenti...
|
|
var result = await dbCtx.SaveChangesAsync();
|
|
answ = result > 0;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione durante ProdGroupUpsertBalance{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
#endif
|
|
|
|
#if true
|
|
/// <summary>
|
|
/// Assegnazione in blocco degli item agli ODL corrispondenti
|
|
/// </summary>
|
|
/// <param name="dbList"></param>
|
|
/// <param name="dictParts"></param>
|
|
/// <returns></returns>
|
|
internal async Task<int> ProdItem2ODL_AssignAsync(List<ProductionODLModel> dbList, Dictionary<(int phaseId, int resId, string machine, int index), List<string>> dictParts)
|
|
{
|
|
int totalCreated = 0;
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
// 1. Recuperiamo tutti i ProdBatchID coinvolti per fare una sola query
|
|
List<int> batchIds = dbList.Select(o => o.ProdBatchID).Distinct().ToList();
|
|
|
|
if (batchIds != null && batchIds.Count > 0)
|
|
{
|
|
// 2. Carichiamo in memoria i ProdItem necessari (solo ID e Tag per risparmiare RAM)
|
|
var itemsList = await dbCtx.DbSetProdItem
|
|
.Where(x => batchIds.Contains(x.ProdBatchID ?? 0) && x.ProdItemTag != null && x.ProdItemTag != "")
|
|
.Select(x => new { x.ProdItemID, x.ProdItemTag })
|
|
.ToListAsync();
|
|
|
|
// 1. Usiamo il "!" (null-forgiving operator) dopo x.ProdItemTag
|
|
// perché il filtro .Where sopra garantisce che non sia null.
|
|
var itemLookup = itemsList
|
|
.GroupBy(x => x.ProdItemTag!)
|
|
.ToDictionary(
|
|
g => g.Key,
|
|
g => g.First().ProdItemID,
|
|
StringComparer.OrdinalIgnoreCase
|
|
);
|
|
|
|
using var transaction = await dbCtx.Database.BeginTransactionAsync();
|
|
try
|
|
{
|
|
var relationsToInsert = new List<ProductionItem2ODLModel>();
|
|
|
|
foreach (var odl in dbList)
|
|
{
|
|
var key = (odl.PhaseID ?? 0, odl.ResourceID ?? 0, odl.ProdPlantCod, odl.Index);
|
|
|
|
if (dictParts.TryGetValue(key, out List<string> tagList))
|
|
{
|
|
foreach (var tag in tagList)
|
|
{
|
|
// 3. Cerchiamo l'ID corrispondente al tag nel nostro lookup locale
|
|
if (itemLookup.TryGetValue(tag, out int realItemId))
|
|
{
|
|
relationsToInsert.Add(new ProductionItem2ODLModel
|
|
{
|
|
ProdODLID = odl.ProdODLID,
|
|
ProdItemID = realItemId,
|
|
DtAssign = DateTime.Now
|
|
});
|
|
}
|
|
else
|
|
{
|
|
//Log.Warning($"Tag {tag} non trovato nel database per i batch selezionati.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (relationsToInsert.Any())
|
|
{
|
|
await dbCtx.DbSetProdItem2ODL.AddRangeAsync(relationsToInsert);
|
|
totalCreated = relationsToInsert.Count;
|
|
await dbCtx.SaveChangesAsync();
|
|
}
|
|
|
|
await transaction.CommitAsync();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
await transaction.RollbackAsync();
|
|
Log.Error($"Errore nel salvataggio relazioni ODL-Parts: {exc.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
return totalCreated;
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Elenco da DB delel stats aggregate dato periodo inizio/fine
|
|
/// </summary>
|
|
/// <param name="dtStart"></param>
|
|
/// <param name="dtEnd"></param>
|
|
/// <returns></returns>
|
|
internal async Task<List<StatsAggregatedModel>> StatsAggrGetAsync(DateTime dtStart, DateTime dtEnd)
|
|
{
|
|
List<StatsAggregatedModel> answ = new List<StatsAggregatedModel>();
|
|
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
// recupero ed ordino per data-ora
|
|
answ = await dbCtx
|
|
.DbSetStatsAggr
|
|
.Where(x => x.Hour >= dtStart && x.Hour <= dtEnd)
|
|
.AsNoTracking()
|
|
.OrderBy(x => x.Hour)
|
|
.ToListAsync();
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Range periodo per chiamate aggregate
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
internal async Task<Utils.DtUtils.Periodo> StatsAggrRangeAsync()
|
|
{
|
|
Utils.DtUtils.Periodo answ = new Utils.DtUtils.Periodo(Utils.DtUtils.PeriodSet.Today);
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
var query = dbCtx.DbSetStatsAggr.AsQueryable();
|
|
|
|
var minHour = await query.MinAsync(x => x.Hour);
|
|
var maxHour = await query.MaxAsync(x => x.Hour);
|
|
answ.Inizio = minHour;
|
|
answ.Fine = maxHour;
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue insert statistiche aggregate sul DB
|
|
/// </summary>
|
|
/// <param name="listRecords">Elenco dei record da inserire</param>
|
|
/// <param name="removeOld">Se true preventivamente elimina record nel periodo richiesto</param>
|
|
/// <returns></returns>
|
|
internal async Task<long> StatsAggrUpsertAsync(List<StatsAggregatedModel> listRecords, bool removeOld)
|
|
{
|
|
int answ = 0;
|
|
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
// in primis se richiesto calcolo range periodo e svuoto...
|
|
if (removeOld)
|
|
{
|
|
var firstRec = listRecords.OrderBy(x => x.Hour).FirstOrDefault();
|
|
var lastRec = listRecords.OrderByDescending(x => x.Hour).FirstOrDefault();
|
|
|
|
if (firstRec != null && lastRec != null)
|
|
{
|
|
DateTime startDate = firstRec.Hour;
|
|
DateTime endDate = lastRec.Hour;
|
|
// uso direttamente ExecuteDelete
|
|
await dbCtx
|
|
.DbSetStatsAggr
|
|
.Where(x => x.Hour >= startDate && x.Hour <= endDate)
|
|
.ExecuteDeleteAsync();
|
|
}
|
|
}
|
|
|
|
// ora preparo inserimento massivo
|
|
await dbCtx
|
|
.DbSetStatsAggr
|
|
.AddRangeAsync(listRecords);
|
|
|
|
// salvo!
|
|
answ = await dbCtx.SaveChangesAsync();
|
|
|
|
// libero memoria del changeTracker
|
|
dbCtx.ChangeTracker.Clear();
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera dati stats di dettaglio dato filtro envir/tipo (opzionali) e periodo
|
|
/// </summary>
|
|
/// <param name="dtStart"></param>
|
|
/// <param name="dtEnd"></param>
|
|
/// <param name="sEnvir"></param>
|
|
/// <param name="sType"></param>
|
|
/// <returns></returns>
|
|
internal async Task<List<StatsDetailModel>> StatsDetailModelGetAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "")
|
|
{
|
|
List<StatsDetailModel> answ = new List<StatsDetailModel>();
|
|
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
// recupero ed ordino per data-ora
|
|
var query = dbCtx.DbSetStatsDet
|
|
.Where(x => x.Hour >= dtStart && x.Hour <= dtEnd);
|
|
|
|
if (!string.IsNullOrEmpty(sEnvir))
|
|
query = query.Where(x => x.Environment == sEnvir);
|
|
|
|
if (!string.IsNullOrEmpty(sType))
|
|
query = query.Where(x => x.Type == sType);
|
|
|
|
answ = await query
|
|
.AsNoTracking()
|
|
.OrderBy(x => x.Hour)
|
|
.ThenBy(x => x.Environment)
|
|
.ThenBy(x => x.Type)
|
|
.ToListAsync();
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Range periodo x chiamate detail eventualmente filtrate
|
|
/// </summary>
|
|
/// <param name="sEnvir"></param>
|
|
/// <param name="sType"></param>
|
|
/// <returns></returns>
|
|
internal async Task<Utils.DtUtils.Periodo> StatsDetailModelRangeAsync(string sEnvir, string sType)
|
|
{
|
|
Utils.DtUtils.Periodo answ = new Utils.DtUtils.Periodo(Utils.DtUtils.PeriodSet.Today);
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
var query = dbCtx.DbSetStatsDet.AsQueryable();
|
|
|
|
if (!string.IsNullOrEmpty(sEnvir))
|
|
query = query.Where(x => x.Environment == sEnvir);
|
|
|
|
if (!string.IsNullOrEmpty(sType))
|
|
query = query.Where(x => x.Type == sType);
|
|
|
|
var minHour = await query.MinAsync(x => x.Hour);
|
|
var maxHour = await query.MaxAsync(x => x.Hour);
|
|
answ.Inizio = minHour;
|
|
answ.Fine = maxHour;
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue insert statistiche di dettaglio sul DB
|
|
/// </summary>
|
|
/// <param name="listRecords">Elenco dei record da inserire</param>
|
|
/// <param name="removeOld">Se true preventivamente elimina record nel periodo richiesto</param>
|
|
/// <returns></returns>
|
|
internal async Task<long> StatsDetailModelUpsertAsync(List<StatsDetailModel> listRecords, bool removeOld)
|
|
{
|
|
int answ = 0;
|
|
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
|
using (DataLayerContext dbCtx = new DataLayerContext())
|
|
{
|
|
// in primis se richiesto calcolo range periodo e svuoto...
|
|
if (removeOld)
|
|
{
|
|
var firstRec = listRecords.OrderBy(x => x.Hour).FirstOrDefault();
|
|
var lastRec = listRecords.OrderByDescending(x => x.Hour).FirstOrDefault();
|
|
|
|
if (firstRec != null && lastRec != null)
|
|
{
|
|
DateTime startDate = firstRec.Hour;
|
|
DateTime endDate = lastRec.Hour;
|
|
// uso direttamente ExecuteDelete
|
|
await dbCtx
|
|
.DbSetStatsDet
|
|
.Where(x => x.Hour >= startDate && x.Hour <= endDate)
|
|
.ExecuteDeleteAsync();
|
|
}
|
|
}
|
|
|
|
// ora preparo inserimento massivo
|
|
await dbCtx
|
|
.DbSetStatsDet
|
|
.AddRangeAsync(listRecords);
|
|
|
|
// salvo!
|
|
answ = await dbCtx.SaveChangesAsync();
|
|
|
|
// libero memoria del changeTracker
|
|
dbCtx.ChangeTracker.Clear();
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#if true
|
|
internal bool UpdateCodGroup(List<BomItemDTO> 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<string> 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;
|
|
}
|
|
#endif
|
|
|
|
#endregion Internal Methods
|
|
|
|
#region Private Fields
|
|
|
|
private static IConfiguration _configuration;
|
|
|
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
|
|
|
#endregion Private Fields
|
|
}
|
|
} |