2025-07-29 14:11:50 -03:00
|
|
|
using GestionIntegral.Api.Models.Suscripciones;
|
|
|
|
|
using System.Data;
|
|
|
|
|
|
|
|
|
|
namespace GestionIntegral.Api.Data.Repositories.Suscripciones
|
|
|
|
|
{
|
|
|
|
|
public interface IFacturaRepository
|
|
|
|
|
{
|
|
|
|
|
Task<Factura?> GetByIdAsync(int idFactura);
|
2025-08-09 18:16:56 -03:00
|
|
|
Task<IEnumerable<Factura>> GetByIdsAsync(IEnumerable<int> ids);
|
2025-07-29 14:11:50 -03:00
|
|
|
Task<IEnumerable<Factura>> GetByPeriodoAsync(string periodo);
|
2025-08-08 09:48:15 -03:00
|
|
|
Task<Factura?> GetBySuscriptorYPeriodoAsync(int idSuscriptor, string periodo, IDbTransaction transaction);
|
|
|
|
|
Task<IEnumerable<Factura>> GetListBySuscriptorYPeriodoAsync(int idSuscriptor, string periodo);
|
Feat: Implementa Reporte de Distribución de Suscripciones y Refactoriza Gestión de Ajustes
Se introduce una nueva funcionalidad de reporte crucial para la logística y se realiza una refactorización mayor del sistema de ajustes para garantizar la correcta imputación contable.
### ✨ Nuevas Características
- **Nuevo Reporte de Distribución de Suscripciones (RR011):**
- Se añade un nuevo reporte en PDF que genera un listado de todas las suscripciones activas en un rango de fechas.
- El reporte está diseñado para el equipo de reparto, incluyendo datos clave como nombre del suscriptor, dirección, teléfono, días de entrega y observaciones.
- Se implementa el endpoint, la lógica de servicio, la consulta a la base de datos y el template de QuestPDF en el backend.
- Se crea la página correspondiente en el frontend (React) con su selector de fechas y se añade la ruta y el enlace en el menú de reportes.
### 🔄 Refactorización Mayor
- **Asociación de Ajustes a Empresas:**
- Se refactoriza por completo la entidad `Ajuste` para incluir una referencia obligatoria a una `IdEmpresa`.
- **Motivo:** Corregir un error crítico en la lógica de negocio donde los ajustes de un suscriptor se aplicaban a la primera factura generada, sin importar a qué empresa correspondía el ajuste.
- Se provee un script de migración SQL para actualizar el esquema de la base de datos (`susc_Ajustes`).
- Se actualizan todos los DTOs, repositorios y servicios (backend) para manejar la nueva relación.
- Se modifica el `FacturacionService` para que ahora aplique los ajustes pendientes correspondientes a cada empresa dentro de su bucle de facturación.
- Se actualiza el formulario de creación/edición de ajustes en el frontend (React) para incluir un selector de empresa obligatorio.
### ⚡️ Optimizaciones de Rendimiento
- **Solución de N+1 Queries:**
- Se optimiza el método `ObtenerTodos` en `SuscriptorService` para obtener todas las formas de pago en una única consulta en lugar de una por cada suscriptor.
- Se optimiza el método `ObtenerAjustesPorSuscriptor` en `AjusteService` para obtener todos los nombres de usuarios y empresas en dos consultas masivas, en lugar de N consultas individuales.
- Se añade el método `GetByIdsAsync` al `IUsuarioRepository` y su implementación para soportar esta optimización.
### 🐛 Corrección de Errores
- Se corrigen múltiples errores en el script de migración de base de datos (uso de `GO` dentro de transacciones, error de "columna inválida").
- Se soluciona un error de SQL (`INSERT` statement) en `AjusteRepository` que impedía la creación de nuevos ajustes.
- Se corrige un bug en el `AjusteService` que causaba que el nombre de la empresa apareciera como "N/A" en la UI debido a un mapeo incompleto en el método optimizado.
- Se corrige la lógica de generación de emails en `FacturacionService` para mostrar correctamente el nombre de la empresa en cada sección del resumen de cuenta.
2025-08-09 17:39:21 -03:00
|
|
|
Task<IEnumerable<(Factura Factura, string NombreEmpresa)>> GetFacturasConEmpresaAsync(int idSuscriptor, string periodo);
|
2025-07-29 14:11:50 -03:00
|
|
|
Task<Factura?> CreateAsync(Factura nuevaFactura, IDbTransaction transaction);
|
2025-08-08 09:48:15 -03:00
|
|
|
Task<bool> UpdateEstadoPagoAsync(int idFactura, string nuevoEstadoPago, IDbTransaction transaction);
|
2025-07-29 14:11:50 -03:00
|
|
|
Task<bool> UpdateNumeroFacturaAsync(int idFactura, string numeroFactura, IDbTransaction transaction);
|
|
|
|
|
Task<bool> UpdateLoteDebitoAsync(IEnumerable<int> idsFacturas, int idLoteDebito, IDbTransaction transaction);
|
Feat(suscripciones): Implementa facturación pro-rata para altas y excluye del débito automático
Se introduce una refactorización mayor del ciclo de facturación para manejar correctamente las suscripciones que inician en un período ya cerrado. Esto soluciona el problema de cobrar un mes completo a un nuevo suscriptor, mejorando la transparencia y la experiencia del cliente.
### ✨ Nuevas Características y Lógica de Negocio
- **Facturación Pro-rata Automática (Factura de Alta):**
- Al crear una nueva suscripción cuya fecha de inicio corresponde a un período de facturación ya cerrado, el sistema ahora calcula automáticamente el costo proporcional por los días restantes de ese mes.
- Se genera de forma inmediata una nueva factura de tipo "Alta" por este monto parcial, separándola del ciclo de facturación mensual regular.
- **Exclusión del Débito Automático para Facturas de Alta:**
- Se implementa una regla de negocio clave: las facturas de tipo "Alta" son **excluidas** del proceso de generación del archivo de débito automático para el banco.
- Esto fuerza a que el primer cobro (el proporcional) se gestione a través de un medio de pago manual (efectivo, transferencia, etc.), evitando cargos inesperados en la cuenta bancaria del cliente.
- El débito automático comenzará a operar normalmente a partir del primer ciclo de facturación completo.
### 🔄 Cambios en el Backend
- **Base de Datos:**
- Se ha añadido la columna `TipoFactura` (`varchar(20)`) a la tabla `susc_Facturas`.
- Se ha implementado una `CHECK constraint` para permitir únicamente los valores 'Mensual' y 'Alta'.
- **Servicios:**
- **`SuscripcionService`:** Ahora contiene la lógica para detectar una alta retroactiva, invocar al `FacturacionService` para el cálculo pro-rata y crear la "Factura de Alta" y su detalle correspondiente dentro de la misma transacción.
- **`FacturacionService`:** Expone públicamente el método `CalcularImporteParaSuscripcion` y se ha actualizado `ObtenerResumenesDeCuentaPorPeriodo` para que envíe la propiedad `TipoFactura` al frontend.
- **`DebitoAutomaticoService`:** El método `GetFacturasParaDebito` ahora filtra y excluye explícitamente las facturas donde `TipoFactura = 'Alta'`.
### 🎨 Mejoras en la Interfaz de Usuario (Frontend)
- **`ConsultaFacturasPage.tsx`:**
- **Nueva Columna:** Se ha añadido una columna "Tipo Factura" en la tabla de detalle, que muestra un `Chip` distintivo para identificar fácilmente las facturas de "Alta".
- **Nuevo Filtro:** Se ha agregado un nuevo menú desplegable para filtrar la vista por "Tipo de Factura" (`Todas`, `Mensual`, `Alta`), permitiendo a los administradores auditar rápidamente los nuevos ingresos.
2025-08-13 14:55:24 -03:00
|
|
|
Task<IEnumerable<(Factura Factura, string NombreSuscriptor, int IdEmpresa, decimal TotalPagado)>> GetByPeriodoEnrichedAsync(
|
|
|
|
|
string periodo, string? nombreSuscriptor, string? estadoPago, string? estadoFacturacion, string? tipoFactura);
|
2025-08-08 09:48:15 -03:00
|
|
|
Task<bool> UpdateEstadoYMotivoAsync(int idFactura, string nuevoEstadoPago, string? motivoRechazo, IDbTransaction transaction);
|
|
|
|
|
Task<string?> GetUltimoPeriodoFacturadoAsync();
|
|
|
|
|
Task<IEnumerable<Factura>> GetFacturasPagadasPendientesDeFacturar(string periodo);
|
2025-07-29 14:11:50 -03:00
|
|
|
}
|
|
|
|
|
}
|