using System.Transactions; using SIGCM2.Application.Abstractions; using SIGCM2.Application.Abstractions.Persistence; using SIGCM2.Application.Audit; using SIGCM2.Domain.Exceptions; namespace SIGCM2.Application.Rubros.Deactivate; public sealed class DeactivateRubroCommandHandler : ICommandHandler { private readonly IRubroRepository _repo; private readonly IAuditLogger _audit; private readonly IProductQueryRepository _productQuery; private readonly TimeProvider _timeProvider; public DeactivateRubroCommandHandler( IRubroRepository repo, IAuditLogger audit, IProductQueryRepository productQuery, TimeProvider timeProvider) { _repo = repo; _audit = audit; _productQuery = productQuery; _timeProvider = timeProvider; } public async Task Handle(DeactivateRubroCommand command) { var target = await _repo.GetByIdAsync(command.Id) ?? throw new RubroNotFoundException(command.Id); var activeChildren = await _repo.CountActiveChildrenAsync(command.Id); if (activeChildren > 0) throw new RubroTieneHijosActivosException(command.Id, activeChildren); var productosActivos = await _productQuery.CountActiveByRubroAsync(command.Id); if (productosActivos > 0) throw new RubroConProductosActivosException(command.Id, productosActivos); var deactivated = target.WithActivo(false, _timeProvider); using var tx = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }, TransactionScopeAsyncFlowOption.Enabled); await _repo.UpdateAsync(deactivated); await _audit.LogAsync( action: "rubro.deleted", targetType: "Rubro", targetId: command.Id.ToString(), metadata: new { rubroId = command.Id, nombre = target.Nombre, activeChildrenCount = 0, }); tx.Complete(); return new RubroStatusDto(Id: deactivated.Id, Activo: deactivated.Activo); } }