using System.Transactions; using SIGCM2.Application.Abstractions; using SIGCM2.Application.Abstractions.Persistence; using SIGCM2.Application.Audit; using SIGCM2.Application.Common; namespace SIGCM2.Application.Pricing.ChargeableChars.Deactivate; /// /// PRC-001 — Handler for DeactivateChargeableCharConfigCommand. /// Flow: load existing → open TX → DeactivateAsync → audit → tx.Complete(). /// public sealed class DeactivateChargeableCharConfigCommandHandler : ICommandHandler { private readonly IChargeableCharConfigRepository _repo; private readonly IAuditLogger _audit; private readonly TimeProvider _timeProvider; public DeactivateChargeableCharConfigCommandHandler( IChargeableCharConfigRepository repo, IAuditLogger audit, TimeProvider timeProvider) { _repo = repo; _audit = audit; _timeProvider = timeProvider; } public async Task Handle( DeactivateChargeableCharConfigCommand command) { var today = _timeProvider.GetArgentinaToday(); // 1. Load existing — ensures the row exists. var existing = await _repo.GetByIdAsync(command.Id) ?? throw new KeyNotFoundException($"ChargeableCharConfig con Id={command.Id} no existe."); // 2. TX + deactivate + audit (fail-closed). using (var tx = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }, TransactionScopeAsyncFlowOption.Enabled)) { await _repo.DeactivateAsync(command.Id, today); await _audit.LogAsync( action: "tasacion.chargeable_char.deactivate", targetType: "ChargeableCharConfig", targetId: command.Id.ToString(), metadata: new { before = new { id = existing.Id, symbol = existing.Symbol, productTypeId = existing.ProductTypeId, validFrom = existing.ValidFrom.ToString("yyyy-MM-dd"), }, deactivatedOn = today.ToString("yyyy-MM-dd"), }); tx.Complete(); } return new DeactivateChargeableCharConfigResponse( Id: command.Id, ValidTo: today); } }