510 lines
19 KiB
C#
510 lines
19 KiB
C#
using GPW.CORE.Data;
|
|
using GPW.CORE.Data.DbModels;
|
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
|
using Newtonsoft.Json;
|
|
using NLog;
|
|
using StackExchange.Redis;
|
|
using System.Diagnostics;
|
|
|
|
namespace GPW.CORE.Api.Data
|
|
{
|
|
public class ApiDataService : IDisposable
|
|
{
|
|
#region Public Fields
|
|
|
|
/// <summary>
|
|
/// Classe Accesso metodi DB
|
|
/// </summary>
|
|
public static CORE.Data.Controllers.GPWController dbController = null!;
|
|
|
|
#endregion Public Fields
|
|
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Init classe
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="logger"></param>
|
|
/// <param name="emailSender"></param>
|
|
/// <param name="redisCacheClient"></param>
|
|
public ApiDataService(IConfiguration configuration, ILogger<ApiDataService> logger, IEmailSender emailSender, IConnectionMultiplexer redisConn)
|
|
{
|
|
_logger = logger;
|
|
_configuration = configuration;
|
|
_emailSender = emailSender;
|
|
// setup compoenti REDIS
|
|
var redConnString = _configuration.GetConnectionString("Redis");
|
|
if (redConnString == null)
|
|
{
|
|
_logger.LogError("REDIS ConnString empty!");
|
|
}
|
|
else
|
|
{
|
|
this.redisConn = ConnectionMultiplexer.Connect(redConnString);
|
|
this.redisDb = this.redisConn.GetDatabase();
|
|
}
|
|
|
|
// Conf DB
|
|
var connStrDB = _configuration.GetConnectionString("GPW.DB");
|
|
if (string.IsNullOrEmpty(connStrDB))
|
|
{
|
|
_logger.LogError("ConnString empty!");
|
|
}
|
|
else
|
|
{
|
|
dbController = new CORE.Data.Controllers.GPWController(configuration);
|
|
_logger.LogInformation("DbController OK");
|
|
}
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Recupera l'elenco fasi (ATTIVE)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<List<AnagFasiModel>> AnagFasiActiv()
|
|
{
|
|
List<AnagFasiModel>? dbResult = new List<AnagFasiModel>();
|
|
string cacheKey = $"{rKeyFasiAct}";
|
|
trackCache(cacheKey);
|
|
string rawData = await getRSV(cacheKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
dbResult = JsonConvert.DeserializeObject<List<AnagFasiModel>>(rawData);
|
|
}
|
|
else
|
|
{
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.AnagFasiAll(true);
|
|
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
|
|
await setRSV(cacheKey, rawData, shortTTL);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per AnagFasiActiv: {ts.TotalMilliseconds} ms");
|
|
}
|
|
if (dbResult == null)
|
|
{
|
|
dbResult = new List<AnagFasiModel>();
|
|
}
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera l'elenco progetti (ATTIVI)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<List<AnagProgettiModel>> AnagProjActiv()
|
|
{
|
|
List<AnagProgettiModel>? dbResult = new List<AnagProgettiModel>();
|
|
string cacheKey = $"{rKeyProjAct}";
|
|
trackCache(cacheKey);
|
|
string rawData = await getRSV(cacheKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
dbResult = JsonConvert.DeserializeObject<List<AnagProgettiModel>>(rawData);
|
|
}
|
|
else
|
|
{
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.AnagProjAll(true);
|
|
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
|
|
await setRSV(cacheKey, rawData, shortTTL);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per AnagProjActiv: {ts.TotalMilliseconds} ms");
|
|
}
|
|
if (dbResult == null)
|
|
{
|
|
dbResult = new List<AnagProgettiModel>();
|
|
}
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase
|
|
/// </summary>
|
|
/// <param name="idxFase"></param>
|
|
/// <returns></returns>
|
|
public async Task<CalcOreFasiModel> CalcOreFase(int idxFase, bool doLog)
|
|
{
|
|
CalcOreFasiModel? dbResult = new CalcOreFasiModel();
|
|
string cacheKey = $"{rKeyCalcOreFase}:{idxFase}";
|
|
trackCache(cacheKey);
|
|
string rawData = await getRSV(cacheKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
dbResult = JsonConvert.DeserializeObject<CalcOreFasiModel>(rawData);
|
|
}
|
|
else
|
|
{
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.CalcOreFase(idxFase);
|
|
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
|
|
await setRSV(cacheKey, rawData, shortTTL);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
if (doLog)
|
|
{
|
|
Log.Trace($"Effettuata lettura da DB per CalcOreFase: {ts.TotalMilliseconds} ms");
|
|
}
|
|
}
|
|
if (dbResult == null)
|
|
{
|
|
dbResult = new CalcOreFasiModel();
|
|
}
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
public async Task<List<CheckVc19Model>> ChecksGetByDip(int idxDip)
|
|
{
|
|
DateTime dtFine = DateTime.Today.AddDays(1);
|
|
List<CheckVc19Model> dbResult = new List<CheckVc19Model>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.GetChecksVC19Filt(idxDip, dtFine.AddMonths(-1), dtFine);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per ChecksGetByDip: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
public async Task<List<CheckVc19Model>> ChecksGetLast(int numRecord)
|
|
{
|
|
List<CheckVc19Model> dbResult = new List<CheckVc19Model>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.GetChecksVC19(numRecord);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per ChecksGetLast: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera record anomalie dipendenti
|
|
/// </summary>
|
|
/// <param name="inizio"></param>
|
|
/// <param name="fine"></param>
|
|
/// <param name="notOkApp"></param>
|
|
/// <param name="notOkTim"></param>
|
|
/// <param name="notOkLav"></param>
|
|
public async Task<List<DipendendiAndAnomalie>> DipAndAnomGetAll(DateTime inizio, DateTime fine, bool notOkApp, bool notOkTim, bool notOkLav)
|
|
{
|
|
List<DipendendiAndAnomalie> dbResult = new List<DipendendiAndAnomalie>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.DipAndAnomGetAll(inizio, fine, notOkApp, notOkTim, notOkLav);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per DipAndAnomGetAll: {ts.TotalMilliseconds} ms");
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
public async Task<List<DipendentiModel>> DipendentiGetAll()
|
|
{
|
|
List<DipendentiModel> dbResult = new List<DipendentiModel>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.DipendentiGetAll();
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per DipendentiGetAll: {ts.TotalMilliseconds} ms");
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
// Clear database controller
|
|
dbController.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imposta stato di una fase
|
|
/// </summary>
|
|
/// <param name="idxFase">ID</param>
|
|
/// <param name="isActive">
|
|
/// Stato attivo true/false (se è amster -_> aggiorna sottofasi x trigger su DB
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public async Task<bool> FasiSetActive(int idxFase, bool isActive)
|
|
{
|
|
return await dbController.FasiSetActive(idxFase, isActive);
|
|
}
|
|
|
|
public async Task<bool> InsertCheck(DCCDecode updItem, string clientIp)
|
|
{
|
|
bool done = false;
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
done = dbController.InsertCheck(updItem, clientIp);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata operazione InsertCheck: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(done);
|
|
}
|
|
|
|
public async Task<bool> InsertManual(int idxDip, string clientIp)
|
|
{
|
|
bool done = false;
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
done = dbController.InsertManual(idxDip, clientIp);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata operazione InsertManual: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(done);
|
|
}
|
|
|
|
/// <summary>
|
|
/// invalida tutta la cache in caso di update
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task InvalidateAllCache()
|
|
{
|
|
foreach (var item in cachedDataList)
|
|
{
|
|
await redisDb.StringSetAsync(item, "", TimeSpan.FromMilliseconds(5));
|
|
}
|
|
cachedDataList = new List<string>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera eventi dato criteri filtro
|
|
/// </summary>
|
|
/// <param name="inizio"></param>
|
|
/// <param name="fine"></param>
|
|
/// <param name="evento"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<RegistroEventiModel>> RegEventiGetFilt(DateTime inizio, DateTime fine, string evento)
|
|
{
|
|
List<RegistroEventiModel> dbResult = new List<RegistroEventiModel>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.RegEventiGetFilt(inizio, fine, evento);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per RegEventiGetFilt: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Insert/Update di un record in Registro Eventi
|
|
/// </summary>
|
|
/// <param name="currItem"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> RegEventiUpdate(RegistroEventiModel currItem)
|
|
{
|
|
bool done = false;
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
done = dbController.RegEventiUpdate(currItem);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata operazione RegEventiUpdate: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(done);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera record anomalie dipendenti
|
|
/// </summary>
|
|
/// <param name="idxDipendente">singolo idx oppure 0 = tutti</param>
|
|
/// <param name="dataFrom"></param>
|
|
/// <param name="dataTo"></param>
|
|
/// <param name="inatt"></param>
|
|
/// <param name="showWE"></param>
|
|
/// <param name="maxErrMin"></param>
|
|
/// <param name="maxErrPlus"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<TeRaExplModel>> TeRaExplGetAll(int idxDipendente, DateTime dataFrom, DateTime dataTo, bool inatt, bool showWE, int maxErrMin, int maxErrPlus)
|
|
{
|
|
List<TeRaExplModel> dbResult = new List<TeRaExplModel>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.TeRaExplGetAll(idxDipendente, dataFrom, dataTo, inatt, showWE, maxErrMin, maxErrPlus);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per TeRaExplGetAll: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera record anomalie dipendenti
|
|
/// </summary>
|
|
/// <param name="idxDipendente">singolo idx oppure 0 = tutti</param>
|
|
/// <param name="inizio"></param>
|
|
/// <param name="fine"></param>
|
|
/// <param name="notOkApp"></param>
|
|
/// <param name="notOkTim"></param>
|
|
/// <param name="notOkLav"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<TimbratureExplModel>> TimbExplGetAnomalie(int idxDipendente, DateTime inizio, DateTime fine, bool notOkApp, bool notOkTim, bool notOkLav)
|
|
{
|
|
List<TimbratureExplModel> dbResult = new List<TimbratureExplModel>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.TimbExplGetAnomalie(idxDipendente, inizio, fine, notOkApp, notOkTim, notOkLav);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per TimbExplGetAnomalie: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera record anomalie dipendenti
|
|
/// </summary>
|
|
/// <param name="idxDipendente">singolo idx oppure 0 = tutti</param>
|
|
/// <param name="inizio"></param>
|
|
/// <param name="fine"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<TimbratureExplModel>> TimbExplGetContinuato(int idxDipendente, DateTime inizio, DateTime fine)
|
|
{
|
|
List<TimbratureExplModel> dbResult = new List<TimbratureExplModel>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.TimbExplGetContinuato(idxDipendente, inizio, fine);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per TimbExplGetContinuato: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera elenco anomalie x timbrature future
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<List<TimbratureModel>> TimbratureAnomalieFuture()
|
|
{
|
|
List<TimbratureModel> dbResult = new List<TimbratureModel>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.TimbratureAnomalieFuture();
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per TimbratureAnomalieFuture: {ts.TotalMilliseconds} ms");
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
protected const string rKeyCalcOreFase = "Check:OreFasi";
|
|
protected const string rKeyFasiAct = "Check:FasiAct";
|
|
protected const string rKeyProjAct = "Check:ProjAct";
|
|
|
|
/// <summary>
|
|
/// TTL da 1 min x cache Redis
|
|
/// </summary>
|
|
protected const int shortTTL = 60 * 5;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Recupero chiave da redis
|
|
/// </summary>
|
|
/// <param name="rKey"></param>
|
|
/// <returns></returns>
|
|
protected async Task<string> getRSV(string rKey)
|
|
{
|
|
string answ = "";
|
|
var rawData = await redisDb.StringGetAsync(rKey);
|
|
if (rawData.HasValue)
|
|
{
|
|
answ = $"{rawData}";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio chiave in redis
|
|
/// </summary>
|
|
/// <param name="rKey"></param>
|
|
/// <param name="rVal"></param>
|
|
/// <param name="ttlSec"></param>
|
|
/// <returns></returns>
|
|
protected async Task<bool> setRSV(string rKey, string rVal, int ttlSec)
|
|
{
|
|
bool fatto = false;
|
|
await redisDb.StringSetAsync(rKey, rVal, TimeSpan.FromSeconds(ttlSec));
|
|
fatto = true;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio chiave in redis
|
|
/// </summary>
|
|
/// <param name="rKey"></param>
|
|
/// <param name="rValInt"></param>
|
|
/// <param name="ttlSec"></param>
|
|
/// <returns></returns>
|
|
protected async Task<bool> setRSV(string rKey, int rValInt, int ttlSec)
|
|
{
|
|
bool fatto = false;
|
|
await redisDb.StringSetAsync(rKey, rValInt, TimeSpan.FromSeconds(ttlSec));
|
|
fatto = true;
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registra in cache chiave se non fosse già in elenco
|
|
/// </summary>
|
|
/// <param name="newKey"></param>
|
|
protected void trackCache(string newKey)
|
|
{
|
|
if (!cachedDataList.Contains(newKey))
|
|
{
|
|
cachedDataList.Add(newKey);
|
|
}
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Private Fields
|
|
|
|
private static IConfiguration _configuration = null!;
|
|
|
|
private static ILogger<ApiDataService> _logger = null!;
|
|
|
|
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
|
|
|
private readonly IEmailSender _emailSender;
|
|
|
|
//private readonly IDistributedCache distributedCache;
|
|
//private readonly IRedisCacheClient _redisCacheClient;
|
|
|
|
/// <summary>
|
|
/// Elenco obj in cache
|
|
/// </summary>
|
|
private List<string> cachedDataList = new List<string>();
|
|
|
|
/// <summary>
|
|
/// Oggetto per connessione a REDIS
|
|
/// </summary>
|
|
private ConnectionMultiplexer redisConn = null!;
|
|
|
|
/// <summary>
|
|
/// Oggetto DB redis da impiegare x chiamate R/W
|
|
/// </summary>
|
|
private IDatabase redisDb = null!;
|
|
|
|
#endregion Private Fields
|
|
}
|
|
} |