diff --git a/src/api/SIGCM2.Application/Abstractions/Persistence/IIngresosBrutosRepository.cs b/src/api/SIGCM2.Application/Abstractions/Persistence/IIngresosBrutosRepository.cs new file mode 100644 index 0000000..f4de5dd --- /dev/null +++ b/src/api/SIGCM2.Application/Abstractions/Persistence/IIngresosBrutosRepository.cs @@ -0,0 +1,43 @@ +using SIGCM2.Application.Common; +using SIGCM2.Domain.Fiscal; +using IibbEntity = SIGCM2.Domain.Entities.IngresosBrutos; + +namespace SIGCM2.Application.Abstractions.Persistence; + +/// +/// Persistence contract for IngresosBrutos. Implemented by Dapper repo in Infrastructure. +/// +public interface IIngresosBrutosRepository +{ + /// Inserts a new IngresosBrutos record and returns the generated identity Id. + Task InsertAsync(IibbEntity entity, CancellationToken ct = default); + + /// Returns the IngresosBrutos with the given Id, or null if not found. + Task GetByIdAsync(int id, CancellationToken ct = default); + + /// + /// Updates cosmetic fields only (Descripcion, Activo). + /// Never touches Alicuota, Provincia, or vigencia dates. + /// + Task UpdateCosmeticoAsync(int id, string descripcion, bool activo, CancellationToken ct = default); + + /// + /// Closes the vigencia of the predecessor: UPDATE SET VigenciaHasta = @vigenciaHasta + /// WHERE Id = @id AND VigenciaHasta IS NULL (optimistic guard for race conditions). + /// Returns true if one row was affected, false if the row was already closed (race detected). + /// + Task UpdateCierreVigenciaAsync(int id, DateOnly vigenciaHasta, CancellationToken ct = default); + + /// Sets Activo to the given value. Returns true if one row was affected. + Task SetActivoAsync(int id, bool activo, CancellationToken ct = default); + + /// Returns a paged list applying optional Activo and Provincia filters. + Task> ListAsync(IngresosBrutosQuery query, CancellationToken ct = default); + + /// + /// Returns the full version chain for the record identified by , + /// ordered from root (no PredecesorId) to the requested Id (inclusive). + /// Implemented via a recursive CTE in the concrete repository. + /// + Task> GetHistorialAsync(int id, CancellationToken ct = default); +} diff --git a/src/api/SIGCM2.Application/Abstractions/Persistence/ITipoDeIvaRepository.cs b/src/api/SIGCM2.Application/Abstractions/Persistence/ITipoDeIvaRepository.cs new file mode 100644 index 0000000..18c75b3 --- /dev/null +++ b/src/api/SIGCM2.Application/Abstractions/Persistence/ITipoDeIvaRepository.cs @@ -0,0 +1,42 @@ +using SIGCM2.Application.Common; +using SIGCM2.Domain.Entities; + +namespace SIGCM2.Application.Abstractions.Persistence; + +/// +/// Persistence contract for TipoDeIva. Implemented by Dapper repo in Infrastructure. +/// +public interface ITipoDeIvaRepository +{ + /// Inserts a new TipoDeIva and returns the generated identity Id. + Task InsertAsync(TipoDeIva entity, CancellationToken ct = default); + + /// Returns the TipoDeIva with the given Id, or null if not found. + Task GetByIdAsync(int id, CancellationToken ct = default); + + /// + /// Updates cosmetic fields only (Codigo, Descripcion, AplicaIVA, Activo). + /// Never touches Porcentaje or vigencia dates. + /// + Task UpdateCosmeticoAsync(int id, string codigo, string descripcion, bool aplicaIVA, bool activo, CancellationToken ct = default); + + /// + /// Closes the vigencia of the predecessor: UPDATE SET VigenciaHasta = @vigenciaHasta + /// WHERE Id = @id AND VigenciaHasta IS NULL (optimistic guard for race conditions). + /// Returns true if one row was affected, false if the row was already closed (race detected). + /// + Task UpdateCierreVigenciaAsync(int id, DateOnly vigenciaHasta, CancellationToken ct = default); + + /// Sets Activo to the given value. Returns true if one row was affected. + Task SetActivoAsync(int id, bool activo, CancellationToken ct = default); + + /// Returns a paged list applying optional Activo and Codigo filters. + Task> ListAsync(TiposDeIvaQuery query, CancellationToken ct = default); + + /// + /// Returns the full version chain for the record identified by , + /// ordered from root (no PredecesorId) to the requested Id (inclusive). + /// Implemented via a recursive CTE in the concrete repository. + /// + Task> GetHistorialAsync(int id, CancellationToken ct = default); +} diff --git a/src/api/SIGCM2.Application/Common/IngresosBrutosQuery.cs b/src/api/SIGCM2.Application/Common/IngresosBrutosQuery.cs new file mode 100644 index 0000000..f293d22 --- /dev/null +++ b/src/api/SIGCM2.Application/Common/IngresosBrutosQuery.cs @@ -0,0 +1,11 @@ +using SIGCM2.Domain.Fiscal; + +namespace SIGCM2.Application.Common; + +/// Query parameters for listing ingresos brutos with optional filters and paging. +public sealed record IngresosBrutosQuery( + int Page, + int PageSize, + bool? Activo, + ProvinciaArgentina? Provincia +); diff --git a/src/api/SIGCM2.Application/Common/TiposDeIvaQuery.cs b/src/api/SIGCM2.Application/Common/TiposDeIvaQuery.cs new file mode 100644 index 0000000..dc36440 --- /dev/null +++ b/src/api/SIGCM2.Application/Common/TiposDeIvaQuery.cs @@ -0,0 +1,9 @@ +namespace SIGCM2.Application.Common; + +/// Query parameters for listing tipos de IVA with optional filters and paging. +public sealed record TiposDeIvaQuery( + int Page, + int PageSize, + bool? Activo, + string? Codigo +); diff --git a/src/api/SIGCM2.Domain/Exceptions/IngresosBrutosNotFoundException.cs b/src/api/SIGCM2.Domain/Exceptions/IngresosBrutosNotFoundException.cs new file mode 100644 index 0000000..e482d5c --- /dev/null +++ b/src/api/SIGCM2.Domain/Exceptions/IngresosBrutosNotFoundException.cs @@ -0,0 +1,15 @@ +namespace SIGCM2.Domain.Exceptions; + +/// +/// Thrown when a requested IngresosBrutos record does not exist in the system. +/// +public sealed class IngresosBrutosNotFoundException : DomainException +{ + public int Id { get; } + + public IngresosBrutosNotFoundException(int id) + : base($"El registro de Ingresos Brutos con id '{id}' no existe.") + { + Id = id; + } +} diff --git a/src/api/SIGCM2.Domain/Exceptions/TipoDeIvaNotFoundException.cs b/src/api/SIGCM2.Domain/Exceptions/TipoDeIvaNotFoundException.cs new file mode 100644 index 0000000..352f382 --- /dev/null +++ b/src/api/SIGCM2.Domain/Exceptions/TipoDeIvaNotFoundException.cs @@ -0,0 +1,15 @@ +namespace SIGCM2.Domain.Exceptions; + +/// +/// Thrown when a requested TipoDeIva does not exist in the system. +/// +public sealed class TipoDeIvaNotFoundException : DomainException +{ + public int Id { get; } + + public TipoDeIvaNotFoundException(int id) + : base($"El tipo de IVA con id '{id}' no existe.") + { + Id = id; + } +}