using AnalyticsDAL.CustomCode.ReportConfig; using AnalyticsDAL.DTO.ReportConfig; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Login; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using Microsoft.Extensions.Logging; using static GB5Shared.GB5Constant.Constant; namespace AnalyticsBLL.ReportConfig { public class ReportConfigBLL : IReportConfigBLL { private readonly IReportConfigDAL _dal; private readonly KeyInvalidate _keyInvalidate; private readonly ILogger _logger; public ReportConfigBLL( IReportConfigDAL dal, KeyInvalidate keyInvalidate, ILogger logger) { _dal = dal; _keyInvalidate = keyInvalidate; _logger = logger; } public async Task GetReportConfig(int reportConfigId, LoginDTO login, CancellationToken ct) => await _dal.GetReportConfig(reportConfigId, login, ct).ConfigureAwait(false); public async Task GetReportConfigByReport(int reportId, LoginDTO login, CancellationToken ct) => await _dal.GetReportConfigByReport(reportId, login, ct).ConfigureAwait(false); public async Task SaveReportConfig(ReportConfigDTO dto, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-reportconfig", new { dto.ReportConfigId, dto.ReportId }); if (dto.ReportId <= 0) throw new ArgumentException("ReportId is required."); if (dto.DataSourceType > 3) throw new ArgumentException("DataSourceType must be 0–3."); if (dto.ReportCategory > 4) throw new ArgumentException("ReportCategory must be 0–4."); if (dto.PivotEngine > 2) throw new ArgumentException("PivotEngine must be 0–2."); if (dto.AsyncThresholdRows <= 0) throw new ArgumentException("AsyncThresholdRows must be greater than 0."); if (dto.MaxExportRows < dto.AsyncThresholdRows) throw new ArgumentException("MaxExportRows must be >= AsyncThresholdRows."); var isNew = dto.ReportConfigId == 0; if (await _dal.IsDuplicateReport(dto.ReportId, dto.ReportConfigId, login, ct).ConfigureAwait(false)) throw new InvalidOperationException($"A ReportConfig already exists for ReportId {dto.ReportId}."); dto.SourceType = isNew ? (byte)4 : dto.SourceType; GB5Trace.Step("save-reportconfig", new { dto.ReportConfigId, dto.ReportId, isNew }); int savedId; if (isNew) savedId = await _dal.SaveReportConfig(dto, login, ct).ConfigureAwait(false); else { savedId = dto.ReportConfigId; await _dal.UpdateReportConfig(dto, login, ct).ConfigureAwait(false); } var cacheKey = new CacheKeyGeneration().KeyGeneration( dto.ReportId, EntityConstant.OBJECTANALYSIS, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {savedId}" : SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-reportconfig-failed", ex); _logger.LogError(ex, "SaveReportConfig failed for ReportId {Id}", dto.ReportId); throw; } } public async Task DeleteReportConfig(int reportConfigId, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("delete-reportconfig", new { reportConfigId }); await _dal.DeleteReportConfig(reportConfigId, login, ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( reportConfigId, EntityConstant.OBJECTANALYSIS, CacheKeyLevel.CLIENT_LEVEL, login); await _keyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.DeleteSuccessMessage; } catch (Exception ex) { GB5Trace.MarkFailed("delete-reportconfig-failed", ex); _logger.LogError(ex, "DeleteReportConfig failed for ReportConfigId {Id}", reportConfigId); throw; } } public async Task GetSelectListReportConfig(LoginDTO login, CancellationToken ct) { try { return await _dal.GetSelectListReportConfig(login, ct).ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-selectlist-reportconfig-failed", ex); _logger.LogError(ex, "GetSelectListReportConfig failed for ClientId {Id}", login.ClientId); throw; } } } }