using GWMS.Data.DatabaseModels; using GWMS.Data.DTO; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using NLog; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace GWMS.Data.Controllers { public class GWMSController : IDisposable { #region Private Fields private static IConfiguration _configuration; private static GWMSContext dbCtx; private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); #endregion Private Fields #region Public Constructors public GWMSController(IConfiguration configuration) { _configuration = configuration; dbCtx = new GWMSContext(configuration); Log.Info("Avviata classe GWMSController"); } #endregion Public Constructors #region Private Methods private void CreateSimData(int numDays, int stepMin, int maxHourRate) { ResetController(); // generazione dati casuale Random rnd = new Random(); foreach (var plant in GetPlants()) { var currPlant = GetPlant(plant.PlantId); // imposto limiti e valori attuali... //currPlant.LevelMax = rnd.Next(24, 28) * 1000; int simLevel = rnd.Next(1, (int)currPlant.LevelMax); double simPress = (double)rnd.Next((int)(currPlant.PressMax - 50) * 10, (int)currPlant.PressMax * 10) / 10; double simPressH = (double)rnd.Next((int)(currPlant.PressBHMax - 70) * 10, (int)currPlant.PressBHMax * 10) / 10; double simPressL = (double)rnd.Next((int)(currPlant.PressBLMax - 70) * 10, (int)currPlant.PressBLMax * 10) / 10; currPlant.LevelAct = simLevel; currPlant.PressAct = simPress; currPlant.PressBHAct = simPressH; currPlant.PressBLAct = simPressL; dbCtx.SaveChanges(); // genero random le soglie x simulare rilievi e ordini int soglia01 = rnd.Next((int)currPlant.LevelMax * 60 / 100, (int)currPlant.LevelMax * 75 / 100); int soglia02 = rnd.Next((int)currPlant.LevelMax * 5 / 100, (int)currPlant.LevelMax * 35 / 100); List LogLevels = new List(); List LogPressures = new List(); List LogOrders = new List(); DateTime adesso = DateTime.Now; int lastLevel = simLevel; int lastOrder = 0; int anticipo = 0; double lastPress = simPress; double lastPressH = simPressH; double lastPressL = simPressL; // simulo numDays gg... for (int i = numDays * 24 * (60 / stepMin); i > 0; i--) { anticipo = i * stepMin; lastLevel = lastLevel - rnd.Next(0, maxHourRate / (60 / stepMin)); // se inferiore a soglia 1 --> ordine if (lastLevel + lastOrder < soglia01) { lastOrder = rnd.Next((int)currPlant.LevelMax - soglia01, (int)currPlant.LevelMax - soglia02); LogOrders.Add(new OrderModel() { DtOrder = adesso.AddMinutes(-anticipo), OrderQty = lastOrder, PlantId = plant.PlantId, OrderCode = $"ORD{i:000000}", OrderDesc = "SIM Order", SupplierId = 1, TransporterId = 1 }); } // se inferiore a soglia 2 --> refill if (lastLevel < soglia02) { lastLevel += lastOrder; lastOrder = 0; } LogLevels.Add(new PlantLogModel() { DtEvent = adesso.AddMinutes(-anticipo), FluxType = "Level", PlantId = plant.PlantId, ValNumber = lastLevel }); // pressioni! lastPress = lastPress - (double)rnd.Next(-30, 25) / 10; lastPressH = lastPressH - (double)rnd.Next(-25, 20) / 10; lastPressL = lastPressL - (double)rnd.Next(-25, 20) / 10; LogPressures.Add(new PlantLogModel() { DtEvent = adesso.AddMinutes(-anticipo), FluxType = "MainPress", PlantId = plant.PlantId, ValNumber = lastPress }); LogPressures.Add(new PlantLogModel() { DtEvent = adesso.AddMinutes(-anticipo), FluxType = "PressBH", PlantId = plant.PlantId, ValNumber = lastPressH }); LogPressures.Add(new PlantLogModel() { DtEvent = adesso.AddMinutes(-anticipo), FluxType = "PressBL", PlantId = plant.PlantId, ValNumber = lastPressL }); } try { dbCtx .DbSetPlantLog .AddRange(LogLevels); dbCtx .DbSetPlantLog .AddRange(LogPressures); // salvo sul DB! dbCtx.SaveChanges(); Log.Info($"Effettuato inserimento {LogLevels.Count} record PlantLog"); } catch (Exception exc) { Log.Error($"Eccezione in salvataggio PlantLog{Environment.NewLine}{exc}"); } try { dbCtx .DbSetOrders .AddRange(LogOrders); // salvo sul DB! dbCtx.SaveChanges(); Log.Info($"Effettuato inserimento {LogOrders.Count} record Orders"); } catch (Exception exc) { Log.Error($"Eccezione in salvataggio Orders{Environment.NewLine}{exc}"); } } } #endregion Private Methods #region Public Methods /// /// Calcola DataOra arrotondata per eccesso secondo intervallo minuti indicato /// /// /// /// public DateTime DateRoundEnd(DateTime dateOrig, int minInt) { int minRound = (int)Math.Ceiling((double)dateOrig.Minute / minInt) * minInt; DateTime roundDate = dateOrig.Date.AddHours(dateOrig.Hour).AddMinutes(minRound); return roundDate; } public void Dispose() { // Clear database context dbCtx.Dispose(); } public List GetConfig() { var dbResult = dbCtx .DbSetConfig .ToList(); return dbResult; } public List GetItems() { var dbResult = dbCtx .DbSetItems .ToList(); return dbResult; } public List GetOrdersFilt(int PlantId, int SupplierId, int TransporterId, DateTime DtStart, DateTime DtEnd) { var dbResult = dbCtx .DbSetOrders .Where(x => (x.PlantId == PlantId || PlantId == 0) && (x.SupplierId == SupplierId || SupplierId == 0) && (x.TransporterId == TransporterId || TransporterId == 0) && (x.DtOrder >= DtStart && x.DtOrder <= DtEnd)) .Include(p => p.Plant) .Include(s => s.Supplier) .Include(t => t.Transporter) .OrderByDescending(x => x.DtOrder) .ToList(); return dbResult; } public PlantDetailModel GetPlant(int PlantId) { var dbResult = dbCtx .DbSetPlant .Where(x => x.PlantId == PlantId) .FirstOrDefault(); return dbResult; } /// /// Elenco log registrati x plant /// /// se 0 = tutto /// consigliato arrotondamento al minuto o multiplo /// num rec max da recuperare /// public List GetPlantLog(int PlantId, DateTime DtMaxDate, int numRec) { var dbResult = dbCtx .DbSetPlantLog .Where(x => (x.PlantId == PlantId || PlantId == 0) && x.DtEvent <= DtMaxDate) .OrderByDescending(x => x.DtEvent) .Take(numRec) .ToList(); return dbResult; } public List GetPlants() { var dbResult = dbCtx .DbSetPlant .ToList(); return dbResult; } public List GetPlantsDTO(int maxRecords) { List dbResult = new List(); using (GWMSContext dbCtxMult = new GWMSContext(_configuration)) { var plantList = dbCtxMult .DbSetPlant .ToList(); dbResult = plantList .Select(x => PlantDTO(x.PlantId, maxRecords)) .ToList(); } return dbResult; } /// /// Restituisce ultimi eventi rebootlog /// /// num eventi, se 0 = tutti /// public List GetRebootLog(int maxNum = 100) { if (maxNum == 0) { maxNum = dbCtx.DbRebootLog.Count(); } var dbResult = dbCtx .DbRebootLog .OrderByDescending(x => x.DtEvent) .Take(maxNum) .ToList(); return dbResult; } public List GetSuppliers() { var dbResult = dbCtx .DbSetSupplier .ToList(); return dbResult; } public List GetTransporters() { var dbResult = dbCtx .DbSetTransporter .ToList(); return dbResult; } public List GetUsersFilt(UserLevel UsrLvl, int PlantId, int SupplierId, int TransporterId) { var dbResult = dbCtx .DbSetUser .Where(x => (x.Livello == UsrLvl || UsrLvl == UserLevel.ND) && (x.MaskPlantId == PlantId || PlantId == 0) && (x.MaskSupplierId == SupplierId || SupplierId == 0) && (x.MaskTranspId == TransporterId || TransporterId == 0)) .OrderBy(x => x.Livello) .ThenBy(x => x.UserName) .ToList(); return dbResult; } public List GetWeekPlan() { var dbResult = dbCtx .DbSetPlantSupplWeekPlan .ToList(); return dbResult; } public bool HasPlantLog() { bool answ = false; try { var numRecord = dbCtx .DbSetPlantLog .Count(); answ = numRecord > 0; } catch { } return answ; } /// /// Aggiorna un Ordine /// /// /// public bool OrderUpdate(OrderModel updItem) { bool done = false; try { var currData = dbCtx .DbSetOrders .Where(x => x.OrderId == updItem.OrderId) .FirstOrDefault(); if (currData != null) { dbCtx.Entry(updItem).State = EntityState.Modified; } else { dbCtx .DbSetOrders .Add(updItem); } dbCtx.SaveChanges(); done = true; } catch (Exception exc) { } return done; } /// /// Recupero info PLANT modalità DTO /// /// Impianto /// Max numero di record da recuperare /// public PlantDTO PlantDTO(int PlantId, int maxRecords) { var currPlant = GetPlant(PlantId); PlantDTO answ = new PlantDTO(); List LevelTS = new List(); Dictionary PressAct = new Dictionary(); Dictionary> PressTS = new Dictionary>(); List PressMainTS = new List(); List PressBHTS = new List(); List PressBLTS = new List(); List OrderTS = new List(); using (GWMSContext dbCtxMult = new GWMSContext(_configuration)) { // recupero dal DB var rawLevelData = dbCtxMult .DbSetPlantLog .Where(x => x.FluxType == "Level" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) .Take(maxRecords) .ToList(); var rawMainPressData = dbCtxMult .DbSetPlantLog .Where(x => x.FluxType == "MainPress" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) .Take(maxRecords) .ToList(); var rawBHPressData = dbCtxMult .DbSetPlantLog .Where(x => x.FluxType == "PressBH" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) .Take(maxRecords) .ToList(); var rawBLPressData = dbCtxMult .DbSetPlantLog .Where(x => x.FluxType == "PressBL" && x.PlantId == PlantId) .OrderBy(x => x.DtEvent) .Take(maxRecords) .ToList(); var rawOrderData = dbCtxMult .DbSetOrders .Where(x => x.PlantId == PlantId) .OrderBy(x => x.DtOrder) .Take(maxRecords) .ToList(); LevelTS = rawLevelData .Select(x => new TSData() { DtEvent = x.DtEvent, ValDouble = x.ValNumber }).ToList(); OrderTS = rawOrderData .Select(x => new TSData() { DtEvent = x.DtOrder, ValDouble = x.OrderQty }).ToList(); PressMainTS = rawMainPressData .Select(x => new TSData() { DtEvent = x.DtEvent, ValDouble = x.ValNumber }).ToList(); PressBHTS = rawBHPressData .Select(x => new TSData() { DtEvent = x.DtEvent, ValDouble = x.ValNumber }).ToList(); PressBLTS = rawBLPressData .Select(x => new TSData() { DtEvent = x.DtEvent, ValDouble = x.ValNumber }).ToList(); PressTS.Add("Main", PressMainTS); PressTS.Add("BH", PressBHTS); PressTS.Add("BL", PressBLTS); double actLevel = LevelTS.Count > 0 ? LevelTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; double valMain = PressMainTS.Count > 0 ? PressMainTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; double valBH = PressBHTS.Count > 0 ? PressBHTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; double valBL = PressBLTS.Count > 0 ? PressBLTS.OrderByDescending(x => x.DtEvent).Take(1).FirstOrDefault().ValDouble : 0; PressAct.Add("Main", valMain); PressAct.Add("BH", valBH); PressAct.Add("BL", valBL); // popolo valolri answ = new PlantDTO() { PlantId = PlantId, PlantCode = currPlant.PlantCode, PlantDesc = currPlant.PlantDesc, LevelAct = actLevel, LevelMax = currPlant.LevelMax, PressAct = PressAct, LevelTS = LevelTS, PressTS = PressTS, OrderTS = OrderTS }; } return answ; } /// /// Recupero da DB l'ultimo record per ogni flusso /// /// public List PlantLogGetLastByFlux(int PlantId) { List lastRec = dbCtx .DbSetPlantLog .Where(x => x.PlantId == PlantId) .OrderByDescending(o => o.DtEvent) .Take(1000) .AsEnumerable() .GroupBy(g => g.FluxType) .Select(s => s.First()) .ToList(); return lastRec; } /// /// Inserimento di un set di record x plant log /// /// Record da inserire (senza ID...) /// public bool PlantLogInsertNew(List newItems) { bool fatto = false; try { dbCtx .DbSetPlantLog .AddRange(newItems); dbCtx.SaveChanges(); fatto = true; } catch (Exception exc) { Log.Error(exc, $"Eccezione durante PlantLogInsertNew per {newItems.Count} rec"); } return fatto; } public bool RecordRebootLog(RebootLogModel newItem) { bool done = false; try { dbCtx .DbRebootLog .Add(newItem); dbCtx.SaveChanges(); done = true; } catch (Exception exc) { } return done; } /// /// Rigenera intero DB se riceve ID di un plant SIM... /// /// public bool RegenDB(int PlantId, int numDays, int stepMin, int maxHourRate) { bool answ = false; var currPlant = GetPlant(PlantId); if (currPlant.PlantCode.StartsWith("PIZ")) { Log.Info("Inizio RegenDB"); DbAdmin.resetPlantLogTable(); ResetController(); CreateSimData(numDays, stepMin, maxHourRate); Log.Info("Dati SIM generati"); answ = true; } return answ; } public void ResetController() { dbCtx = new GWMSContext(_configuration); } /// /// Annulla modifiche su una specifica entity (cancel update) /// /// /// public bool rollBackEntity(object item) { bool answ = false; try { if (dbCtx.Entry(item).State == EntityState.Deleted || dbCtx.Entry(item).State == EntityState.Modified) { dbCtx.Entry(item).Reload(); } } catch (Exception exc) { Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}"); } return answ; } /// /// Aggiorna un User /// /// /// public bool UserUpdate(UserModel updItem) { bool done = false; try { var currData = dbCtx .DbSetUser .Where(x => x.UserId == updItem.UserId) .FirstOrDefault(); if (currData != null) { dbCtx.Entry(updItem).State = EntityState.Modified; } else { dbCtx .DbSetUser .Add(updItem); } dbCtx.SaveChanges(); done = true; } catch (Exception exc) { } return done; } /// /// Elimina un item WeekPlan /// /// /// public bool WeekPlanDelete(WeekPlanModel selRecord) { bool done = false; try { var item2del = dbCtx .DbSetPlantSupplWeekPlan .Where(x => x.WeekPlanId == selRecord.WeekPlanId) .FirstOrDefault(); dbCtx.DbSetPlantSupplWeekPlan.Remove(item2del); dbCtx.SaveChanges(); done = true; } catch (Exception exc) { } return done; } /// /// Aggiorna un item WeekPlan /// /// /// public bool WeekPlanUpdate(WeekPlanModel updItem) { bool done = false; try { var currData = dbCtx .DbSetPlantSupplWeekPlan .Where(x => x.WeekPlanId == updItem.WeekPlanId) .FirstOrDefault(); if (currData != null) { dbCtx.Entry(updItem).State = EntityState.Modified; } else { dbCtx .DbSetPlantSupplWeekPlan .Add(updItem); } dbCtx.SaveChanges(); done = true; } catch (Exception exc) { } return done; } #endregion Public Methods } }