From 7ac306c4e38e1b0779a82c15470628d49ba3039f Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 7 Dec 2021 15:46:28 +0100 Subject: [PATCH] Primo ciclo raccolta dati con elenco dipendenti --- GPW.CORE.Data/Controllers/GPWController.cs | 2 +- GPW.CORE.Data/GPWContext.cs | 2 +- GPW.CORE.UI/Data/GpwDataService.cs | 332 +++++++++++++++++++++ GPW.CORE.UI/Data/MessageService.cs | 142 +++++++++ GPW.CORE.UI/GPW.CORE.UI.csproj | 7 + 5 files changed, 483 insertions(+), 2 deletions(-) create mode 100644 GPW.CORE.UI/Data/GpwDataService.cs create mode 100644 GPW.CORE.UI/Data/MessageService.cs diff --git a/GPW.CORE.Data/Controllers/GPWController.cs b/GPW.CORE.Data/Controllers/GPWController.cs index 627d91a..5139ede 100644 --- a/GPW.CORE.Data/Controllers/GPWController.cs +++ b/GPW.CORE.Data/Controllers/GPWController.cs @@ -43,7 +43,7 @@ namespace GPW.CORE.Data.Controllers } - public List MaterialsGetAll() + public List DipendentiGetAll() { List dbResult = new List(); using (GPWContext localDbCtx = new GPWContext(_configuration)) diff --git a/GPW.CORE.Data/GPWContext.cs b/GPW.CORE.Data/GPWContext.cs index 3446ec7..f660d2b 100644 --- a/GPW.CORE.Data/GPWContext.cs +++ b/GPW.CORE.Data/GPWContext.cs @@ -47,7 +47,7 @@ namespace GPW.CORE.Data { if (!optionsBuilder.IsConfigured) { - string connString = _configuration.GetConnectionString("NKC.DB"); + string connString = _configuration.GetConnectionString("GPW.DB"); if (!string.IsNullOrEmpty(connString)) { optionsBuilder.UseSqlServer(connString); diff --git a/GPW.CORE.UI/Data/GpwDataService.cs b/GPW.CORE.UI/Data/GpwDataService.cs new file mode 100644 index 0000000..35b93fb --- /dev/null +++ b/GPW.CORE.UI/Data/GpwDataService.cs @@ -0,0 +1,332 @@ +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Caching.Memory; +using Newtonsoft.Json; +using GPW.CORE.Data.DbModels; +using NLog; +using System.Diagnostics; +using System.Text; + +namespace GPW.CORE.UI.Data +{ + public class GpwDataService : IDisposable + { + #region Private Fields + + private static IConfiguration _configuration = null!; + private static ILogger _logger = null!; + private static JsonSerializerSettings? JSSettings; + + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + //private readonly IEmailSender _emailSender; + //private readonly UserManager _userManager; + private readonly IDistributedCache distributedCache; + + private readonly IMemoryCache memoryCache; + private List cachedDataList = new List(); + + /// + /// Durata assoluta massima della cache IN SECONDI + /// + private int chAbsExp = 60 * 5; + + /// + /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa + /// NON estende oltre il tempo massimo di validità della cache (chAbsExp) + /// + private int chSliExp = 60 * 1; + + #endregion Private Fields + + #region Protected Fields + + protected const string rKeyDipendenti = "Cache:Dipendenti"; + protected const string rKeyQrRemnants = "Cache:QrRemnants"; + protected const string rKeyRemnants = "Cache:Remnants"; + protected static string connStringBBM = ""; + + #endregion Protected Fields + + #region Public Fields + + public static CORE.Data.Controllers.GPWController dbController = null!; + + #endregion Public Fields + + #region Public Constructors + + public GpwDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache) + { + _logger = logger; + _configuration = configuration; + // conf cache + this.memoryCache = memoryCache; + this.distributedCache = distributedCache; + + // json serializer... + // FIX errore loop circolare + // https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ + JSSettings = new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; + // conf DB + string connStr = _configuration.GetConnectionString("GPW.DB"); + if (string.IsNullOrEmpty(connStr)) + { + _logger.LogError("ConnString empty!"); + } + else + { + dbController = new CORE.Data.Controllers.GPWController(configuration); + } + } + + #endregion Public Constructors + + #region Private Methods + + private DistributedCacheEntryOptions cacheOpt(bool fastCache) + { + var numSecAbsExp = fastCache ? chAbsExp : chAbsExp * 10; + var numSecSliExp = fastCache ? chSliExp : chSliExp * 10; + return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); + } + + #endregion Private Methods + + #region Public Methods + + public void Dispose() + { + // Clear database controller + dbController.Dispose(); + } + + /// + /// invalida tutta la cache in caso di update + /// + /// + public async Task InvalidateAllCache() + { + await distributedCache.RemoveAsync(rKeyDipendenti); + await distributedCache.RemoveAsync(rKeyRemnants); + foreach (var item in cachedDataList) + { + await distributedCache.RemoveAsync(item); + } + cachedDataList = new List(); + } + + + public async Task> DipendentiGetAll() + { + List? dbResult = new List(); + string rawData; + var redisDataList = await distributedCache.GetAsync(rKeyDipendenti); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.DipendentiGetAll(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(rKeyDipendenti, redisDataList, cacheOpt(false)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per DipendentiGetAll: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + +#if false + public async Task> MaterialsGetAll() + { + List? dbResult = new List(); + string rawData; + var redisDataList = await distributedCache.GetAsync(rKeyDipendenti); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.MaterialsGetAll(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(rKeyDipendenti, redisDataList, cacheOpt(false)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per GetMaterials: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + public async Task> MovMagGetFilt(int RemnId, int numShow) + { + List dbResult = new List(); + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.MovMagGetFilt(RemnId, numShow); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per MovMagGetFilt: {ts.TotalMilliseconds} ms"); + return await Task.FromResult(dbResult); + } + + public async Task AddPrintJob(int RemnId) + { + bool answ = dbController.AddPrintJob("docRemnant", $"{RemnId}", "queueRemnants"); + return await Task.FromResult(answ); + } + + public async Task> RemnantsGetFilt(int matId, int minQty) + { + List? dbResult = new List(); + string rawData; + string cacheKey = $"{rKeyRemnants}:{matId}:{minQty}"; + if (!cachedDataList.Contains(cacheKey)) + { + cachedDataList.Add(cacheKey); + } + + var redisDataList = await distributedCache.GetAsync(cacheKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + var rawList = dbController.RemnantsGetFilt(matId, minQty); + dbResult = rawList.OrderBy(o => o.Area).ToList(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(cacheKey, redisDataList, cacheOpt(false)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per RemnantsGetAll: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + public async Task RemnantsIsDupl(RemnantsModel currItem) + { + bool answ = false; + var rawList = dbController.RemnantsGetFilt(currItem.MatID, 0); + var duplicati = rawList + .Where(x => x.RemnID != currItem.RemnID && x.LMm == currItem.LMm && x.WMm == currItem.WMm && x.TMm == currItem.TMm) + .ToList(); + answ = duplicati.Count > 0; + return await Task.FromResult(answ); + } + + public async Task RemnantsMovMag(RemnantsModel currItem, string userId, int deltaQty) + { + bool done = false; + try + { + // recupero item da DB + var currRecord = dbController.RemnantGetByid(currItem.RemnID); + if (currRecord != null && currRecord.RemnID == currItem.RemnID) + { + // modifico qty entro limiti >=0.. + if (currRecord.QtyAvail + deltaQty >= 0) + { + currRecord.QtyAvail = currRecord.QtyAvail + deltaQty; + done = dbController.RemnantsUpsert(currRecord, userId); + await InvalidateAllCache(); + } + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in RemnantsMovMag:{Environment.NewLine}{exc}"); + } + return await Task.FromResult(done); + } + + public async Task RemnantsUpsert(RemnantsModel currItem, string userId) + { + bool done = false; + try + { + done = dbController.RemnantsUpsert(currItem, userId); + await InvalidateAllCache(); + } + catch (Exception exc) + { + Log.Error($"Eccezione in RemnantsUpsert:{Environment.NewLine}{exc}"); + } + return await Task.FromResult(done); + } +#endif + + public void rollBackEdit(object item) + { + dbController.rollBackEntity(item); + } + +#if false + public async Task SearchQrRemnant(string QrCode) + { + RemnantsModel? answ = new RemnantsModel(); + string rawData = ""; + string cacheKey = $"{rKeyQrRemnants}:{QrCode}"; + // cerco in redis + var redisData = await distributedCache.GetAsync(cacheKey); + if (redisData != null) + { + rawData = Encoding.UTF8.GetString(redisData); + answ = JsonConvert.DeserializeObject(rawData); + } + // se non trovo cerco su DB + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + var foundItem = dbController.RemnantGetByQr(QrCode); + if (foundItem != null && foundItem.RemDtmx == QrCode) + { + rawData = JsonConvert.SerializeObject(foundItem, JSSettings); + redisData = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(cacheKey, redisData, cacheOpt(false)); + answ = foundItem; + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per SearchQrRemnant: {ts.TotalMilliseconds} ms"); + } + if (answ == null) + { + answ = new RemnantsModel(); + } + return await Task.FromResult(answ); + } +#endif + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Data/MessageService.cs b/GPW.CORE.UI/Data/MessageService.cs new file mode 100644 index 0000000..011e5ac --- /dev/null +++ b/GPW.CORE.UI/Data/MessageService.cs @@ -0,0 +1,142 @@ +namespace GPW.CORE.UI.Data +{ + public class MessageService + { + + #region Private Fields + + private string _pageIcon = ""; + + private string _pageName = ""; + + private string _searchVal = ""; + + private int _matId; + + private bool showSearch; + + #endregion Private Fields + + #region Public Events + + public event Action EA_HideSearch = null!; + + public event Action EA_PageUpdated = null!; + + public event Action EA_SearchUpdated = null!; + + public event Action EA_ShowSearch = null!; + + #endregion Public Events + + #region Public Properties + + public string PageIcon + { + get => _pageIcon; + set + { + if (_pageIcon != value) + { + _pageIcon = value; + ReportPageUpd(); + } + } + } + + public string PageName + { + get => _pageName; + set + { + if (_pageName != value) + { + _pageName = value; + ReportPageUpd(); + } + } + } + + public string SearchVal + { + get => _searchVal; + set + { + if (_searchVal != value) + { + _searchVal = value; + + if (EA_SearchUpdated != null) + { + EA_SearchUpdated?.Invoke(); + } + } + } + } + + public int MatIdSel + { + get => _matId; + set + { + if (_matId != value) + { + _matId = value; + + if (EA_SearchUpdated != null) + { + EA_SearchUpdated?.Invoke(); + } + } + } + } + + public bool ShowSearch + { + get => showSearch; + set + { + if (showSearch != value) + { + showSearch = value; + if (showSearch) + { + if (EA_ShowSearch != null) + { + EA_ShowSearch?.Invoke(); + } + } + else + { + if (EA_HideSearch != null) + { + EA_HideSearch?.Invoke(); + } + } + } + } + } + + #endregion Public Properties + + #region Private Methods + + private void ReportPageUpd() + { + if (EA_PageUpdated != null) + { + EA_PageUpdated?.Invoke(); + } + } + + private void ReportSearch() + { + if (EA_SearchUpdated != null) + { + EA_SearchUpdated?.Invoke(); + } + } + + #endregion Private Methods + } +} diff --git a/GPW.CORE.UI/GPW.CORE.UI.csproj b/GPW.CORE.UI/GPW.CORE.UI.csproj index 2764225..aef9c1f 100644 --- a/GPW.CORE.UI/GPW.CORE.UI.csproj +++ b/GPW.CORE.UI/GPW.CORE.UI.csproj @@ -8,6 +8,13 @@ + + + + + + +