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.
28 lines
1.9 KiB
C#
28 lines
1.9 KiB
C#
// Archivo: GestionIntegral.Api/Data/Repositories/Usuarios/IUsuarioRepository.cs
|
|
|
|
using GestionIntegral.Api.Models.Usuarios; // Para Usuario
|
|
using GestionIntegral.Api.Dtos.Usuarios.Auditoria;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using System.Data;
|
|
|
|
namespace GestionIntegral.Api.Data.Repositories.Usuarios
|
|
{
|
|
public interface IUsuarioRepository
|
|
{
|
|
Task<IEnumerable<Usuario>> GetAllAsync(string? userFilter, string? nombreFilter);
|
|
Task<Usuario?> GetByIdAsync(int id);
|
|
Task<IEnumerable<Usuario>> GetByIdsAsync(IEnumerable<int> ids);
|
|
Task<Usuario?> GetByUsernameAsync(string username); // Ya existe en IAuthRepository, pero lo duplicamos para cohesión del CRUD
|
|
Task<Usuario?> CreateAsync(Usuario nuevoUsuario, int idUsuarioCreador, IDbTransaction transaction);
|
|
Task<bool> UpdateAsync(Usuario usuarioAActualizar, int idUsuarioModificador, IDbTransaction transaction);
|
|
// DeleteAsync no es común para usuarios, se suelen deshabilitar.
|
|
// Task<bool> DeleteAsync(int id, int idUsuarioModificador, IDbTransaction transaction);
|
|
Task<bool> SetPasswordAsync(int userId, string newHash, string newSalt, bool debeCambiarClave, int idUsuarioModificador, IDbTransaction transaction);
|
|
Task<bool> UserExistsAsync(string username, int? excludeId = null);
|
|
Task<IEnumerable<(Usuario Usuario, string NombrePerfil)>> GetAllWithProfileNameAsync(string? userFilter, string? nombreFilter);
|
|
Task<(Usuario? Usuario, string? NombrePerfil)> GetByIdWithProfileNameAsync(int id);
|
|
Task<IEnumerable<UsuarioHistorialDto>> GetHistorialByUsuarioIdAsync(int idUsuarioAfectado, DateTime? fechaDesde, DateTime? fechaHasta);
|
|
Task<IEnumerable<UsuarioHistorialDto>> GetAllHistorialAsync(DateTime? fechaDesde, DateTime? fechaHasta, int? idUsuarioModificoFilter, string? tipoModFilter);
|
|
}
|
|
} |