using FMDAL.CustomCode.Meter; using FMDAL.DTO.Meter; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.QueryExecutor; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using static GB5Shared.GB5Constant.Constant; namespace FMBLL.Meter { public class MeterBLL : IMeterBLL { private readonly IMeterDAL _MeterDAL; private readonly IQueryExecutor _queryExecutor; private readonly AutoNumber _autoNumber; private readonly KeyInvalidate _keyInvalidate; private readonly ILogger _logger; public MeterBLL( IMeterDAL MeterDAL, IQueryExecutor queryExecutor, AutoNumber autoNumber, KeyInvalidate keyInvalidate, ILogger logger) { _MeterDAL = MeterDAL; _queryExecutor = queryExecutor; _autoNumber = autoNumber; _keyInvalidate = keyInvalidate; _logger = logger; } public async Task GetSelectListMeter(int FirstNumber, int MaxResult, CriteriaDTO CriteriaDTO, LoginDTO LoginDTO) { try { var result = await _MeterDAL.GetSelectListMeter(FirstNumber, MaxResult, CriteriaDTO, LoginDTO); return result; } catch (Exception ex) { throw new Exception($"Error in MeterBLL.GetSelectListMeter: {ex.Message}", ex); } } public async Task GetMeter(int meterId, LoginDTO login, CancellationToken ct) => await _MeterDAL.GetMeter(meterId, login, ct).ConfigureAwait(false); public async Task SaveMeter(MeterDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-meter", new { dto.MeterId }); if (string.IsNullOrWhiteSpace(dto.MeterName)) throw new ArgumentException("MeterName is required"); bool isNew = dto.MeterId == 0; GB5Trace.Step("save-meter", new { dto.MeterId, isNew }); await using var tx = await _queryExecutor.BeginTransactionAsync(login).ConfigureAwait(false); try { if (isNew) { var auto = await _autoNumber.GetNumberAsync(1, AUTONUMBERCONSTANT.METER, login).ConfigureAwait(false); dto.MeterId = auto.StartNumber; await _MeterDAL.SaveMeter(dto, login, tx, ct).ConfigureAwait(false); } else { await _MeterDAL.UpdateMeter(dto, login, tx, ct).ConfigureAwait(false); } await tx.CommitAsync(ct).ConfigureAwait(false); } catch { await tx.RollbackAsync(ct).ConfigureAwait(false); throw; } var cacheKey = new CacheKeyGeneration().KeyGeneration(dto.MeterId, EntityConstant.OBJECTMETER, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {dto.MeterId}" : SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-meter-failed", ex); _logger.LogError(ex, "SaveMeter failed for MeterId {Id}", dto.MeterId); throw; } } public async Task DeleteMeter(int meterId, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("delete-meter", new { meterId }); await using var tx = await _queryExecutor.BeginTransactionAsync(login).ConfigureAwait(false); try { await _MeterDAL.DeleteMeter(meterId, login.UserId, login, tx, ct).ConfigureAwait(false); await tx.CommitAsync(ct).ConfigureAwait(false); } catch { await tx.RollbackAsync(ct).ConfigureAwait(false); throw; } var cacheKey = new CacheKeyGeneration().KeyGeneration(meterId, EntityConstant.OBJECTMETER, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.DeleteSuccessMessage; } catch (Exception ex) { GB5Trace.MarkFailed("delete-meter-failed", ex); _logger.LogError(ex, "DeleteMeter failed for MeterId {Id}", meterId); throw; } } } }