diff --git a/src/api/SIGCM2.Api/Controllers/PuntosDeVentaController.cs b/src/api/SIGCM2.Api/Controllers/PuntosDeVentaController.cs
index cc3b2c2..0ebffb9 100644
--- a/src/api/SIGCM2.Api/Controllers/PuntosDeVentaController.cs
+++ b/src/api/SIGCM2.Api/Controllers/PuntosDeVentaController.cs
@@ -7,11 +7,8 @@ using SIGCM2.Application.PuntosDeVenta.Create;
using SIGCM2.Application.PuntosDeVenta.Deactivate;
using SIGCM2.Application.PuntosDeVenta.GetById;
using SIGCM2.Application.PuntosDeVenta.List;
-using SIGCM2.Application.PuntosDeVenta.ProximoNumero;
using SIGCM2.Application.PuntosDeVenta.Reactivate;
-using SIGCM2.Application.PuntosDeVenta.Reservar;
using SIGCM2.Application.PuntosDeVenta.Update;
-using SIGCM2.Domain.Enums;
namespace SIGCM2.Api.Controllers;
@@ -160,34 +157,6 @@ public sealed class PuntosDeVentaController : ControllerBase
return NoContent();
}
- /// Reserves the next sequential number for a given PdV and TipoComprobante.
- [HttpPost("{id:int}/secuencias/{tipoComprobante}/reservar")]
- [RequirePermission("administracion:puntos_de_venta:gestionar")]
- [ProducesResponseType(typeof(ReservaNumeroDto), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status401Unauthorized)]
- [ProducesResponseType(StatusCodes.Status403Forbidden)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- [ProducesResponseType(StatusCodes.Status409Conflict)]
- public async Task ReservarNumero([FromRoute] int id, [FromRoute] TipoComprobante tipoComprobante)
- {
- var command = new ReservarNumeroCommand(id, tipoComprobante);
- var result = await _dispatcher.Send(command);
- return Ok(result);
- }
-
- /// Returns the next available number (read-only, no reservation).
- [HttpGet("{id:int}/secuencias/{tipoComprobante}/proximo")]
- [RequirePermission("administracion:puntos_de_venta:gestionar")]
- [ProducesResponseType(typeof(ProximoNumeroDto), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status401Unauthorized)]
- [ProducesResponseType(StatusCodes.Status403Forbidden)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- public async Task GetProximoNumero([FromRoute] int id, [FromRoute] TipoComprobante tipoComprobante)
- {
- var query = new GetProximoNumeroQuery(id, tipoComprobante);
- var result = await _dispatcher.Send(query);
- return Ok(result);
- }
}
// ── Request body records ──────────────────────────────────────────────────────
diff --git a/src/api/SIGCM2.Api/Filters/ExceptionFilter.cs b/src/api/SIGCM2.Api/Filters/ExceptionFilter.cs
index 35fb5be..b86c0e2 100644
--- a/src/api/SIGCM2.Api/Filters/ExceptionFilter.cs
+++ b/src/api/SIGCM2.Api/Filters/ExceptionFilter.cs
@@ -244,18 +244,6 @@ public sealed class ExceptionFilter : IExceptionFilter
context.ExceptionHandled = true;
break;
- case PuntoDeVentaInactivoException puntoDeVentaInactivoEx:
- context.Result = new ObjectResult(new
- {
- error = "punto_de_venta_inactivo",
- message = puntoDeVentaInactivoEx.Message
- })
- {
- StatusCode = StatusCodes.Status409Conflict
- };
- context.ExceptionHandled = true;
- break;
-
case NumeroAFIPDuplicadoException numeroAFIPDupEx:
context.Result = new ObjectResult(new
{
diff --git a/src/api/SIGCM2.Application/Abstractions/Persistence/IPuntoDeVentaRepository.cs b/src/api/SIGCM2.Application/Abstractions/Persistence/IPuntoDeVentaRepository.cs
index 5d5cabd..eb6cf04 100644
--- a/src/api/SIGCM2.Application/Abstractions/Persistence/IPuntoDeVentaRepository.cs
+++ b/src/api/SIGCM2.Application/Abstractions/Persistence/IPuntoDeVentaRepository.cs
@@ -1,6 +1,5 @@
using SIGCM2.Application.Common;
using SIGCM2.Domain.Entities;
-using SIGCM2.Domain.Enums;
namespace SIGCM2.Application.Abstractions.Persistence;
@@ -11,6 +10,4 @@ public interface IPuntoDeVentaRepository
Task ExistsByNumeroAFIPInMedioAsync(int medioId, short numeroAFIP, int? excludeId = null, CancellationToken ct = default);
Task UpdateAsync(PuntoDeVenta pdv, CancellationToken ct = default);
Task> GetPagedAsync(PuntosDeVentaQuery q, CancellationToken ct = default);
- Task ReservarNumeroAsync(int puntoDeVentaId, TipoComprobante tipo, CancellationToken ct = default);
- Task GetUltimoNumeroAsync(int puntoDeVentaId, TipoComprobante tipo, CancellationToken ct = default);
}
diff --git a/src/api/SIGCM2.Application/DependencyInjection.cs b/src/api/SIGCM2.Application/DependencyInjection.cs
index 83e0276..cda65d3 100644
--- a/src/api/SIGCM2.Application/DependencyInjection.cs
+++ b/src/api/SIGCM2.Application/DependencyInjection.cs
@@ -25,9 +25,7 @@ using SIGCM2.Application.PuntosDeVenta.Create;
using SIGCM2.Application.PuntosDeVenta.Deactivate;
using SIGCM2.Application.PuntosDeVenta.GetById;
using SIGCM2.Application.PuntosDeVenta.List;
-using SIGCM2.Application.PuntosDeVenta.ProximoNumero;
using SIGCM2.Application.PuntosDeVenta.Reactivate;
-using SIGCM2.Application.PuntosDeVenta.Reservar;
using SIGCM2.Application.PuntosDeVenta.Update;
using SIGCM2.Application.Secciones.Create;
using SIGCM2.Application.Secciones.Deactivate;
@@ -105,8 +103,6 @@ public static class DependencyInjection
services.AddScoped, ReactivatePuntoDeVentaCommandHandler>();
services.AddScoped>, ListPuntosDeVentaQueryHandler>();
services.AddScoped, GetPuntoDeVentaByIdQueryHandler>();
- services.AddScoped, ReservarNumeroCommandHandler>();
- services.AddScoped, GetProximoNumeroQueryHandler>();
// FluentValidation validators (scans entire Application assembly)
services.AddValidatorsFromAssemblyContaining();
diff --git a/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/GetProximoNumeroQuery.cs b/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/GetProximoNumeroQuery.cs
deleted file mode 100644
index 7fb0ada..0000000
--- a/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/GetProximoNumeroQuery.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using SIGCM2.Domain.Enums;
-
-namespace SIGCM2.Application.PuntosDeVenta.ProximoNumero;
-
-public sealed record GetProximoNumeroQuery(int PuntoDeVentaId, TipoComprobante TipoComprobante);
diff --git a/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/GetProximoNumeroQueryHandler.cs b/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/GetProximoNumeroQueryHandler.cs
deleted file mode 100644
index e0c930c..0000000
--- a/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/GetProximoNumeroQueryHandler.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using SIGCM2.Application.Abstractions;
-using SIGCM2.Application.Abstractions.Persistence;
-
-namespace SIGCM2.Application.PuntosDeVenta.ProximoNumero;
-
-///
-/// Consulta el próximo número disponible sin reservarlo (read-only, REQ-SEC-CMB-005).
-/// Retorna UltimoNumero+1; si no existe fila devuelve 1.
-///
-public sealed class GetProximoNumeroQueryHandler : ICommandHandler
-{
- private readonly IPuntoDeVentaRepository _repo;
-
- public GetProximoNumeroQueryHandler(IPuntoDeVentaRepository repo)
- {
- _repo = repo;
- }
-
- public async Task Handle(GetProximoNumeroQuery query)
- {
- var ultimoNumero = await _repo.GetUltimoNumeroAsync(query.PuntoDeVentaId, query.TipoComprobante);
-
- var proximo = ultimoNumero.HasValue ? ultimoNumero.Value + 1 : 1;
-
- return new ProximoNumeroDto(query.TipoComprobante, proximo);
- }
-}
diff --git a/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/ProximoNumeroDto.cs b/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/ProximoNumeroDto.cs
deleted file mode 100644
index 3b2fb8f..0000000
--- a/src/api/SIGCM2.Application/PuntosDeVenta/ProximoNumero/ProximoNumeroDto.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using SIGCM2.Domain.Enums;
-
-namespace SIGCM2.Application.PuntosDeVenta.ProximoNumero;
-
-public sealed record ProximoNumeroDto(TipoComprobante TipoComprobante, int ProximoNumero);
diff --git a/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservaNumeroDto.cs b/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservaNumeroDto.cs
deleted file mode 100644
index 1544c7e..0000000
--- a/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservaNumeroDto.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using SIGCM2.Domain.Enums;
-
-namespace SIGCM2.Application.PuntosDeVenta.Reservar;
-
-public sealed record ReservaNumeroDto(TipoComprobante TipoComprobante, int NumeroReservado);
diff --git a/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservarNumeroCommand.cs b/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservarNumeroCommand.cs
deleted file mode 100644
index 44d4918..0000000
--- a/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservarNumeroCommand.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using SIGCM2.Domain.Enums;
-
-namespace SIGCM2.Application.PuntosDeVenta.Reservar;
-
-public sealed record ReservarNumeroCommand(int PuntoDeVentaId, TipoComprobante TipoComprobante);
diff --git a/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservarNumeroCommandHandler.cs b/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservarNumeroCommandHandler.cs
deleted file mode 100644
index 86896e7..0000000
--- a/src/api/SIGCM2.Application/PuntosDeVenta/Reservar/ReservarNumeroCommandHandler.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using SIGCM2.Application.Abstractions;
-using SIGCM2.Application.Abstractions.Persistence;
-using SIGCM2.Domain.Exceptions;
-
-namespace SIGCM2.Application.PuntosDeVenta.Reservar;
-
-///
-/// Reserva el próximo número correlativo para (PdvId × TipoComprobante) ejecutando
-/// usp_ReservarNumeroComprobante vía el repositorio.
-///
-/// NOTAS DE DISEÑO (AD4, AD9):
-/// - NO se envuelve en TransactionScope: el SP ya es atómico bajo SERIALIZABLE.
-/// Un TransactionScope ambiente aquí escalaría a DTC → innecesario.
-/// - NO usa Polly: no está en el proyecto. Retry deadlock con bucle simple.
-/// - Infrastructure traduce SqlException 1205 → DeadlockTransientException.
-/// - Backoff en ms: [25, 75, 200, 500, 1200] — 5 retries máximo (6 intentos totales).
-/// - La auditoría de reservas corre solo vía Temporal Tables (AD8).
-///
-public sealed class ReservarNumeroCommandHandler : ICommandHandler
-{
- private readonly IPuntoDeVentaRepository _repo;
- private readonly int[] _deadlockBackoffMs;
-
- private static readonly int[] DefaultBackoffMs = [25, 75, 200, 500, 1200];
-
- public ReservarNumeroCommandHandler(IPuntoDeVentaRepository repo)
- : this(repo, DefaultBackoffMs) { }
-
- /// Constructor with custom backoff for testing (e.g., [0,0,0] for fast tests).
- public ReservarNumeroCommandHandler(IPuntoDeVentaRepository repo, int[] deadlockBackoffMs)
- {
- _repo = repo;
- _deadlockBackoffMs = deadlockBackoffMs;
- }
-
- public async Task Handle(ReservarNumeroCommand command)
- {
- for (var i = 0; ; i++)
- {
- try
- {
- var numero = await _repo.ReservarNumeroAsync(command.PuntoDeVentaId, command.TipoComprobante);
- return new ReservaNumeroDto(command.TipoComprobante, numero);
- }
- catch (DeadlockTransientException) when (i < _deadlockBackoffMs.Length)
- {
- // Deadlock — retry with backoff
- await Task.Delay(_deadlockBackoffMs[i]);
- }
- // All other exceptions bubble up immediately
- }
- }
-}
diff --git a/src/api/SIGCM2.Domain/Entities/SecuenciaComprobante.cs b/src/api/SIGCM2.Domain/Entities/SecuenciaComprobante.cs
deleted file mode 100644
index c936c67..0000000
--- a/src/api/SIGCM2.Domain/Entities/SecuenciaComprobante.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using SIGCM2.Domain.Enums;
-
-namespace SIGCM2.Domain.Entities;
-
-///
-/// Lleva el correlativo de números de comprobante por (PuntoDeVentaId × TipoComprobante).
-/// La reserva atómica la ejecuta usp_ReservarNumeroComprobante directamente en BD.
-/// Este objeto es un helper de lectura/proyección.
-///
-public sealed class SecuenciaComprobante
-{
- public int PuntoDeVentaId { get; }
- public TipoComprobante TipoComprobante { get; }
- public int UltimoNumero { get; }
- public DateTime FechaCreacion { get; }
- public DateTime? FechaModificacion { get; }
-
- /// El próximo número disponible (read-only, sin modificar el estado).
- public int ProximoNumero => UltimoNumero + 1;
-
- public SecuenciaComprobante(
- int puntoDeVentaId,
- TipoComprobante tipoComprobante,
- int ultimoNumero,
- DateTime fechaCreacion,
- DateTime? fechaModificacion)
- {
- PuntoDeVentaId = puntoDeVentaId;
- TipoComprobante = tipoComprobante;
- UltimoNumero = ultimoNumero;
- FechaCreacion = fechaCreacion;
- FechaModificacion = fechaModificacion;
- }
-}
diff --git a/src/api/SIGCM2.Domain/Enums/TipoComprobante.cs b/src/api/SIGCM2.Domain/Enums/TipoComprobante.cs
deleted file mode 100644
index e1be111..0000000
--- a/src/api/SIGCM2.Domain/Enums/TipoComprobante.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace SIGCM2.Domain.Enums;
-
-///
-/// Tipos de comprobante AFIP soportados por ADM-008.
-/// Valor TINYINT persistido en BD (CHECK TipoComprobante BETWEEN 1 AND 6).
-/// Migración a tabla maestra diferida a FAC-001.
-///
-public enum TipoComprobante : byte
-{
- FacturaA = 1,
- FacturaB = 2,
- FacturaC = 3,
- NotaCreditoA = 4,
- NotaCreditoB = 5,
- NotaCreditoC = 6,
-}
diff --git a/src/api/SIGCM2.Domain/Exceptions/DeadlockTransientException.cs b/src/api/SIGCM2.Domain/Exceptions/DeadlockTransientException.cs
deleted file mode 100644
index fef02a6..0000000
--- a/src/api/SIGCM2.Domain/Exceptions/DeadlockTransientException.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace SIGCM2.Domain.Exceptions;
-
-///
-/// Thrown by Infrastructure when a database deadlock (SQL 1205) is detected.
-/// Allows Application handlers to retry without referencing SqlClient.
-///
-public sealed class DeadlockTransientException : DomainException
-{
- public DeadlockTransientException()
- : base("Se detectó un deadlock en la base de datos. Reintentando operación.") { }
-
- public DeadlockTransientException(Exception innerException)
- : base("Se detectó un deadlock en la base de datos. Reintentando operación.", innerException) { }
-}
diff --git a/src/api/SIGCM2.Domain/Exceptions/PuntoDeVentaInactivoException.cs b/src/api/SIGCM2.Domain/Exceptions/PuntoDeVentaInactivoException.cs
deleted file mode 100644
index 3405365..0000000
--- a/src/api/SIGCM2.Domain/Exceptions/PuntoDeVentaInactivoException.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace SIGCM2.Domain.Exceptions;
-
-///
-/// Thrown when a mutation (reserva) is attempted on an inactive PuntoDeVenta.
-///
-public sealed class PuntoDeVentaInactivoException : DomainException
-{
- public int PuntoDeVentaId { get; }
-
- public PuntoDeVentaInactivoException(int puntoDeVentaId)
- : base($"El punto de venta {puntoDeVentaId} está inactivo. No se pueden realizar operaciones hasta reactivarlo.")
- {
- PuntoDeVentaId = puntoDeVentaId;
- }
-}
diff --git a/src/api/SIGCM2.Infrastructure/Persistence/PuntoDeVentaRepository.cs b/src/api/SIGCM2.Infrastructure/Persistence/PuntoDeVentaRepository.cs
index 657f573..d276536 100644
--- a/src/api/SIGCM2.Infrastructure/Persistence/PuntoDeVentaRepository.cs
+++ b/src/api/SIGCM2.Infrastructure/Persistence/PuntoDeVentaRepository.cs
@@ -1,11 +1,9 @@
-using System.Data;
using System.Text;
using Dapper;
using Microsoft.Data.SqlClient;
using SIGCM2.Application.Abstractions.Persistence;
using SIGCM2.Application.Common;
using SIGCM2.Domain.Entities;
-using SIGCM2.Domain.Enums;
using SIGCM2.Domain.Exceptions;
namespace SIGCM2.Infrastructure.Persistence;
@@ -153,56 +151,6 @@ public sealed class PuntoDeVentaRepository : IPuntoDeVentaRepository
return new PagedResult(items, page, pageSize, total);
}
- public async Task ReservarNumeroAsync(int puntoDeVentaId, TipoComprobante tipo, CancellationToken ct = default)
- {
- var parameters = new DynamicParameters();
- parameters.Add("PuntoDeVentaId", puntoDeVentaId, DbType.Int32);
- parameters.Add("TipoComprobante", (byte)tipo, DbType.Byte);
- parameters.Add("NumeroReservado", dbType: DbType.Int32, direction: ParameterDirection.Output);
-
- await using var connection = _connectionFactory.CreateConnection();
- await connection.OpenAsync(ct);
-
- try
- {
- await connection.ExecuteAsync(
- "dbo.usp_ReservarNumeroComprobante",
- parameters,
- commandType: CommandType.StoredProcedure);
- }
- catch (SqlException ex)
- {
- throw ex.Number switch
- {
- 50001 => new PuntoDeVentaInactivoException(puntoDeVentaId),
- 50002 => new MedioInactivoException(puntoDeVentaId),
- 50003 => new PuntoDeVentaNotFoundException(puntoDeVentaId),
- 1205 => new DeadlockTransientException(ex),
- _ => ex,
- };
- }
-
- return parameters.Get("NumeroReservado");
- }
-
- public async Task GetUltimoNumeroAsync(int puntoDeVentaId, TipoComprobante tipo, CancellationToken ct = default)
- {
- const string sql = """
- SELECT UltimoNumero
- FROM dbo.SecuenciaComprobante
- WHERE PuntoDeVentaId = @PuntoDeVentaId AND TipoComprobante = @TipoComprobante
- """;
-
- await using var connection = _connectionFactory.CreateConnection();
- await connection.OpenAsync(ct);
-
- return await connection.QuerySingleOrDefaultAsync(sql, new
- {
- PuntoDeVentaId = puntoDeVentaId,
- TipoComprobante = (byte)tipo,
- });
- }
-
// ── mapping ───────────────────────────────────────────────────────────────
private static PuntoDeVenta MapRow(PdvRow r)