using System.ComponentModel.DataAnnotations; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.AutoNumber; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.EntityHandler; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using GB5Shared.Validation; using MarketingDAL.CustomCode.Advertisement; using MarketingDAL.DTO.Advertisement; using Microsoft.Extensions.Logging; using static GB5Shared.GB5Constant.Constant; namespace MarketingBLL.Advertisement; public class AdvertisementBLL : IAdvertisementBLL { private readonly IAdvertisementDAL _AdvertisementDAL; private readonly AutoNumber _AutoNumber; private readonly IValidation _Validation; private readonly KeyInvalidate _KeyInvalidate; private readonly BaseEntityAppService _BaseEntityAppService; private readonly ILogger _Logger; public AdvertisementBLL( IAdvertisementDAL advertisementDAL, AutoNumber autoNumber, IValidation validation, KeyInvalidate keyInvalidate, BaseEntityAppService baseEntityAppService, ILogger logger) { _AdvertisementDAL = advertisementDAL; _AutoNumber = autoNumber; _Validation = validation; _KeyInvalidate = keyInvalidate; _BaseEntityAppService = baseEntityAppService; _Logger = logger; } public async Task GetAdvertisement(int adId, LoginDTO loginDTO, CancellationToken ct) { try { return await _AdvertisementDAL.GetAdvertisement(adId, loginDTO, ct).ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-advertisement-failed", ex); _Logger.LogError(ex, "GetAdvertisement failed for AdId {AdId}", adId); throw; } } public async Task SaveAdvertisement(AdvertisementDTO advertisementDTO, LoginDTO loginDTO, CancellationToken ct) { if (advertisementDTO == null) throw new ArgumentNullException(nameof(advertisementDTO)); AutoNumberDTO? autoNumberDTO = null; try { GB5Trace.Step("validate-advertisement", new { advertisementDTO.AdId }); await _Validation.NotEmpty(advertisementDTO.AdCode, nameof(advertisementDTO.AdCode)); await _Validation.NotEmpty(advertisementDTO.AdName, nameof(advertisementDTO.AdName)); if (advertisementDTO.CampaignId == 0) advertisementDTO.CampaignId = -1; advertisementDTO.ModifiedById = loginDTO.UserId; advertisementDTO.ModifiedOn = DateTime.UtcNow; bool isNew = advertisementDTO.AdId == 0; if (isNew) { autoNumberDTO = await _AutoNumber.GetNumberAsync(1, "ADVERTISEMENT", loginDTO).ConfigureAwait(false); advertisementDTO.AdId = autoNumberDTO.StartNumber; advertisementDTO.CreatedById = loginDTO.UserId; advertisementDTO.CreatedOn = DateTime.UtcNow; } GB5Trace.Step("save-advertisement", new { advertisementDTO.AdId, isNew }); await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTMARKETINGADVERTISEMENT, isNew ? EventTypeConstant.SAVEMARKETINGADVERTISEMENTEVENTTYPEID : EventTypeConstant.UPDATEMARKETINGADVERTISEMENTEVENTTYPEID, advertisementDTO, loginDTO, async tx => { _ = isNew ? await _AdvertisementDAL.SaveAdvertisement(advertisementDTO, loginDTO, tx, ct).ConfigureAwait(false) : await _AdvertisementDAL.UpdateAdvertisement(advertisementDTO, loginDTO, tx, ct).ConfigureAwait(false); return advertisementDTO.AdId; }, null, -1, -1, null, isNew).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = isNew ? EventTypeConstant.SAVEMARKETINGADVERTISEMENTEVENTTYPEID : EventTypeConstant.UPDATEMARKETINGADVERTISEMENTEVENTTYPEID }); var cacheKey = new CacheKeyGeneration().KeyGeneration( advertisementDTO.AdId, EntityConstant.OBJECTMARKETINGADVERTISEMENT, CacheKeyLevel.CLIENT_LEVEL, loginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation("Advertisement {AdId} {Action} by user {UserId}", advertisementDTO.AdId, isNew ? "saved" : "updated", loginDTO.UserId); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {advertisementDTO.AdId}" : $"{SuccessResponse.UpdateSuccessMessage} {advertisementDTO.AdId}"; } catch (ValidationException vex) { GB5Trace.MarkFailed("save-advertisement-failed", vex); if (autoNumberDTO != null && advertisementDTO.AdId > 0) await _AutoNumber.RollbackAutoNumber("ADVERTISEMENT", advertisementDTO.AdId, loginDTO).ConfigureAwait(false); throw new Exception(vex.Message); } catch (Exception ex) { GB5Trace.MarkFailed("save-advertisement-failed", ex); _Logger.LogError(ex, "SaveAdvertisement failed for AdId {AdId}", advertisementDTO.AdId); if (autoNumberDTO != null && advertisementDTO.AdId > 0) await _AutoNumber.RollbackAutoNumber("ADVERTISEMENT", advertisementDTO.AdId, loginDTO).ConfigureAwait(false); throw; } } public async Task GetSelectListAdvertisement(CriteriaDTO criteriaDTO, LoginDTO loginDTO, CancellationToken ct) { try { return await _AdvertisementDAL.GetSelectListAdvertisement(criteriaDTO, loginDTO, ct).ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-selectlist-advertisement-failed", ex); _Logger.LogError(ex, "GetSelectListAdvertisement failed"); throw; } } public async Task DeleteAdvertisement(int adId, LoginDTO loginDTO, CancellationToken ct) { try { GB5Trace.Step("delete-advertisement", new { adId }); var result = await _AdvertisementDAL.DeleteAdvertisement(adId, loginDTO, ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( adId, EntityConstant.OBJECTMARKETINGADVERTISEMENT, CacheKeyLevel.CLIENT_LEVEL, loginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation("Advertisement {AdId} deleted by user {UserId}", adId, loginDTO.UserId); return result; } catch (Exception ex) { GB5Trace.MarkFailed("delete-advertisement-failed", ex); _Logger.LogError(ex, "DeleteAdvertisement failed for AdId {AdId}", adId); throw; } } }