From f267e4f42742c7a96f827190b6611a8e1c61a22f Mon Sep 17 00:00:00 2001 From: dmolinari Date: Fri, 17 Apr 2026 17:52:57 -0300 Subject: [PATCH] feat(adm-009): domain exceptions for fiscal entities --- .../Exceptions/AlicuotaInmutableException.cs | 13 +++++++++++++ .../Exceptions/DuplicateCodigoException.cs | 16 ++++++++++++++++ .../Exceptions/DuplicateProvinciaException.cs | 18 ++++++++++++++++++ .../Exceptions/PorcentajeInmutableException.cs | 13 +++++++++++++ .../Exceptions/PredecesorYaCerradoException.cs | 16 ++++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 src/api/SIGCM2.Domain/Exceptions/AlicuotaInmutableException.cs create mode 100644 src/api/SIGCM2.Domain/Exceptions/DuplicateCodigoException.cs create mode 100644 src/api/SIGCM2.Domain/Exceptions/DuplicateProvinciaException.cs create mode 100644 src/api/SIGCM2.Domain/Exceptions/PorcentajeInmutableException.cs create mode 100644 src/api/SIGCM2.Domain/Exceptions/PredecesorYaCerradoException.cs diff --git a/src/api/SIGCM2.Domain/Exceptions/AlicuotaInmutableException.cs b/src/api/SIGCM2.Domain/Exceptions/AlicuotaInmutableException.cs new file mode 100644 index 0000000..24f159b --- /dev/null +++ b/src/api/SIGCM2.Domain/Exceptions/AlicuotaInmutableException.cs @@ -0,0 +1,13 @@ +namespace SIGCM2.Domain.Exceptions; + +/// +/// Thrown when a PATCH request attempts to change the Alicuota of an IngresosBrutos. +/// Alicuota is immutable post-creation; use POST /iibb/{id}/nueva-version instead. +/// +public sealed class AlicuotaInmutableException : DomainException +{ + public AlicuotaInmutableException() + : base("La alícuota de IngresosBrutos es inmutable. Creá una nueva versión vía POST /iibb/{id}/nueva-version.") + { + } +} diff --git a/src/api/SIGCM2.Domain/Exceptions/DuplicateCodigoException.cs b/src/api/SIGCM2.Domain/Exceptions/DuplicateCodigoException.cs new file mode 100644 index 0000000..5b1beb5 --- /dev/null +++ b/src/api/SIGCM2.Domain/Exceptions/DuplicateCodigoException.cs @@ -0,0 +1,16 @@ +namespace SIGCM2.Domain.Exceptions; + +/// +/// Thrown when a TipoDeIva with the same Codigo already exists for the same VigenciaDesde. +/// Maps to SQL unique constraint UQ_TipoDeIva_Codigo_Vigencia (SqlException 2627/2601). +/// +public sealed class DuplicateCodigoException : DomainException +{ + public string Codigo { get; } + + public DuplicateCodigoException(string codigo) + : base($"Ya existe un TipoDeIva con Codigo '{codigo}' en la misma vigencia.") + { + Codigo = codigo; + } +} diff --git a/src/api/SIGCM2.Domain/Exceptions/DuplicateProvinciaException.cs b/src/api/SIGCM2.Domain/Exceptions/DuplicateProvinciaException.cs new file mode 100644 index 0000000..84e9b12 --- /dev/null +++ b/src/api/SIGCM2.Domain/Exceptions/DuplicateProvinciaException.cs @@ -0,0 +1,18 @@ +using SIGCM2.Domain.Fiscal; + +namespace SIGCM2.Domain.Exceptions; + +/// +/// Thrown when an IngresosBrutos entry for the same Provincia already exists for the same VigenciaDesde. +/// Maps to SQL unique constraint UQ_IIBB_Provincia_Vigencia (SqlException 2627/2601). +/// +public sealed class DuplicateProvinciaException : DomainException +{ + public ProvinciaArgentina Provincia { get; } + + public DuplicateProvinciaException(ProvinciaArgentina provincia) + : base($"Ya existe una entrada de IIBB para '{provincia}' en la misma vigencia.") + { + Provincia = provincia; + } +} diff --git a/src/api/SIGCM2.Domain/Exceptions/PorcentajeInmutableException.cs b/src/api/SIGCM2.Domain/Exceptions/PorcentajeInmutableException.cs new file mode 100644 index 0000000..3a0da31 --- /dev/null +++ b/src/api/SIGCM2.Domain/Exceptions/PorcentajeInmutableException.cs @@ -0,0 +1,13 @@ +namespace SIGCM2.Domain.Exceptions; + +/// +/// Thrown when a PATCH request attempts to change the Porcentaje of a TipoDeIva. +/// Porcentaje is immutable post-creation; use POST /iva/{id}/nueva-version instead. +/// +public sealed class PorcentajeInmutableException : DomainException +{ + public PorcentajeInmutableException() + : base("El porcentaje de un TipoDeIva es inmutable. Creá una nueva versión vía POST /iva/{id}/nueva-version.") + { + } +} diff --git a/src/api/SIGCM2.Domain/Exceptions/PredecesorYaCerradoException.cs b/src/api/SIGCM2.Domain/Exceptions/PredecesorYaCerradoException.cs new file mode 100644 index 0000000..4e45c70 --- /dev/null +++ b/src/api/SIGCM2.Domain/Exceptions/PredecesorYaCerradoException.cs @@ -0,0 +1,16 @@ +namespace SIGCM2.Domain.Exceptions; + +/// +/// Thrown when attempting to create a new version from a predecessor that is already closed +/// (VigenciaHasta is not null). The predecessor must be open to generate a new version. +/// +public sealed class PredecesorYaCerradoException : DomainException +{ + public int PredecesorId { get; } + + public PredecesorYaCerradoException(int predecesorId) + : base($"La versión {predecesorId} ya está cerrada o inactiva. No puede generar nueva versión.") + { + PredecesorId = predecesorId; + } +}