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.Persona; using MarketingDAL.DTO.Persona; using Microsoft.Extensions.Logging; using static GB5Shared.GB5Constant.Constant; namespace MarketingBLL.Persona; public class PersonaBLL : IPersonaBLL { private readonly IPersonaDAL _PersonaDAL; private readonly AutoNumber _AutoNumber; private readonly IValidation _Validation; private readonly KeyInvalidate _KeyInvalidate; private readonly BaseEntityAppService _BaseEntityAppService; private readonly ILogger _Logger; public PersonaBLL( IPersonaDAL personaDAL, AutoNumber autoNumber, IValidation validation, KeyInvalidate keyInvalidate, BaseEntityAppService baseEntityAppService, ILogger logger) { _PersonaDAL = personaDAL; _AutoNumber = autoNumber; _Validation = validation; _KeyInvalidate = keyInvalidate; _BaseEntityAppService = baseEntityAppService; _Logger = logger; } public async Task GetPersona(int personaId, LoginDTO loginDTO, CancellationToken ct) { try { return await _PersonaDAL.GetPersona(personaId, loginDTO, ct).ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-persona-failed", ex); _Logger.LogError(ex, "GetPersona failed for PersonaId {PersonaId}", personaId); throw; } } public async Task SavePersona(PersonaDTO personaDTO, LoginDTO loginDTO, CancellationToken ct) { if (personaDTO == null) throw new ArgumentNullException(nameof(personaDTO)); AutoNumberDTO? autoNumberDTO = null; try { GB5Trace.Step("validate-persona", new { personaDTO.PersonaId }); await _Validation.NotEmpty(personaDTO.PersonaCode, nameof(personaDTO.PersonaCode)); await _Validation.NotEmpty(personaDTO.PersonaName, nameof(personaDTO.PersonaName)); if (personaDTO.ICPId == 0) personaDTO.ICPId = -1; personaDTO.ModifiedById = loginDTO.UserId; personaDTO.ModifiedOn = DateTime.UtcNow; bool isNew = personaDTO.PersonaId == 0; if (isNew) { autoNumberDTO = await _AutoNumber.GetNumberAsync(1, "PERSONA", loginDTO).ConfigureAwait(false); personaDTO.PersonaId = autoNumberDTO.StartNumber; personaDTO.CreatedById = loginDTO.UserId; personaDTO.CreatedOn = DateTime.UtcNow; } GB5Trace.Step("save-persona", new { personaDTO.PersonaId, isNew }); await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTMARKETINGPERSONA, isNew ? EventTypeConstant.SAVEMARKETINGPERSONAEVENTTYPEID : EventTypeConstant.UPDATEMARKETINGPERSONAEVENTTYPEID, personaDTO, loginDTO, async tx => { _ = isNew ? await _PersonaDAL.SavePersona(personaDTO, loginDTO, tx, ct).ConfigureAwait(false) : await _PersonaDAL.UpdatePersona(personaDTO, loginDTO, tx, ct).ConfigureAwait(false); return personaDTO.PersonaId; }, null, -1, -1, null, isNew).ConfigureAwait(false); GB5Trace.Step("event-publish", new { EventTypeId = isNew ? EventTypeConstant.SAVEMARKETINGPERSONAEVENTTYPEID : EventTypeConstant.UPDATEMARKETINGPERSONAEVENTTYPEID }); var cacheKey = new CacheKeyGeneration().KeyGeneration( personaDTO.PersonaId, EntityConstant.OBJECTMARKETINGPERSONA, CacheKeyLevel.CLIENT_LEVEL, loginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation("Persona {PersonaId} {Action} by user {UserId}", personaDTO.PersonaId, isNew ? "saved" : "updated", loginDTO.UserId); return isNew ? $"{SuccessResponse.SaveSuccessMessage} {personaDTO.PersonaId}" : $"{SuccessResponse.UpdateSuccessMessage} {personaDTO.PersonaId}"; } catch (ValidationException vex) { GB5Trace.MarkFailed("save-persona-failed", vex); if (autoNumberDTO != null && personaDTO.PersonaId > 0) await _AutoNumber.RollbackAutoNumber("PERSONA", personaDTO.PersonaId, loginDTO).ConfigureAwait(false); throw new Exception(vex.Message); } catch (Exception ex) { GB5Trace.MarkFailed("save-persona-failed", ex); _Logger.LogError(ex, "SavePersona failed for PersonaId {PersonaId}", personaDTO.PersonaId); if (autoNumberDTO != null && personaDTO.PersonaId > 0) await _AutoNumber.RollbackAutoNumber("PERSONA", personaDTO.PersonaId, loginDTO).ConfigureAwait(false); throw; } } public async Task GetSelectListPersona(CriteriaDTO criteriaDTO, LoginDTO loginDTO, CancellationToken ct) { try { return await _PersonaDAL.GetSelectListPersona(criteriaDTO, loginDTO, ct).ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("get-selectlist-persona-failed", ex); _Logger.LogError(ex, "GetSelectListPersona failed"); throw; } } public async Task DeletePersona(int personaId, LoginDTO loginDTO, CancellationToken ct) { try { GB5Trace.Step("delete-persona", new { personaId }); var result = await _PersonaDAL.DeletePersona(personaId, loginDTO, ct).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( personaId, EntityConstant.OBJECTMARKETINGPERSONA, CacheKeyLevel.CLIENT_LEVEL, loginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); _Logger.LogInformation("Persona {PersonaId} deleted by user {UserId}", personaId, loginDTO.UserId); return result; } catch (Exception ex) { GB5Trace.MarkFailed("delete-persona-failed", ex); _Logger.LogError(ex, "DeletePersona failed for PersonaId {PersonaId}", personaId); throw; } } }