using GB5Shared.DaprCache; using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using GB5Shared.Resource.Response; using IDMSDAL.DTOs; using IDMSDAL.Interfaces; using IDMSBLL.Interfaces; using static GB5Shared.GB5Constant.Constant; using GB5Shared.EntityHandler; namespace IDMSBLL.Implementations; public class ReworkBLL : IReworkBLL { private readonly IReworkDAL _ReworkDAL; private readonly IQueryExecutor _QueryExecutor; private readonly KeyInvalidate _KeyInvalidate; private readonly BaseEntityAppService _BaseEntityAppService; public ReworkBLL( IReworkDAL reworkDAL, IQueryExecutor queryExecutor, KeyInvalidate keyInvalidate, BaseEntityAppService baseEntityAppService) { _ReworkDAL = reworkDAL; _QueryExecutor = queryExecutor; _KeyInvalidate = keyInvalidate; _BaseEntityAppService = baseEntityAppService; } // ── Reads ───────────────────────────────────────────────────────────────── public async Task GetReworkAsync( int reworkId, LoginDTO login, CancellationToken ct) { return await _ReworkDAL.GetReworkAsync(reworkId, login, ct) .ConfigureAwait(false); } public async Task> GetReworkByEngagementAsync( int engagementId, LoginDTO login, CancellationToken ct) { return await _ReworkDAL.GetReworkByEngagementAsync(engagementId, login, ct) .ConfigureAwait(false); } // ── Writes ──────────────────────────────────────────────────────────────── public async Task SaveReworkAsync( ReworkDTO dto, LoginDTO login, CancellationToken ct) { if (dto is null) throw new ArgumentNullException(nameof(dto)); if (dto.ReasonCode == 0) throw new ArgumentException("ReasonCode is required.", nameof(dto)); if (dto.DeliveryItemId == 0) throw new ArgumentException("DeliveryItemId is required.", nameof(dto)); var Trans = await _QueryExecutor.BeginTransactionAsync(login).ConfigureAwait(false); try { await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTIDMSREWORK, EventTypeConstant.SAVEIDMSREWORKEVENTTYPEID, dto, login, async tx => { int newId = await _ReworkDAL.SaveReworkAsync(dto, login, tx, ct).ConfigureAwait(false); dto.ReworkId = newId; return dto.ReworkId; }, new Dictionary { { "EngagementId", dto.EngagementId } }, BIZTRANSACTIONCLASSCONSTANT.IDMSREWORK, BizTransactionConstant.IDMSREWORK, Trans).ConfigureAwait(false); await _QueryExecutor.CommitAsync(Trans).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( dto.EngagementId, EntityConstant.OBJECTIDMSREWORK, CacheKeyLevel.CLIENT_LEVEL, login); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.SaveSuccess; } catch (Exception) { await _QueryExecutor.RollbackAsync(Trans).ConfigureAwait(false); throw; } } public async Task ResolveReworkAsync( int reworkId, int resolvedById, LoginDTO login, CancellationToken ct) { var rework = await _ReworkDAL.GetReworkAsync(reworkId, login, ct) .ConfigureAwait(false) ?? throw new InvalidOperationException($"Rework item {reworkId} not found."); if (rework.ResolvedOn.HasValue) throw new InvalidOperationException("Rework item is already resolved."); var Trans = await _QueryExecutor.BeginTransactionAsync(login).ConfigureAwait(false); try { await _BaseEntityAppService.ExecuteSaveAsync( EntityConstant.OBJECTIDMSREWORK, EventTypeConstant.RESOLVEIDMSREWORKEVENTTYPEID, rework, login, async tx => { await _ReworkDAL.ResolveReworkAsync( reworkId, resolvedById, DateTime.UtcNow, login, tx, ct).ConfigureAwait(false); return reworkId; }, new Dictionary { { "EngagementId", rework.EngagementId } }, BIZTRANSACTIONCLASSCONSTANT.IDMSREWORK, BizTransactionConstant.IDMSREWORK, Trans).ConfigureAwait(false); await _QueryExecutor.CommitAsync(Trans).ConfigureAwait(false); var cacheKey = new CacheKeyGeneration().KeyGeneration( rework.EngagementId, EntityConstant.OBJECTIDMSREWORK, CacheKeyLevel.CLIENT_LEVEL, login); await _KeyInvalidate.AllInvalidateCache(cacheKey).ConfigureAwait(false); return SuccessResponse.UpdateSuccess; } catch (Exception) { await _QueryExecutor.RollbackAsync(Trans).ConfigureAwait(false); throw; } } }