Files
SHERPA/SHERPA.BBM.UI/Data/BBM_EFService.cs
T
2023-06-30 16:48:12 +02:00

812 lines
25 KiB
C#

using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System.Diagnostics;
namespace SHERPA.BBM.UI.Data
{
public class BBM_EFService : IDisposable
{
#region Public Constructors
public BBM_EFService(IConfiguration configuration, ILogger<BBM_EFService> logger, IConnectionMultiplexer redisConnMult)
{
_logger = logger;
_configuration = configuration;
connStringBBM = _configuration.GetConnectionString("Sherpa.BBM");
connStringFatt = _configuration.GetConnectionString("Sherpa.Fatt");
// Conf cache
redisConn = redisConnMult;
redisDb = this.redisConn.GetDatabase();
// 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
};
//_logger.LogInformation($"ConnString: {connString}");
if (string.IsNullOrEmpty(connStringBBM) || string.IsNullOrEmpty(connStringFatt))
{
_logger.LogError($"ConnString empty | connStringBBM: {connStringBBM} | connStringFatt: {connStringFatt}");
}
else
{
dbController = new CORE.Controllers.BBMController(_configuration);
}
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// effettua reset del controller (nuova istanza)
/// </summary>
/// <returns></returns>
public static bool resetController()
{
bool answ = false;
try
{
dbController = new CORE.Controllers.BBMController(_configuration);
}
catch
{ }
return answ;
}
public async Task<List<int>> Annualita()
{
var allNegot = await NegotiationsGetAllAsync();
List<int> answ = allNegot.Select(x => x.Anno).Distinct().ToList();
return answ;
}
public void BasketsAdd(CORE.DbModels.BasketsModel newItem)
{
try
{
dbController.BaskAddNew(newItem);
}
catch
{
}
}
public void BasketsDelete(CORE.DbModels.BasketsModel currItem)
{
try
{
dbController.BaskDelete(currItem.CodBasket);
}
catch
{
}
}
/// <summary>
/// Elenco ultimi Baskets
/// </summary>
/// <param name="CompanyId"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public Task<List<CORE.DbModels.BasketsModel>> BasketsGetAsync(int CompanyId, string searchVal)
{
return Task.FromResult(dbController.BaskGetLastDesc(CompanyId, searchVal));
}
public void BasketsUpdate(CORE.DbModels.BasketsModel currItem)
{
try
{
dbController.BaskUpdate(currItem);
}
catch
{
}
}
public void BillDelete(CORE.DbModels.Fatt2DocModel currItem)
{
try
{
dbController.BillDelete(currItem);
}
catch
{
}
}
public Task<List<CORE.DbModels.Fatt2DocModel>> BillsGetAsync(int DocId)
{
return Task.FromResult(dbController.BillsGetByDoc(DocId));
}
public Task<decimal> BillsGetTotFatturato(int anno, int baskId, int negotId, int docId)
{
return Task.FromResult(dbController.BillsGetTotFatturato(anno, baskId, negotId, docId));
}
public Task<decimal> BillsGetTotIncasso(int anno, int baskId, int negotId, int docId)
{
return Task.FromResult(dbController.BillsGetTotIncasso(anno, baskId, negotId, docId));
}
public void BillUpdate(CORE.DbModels.Fatt2DocModel currItem)
{
try
{
dbController.BillUpdate(currItem);
}
catch
{
}
}
public Task<List<CORE.DbModels.CompanyModel>> CompanyGetAll()
{
return Task.FromResult(dbController.CompanyGetAll());
}
public Task<List<CORE.DbModels.FluxCountersModel>> CounterGetAll()
{
return Task.FromResult(dbController.CountersGetAll());
}
public Task<List<CORE.DbModels.FluxCountersModel>> CounterGetFilt(string searchVal)
{
return Task.FromResult(dbController.CountersGetAll(searchVal));
}
public string CounterGetNext(string CodCounter, int numZeros)
{
return dbController.CounterGetNext(CodCounter, numZeros);
}
public void CounterUpdate(CORE.DbModels.FluxCountersModel currItem)
{
try
{
dbController.CounterUpdate(currItem);
}
catch
{
}
}
public Task<List<CORE.DbModels.CustomersModel>> CustomersGetAll(string searchVal)
{
return Task.FromResult(dbController.CustomersGetAll(searchVal));
}
public void CustomerUpdate(CORE.DbModels.CustomersModel currItem)
{
try
{
dbController.CustomerUpdate(currItem);
}
catch
{
}
}
public void Dispose()
{
// Clear database controller
dbController.Dispose();
}
public Task<CORE.DbModels.DocsModel> DocGetByKeyAsync(int DocId)
{
return Task.FromResult(dbController.DocGetByKey(DocId));
}
public void DocsAdd(CORE.DbModels.DocsModel newItem)
{
try
{
dbController.DocsAddNew(newItem);
}
catch
{
}
}
public void DocsDelete(CORE.DbModels.DocsModel currItem)
{
try
{
dbController.ResourceDeleteByDoc(currItem.DocId);
dbController.DocDelete(currItem.DocId);
}
catch
{
}
}
public void DocSetActive(CORE.DbModels.DocsModel currItem)
{
dbController.DocSetActive(currItem);
}
// da rivedere...
public Task<CORE.DbModels.DocsModel[]> DocsGetAsync(int numRec)
{
return Task.FromResult(dbController.DocGetLastDesc(numRec).ToArray());
}
public Task<List<CORE.DbModels.DocsModel>> DocsGetAsync(string searchVal, int anno, int basketId, int negotiationId, bool showAll)
{
return Task.FromResult(dbController.DocGetLastDesc(searchVal, anno, basketId, negotiationId, showAll));
}
public Task<bool> DocsMoveNegot(int DocId, int NegotiationId)
{
return Task.FromResult(dbController.DocsMoveNegot(DocId, NegotiationId));
}
public void DocsUpdate(CORE.DbModels.DocsModel currItem)
{
dbController.DocUpdate(currItem);
}
/// <summary>
/// Elenco annualità valide x documenti caricati
/// </summary>
/// <returns></returns>
public Task<List<int>> DocsYears()
{
return Task.FromResult(dbController.DocsYears());
}
public void ItemAdd(CORE.DbModels.ItemsModel newItem)
{
try
{
dbController.ItemAddNew(newItem);
}
catch
{
}
}
public void ItemDelete(CORE.DbModels.ItemsModel currItem)
{
try
{
dbController.ItemDelete(currItem.CodItem);
}
catch
{
}
}
public Task<CORE.DbModels.ItemsModel> ItemFind(int ItemId)
{
return Task.FromResult(dbController.ItemFind(ItemId));
}
// da rivedere...
public Task<List<CORE.DbModels.ItemsModel>> ItemsGetAsync()
{
return Task.FromResult(dbController.ItemGetAsc());
}
public Task<List<CORE.DbModels.ItemsModel>> ItemsGetAsync(string searchVal, BbmResType ResType, string UM)
{
return Task.FromResult(dbController.ItemGetLastDesc(searchVal, ResType, UM));
}
public void ItemUpdate(CORE.DbModels.ItemsModel currItem)
{
try
{
dbController.ItemUpdate(currItem);
}
catch
{
}
}
public void NegotiationAdd(CORE.DbModels.NegotiationsModel newItem)
{
try
{
dbController.NegotAddNew(newItem);
}
catch
{
}
}
public void NegotiationDelete(CORE.DbModels.NegotiationsModel currItem)
{
try
{
dbController.NegotDelete(currItem.CodNegotiation);
}
catch
{
}
}
/// <summary>
/// Recupera negoziazione
/// </summary>
/// <param name="NegotId"></param>
/// <returns></returns>
public Task<CORE.DbModels.NegotiationsModel> NegotiationGetByKey(int NegotId)
{
return Task.FromResult(dbController.NegotGetByKey(NegotId));
}
public Task<List<CORE.DbModels.NegotiationsModel>> NegotiationsGetAllAsync()
{
return Task.FromResult(dbController.NegotGetAllDesc());
}
public Task<List<CORE.DbModels.NegotiationsModel>> NegotiationsGetAsync(int anno, int companyId, int customerId, int basketId, string searchVal)
{
return Task.FromResult(dbController.NegotGetLastDesc(anno, companyId, customerId, basketId, searchVal));
}
public void NegotiationUpdate(CORE.DbModels.NegotiationsModel currItem)
{
try
{
dbController.NegotUpdate(currItem);
}
catch
{
}
}
/// <summary>
/// Elenco annualità valide x negoziazioni
/// </summary>
/// <returns></returns>
public Task<List<int>> NegotYears()
{
return Task.FromResult(dbController.NegotYears());
}
/// <summary>
/// Remove for single hash record
/// </summary>
/// <param name="currKey">Chiave redis della Hashlist</param>
/// <param name="chiave">Chiave nella HashList</param>
/// <returns>Esito rimozione</returns>
public async Task<bool> RedHashRemove(RedisKey currKey, string chiave)
{
bool fatto = false;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
fatto = await redisDb.HashDeleteAsync(currKey, chiave);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"RedHashRemove | {currKey} | in: {ts.TotalMilliseconds} ms");
return fatto;
}
public void ResourceAdd(CORE.DbModels.ResourcesModel newItem)
{
try
{
dbController.ResourceAddNew(newItem);
}
catch
{
}
}
public void ResourceCloneByDoc(int DocIdSrc, int DocIdTgt)
{
try
{
// recupero elenco
var newRes = dbController.ResourceCloneByDoc(DocIdSrc, DocIdTgt);
}
catch
{
}
}
public void ResourceDelete(CORE.DbModels.ResourcesModel currItem)
{
try
{
dbController.ResourceDelete(currItem.ResourceId);
}
catch
{
}
}
// da rivedere...
public Task<List<CORE.DbModels.ResourcesModel>> ResourcesGetAsync(int anno, int numRec)
{
return Task.FromResult(dbController.ResourceGetLastDesc(anno, numRec));
}
public Task<List<CORE.DbModels.ResourcesModel>> ResourcesGetAsync(int anno, int baskId, int negoId, int docId, BbmResType resType)
{
//baskId, negoId,
return Task.FromResult(dbController.ResourceGetLastDesc(anno, baskId, negoId, docId, resType));
}
public Task<double> ResourcesGetGrandTotal(int DocId)
{
return Task.FromResult(dbController.ResourceGetGrandTotal(DocId));
}
public void ResourceUpdate(CORE.DbModels.ResourcesModel currItem)
{
try
{
dbController.ResourceUpdate(currItem);
}
catch
{
}
}
public void ResourceUpdateOrder(int ResourceId, int move)
{
try
{
dbController.ResourceUpdateOrder(ResourceId, move);
}
catch
{
}
}
public void rollBackEdit(object item)
{
dbController.rollBackEntity(item);
}
public Task<decimal> SumTotDraft(int anno)
{
string source = "DB";
decimal dbResult = 0;
string currKey = $"{rKeyResoconti}:{anno}:SumTotDraft";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//string? rawData = await redisDb.StringGetAsync(currKey);
string? rawData = redisDb.StringGet(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
try
{
dbResult = JsonConvert.DeserializeObject<decimal>(rawData);
}
catch
{ }
}
else
{
dbResult = (decimal)dbController.SumTotDraft(anno);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDb.StringSet(currKey, rawData, LongCache);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"SumTotDraft | {source} in: {ts.TotalMilliseconds} ms");
return Task.FromResult(dbResult);
//return Task.FromResult(dbController.SumTotDraft(anno));
}
public Task<decimal> SumTotImporto(int anno)
{
string source = "DB";
decimal dbResult = 0;
string currKey = $"{rKeyResoconti}:{anno}:SumTotImporto";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//string? rawData = await redisDb.StringGetAsync(currKey);
string? rawData = redisDb.StringGet(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
try
{
dbResult = JsonConvert.DeserializeObject<decimal>(rawData);
}
catch
{ }
}
else
{
dbResult = dbController.SumTotImporto(anno);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDb.StringSet(currKey, rawData, LongCache);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"SumTotImporto | {source} in: {ts.TotalMilliseconds} ms");
return Task.FromResult(dbResult);
//return Task.FromResult(dbController.SumTotImporto(anno));
}
public Task<decimal> SumTotIncasso(int anno)
{
string source = "DB";
decimal dbResult = 0;
string currKey = $"{rKeyResoconti}:{anno}:SumTotIncasso";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//string? rawData = await redisDb.StringGetAsync(currKey);
string? rawData = redisDb.StringGet(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
try
{
dbResult = JsonConvert.DeserializeObject<decimal>(rawData);
}
catch
{ }
}
else
{
dbResult = dbController.SumTotIncasso(anno);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDb.StringSet(currKey, rawData, LongCache);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"SumTotIncasso | {source} in: {ts.TotalMilliseconds} ms");
return Task.FromResult(dbResult);
//return Task.FromResult(dbController.SumTotIncasso(anno));
}
public Task<decimal> SumTotOrdinato(int anno)
{
string source = "DB";
decimal dbResult = 0;
string currKey = $"{rKeyResoconti}:{anno}:SumTotOrdinato";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//string? rawData = await redisDb.StringGetAsync(currKey);
string? rawData = redisDb.StringGet(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
try
{
dbResult = JsonConvert.DeserializeObject<decimal>(rawData);
}
catch
{ }
}
else
{
dbResult = (decimal)dbController.SumTotOrdinato(anno);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDb.StringSet(currKey, rawData, LongCache);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"SumTotOrdinato | {source} in: {ts.TotalMilliseconds} ms");
return Task.FromResult(dbResult);
//return Task.FromResult(dbController.SumTotOrdinato(anno));
}
public Task<decimal> SumTotTrattato(int anno)
{
string source = "DB";
decimal dbResult = 0;
string currKey = $"{rKeyResoconti}:{anno}:SumTotTrattato";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//string? rawData = await redisDb.StringGetAsync(currKey);
string? rawData = redisDb.StringGet(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
try
{
dbResult = JsonConvert.DeserializeObject<decimal>(rawData);
}
catch
{ }
}
else
{
dbResult = (decimal)dbController.SumTotTrattato(anno);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
redisDb.StringSet(currKey, rawData, LongCache);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"SumTotTrattato | {source} in: {ts.TotalMilliseconds} ms");
return Task.FromResult(dbResult);
//return Task.FromResult(dbController.SumTotTrattato(anno));
}
public void TagDelete(CORE.DbModels.TagModel currRecord)
{
dbController.TagDelete(currRecord.TagId);
}
/// <summary>
/// Delete Tag2Item
/// </summary>
/// <param name="currRecord"></param>
public void TagItemDelete(CORE.DbModels.TagItemModel currRecord)
{
dbController.TagItemDelete(currRecord);
}
/// <summary>
/// Elenco tags dato item
/// </summary>
/// <param name="CompanyId"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public Task<List<CORE.DbModels.TagItemModel>> TagItemGetByItem(int itemId)
{
return Task.FromResult(dbController.TagItemGetByItem(itemId));
}
/// <summary>
/// Upsert Tag2Item
/// </summary>
/// <param name="currRecord"></param>
public void TagItemUpdate(CORE.DbModels.TagItemModel currRecord)
{
dbController.TagItemUpdate(currRecord);
}
/// <summary>
/// Elenco tags
/// </summary>
/// <param name="CompanyId"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public Task<List<CORE.DbModels.TagModel>> TagsGetAll(TagType selType)
{
return Task.FromResult(dbController.TagsGetAll(selType));
}
public void TagUpdate(CORE.DbModels.TagModel currRecord)
{
dbController.TagUpdate(currRecord);
}
#endregion Public Methods
#region Protected Fields
protected const string redisBaseAddr = "SHERPA:BBM-UI";
protected const string rKeyResoconti = $"{redisBaseAddr}:Cache:Resoconti";
protected static string connStringBBM = "";
protected static string connStringFatt = "";
protected static CORE.Controllers.BBMController dbController = null!;
protected Random rnd = new Random();
#endregion Protected Fields
#region Protected Methods
/// <summary>
/// Effettua upsert in HasList redis
/// </summary>
/// <param name="currKey">Chiave redis della Hashlist</param>
/// <param name="chiave">Chiave nella HashList</param>
/// <param name="valore">Valore da salvare</param>
/// <returns>Num record nella HashList</returns>
protected async Task<long> RedHashUpsert(RedisKey currKey, string chiave, string valore)
{
long numReq = 0;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
await redisDb.HashSetAsync(currKey, chiave, valore);
numReq = await redisDb.HashLengthAsync(currKey);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"RedHashUpsert | {currKey} | in: {ts.TotalMilliseconds} ms");
return numReq;
}
#endregion Protected Methods
#region Private Fields
private static IConfiguration _configuration = null!;
private static ILogger<BBM_EFService> _logger = null!;
private static JsonSerializerSettings? JSSettings;
private static Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// Durata cache lunga IN SECONDI
/// </summary>
private int cacheTtlLong = 60 * 5;
/// <summary>
/// Durata cache breve IN SECONDI
/// </summary>
private int cacheTtlShort = 60 * 1;
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private IConnectionMultiplexer redisConn;
//ISubscriber sub = redis.GetSubscriber();
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
#endregion Private Fields
#region Private Properties
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan FastCache
{
get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan LongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan UltraLongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
}
#endregion Private Properties
#region Private Methods
/// <summary>
/// Esegue flush memoria redis dato pattern
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
private async Task<bool> ExecFlushRedisPattern(RedisValue pattern)
{
bool answ = false;
var listEndpoints = redisConn.GetEndPoints();
foreach (var endPoint in listEndpoints)
{
//var server = redisConnAdmin.GetServer(listEndpoints[0]);
var server = redisConn.GetServer(endPoint);
if (server != null)
{
var keyList = server.Keys(redisDb.Database, pattern);
foreach (var item in keyList)
{
await redisDb.KeyDeleteAsync(item);
}
answ = true;
}
}
return answ;
}
#endregion Private Methods
}
}