using AccountsDAL.CustomCode.PartyOU; using AccountsDAL.DTO.AccountGroup; using AccountsDAL.DTO.PartyOU; using Dapr.Client; using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.HybridCache; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Qualifier; using GB5Shared.EntityHandler; using GB5Shared.GB5Library.Qualifier; using GB5Shared.GenerateAutoNumber; using GB5Shared.PubSub.OutBox; using GB5Shared.QueryExecutor; using GB5Shared.Resource.Response; using GB5Shared.WorkFlow.WorkFlowEngine; using static GB5Shared.GB5Constant.Constant; namespace AccountsBLL.PartyOU { public class PartyOUBLL : IPartyOUBLL { private readonly IPartyOUDAL _PartyOUDAL; private readonly AutoNumber _AutoNumber; private readonly IWorkFlowEngine _WorkFlowEngine; private readonly IQueryExecutor _QueryExecutor; private readonly IOutBox _OutBox; private readonly KeyInvalidate _KeyInvalidate; private readonly DaprClient _DaprClient; private readonly BaseEntityAppService _BaseEntityAppService; public PartyOUBLL( IPartyOUDAL partyOUDAL, AutoNumber autoNumber, IWorkFlowEngine workFlowEngine, IQueryExecutor queryExecutor, IOutBox outBox, KeyInvalidate keyInvalidate, DaprClient daprClient, BaseEntityAppService baseEntityAppService) { _PartyOUDAL = partyOUDAL; _AutoNumber = autoNumber; _WorkFlowEngine = workFlowEngine; _QueryExecutor = queryExecutor; _OutBox = outBox; _KeyInvalidate = keyInvalidate; _DaprClient = daprClient; _BaseEntityAppService = baseEntityAppService; } public async Task GetPartyOU(int partyOUId, LoginDTO loginDTO) { try { return await _PartyOUDAL.GetPartyOU(partyOUId, loginDTO) .ConfigureAwait(false); } catch (Exception) { throw; } } public async Task SavePartyOU(PartyOUDTO dto, LoginDTO loginDTO) { var Trans = await _QueryExecutor.BeginTransactionAsync(loginDTO); try { bool isNew = dto.PartyOUId == 0; if (isNew) { var auto = await _AutoNumber.GetNumberAsync(1, AUTONUMBERCONSTANT.PARTYOU, loginDTO) .ConfigureAwait(false); dto.PartyOUId = auto.StartNumber; } dto.PartyOUSourceType = loginDTO.SourceType; //var definitions = new List(); //var executors = new List(); //var engine = new QualifierEngine((IQualifierDefinitionLoader)definitions, executors); //var facade = new QualifierFacade(engine); //var baseSvc = new BaseEntityAppService( // facade, _WorkFlowEngine, _OutBox, _QueryExecutor, _DaprClient); await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTPARTYOU, EventTypeConstant.SAVEPARTYOUEVENTTYPEID, dto, loginDTO, async tx => { if (isNew) await _PartyOUDAL.SavePartyOU(dto, loginDTO, tx).ConfigureAwait(false); else await _PartyOUDAL.UpdatePartyOU(dto, loginDTO, tx).ConfigureAwait(false); return dto.PartyOUId; }, null, -1, -1, Trans); await _QueryExecutor.CommitAsync(Trans); // Cache invalidation is a best-effort side effect on data that's already durably // committed above — a Dapr/statestore outage here must never surface as a save // failure to the client (and must never trigger the catch block's RollbackAsync, // which would be invalid against an already-committed transaction). try { var cacheKey = CacheKeyGenerator.KeyGeneration( dto.PartyOUId, EntityConstant.OBJECTPARTYOU, CacheKeyLevel.CLIENT_LEVEL, string.Empty, loginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey); } catch (Exception) { // Swallow — the save already succeeded; a stale cache entry is recoverable, // an incorrectly-reported save failure is not. } return isNew ? SuccessResponse.SaveSuccess : SuccessResponse.UpdateSuccess; } catch (Exception) { await _QueryExecutor.RollbackAsync(Trans); throw; } } public async Task DeletePartyOU(int partyOUId, LoginDTO loginDTO) { var Trans = await _QueryExecutor.BeginTransactionAsync(loginDTO); try { //var definitions = new List(); //var executors = new List(); //var engine = new QualifierEngine((IQualifierDefinitionLoader)definitions, executors); //var facade = new QualifierFacade(engine); //var baseSvc = new BaseEntityAppService( // facade, _WorkFlowEngine, _OutBox, _QueryExecutor, _DaprClient); await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTPARTYOU, EventTypeConstant.DELETEPARTYOUEVENTTYPEID, new PartyOUDTO { PartyOUId = partyOUId }, loginDTO, async tx => { await _PartyOUDAL.DeletePartyOU(partyOUId, loginDTO, tx) .ConfigureAwait(false); return partyOUId; }, null, -1, -1, Trans); await _QueryExecutor.CommitAsync(Trans); // See SavePartyOU — cache invalidation must never turn an already-committed // delete into a reported failure, nor trigger a RollbackAsync post-commit. try { var cacheKey = CacheKeyGenerator.KeyGeneration( partyOUId, EntityConstant.OBJECTPARTYOU, CacheKeyLevel.CLIENT_LEVEL, string.Empty, loginDTO); await _KeyInvalidate.AllInvalidateCache(cacheKey); } catch (Exception) { // Swallow — see SavePartyOU for rationale. } return SuccessResponse.DeleteSuccessMessage; } catch (Exception) { await _QueryExecutor.RollbackAsync(Trans); throw; } } public async Task GetSelectListPartyOU(CriteriaDTO criteriaDTO, LoginDTO loginDTO) { try { return await _PartyOUDAL.GetSelectListPartyOU(criteriaDTO, loginDTO) .ConfigureAwait(false); } catch (Exception) { throw; } } } }