From e7bda29ef336296c1e259405c6abd76fa51ca887 Mon Sep 17 00:00:00 2001 From: Nurfog Date: Wed, 8 Jul 2026 13:57:29 -0400 Subject: [PATCH] Refactor services to use repository pattern for database operations - Updated EmpresaReportService to utilize ICatalogoRepository for stored procedure calls. - Refactored InformeService to include new method for executing Crystal Reports stored procedures. - Simplified LeadService by removing direct database connections and using ILeadRepository and ILeadQueryRepository. - Modified ReportService to leverage ICatalogoRepository for querying stored procedures. - Streamlined UsuarioService to use IUsuarioRepository for user authentication and profile retrieval. - Added new CatalogoService to handle various catalog-related queries and operations. - Introduced ArqueoRepository and CatalogoRepository for managing database interactions. - Created DTOs for various entities including Alumno, Contrato, Cotizacion, Descuento, Documento, Empresa, and Propuesta. - Implemented BaseController and ErrorController for standardized API responses and error handling. - Added QuestPDF package for PDF generation capabilities. --- .../Controllers/AlumnoController.cs | 35 +--- .../Ventas.API/Controllers/AuthController.cs | 5 +- .../Ventas.API/Controllers/BaseController.cs | 12 ++ .../Controllers/ContratoController.cs | 31 ++-- .../Controllers/CotizacionController.cs | 35 ++-- .../Ventas.API/Controllers/CursoController.cs | 41 ++--- .../Controllers/DescuentoController.cs | 44 ++--- .../Controllers/DocumentoController.cs | 54 ++---- .../Controllers/EmpresaController.cs | 60 ++---- .../Ventas.API/Controllers/ErrorController.cs | 16 ++ .../Controllers/HorarioController.cs | 21 +-- .../Controllers/InformeController.cs | 18 +- .../Controllers/JornadaController.cs | 21 +-- .../Ventas.API/Controllers/LeadController.cs | 18 +- .../Controllers/ProgramaController.cs | 21 +-- .../Controllers/PropuestaController.cs | 43 +---- .../Controllers/RegionController.cs | 21 +-- .../Controllers/ReportController.cs | 12 +- .../Ventas.API/Controllers/SalaController.cs | 27 +-- .../Ventas.API/Controllers/SedeController.cs | 21 +-- .../Controllers/TarifaController.cs | 31 +--- .../Controllers/UsuarioController.cs | 44 ++--- .../Ventas.API/Middleware/JwtMiddleware.cs | 45 ----- backend/src/Ventas.API/Program.cs | 52 ++++-- backend/src/Ventas.API/Ventas.API.csproj | 1 + backend/src/Ventas.Core/DTOs/AlumnoDto.cs | 30 +++ backend/src/Ventas.Core/DTOs/ContratoDto.cs | 53 ++++++ backend/src/Ventas.Core/DTOs/CotizacionDto.cs | 60 ++++++ backend/src/Ventas.Core/DTOs/DescuentoDto.cs | 9 + backend/src/Ventas.Core/DTOs/DocumentoDto.cs | 20 ++ backend/src/Ventas.Core/DTOs/EmpresaDto.cs | 15 ++ backend/src/Ventas.Core/DTOs/LeadDto.cs | 17 ++ backend/src/Ventas.Core/DTOs/PropuestaDto.cs | 25 +++ .../Interfaces/IArqueoRepository.cs | 7 + .../Interfaces/ICatalogoRepository.cs | 8 + .../Interfaces/IUsuarioRepository.cs | 8 +- .../Repositories/ArqueoRepository.cs | 33 ++++ .../Repositories/CatalogoRepository.cs | 36 ++++ .../Repositories/LeadRepository.cs | 2 +- .../Repositories/UsuarioRepository.cs | 54 +++++- backend/src/Ventas.Services/AlumnoService.cs | 63 +++---- backend/src/Ventas.Services/ArqueoService.cs | 31 +--- .../src/Ventas.Services/CatalogoService.cs | 92 +++++++++ .../src/Ventas.Services/ContratoService.cs | 77 +++----- .../src/Ventas.Services/CotizacionService.cs | 69 ++----- .../Ventas.Services/EmpresaReportService.cs | 35 ++-- backend/src/Ventas.Services/InformeService.cs | 3 + backend/src/Ventas.Services/LeadService.cs | 174 ++++-------------- backend/src/Ventas.Services/ReportService.cs | 20 +- backend/src/Ventas.Services/UsuarioService.cs | 47 +---- .../Ventas.Services/Ventas.Services.csproj | 4 + 51 files changed, 845 insertions(+), 876 deletions(-) create mode 100644 backend/src/Ventas.API/Controllers/BaseController.cs create mode 100644 backend/src/Ventas.API/Controllers/ErrorController.cs delete mode 100644 backend/src/Ventas.API/Middleware/JwtMiddleware.cs create mode 100644 backend/src/Ventas.Core/DTOs/AlumnoDto.cs create mode 100644 backend/src/Ventas.Core/DTOs/ContratoDto.cs create mode 100644 backend/src/Ventas.Core/DTOs/CotizacionDto.cs create mode 100644 backend/src/Ventas.Core/DTOs/DescuentoDto.cs create mode 100644 backend/src/Ventas.Core/DTOs/DocumentoDto.cs create mode 100644 backend/src/Ventas.Core/DTOs/EmpresaDto.cs create mode 100644 backend/src/Ventas.Core/DTOs/PropuestaDto.cs create mode 100644 backend/src/Ventas.Core/Interfaces/IArqueoRepository.cs create mode 100644 backend/src/Ventas.Core/Interfaces/ICatalogoRepository.cs create mode 100644 backend/src/Ventas.Infrastructure/Repositories/ArqueoRepository.cs create mode 100644 backend/src/Ventas.Infrastructure/Repositories/CatalogoRepository.cs create mode 100644 backend/src/Ventas.Services/CatalogoService.cs diff --git a/backend/src/Ventas.API/Controllers/AlumnoController.cs b/backend/src/Ventas.API/Controllers/AlumnoController.cs index f3969e1..f811338 100644 --- a/backend/src/Ventas.API/Controllers/AlumnoController.cs +++ b/backend/src/Ventas.API/Controllers/AlumnoController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; using Ventas.Services; namespace Ventas.API.Controllers; @@ -28,7 +29,8 @@ public class AlumnoController : ControllerBase { var result = await _alumnoService.IngresarV2Async( request.Rut, request.Nombre, request.Paterno, request.Materno, - request.Fecha, request.Fono, request.Mail, request.Ocupacion, request.ProfesionOficio); + request.Direccion, request.Comuna, request.Fecha, request.Fono, + request.Mail, request.Ocupacion, request.ProfesionOficio); return Ok(new { mensaje = result }); } @@ -77,8 +79,8 @@ public class AlumnoController : ControllerBase return Ok(result); } - [HttpGet("{id}/formas-pago")] - public async Task FormasPago(string id, [FromQuery] int boleta) + [HttpGet("formas-pago")] + public async Task FormasPago([FromQuery] int boleta) { var result = await _alumnoService.BuscarFormasPagoAsync(boleta); return Ok(result); @@ -112,30 +114,3 @@ public class AlumnoController : ControllerBase return Ok(result); } } - -public class AlumnoIngresoRequest -{ - public string Rut { get; set; } = string.Empty; - public string Nombre { get; set; } = string.Empty; - public string Paterno { get; set; } = string.Empty; - public string Materno { get; set; } = string.Empty; - public string Fecha { get; set; } = string.Empty; - public string Fono { get; set; } = string.Empty; - public string Mail { get; set; } = string.Empty; - public int Ocupacion { get; set; } - public string ProfesionOficio { get; set; } = string.Empty; -} - -public class ApoderadoIngresoRequest -{ - public string RutApoderado { get; set; } = string.Empty; - public string RutAlumno { get; set; } = string.Empty; - public string Nombre { get; set; } = string.Empty; - public string Paterno { get; set; } = string.Empty; - public string Materno { get; set; } = string.Empty; - public string Direccion { get; set; } = string.Empty; - public string Comuna { get; set; } = string.Empty; - public int Nacionalidad { get; set; } - public string Fono { get; set; } = string.Empty; - public string Mail { get; set; } = string.Empty; -} diff --git a/backend/src/Ventas.API/Controllers/AuthController.cs b/backend/src/Ventas.API/Controllers/AuthController.cs index d77f509..7ebdc6e 100644 --- a/backend/src/Ventas.API/Controllers/AuthController.cs +++ b/backend/src/Ventas.API/Controllers/AuthController.cs @@ -18,6 +18,7 @@ public class AuthController : ControllerBase _jwtService = jwtService; } + [AllowAnonymous] [HttpPost("login")] public async Task Login([FromBody] LoginRequest request) { @@ -25,12 +26,12 @@ public class AuthController : ControllerBase if (usuario == null) return Unauthorized(new { mensaje = "Credenciales inválidas" }); - var token = _jwtService.GenerateToken(request.Rut, usuario.Nombre, usuario.Sede ?? ""); + var token = _jwtService.GenerateToken(request.Rut, usuario.Nombre ?? "", usuario.Sede ?? ""); Response.Cookies.Append("SAM_TOKEN", token, new CookieOptions { HttpOnly = true, - Secure = true, + Secure = HttpContext.Request.IsHttps, SameSite = SameSiteMode.Strict, Expires = DateTime.UtcNow.AddMinutes(30) }); diff --git a/backend/src/Ventas.API/Controllers/BaseController.cs b/backend/src/Ventas.API/Controllers/BaseController.cs new file mode 100644 index 0000000..6903dda --- /dev/null +++ b/backend/src/Ventas.API/Controllers/BaseController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Ventas.API.Controllers; + +[ApiController] +public abstract class BaseController : ControllerBase +{ + protected static async Task OkResult(Task>> task) + => new OkObjectResult(await task); + + protected static IActionResult OkResultSync(T value) => new OkObjectResult(value); +} diff --git a/backend/src/Ventas.API/Controllers/ContratoController.cs b/backend/src/Ventas.API/Controllers/ContratoController.cs index c70576d..668408f 100644 --- a/backend/src/Ventas.API/Controllers/ContratoController.cs +++ b/backend/src/Ventas.API/Controllers/ContratoController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; using Ventas.Services; namespace Ventas.API.Controllers; @@ -17,16 +18,19 @@ public class ContratoController : ControllerBase } [HttpPost] - public async Task Ingresar([FromQuery] int cotizacionId, [FromQuery] string fechaContrato, [FromQuery] int boletaId, [FromQuery] int vendedorId) + public async Task Ingresar([FromBody] ContratoIngresoRequest request) { - var result = await _contratoService.IngresarAsync(cotizacionId, fechaContrato, boletaId, vendedorId); + if (string.IsNullOrEmpty(request.FechaContrato)) + return BadRequest(new { mensaje = "FechaContrato es requerido" }); + + var result = await _contratoService.IngresarAsync(request.CotizacionId, request.BoletaCKT, request.FechaContrato, request.BoletaId, request.VendedorId); return Ok(new { id = result }); } [HttpPost("detalle")] - public async Task IngresarDetalle([FromQuery] int contratoId, [FromQuery] string empresaId, [FromQuery] string alumnoId, [FromQuery] string cursoId, [FromQuery] string fecha, [FromQuery] int vendedor, [FromQuery] int registroAcademico, [FromQuery] int alumnoTipo) + public async Task IngresarDetalle([FromBody] ContratoDetalleRequest request) { - var result = await _contratoService.IngresarDetalleAsync(contratoId, empresaId, alumnoId, cursoId, fecha, vendedor, registroAcademico, alumnoTipo); + var result = await _contratoService.IngresarDetalleAsync(request.ContratoId, request.EmpresaId, request.AlumnoId, request.CursoId, request.Fecha, request.Vendedor, request.RegistroAcademico, request.AlumnoTipo); return Ok(new { id = result }); } @@ -49,16 +53,19 @@ public class ContratoController : ControllerBase } [HttpPost("empresa")] - public async Task IngresarContratoEmpresa([FromQuery] int cotizacionId, [FromQuery] string empresaId, [FromQuery] int tipoVenta, [FromQuery] int facturaId, [FromQuery] int cantCursos, [FromQuery] int vendedorId) + public async Task IngresarContratoEmpresa([FromBody] ContratoEmpresaRequest request) { - var result = await _contratoService.IngresarContratoEmpresaAsync(cotizacionId, empresaId, tipoVenta, facturaId, cantCursos, vendedorId); + var result = await _contratoService.IngresarContratoEmpresaAsync(request.CotizacionId, request.EmpresaId, request.TipoVenta, request.FacturaId, request.CantCursos, request.VendedorId); return Ok(new { id = result }); } [HttpPost("cerrado")] - public async Task IngresarContratoCerrado([FromQuery] int prop, [FromQuery] string rut, [FromQuery] int tipoVenta, [FromQuery] string vendedorId) + public async Task IngresarContratoCerrado([FromBody] ContratoCerradoRequest request) { - var result = await _contratoService.IngresarContratoCerradoAsync(prop, rut, tipoVenta, vendedorId); + if (string.IsNullOrEmpty(request.Rut)) + return BadRequest(new { mensaje = "Rut es requerido" }); + + var result = await _contratoService.IngresarContratoCerradoAsync(request.PropuestaId, request.Rut, request.TipoVenta, request.VendedorId); return Ok(new { id = result }); } @@ -70,16 +77,16 @@ public class ContratoController : ControllerBase } [HttpPut("{id}/estado")] - public async Task ActualizarEstado(int id, [FromQuery] string tipo, [FromQuery] string varA, [FromQuery] int varB) + public async Task ActualizarEstado(int id, [FromBody] ContratoEstadoUpdateRequest request) { - var result = await _contratoService.ActualizarEstadoContratoAsync(tipo, id, varA, varB); + var result = await _contratoService.ActualizarEstadoContratoAsync(request.Tipo, id, request.ValorA ?? "", request.ValorB); return Ok(new { mensaje = result }); } [HttpPut("{id}/firma")] - public async Task ActualizarFirma(int id, [FromQuery] string tipo, [FromQuery] int firmado) + public async Task ActualizarFirma(int id, [FromBody] ContratoFirmaRequest request) { - var result = await _contratoService.ActualizarFirmaContratoAsync(tipo, id, firmado); + var result = await _contratoService.ActualizarFirmaContratoAsync(request.Tipo, id, request.Firmado); return Ok(new { mensaje = result }); } } diff --git a/backend/src/Ventas.API/Controllers/CotizacionController.cs b/backend/src/Ventas.API/Controllers/CotizacionController.cs index 7b5b3f9..2cc2548 100644 --- a/backend/src/Ventas.API/Controllers/CotizacionController.cs +++ b/backend/src/Ventas.API/Controllers/CotizacionController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; using Ventas.Services; namespace Ventas.API.Controllers; @@ -17,23 +18,23 @@ public class CotizacionController : ControllerBase } [HttpPost] - public async Task Ingresar([FromQuery] string apoderadoId, [FromQuery] string vendedorId, [FromQuery] int descuento, [FromQuery] int tipoDescuento, [FromQuery] string fecha, [FromQuery] int monto, [FromQuery] string validez, [FromQuery] int leadId) + public async Task Ingresar([FromBody] CotizacionIngresoRequest request) { - var result = await _cotizacionService.IngresarAsync(apoderadoId, vendedorId, descuento, tipoDescuento, fecha, monto, validez, leadId); + var result = await _cotizacionService.IngresarAsync(request.ApoderadoId, request.VendedorId, request.SolicitudDescuento, request.Descuento, request.TipoDescuento, request.Fecha, request.Alumnos, request.Curso, request.Monto, request.Validez, request.LeadId); return Ok(new { id = result }); } [HttpPost("detalle")] - public async Task IngresarDetalle([FromQuery] int cotizacion, [FromQuery] string alumnoId, [FromQuery] int cursoId, [FromQuery] int cantidad, [FromQuery] int tarifa) + public async Task IngresarDetalle([FromBody] CotizacionDetalleRequest request) { - var result = await _cotizacionService.IngresarDetalleAsync(cotizacion, alumnoId, cursoId, cantidad, tarifa); + var result = await _cotizacionService.IngresarDetalleAsync(request.CotizacionId, request.AlumnoId, request.CursoId, request.Cantidad, request.Tarifa); return Ok(new { mensaje = result }); } [HttpPost("detalle-sin-curso")] - public async Task DetalleSinCurso([FromQuery] int cotizacion, [FromQuery] string alumnoId, [FromQuery] string apoderadoId, [FromQuery] int programaId, [FromQuery] int cantidad, [FromQuery] int tarifa, [FromQuery] int sedeId) + public async Task DetalleSinCurso([FromBody] CotizacionDetalleSinCursoRequest request) { - var result = await _cotizacionService.DetalleSinCursoAsync(cotizacion, alumnoId, apoderadoId, programaId, cantidad, tarifa, sedeId); + var result = await _cotizacionService.DetalleSinCursoAsync(request.CotizacionId, request.AlumnoId, request.ApoderadoId, request.ProgramaId, request.Cantidad, request.Tarifa, request.SedeId); return Ok(new { mensaje = result }); } @@ -89,21 +90,11 @@ public class CotizacionController : ControllerBase request.EstadoId, request.OticId, request.Motivo); return Ok(new { id = result }); } -} -public class CotizacionEmpRequest -{ - public string EmpresaId { get; set; } = string.Empty; - public string Vendedor { get; set; } = string.Empty; - public int Alumnos { get; set; } - public int Curso { get; set; } - public int EmpresaMonto { get; set; } - public int OticMonto { get; set; } - public int AlumnoMonto { get; set; } - public int CotizacionTipo { get; set; } - public DateTime Validez { get; set; } - public int DescuentoId { get; set; } - public int EstadoId { get; set; } - public string OticId { get; set; } = string.Empty; - public string Motivo { get; set; } = string.Empty; + [HttpPut("{id}/estado")] + public async Task ActualizarEstado(int id, [FromBody] CotizacionEstadoUpdateRequest request) + { + var result = await _cotizacionService.ActualizaEstadoCotizacionAsync(request.Tipo, id, request.ValorA ?? "", request.ValorB); + return Ok(new { mensaje = result }); + } } diff --git a/backend/src/Ventas.API/Controllers/CursoController.cs b/backend/src/Ventas.API/Controllers/CursoController.cs index 17cb8ff..cb3e6fd 100644 --- a/backend/src/Ventas.API/Controllers/CursoController.cs +++ b/backend/src/Ventas.API/Controllers/CursoController.cs @@ -1,47 +1,32 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class CursoController : ControllerBase +public class CursoController : BaseController { - private readonly string _connectionString; + private readonly CatalogoService _catalogo; - public CursoController(IConfiguration configuration) - { - _connectionString = configuration.GetConnectionString("Default")!; - } - - private async Task>> QuerySpAsync(string sp, object parameters) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync(sp, parameters, commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public CursoController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) - => Ok(await QuerySpAsync("sige_sam_v3.BuscarCurso", new { tipobusqueda = tipoBusqueda, cursonombre = nombre })); + public Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) + => OkResult(_catalogo.CursoBuscarAsync(tipoBusqueda, nombre)); [HttpGet("horario")] - public async Task BuscarHorario([FromQuery] int sede, [FromQuery] int curso) - => Ok(await QuerySpAsync("sam.WEB_Horarios_ecommerce", new { cursoid = curso, sedeid = sede })); + public Task BuscarHorario([FromQuery] int sede, [FromQuery] int curso) + => OkResult(_catalogo.CursoHorarioAsync(sede, curso)); [HttpGet("fechas-disponibles")] - public async Task FechaDisponibles([FromQuery] int curso, [FromQuery] int sede) - => Ok(await QuerySpAsync("sige_sam_v3.EcommerceFechas", new { cursoid = curso, sedeid = sede })); + public Task FechaDisponibles([FromQuery] int curso, [FromQuery] int sede) + => OkResult(_catalogo.CursoFechasAsync(curso, sede)); [HttpGet("apertura")] - public async Task BuscarApertura( - [FromQuery] string tipoBusqueda, [FromQuery] int codigoCurso, [FromQuery] int periodo, - [FromQuery] int year, [FromQuery] int producto, [FromQuery] int sede, + public Task BuscarApertura([FromQuery] string tipoBusqueda, [FromQuery] int codigoCurso, + [FromQuery] int periodo, [FromQuery] int year, [FromQuery] int producto, [FromQuery] int sede, [FromQuery] int jornada, [FromQuery] int asignacionProfe, [FromQuery] DateTime fecha) - => Ok(await QuerySpAsync("sige_sam_v3.BuscarCursosAperturados", - new { tipobusqueda = tipoBusqueda, codigocurso = codigoCurso, periodo, yearperiodo = year, - producto, sede, jornada, asignacion = asignacionProfe, fechatermino = fecha })); + => OkResult(_catalogo.CursoAperturaAsync(tipoBusqueda, codigoCurso, periodo, year, producto, sede, jornada, asignacionProfe, fecha)); } diff --git a/backend/src/Ventas.API/Controllers/DescuentoController.cs b/backend/src/Ventas.API/Controllers/DescuentoController.cs index 35a622c..f3774e6 100644 --- a/backend/src/Ventas.API/Controllers/DescuentoController.cs +++ b/backend/src/Ventas.API/Controllers/DescuentoController.cs @@ -1,49 +1,29 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class DescuentoController : ControllerBase +public class DescuentoController : BaseController { - private readonly string _connectionString; - - public DescuentoController(IConfiguration configuration) - { - _connectionString = configuration.GetConnectionString("Default")!; - } + private readonly CatalogoService _catalogo; + public DescuentoController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] int sede, [FromQuery] int programa, [FromQuery] int horario) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarDescuentos", - new { tipobusqueda = tipoBusqueda, sedeid = sede, programaid = programa, horarioid = horario }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] int sede, [FromQuery] int programa, [FromQuery] int horario) + => OkResult(_catalogo.DescuentoBuscarAsync(tipoBusqueda, sede, programa, horario)); [HttpGet("summer")] - public async Task Summer([FromQuery] int cantidadCursos) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarDesctoSummer", - new { cantidad = cantidadCursos }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Summer([FromQuery] int cantidadCursos) + => OkResult(_catalogo.DescuentoSummerAsync(cantidadCursos)); [HttpPost] - public async Task Ingresar([FromQuery] int cotizacionId, [FromQuery] int descuentoId, [FromQuery] int tipoDescuento, [FromQuery] int nuevoMonto) + public async Task Ingresar([FromBody] DescuentoIngresoRequest request) { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("sige_sam_v3.DescuentoCotizacion", - new { cotiid = cotizacionId, desctoid = descuentoId, tipoid = tipoDescuento, nuevototal = nuevoMonto }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(new { mensaje = "ok" }); + var result = await _catalogo.DescuentoIngresarAsync(request.CotizacionId, request.DescuentoId, request.TipoDescuento, request.NuevoMonto); + return Ok(new { mensaje = result }); } } diff --git a/backend/src/Ventas.API/Controllers/DocumentoController.cs b/backend/src/Ventas.API/Controllers/DocumentoController.cs index fea6804..06903e1 100644 --- a/backend/src/Ventas.API/Controllers/DocumentoController.cs +++ b/backend/src/Ventas.API/Controllers/DocumentoController.cs @@ -1,60 +1,28 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class DocumentoController : ControllerBase +public class DocumentoController : BaseController { - private readonly string _connectionString; - - public DocumentoController(IConfiguration configuration) - { - _connectionString = configuration.GetConnectionString("Default")!; - } + private readonly CatalogoService _catalogo; + public DocumentoController(CatalogoService catalogo) => _catalogo = catalogo; [HttpPost("orden-compra")] - public async Task IngresaOC([FromBody] OCRequest request) + public async Task IngresarOC([FromBody] OCRequest request) { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("Empresa_IngresoOrdenCompra", - new { numeroin = request.NumeroInterno, contid = request.ContratoId, tipodoc = request.TipoId, - glosa = request.Glosa, orig = request.Ubicacion, vendedor = request.Usuario }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(new { mensaje = "ok" }); + var result = await _catalogo.DocumentoIngresarOCAsync(request.NumeroInterno, request.ContratoId, request.TipoId, request.Glosa, request.Ubicacion, request.Usuario); + return Ok(new { mensaje = result }); } [HttpPost("sence")] - public async Task IngresaSNC([FromBody] SNCRequest request) + public async Task IngresarSNC([FromBody] SNCRequest request) { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("Empresa_IngresoInscripcionSence", - new { numsence = request.NumeroInterno, cont = request.ContratoId, alumnoid = request.Alumno, - obsv = request.Glosa, vendedorid = request.Usuario }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(new { mensaje = "ok" }); + var result = await _catalogo.DocumentoIngresarSNCAsync(request.NumeroInterno, request.Alumno, request.ContratoId, request.Glosa, request.Usuario); + return Ok(new { mensaje = result }); } } - -public class OCRequest -{ - public string NumeroInterno { get; set; } = string.Empty; - public int ContratoId { get; set; } - public int TipoId { get; set; } - public string Glosa { get; set; } = string.Empty; - public string Ubicacion { get; set; } = string.Empty; - public string Usuario { get; set; } = string.Empty; -} - -public class SNCRequest -{ - public string NumeroInterno { get; set; } = string.Empty; - public string Alumno { get; set; } = string.Empty; - public int ContratoId { get; set; } - public string Glosa { get; set; } = string.Empty; - public string Usuario { get; set; } = string.Empty; -} diff --git a/backend/src/Ventas.API/Controllers/EmpresaController.cs b/backend/src/Ventas.API/Controllers/EmpresaController.cs index db9a4b8..2d4afe0 100644 --- a/backend/src/Ventas.API/Controllers/EmpresaController.cs +++ b/backend/src/Ventas.API/Controllers/EmpresaController.cs @@ -1,66 +1,30 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class EmpresaController : ControllerBase +public class EmpresaController : BaseController { - private readonly string _connectionString; - - public EmpresaController(IConfiguration configuration) - { - _connectionString = configuration.GetConnectionString("Default")!; - } + private readonly CatalogoService _catalogo; + public EmpresaController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string busqueda, [FromQuery] string rut, [FromQuery] string varB, [FromQuery] int varC) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("ModuloEmpresa_BusquedaEmpresa", - new { tipo = busqueda, varz = rut, vary = varB, varx = varC }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] string busqueda, [FromQuery] string rut, [FromQuery] string nombre, [FromQuery] int tipo) + => OkResult(_catalogo.EmpresaBuscarAsync(busqueda, rut, nombre, tipo)); [HttpGet("tipos")] - public async Task BuscarTipos([FromQuery] string busqueda) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("Empresa_BuscarTiposEmpresas", - new { tipo = busqueda }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task BuscarTipos([FromQuery] string busqueda) + => OkResult(_catalogo.EmpresaTiposAsync(busqueda)); [HttpPost] public async Task Ingresar([FromBody] EmpresaIngresoRequest request) { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("IngresarEmpresaV2", - new { rutempresa = request.Rut, razonsocial = request.Nombre, drccnempresa = request.Direccion, - comunaid = request.Comuna, tipoid = request.Tipo, gironombre = request.GiroNombre, - contactoempresa = request.Contacto, fonocontacto = request.Fono, mailcontacto = request.Mail, - originemp = request.Origen }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(new { mensaje = "ok" }); + var result = await _catalogo.EmpresaIngresarAsync(request.Rut, request.Nombre, request.Direccion, request.Comuna, + request.Tipo, request.GiroNombre, request.Contacto, request.Fono, request.Mail, request.Origen); + return Ok(new { mensaje = result }); } } - -public class EmpresaIngresoRequest -{ - public string Rut { get; set; } = string.Empty; - public string Nombre { get; set; } = string.Empty; - public string Direccion { get; set; } = string.Empty; - public string Comuna { get; set; } = string.Empty; - public int Tipo { get; set; } - public string GiroNombre { get; set; } = string.Empty; - public string Contacto { get; set; } = string.Empty; - public int Fono { get; set; } - public string Mail { get; set; } = string.Empty; - public string Origen { get; set; } = string.Empty; -} diff --git a/backend/src/Ventas.API/Controllers/ErrorController.cs b/backend/src/Ventas.API/Controllers/ErrorController.cs new file mode 100644 index 0000000..2082007 --- /dev/null +++ b/backend/src/Ventas.API/Controllers/ErrorController.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Diagnostics; +using Microsoft.AspNetCore.Mvc; + +namespace Ventas.API.Controllers; + +[ApiController] +[Route("/")] +public class ErrorController : ControllerBase +{ + [HttpGet("error")] + public IActionResult Error() + { + var exception = HttpContext.Features.Get()?.Error; + return Problem(detail: exception?.Message, statusCode: 500); + } +} diff --git a/backend/src/Ventas.API/Controllers/HorarioController.cs b/backend/src/Ventas.API/Controllers/HorarioController.cs index 2bcf029..14e657f 100644 --- a/backend/src/Ventas.API/Controllers/HorarioController.cs +++ b/backend/src/Ventas.API/Controllers/HorarioController.cs @@ -1,26 +1,17 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class HorarioController : ControllerBase +public class HorarioController : BaseController { - private readonly string _connectionString; - - public HorarioController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public HorarioController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet("bloques")] - public async Task BuscarBloques([FromQuery] string busqueda, [FromQuery] string varA, [FromQuery] string varB) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("Empresa_HorarioBuscar", - new { tipo = busqueda, varz = varA, vary = varB }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task BuscarBloques([FromQuery] string busqueda, [FromQuery] string tipoBusqueda, [FromQuery] string sede) + => OkResult(_catalogo.HorarioBuscarAsync(busqueda, tipoBusqueda, sede)); } diff --git a/backend/src/Ventas.API/Controllers/InformeController.cs b/backend/src/Ventas.API/Controllers/InformeController.cs index b9fb9d3..0e3024e 100644 --- a/backend/src/Ventas.API/Controllers/InformeController.cs +++ b/backend/src/Ventas.API/Controllers/InformeController.cs @@ -19,6 +19,9 @@ public class InformeController : ControllerBase [HttpGet("ventas-mensuales")] public async Task InformeMensual([FromQuery] int mes, [FromQuery] int agno, [FromQuery] string tipo) { + if (string.IsNullOrEmpty(tipo)) + return BadRequest(new { mensaje = "tipo es requerido" }); + var result = await _informeService.InformeMensualAsync(mes, agno, tipo); return Ok(result); } @@ -33,28 +36,31 @@ public class InformeController : ControllerBase [HttpGet("lead-diarios")] public async Task InformeLeadDias([FromQuery] DateTime inicio, [FromQuery] DateTime termino, [FromQuery] string vendedorId) { + if (string.IsNullOrEmpty(vendedorId)) + return BadRequest(new { mensaje = "vendedorId es requerido" }); + var result = await _informeService.InformeLeadDiasAsync(inicio, termino, vendedorId); return Ok(result); } [HttpGet("ventas-empresa")] - public async Task VentasCursosEmpresa([FromQuery] string tipo, [FromQuery] string varA, [FromQuery] string varB, [FromQuery] int varC) + public async Task VentasCursosEmpresa([FromQuery] string tipo, [FromQuery] string valorA, [FromQuery] string valorB, [FromQuery] int valorC) { - var result = await _informeService.InformeVentasCursosEmpresaAsync(tipo, varA, varB, varC); + var result = await _informeService.InformeVentasCursosEmpresaAsync(tipo, valorA, valorB, valorC); return Ok(result); } [HttpGet("documentos")] - public async Task InformeDocumentos([FromQuery] string tipo, [FromQuery] string varA, [FromQuery] string varB, [FromQuery] int varC) + public async Task InformeDocumentos([FromQuery] string tipo, [FromQuery] string valorA, [FromQuery] string valorB, [FromQuery] int valorC) { - var result = await _informeService.InformeDocumentosAsync(tipo, varA, varB, varC); + var result = await _informeService.InformeDocumentosAsync(tipo, valorA, valorB, valorC); return Ok(result); } [HttpGet("general")] - public async Task InformeGeneral([FromQuery] string busqueda, [FromQuery] string varA, [FromQuery] string varB) + public async Task InformeGeneral([FromQuery] string busqueda, [FromQuery] string valorA, [FromQuery] string valorB) { - var result = await _informeService.InformeGeneralAsync(busqueda, varA, varB); + var result = await _informeService.InformeGeneralAsync(busqueda, valorA, valorB); return Ok(result); } } diff --git a/backend/src/Ventas.API/Controllers/JornadaController.cs b/backend/src/Ventas.API/Controllers/JornadaController.cs index 64c0db6..1cf4f92 100644 --- a/backend/src/Ventas.API/Controllers/JornadaController.cs +++ b/backend/src/Ventas.API/Controllers/JornadaController.cs @@ -1,26 +1,17 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class JornadaController : ControllerBase +public class JornadaController : BaseController { - private readonly string _connectionString; - - public JornadaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public JornadaController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarJornada", - new { tipobusqueda = tipoBusqueda, jornadanombre = nombre }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) + => OkResult(_catalogo.JornadaBuscarAsync(tipoBusqueda, nombre)); } diff --git a/backend/src/Ventas.API/Controllers/LeadController.cs b/backend/src/Ventas.API/Controllers/LeadController.cs index 4901e35..96a917c 100644 --- a/backend/src/Ventas.API/Controllers/LeadController.cs +++ b/backend/src/Ventas.API/Controllers/LeadController.cs @@ -67,23 +67,23 @@ public class LeadController : ControllerBase } [HttpPost("{id}/actividad")] - public async Task IngresarActividad(int id, [FromBody] ActividadCreateDto dto, [FromQuery] string usuarioId) + public async Task IngresarActividad(int id, [FromBody] ActividadCreateDto dto) { - var result = await _leadService.IngresarActividadAsync(id, dto.Tipo, dto.Descripcion, usuarioId); + var result = await _leadService.IngresarActividadAsync(id, dto.Tipo, dto.Descripcion, dto.UsuarioId ?? ""); return Ok(new { mensaje = result }); } [HttpPut("{id}/estado")] - public async Task ActualizarEstado(int id, [FromQuery] int estadoId) + public async Task ActualizarEstado(int id, [FromBody] LeadEstadoUpdateRequest request) { - var result = await _leadService.EstadoUpdateAsync(id, estadoId); + var result = await _leadService.EstadoUpdateAsync(id, request.EstadoId); return Ok(new { mensaje = result }); } [HttpPut("{id}/producto")] - public async Task ActualizarProducto(int id, [FromQuery] string producto) + public async Task ActualizarProducto(int id, [FromBody] LeadProductoUpdateRequest request) { - var result = await _leadService.ActualizarProductoAsync(id, producto); + var result = await _leadService.ActualizarProductoAsync(id, request.Producto); return Ok(new { mensaje = result }); } @@ -95,16 +95,16 @@ public class LeadController : ControllerBase } [HttpPost("{id}/perder")] - public async Task IngresarLeadPerdido(int id, [FromQuery] int motivo, [FromQuery] int estado) + public async Task IngresarLeadPerdido(int id, [FromBody] LeadPerderRequest request) { - var result = await _leadService.IngresarLeadPerdidoAsync(id, motivo, estado); + var result = await _leadService.IngresarLeadPerdidoAsync(id, request.Motivo, request.Estado); return Ok(new { mensaje = result }); } [HttpPost("{id}/pago")] public async Task IngresarPago(int id, [FromBody] PagoLeadDto dto) { - var result = await _leadService.IngresarPagoAsync(dto.LeadId, dto.CotizacionId, dto.FormaPago, dto.Monto, dto.CodigoAutorizacion ?? "", dto.DigitoTarjeta ?? "", dto.Cuotas); + var result = await _leadService.IngresarPagoAsync(id, dto.CotizacionId, dto.FormaPago, dto.Monto, dto.CodigoAutorizacion ?? "", dto.DigitoTarjeta ?? "", dto.Cuotas); return Ok(new { mensaje = result }); } } diff --git a/backend/src/Ventas.API/Controllers/ProgramaController.cs b/backend/src/Ventas.API/Controllers/ProgramaController.cs index 910ac16..46c51cb 100644 --- a/backend/src/Ventas.API/Controllers/ProgramaController.cs +++ b/backend/src/Ventas.API/Controllers/ProgramaController.cs @@ -1,26 +1,17 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class ProgramaController : ControllerBase +public class ProgramaController : BaseController { - private readonly string _connectionString; - - public ProgramaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public ProgramaController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarProgramas", - new { tipobusqueda = tipoBusqueda, nombreprograma = nombre }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) + => OkResult(_catalogo.ProgramaBuscarAsync(tipoBusqueda, nombre)); } diff --git a/backend/src/Ventas.API/Controllers/PropuestaController.cs b/backend/src/Ventas.API/Controllers/PropuestaController.cs index 54748f8..9b0856d 100644 --- a/backend/src/Ventas.API/Controllers/PropuestaController.cs +++ b/backend/src/Ventas.API/Controllers/PropuestaController.cs @@ -1,51 +1,26 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class PropuestaController : ControllerBase +public class PropuestaController : BaseController { - private readonly string _connectionString; - - public PropuestaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public PropuestaController(CatalogoService catalogo) => _catalogo = catalogo; [HttpPost] public async Task Ingresar([FromBody] PropuestaIngresoRequest request) { - using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QuerySingleOrDefaultAsync( - "Empresa_IngresoPropuestaV2", - new { tipo = request.TipoPropuesta, estado = request.Estado, venta = request.TipoVenta, - vendedor = request.Vendedor, fecha = request.Fecha, monto = request.Monto, - otic = request.OticId, libro = request.EnvioLibre }, - commandType: System.Data.CommandType.StoredProcedure); + var result = await _catalogo.PropuestaIngresarAsync(request.TipoPropuesta, request.Estado, request.TipoVenta, + request.Vendedor, request.Fecha, request.Monto, request.OticId, request.EnvioLibre); return Ok(new { id = result }); } [HttpGet("datos")] - public async Task Datos([FromQuery] string busqueda, [FromQuery] int prop, [FromQuery] int cotz, [FromQuery] int cont) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("ModuloEmpresa_PropuestaCrystalReport", - new { tipo = busqueda, prop, cotz, cont }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } -} - -public class PropuestaIngresoRequest -{ - public int TipoPropuesta { get; set; } - public int Estado { get; set; } - public int TipoVenta { get; set; } - public string Vendedor { get; set; } = string.Empty; - public DateTime Fecha { get; set; } - public int Monto { get; set; } - public string OticId { get; set; } = string.Empty; - public string EnvioLibre { get; set; } = string.Empty; + public Task Datos([FromQuery] string busqueda, [FromQuery] int propuestaId, [FromQuery] int cotizacionId, [FromQuery] int contratoId) + => OkResult(_catalogo.PropuestaDatosAsync(busqueda, propuestaId, cotizacionId, contratoId)); } diff --git a/backend/src/Ventas.API/Controllers/RegionController.cs b/backend/src/Ventas.API/Controllers/RegionController.cs index 7d6380c..a1eccb7 100644 --- a/backend/src/Ventas.API/Controllers/RegionController.cs +++ b/backend/src/Ventas.API/Controllers/RegionController.cs @@ -1,26 +1,17 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class RegionController : ControllerBase +public class RegionController : BaseController { - private readonly string _connectionString; - - public RegionController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public RegionController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarRegion", - new { tipobusqueda = tipoBusqueda, nombre }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) + => OkResult(_catalogo.RegionBuscarAsync(tipoBusqueda, nombre)); } diff --git a/backend/src/Ventas.API/Controllers/ReportController.cs b/backend/src/Ventas.API/Controllers/ReportController.cs index 3e73c39..129ec92 100644 --- a/backend/src/Ventas.API/Controllers/ReportController.cs +++ b/backend/src/Ventas.API/Controllers/ReportController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Core.DTOs; using Ventas.Services; namespace Ventas.API.Controllers; @@ -37,11 +38,8 @@ public class ReportController : ControllerBase => File(await _reportService.GenerarPresupuestoPdfAsync(id), "application/pdf", $"presupuesto_{id}.pdf"); [HttpPost("arqueo")] - public async Task ArqueoPdf( - [FromQuery] string usuario, [FromQuery] DateTime fecha, - [FromBody] List> ingresos, - [FromQuery] int totalCredito, [FromQuery] int totalDebito, - [FromQuery] int totalIntl, [FromQuery] int totalEstado, [FromQuery] int totalGeneral) - => File(await _reportService.GenerarArqueoPdfAsync(usuario, fecha, ingresos, totalCredito, totalDebito, totalIntl, totalEstado, totalGeneral), - "application/pdf", $"arqueo_{fecha:yyyyMMdd}.pdf"); + public async Task ArqueoPdf([FromBody] ArqueoPdfRequest request) + => File(await _reportService.GenerarArqueoPdfAsync(request.Usuario, request.Fecha, request.Ingresos, + request.TotalCredito, request.TotalDebito, request.TotalIntl, request.TotalEstado, request.TotalGeneral), + "application/pdf", $"arqueo_{request.Fecha:yyyyMMdd}.pdf"); } diff --git a/backend/src/Ventas.API/Controllers/SalaController.cs b/backend/src/Ventas.API/Controllers/SalaController.cs index 1eb7caa..97de7d5 100644 --- a/backend/src/Ventas.API/Controllers/SalaController.cs +++ b/backend/src/Ventas.API/Controllers/SalaController.cs @@ -1,38 +1,25 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class SalaController : ControllerBase +public class SalaController : BaseController { - private readonly string _connectionString; - - public SalaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public SalaController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre, [FromQuery] string sede) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarSala", - new { tipobusqueda = tipoBusqueda, salanombre = nombre, sedenombre = sede }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre, [FromQuery] string sede) + => OkResult(_catalogo.SalaBuscarAsync(tipoBusqueda, nombre, sede)); [HttpGet("ocupacion")] public async Task Ocupacion([FromQuery] int sedeId, [FromQuery] int jornadaId, [FromQuery] int salaId, [FromQuery] string fechaInicio, [FromQuery] int horario, [FromQuery] string dia, [FromQuery] string hora) { - using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QuerySingleOrDefaultAsync( - "sige_sam_v3.BuscarSalaOcupada", - new { sede = sedeId, jornada = jornadaId, fecha = fechaInicio, sala = salaId, horario, diacorto = dia, varhora = hora }, - commandType: System.Data.CommandType.StoredProcedure); + var result = await _catalogo.SalaOcupacionAsync(sedeId, jornadaId, salaId, fechaInicio, horario, dia, hora); return Ok(new { ocupado = !string.IsNullOrEmpty(result), curso = result }); } } diff --git a/backend/src/Ventas.API/Controllers/SedeController.cs b/backend/src/Ventas.API/Controllers/SedeController.cs index 076d0c8..229cd78 100644 --- a/backend/src/Ventas.API/Controllers/SedeController.cs +++ b/backend/src/Ventas.API/Controllers/SedeController.cs @@ -1,26 +1,17 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class SedeController : ControllerBase +public class SedeController : BaseController { - private readonly string _connectionString; - - public SedeController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public SedeController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarSedes", - new { tipobusqueda = tipoBusqueda, sedenombre = nombre }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre) + => OkResult(_catalogo.SedeBuscarAsync(tipoBusqueda, nombre)); } diff --git a/backend/src/Ventas.API/Controllers/TarifaController.cs b/backend/src/Ventas.API/Controllers/TarifaController.cs index c6d8481..449efcf 100644 --- a/backend/src/Ventas.API/Controllers/TarifaController.cs +++ b/backend/src/Ventas.API/Controllers/TarifaController.cs @@ -1,36 +1,21 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class TarifaController : ControllerBase +public class TarifaController : BaseController { - private readonly string _connectionString; - - public TarifaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + private readonly CatalogoService _catalogo; + public TarifaController(CatalogoService catalogo) => _catalogo = catalogo; [HttpGet] - public async Task Buscar([FromQuery] int producto, [FromQuery] int programa, [FromQuery] int jornada, [FromQuery] int sede, [FromQuery] string fecha) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarTarifa", - new { producto, programa, jornada, sede, fecha }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Buscar([FromQuery] int producto, [FromQuery] int programa, [FromQuery] int jornada, [FromQuery] int sede, [FromQuery] string fecha) + => OkResult(_catalogo.TarifaBuscarAsync(producto, programa, jornada, sede, fecha)); [HttpGet("promocion")] - public async Task Promocion([FromQuery] int tarifaId, [FromQuery] int cantidadCursos) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarTarifaPromocion", - new { tarifa = tarifaId, cantcursos = cantidadCursos }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task Promocion([FromQuery] int tarifaId, [FromQuery] int cantidadCursos) + => OkResult(_catalogo.TarifaPromocionAsync(tarifaId, cantidadCursos)); } diff --git a/backend/src/Ventas.API/Controllers/UsuarioController.cs b/backend/src/Ventas.API/Controllers/UsuarioController.cs index eb9959f..f98c673 100644 --- a/backend/src/Ventas.API/Controllers/UsuarioController.cs +++ b/backend/src/Ventas.API/Controllers/UsuarioController.cs @@ -1,45 +1,25 @@ -using Dapper; -using Npgsql; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Ventas.Services; namespace Ventas.API.Controllers; -[ApiController] [Route("api/[controller]")] [Authorize] -public class UsuarioController : ControllerBase +public class UsuarioController : BaseController { - private readonly string _connectionString; + private readonly CatalogoService _catalogo; + public UsuarioController(CatalogoService catalogo) => _catalogo = catalogo; - public UsuarioController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!; + [HttpGet("{usuarioId}")] + public Task Info(string usuarioId) + => OkResult(_catalogo.UsuarioInfoAsync(usuarioId)); - [HttpGet("{id}")] - public async Task Info(string id) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarUsuario", - new { usuarioid = id }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } - - [HttpGet("{id}/perfil")] - public async Task Perfil(string id) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarPerfilUsuario", - new { usuario = id }, - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + [HttpGet("{usuarioId}/perfil")] + public Task Perfil(string usuarioId) + => OkResult(_catalogo.UsuarioPerfilAsync(usuarioId)); [HttpGet("vendedores")] - public async Task VendedoresActivos() - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync("sige_sam_v3.BuscarVendedoresActivos", - commandType: System.Data.CommandType.StoredProcedure); - return Ok(rows.Select(r => (Dictionary)(IDictionary)r!)); - } + public Task VendedoresActivos() + => OkResult(_catalogo.VendedoresActivosAsync()); } diff --git a/backend/src/Ventas.API/Middleware/JwtMiddleware.cs b/backend/src/Ventas.API/Middleware/JwtMiddleware.cs deleted file mode 100644 index 38ecb2f..0000000 --- a/backend/src/Ventas.API/Middleware/JwtMiddleware.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Text; -using Microsoft.IdentityModel.Tokens; - -namespace Ventas.API.Middleware; - -public class JwtMiddleware -{ - private readonly RequestDelegate _next; - private readonly string _secret; - - public JwtMiddleware(RequestDelegate next, IConfiguration configuration) - { - _next = next; - _secret = configuration["Jwt:Secret"] ?? "default-dev-secret-change-in-production"; - } - - public async Task InvokeAsync(HttpContext context) - { - var token = context.Request.Cookies["SAM_TOKEN"] - ?? context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); - - if (token != null) - { - try - { - var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_secret)); - var handler = new JwtSecurityTokenHandler(); - var principal = handler.ValidateToken(token, new TokenValidationParameters - { - ValidateIssuer = false, - ValidateAudience = false, - ValidateLifetime = true, - ValidateIssuerSigningKey = true, - IssuerSigningKey = key - }, out _); - - context.User = principal; - } - catch { } - } - - await _next(context); - } -} diff --git a/backend/src/Ventas.API/Program.cs b/backend/src/Ventas.API/Program.cs index 6a4a25e..2281dec 100644 --- a/backend/src/Ventas.API/Program.cs +++ b/backend/src/Ventas.API/Program.cs @@ -1,9 +1,8 @@ using System.Text; using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using QuestPDF.Infrastructure; -using Ventas.Infrastructure.Data; +using Ventas.Infrastructure.Dapper; using Ventas.Infrastructure.Repositories; using Ventas.Core.Interfaces; using Ventas.Services; @@ -17,9 +16,6 @@ var connectionString = builder.Configuration.GetConnectionString("Default")!; builder.Services.AddControllers(); builder.Services.AddOpenApi(); -builder.Services.AddDbContext(options => - options.UseNpgsql(connectionString)); - builder.Services.AddScoped(sp => new LeadRepository(connectionString)); builder.Services.AddScoped(sp => @@ -34,27 +30,34 @@ builder.Services.AddScoped(sp => new UsuarioRepository(connectionString)); builder.Services.AddScoped(sp => new InformeRepository(connectionString)); +builder.Services.AddScoped(sp => + new ArqueoRepository(connectionString)); +builder.Services.AddScoped(sp => + new SpComplexQueries(connectionString)); +builder.Services.AddScoped(sp => + new CatalogoRepository(connectionString)); +builder.Services.AddScoped(sp => + new CatalogoService(sp.GetRequiredService())); builder.Services.AddScoped(sp => - new LeadService(connectionString)); + new LeadService(sp.GetRequiredService(), sp.GetRequiredService())); builder.Services.AddScoped(sp => - new UsuarioService(sp.GetRequiredService(), connectionString)); + new UsuarioService(sp.GetRequiredService())); builder.Services.AddScoped(sp => - new ContratoService(sp.GetRequiredService(), connectionString)); + new ContratoService(sp.GetRequiredService(), sp.GetRequiredService())); builder.Services.AddScoped(sp => - new CotizacionService(sp.GetRequiredService(), connectionString)); + new CotizacionService(sp.GetRequiredService(), sp.GetRequiredService())); builder.Services.AddScoped(sp => - new AlumnoService(sp.GetRequiredService(), connectionString)); + new AlumnoService(sp.GetRequiredService(), sp.GetRequiredService())); builder.Services.AddScoped(sp => - new ArqueoService(connectionString)); + new ArqueoService(sp.GetRequiredService())); builder.Services.AddScoped(); builder.Services.AddScoped(sp => - new ReportService(sp.GetRequiredService(), sp.GetRequiredService(), connectionString)); + new ReportService(sp.GetRequiredService(), sp.GetRequiredService(), sp.GetRequiredService())); builder.Services.AddScoped(sp => - new EmpresaReportService(sp.GetRequiredService(), connectionString)); + new EmpresaReportService(sp.GetRequiredService(), sp.GetRequiredService())); -var jwtSecret = builder.Configuration["Jwt:Secret"]; -if (string.IsNullOrEmpty(jwtSecret)) jwtSecret = "default-dev-secret-change-in-production"; +var jwtSecret = builder.Configuration["Jwt:Secret"] ?? "default-dev-secret-change-in-production"; var jwtExpiration = int.Parse(builder.Configuration["Jwt:ExpirationMinutes"] ?? "30"); builder.Services.AddScoped(sp => new JwtService(jwtSecret, jwtExpiration)); @@ -67,9 +70,23 @@ builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, + ClockSkew = TimeSpan.Zero, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret)) }; + + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + var cookieToken = context.Request.Cookies["SAM_TOKEN"]; + if (!string.IsNullOrEmpty(cookieToken)) + { + context.Token = cookieToken; + } + return Task.CompletedTask; + } + }; }); builder.Services.AddCors(options => @@ -88,9 +105,12 @@ if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } +else +{ + app.UseExceptionHandler("/error"); +} app.UseCors(); -app.UseMiddleware(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); diff --git a/backend/src/Ventas.API/Ventas.API.csproj b/backend/src/Ventas.API/Ventas.API.csproj index b4b9809..7190bf2 100644 --- a/backend/src/Ventas.API/Ventas.API.csproj +++ b/backend/src/Ventas.API/Ventas.API.csproj @@ -8,6 +8,7 @@ + diff --git a/backend/src/Ventas.Core/DTOs/AlumnoDto.cs b/backend/src/Ventas.Core/DTOs/AlumnoDto.cs new file mode 100644 index 0000000..b0a6896 --- /dev/null +++ b/backend/src/Ventas.Core/DTOs/AlumnoDto.cs @@ -0,0 +1,30 @@ +namespace Ventas.Core.DTOs; + +public class AlumnoIngresoRequest +{ + public string Rut { get; set; } = string.Empty; + public string Nombre { get; set; } = string.Empty; + public string Paterno { get; set; } = string.Empty; + public string Materno { get; set; } = string.Empty; + public string Direccion { get; set; } = "SIN DIRECCION"; + public string Comuna { get; set; } = "1"; + public string Fecha { get; set; } = string.Empty; + public string Fono { get; set; } = string.Empty; + public string Mail { get; set; } = string.Empty; + public int Ocupacion { get; set; } + public string ProfesionOficio { get; set; } = string.Empty; +} + +public class ApoderadoIngresoRequest +{ + public string RutApoderado { get; set; } = string.Empty; + public string RutAlumno { get; set; } = string.Empty; + public string Nombre { get; set; } = string.Empty; + public string Paterno { get; set; } = string.Empty; + public string Materno { get; set; } = string.Empty; + public string Direccion { get; set; } = string.Empty; + public string Comuna { get; set; } = string.Empty; + public int Nacionalidad { get; set; } + public string Fono { get; set; } = string.Empty; + public string Mail { get; set; } = string.Empty; +} diff --git a/backend/src/Ventas.Core/DTOs/ContratoDto.cs b/backend/src/Ventas.Core/DTOs/ContratoDto.cs new file mode 100644 index 0000000..cc25b79 --- /dev/null +++ b/backend/src/Ventas.Core/DTOs/ContratoDto.cs @@ -0,0 +1,53 @@ +namespace Ventas.Core.DTOs; + +public class ContratoIngresoRequest +{ + public int CotizacionId { get; set; } + public int BoletaCKT { get; set; } = 1; + public string FechaContrato { get; set; } = string.Empty; + public int BoletaId { get; set; } + public int VendedorId { get; set; } +} + +public class ContratoDetalleRequest +{ + public int ContratoId { get; set; } + public string EmpresaId { get; set; } = string.Empty; + public string AlumnoId { get; set; } = string.Empty; + public string CursoId { get; set; } = string.Empty; + public string Fecha { get; set; } = string.Empty; + public int Vendedor { get; set; } + public int RegistroAcademico { get; set; } + public int AlumnoTipo { get; set; } +} + +public class ContratoEmpresaRequest +{ + public int CotizacionId { get; set; } + public string EmpresaId { get; set; } = string.Empty; + public int TipoVenta { get; set; } + public int FacturaId { get; set; } + public int CantCursos { get; set; } + public int VendedorId { get; set; } +} + +public class ContratoCerradoRequest +{ + public int PropuestaId { get; set; } + public string Rut { get; set; } = string.Empty; + public int TipoVenta { get; set; } + public string VendedorId { get; set; } = string.Empty; +} + +public class ContratoEstadoUpdateRequest +{ + public string Tipo { get; set; } = string.Empty; + public string? ValorA { get; set; } + public int ValorB { get; set; } +} + +public class ContratoFirmaRequest +{ + public string Tipo { get; set; } = string.Empty; + public int Firmado { get; set; } +} diff --git a/backend/src/Ventas.Core/DTOs/CotizacionDto.cs b/backend/src/Ventas.Core/DTOs/CotizacionDto.cs new file mode 100644 index 0000000..99fec19 --- /dev/null +++ b/backend/src/Ventas.Core/DTOs/CotizacionDto.cs @@ -0,0 +1,60 @@ +namespace Ventas.Core.DTOs; + +public class CotizacionIngresoRequest +{ + public string ApoderadoId { get; set; } = string.Empty; + public string VendedorId { get; set; } = string.Empty; + public int SolicitudDescuento { get; set; } = 1; + public int Descuento { get; set; } + public int TipoDescuento { get; set; } + public string Fecha { get; set; } = string.Empty; + public int Alumnos { get; set; } = 1; + public int Curso { get; set; } = 1; + public int Monto { get; set; } + public string Validez { get; set; } = string.Empty; + public int LeadId { get; set; } +} + +public class CotizacionDetalleRequest +{ + public int CotizacionId { get; set; } + public string AlumnoId { get; set; } = string.Empty; + public int CursoId { get; set; } + public int Cantidad { get; set; } + public int Tarifa { get; set; } +} + +public class CotizacionDetalleSinCursoRequest +{ + public int CotizacionId { get; set; } + public string AlumnoId { get; set; } = string.Empty; + public string ApoderadoId { get; set; } = string.Empty; + public int ProgramaId { get; set; } + public int Cantidad { get; set; } + public int Tarifa { get; set; } + public int SedeId { get; set; } +} + +public class CotizacionEmpRequest +{ + public string EmpresaId { get; set; } = string.Empty; + public string Vendedor { get; set; } = string.Empty; + public int Alumnos { get; set; } + public int Curso { get; set; } + public int EmpresaMonto { get; set; } + public int OticMonto { get; set; } + public int AlumnoMonto { get; set; } + public int CotizacionTipo { get; set; } + public DateTime Validez { get; set; } + public int DescuentoId { get; set; } + public int EstadoId { get; set; } + public string OticId { get; set; } = string.Empty; + public string Motivo { get; set; } = string.Empty; +} + +public class CotizacionEstadoUpdateRequest +{ + public string Tipo { get; set; } = string.Empty; + public string? ValorA { get; set; } + public int ValorB { get; set; } +} diff --git a/backend/src/Ventas.Core/DTOs/DescuentoDto.cs b/backend/src/Ventas.Core/DTOs/DescuentoDto.cs new file mode 100644 index 0000000..37b1618 --- /dev/null +++ b/backend/src/Ventas.Core/DTOs/DescuentoDto.cs @@ -0,0 +1,9 @@ +namespace Ventas.Core.DTOs; + +public class DescuentoIngresoRequest +{ + public int CotizacionId { get; set; } + public int DescuentoId { get; set; } + public int TipoDescuento { get; set; } + public int NuevoMonto { get; set; } +} diff --git a/backend/src/Ventas.Core/DTOs/DocumentoDto.cs b/backend/src/Ventas.Core/DTOs/DocumentoDto.cs new file mode 100644 index 0000000..7de7507 --- /dev/null +++ b/backend/src/Ventas.Core/DTOs/DocumentoDto.cs @@ -0,0 +1,20 @@ +namespace Ventas.Core.DTOs; + +public class OCRequest +{ + public string NumeroInterno { get; set; } = string.Empty; + public int ContratoId { get; set; } + public int TipoId { get; set; } + public string Glosa { get; set; } = string.Empty; + public string Ubicacion { get; set; } = string.Empty; + public string Usuario { get; set; } = string.Empty; +} + +public class SNCRequest +{ + public string NumeroInterno { get; set; } = string.Empty; + public string Alumno { get; set; } = string.Empty; + public int ContratoId { get; set; } + public string Glosa { get; set; } = string.Empty; + public string Usuario { get; set; } = string.Empty; +} diff --git a/backend/src/Ventas.Core/DTOs/EmpresaDto.cs b/backend/src/Ventas.Core/DTOs/EmpresaDto.cs new file mode 100644 index 0000000..2a3d095 --- /dev/null +++ b/backend/src/Ventas.Core/DTOs/EmpresaDto.cs @@ -0,0 +1,15 @@ +namespace Ventas.Core.DTOs; + +public class EmpresaIngresoRequest +{ + public string Rut { get; set; } = string.Empty; + public string Nombre { get; set; } = string.Empty; + public string Direccion { get; set; } = string.Empty; + public string Comuna { get; set; } = string.Empty; + public int Tipo { get; set; } + public string GiroNombre { get; set; } = string.Empty; + public string Contacto { get; set; } = string.Empty; + public string Fono { get; set; } = string.Empty; + public string Mail { get; set; } = string.Empty; + public string Origen { get; set; } = string.Empty; +} diff --git a/backend/src/Ventas.Core/DTOs/LeadDto.cs b/backend/src/Ventas.Core/DTOs/LeadDto.cs index 42f92e3..07a89dd 100644 --- a/backend/src/Ventas.Core/DTOs/LeadDto.cs +++ b/backend/src/Ventas.Core/DTOs/LeadDto.cs @@ -44,9 +44,26 @@ public class ActividadCreateDto { public string Tipo { get; set; } = string.Empty; public string Descripcion { get; set; } = string.Empty; + public string? UsuarioId { get; set; } public DateTime? FechaPlanificada { get; set; } } +public class LeadEstadoUpdateRequest +{ + public int EstadoId { get; set; } +} + +public class LeadProductoUpdateRequest +{ + public string Producto { get; set; } = string.Empty; +} + +public class LeadPerderRequest +{ + public int Motivo { get; set; } + public int Estado { get; set; } +} + public class PagoLeadDto { public int LeadId { get; set; } diff --git a/backend/src/Ventas.Core/DTOs/PropuestaDto.cs b/backend/src/Ventas.Core/DTOs/PropuestaDto.cs new file mode 100644 index 0000000..08d35e0 --- /dev/null +++ b/backend/src/Ventas.Core/DTOs/PropuestaDto.cs @@ -0,0 +1,25 @@ +namespace Ventas.Core.DTOs; + +public class PropuestaIngresoRequest +{ + public int TipoPropuesta { get; set; } + public int Estado { get; set; } + public int TipoVenta { get; set; } + public string Vendedor { get; set; } = string.Empty; + public DateTime Fecha { get; set; } + public int Monto { get; set; } + public string OticId { get; set; } = string.Empty; + public string EnvioLibre { get; set; } = string.Empty; +} + +public class ArqueoPdfRequest +{ + public string Usuario { get; set; } = string.Empty; + public DateTime Fecha { get; set; } + public List> Ingresos { get; set; } = []; + public int TotalCredito { get; set; } + public int TotalDebito { get; set; } + public int TotalIntl { get; set; } + public int TotalEstado { get; set; } + public int TotalGeneral { get; set; } +} diff --git a/backend/src/Ventas.Core/Interfaces/IArqueoRepository.cs b/backend/src/Ventas.Core/Interfaces/IArqueoRepository.cs new file mode 100644 index 0000000..e411efc --- /dev/null +++ b/backend/src/Ventas.Core/Interfaces/IArqueoRepository.cs @@ -0,0 +1,7 @@ +namespace Ventas.Core.Interfaces; + +public interface IArqueoRepository +{ + Task>> TodosHoyAsync(DateTime fecha); + Task>> HoyAsync(string usuarioId, DateTime fecha); +} diff --git a/backend/src/Ventas.Core/Interfaces/ICatalogoRepository.cs b/backend/src/Ventas.Core/Interfaces/ICatalogoRepository.cs new file mode 100644 index 0000000..ea2a383 --- /dev/null +++ b/backend/src/Ventas.Core/Interfaces/ICatalogoRepository.cs @@ -0,0 +1,8 @@ +namespace Ventas.Core.Interfaces; + +public interface ICatalogoRepository +{ + Task>> QuerySpAsync(string sp, object parameters); + Task ExecuteSpAsync(string sp, object parameters); + Task QuerySingleSpAsync(string sp, object parameters); +} diff --git a/backend/src/Ventas.Core/Interfaces/IUsuarioRepository.cs b/backend/src/Ventas.Core/Interfaces/IUsuarioRepository.cs index 67c0b59..005e900 100644 --- a/backend/src/Ventas.Core/Interfaces/IUsuarioRepository.cs +++ b/backend/src/Ventas.Core/Interfaces/IUsuarioRepository.cs @@ -1,8 +1,10 @@ +using Ventas.Core.DTOs; + namespace Ventas.Core.Interfaces; public interface IUsuarioRepository { - Task BuscarAsync(string usuario, string clave); - Task InfoAsync(string usuario); - Task PerfilAsync(string usuario); + Task BuscarAsync(string usuario, string clave); + Task InfoAsync(string usuario); + Task PerfilAsync(string usuario); } diff --git a/backend/src/Ventas.Infrastructure/Repositories/ArqueoRepository.cs b/backend/src/Ventas.Infrastructure/Repositories/ArqueoRepository.cs new file mode 100644 index 0000000..9ebd901 --- /dev/null +++ b/backend/src/Ventas.Infrastructure/Repositories/ArqueoRepository.cs @@ -0,0 +1,33 @@ +using Dapper; +using Npgsql; +using Ventas.Core.Interfaces; + +namespace Ventas.Infrastructure.Repositories; + +public class ArqueoRepository : IArqueoRepository +{ + private readonly string _connectionString; + + public ArqueoRepository(string connectionString) + { + _connectionString = connectionString; + } + + public async Task>> TodosHoyAsync(DateTime fecha) + { + using var connection = new NpgsqlConnection(_connectionString); + var rows = await connection.QueryAsync("sige_sam_v3.ArqueoHoy", + new { fechaarqueo = fecha }, + commandType: System.Data.CommandType.StoredProcedure); + return rows.Select(r => (Dictionary)(IDictionary)r!); + } + + public async Task>> HoyAsync(string usuarioId, DateTime fecha) + { + using var connection = new NpgsqlConnection(_connectionString); + var rows = await connection.QueryAsync("sige_sam_v3.ArqueoEjecutivo", + new { usuarioid = usuarioId, fechaarqueo = fecha }, + commandType: System.Data.CommandType.StoredProcedure); + return rows.Select(r => (Dictionary)(IDictionary)r!); + } +} diff --git a/backend/src/Ventas.Infrastructure/Repositories/CatalogoRepository.cs b/backend/src/Ventas.Infrastructure/Repositories/CatalogoRepository.cs new file mode 100644 index 0000000..55d0aa3 --- /dev/null +++ b/backend/src/Ventas.Infrastructure/Repositories/CatalogoRepository.cs @@ -0,0 +1,36 @@ +using Dapper; +using Npgsql; +using Ventas.Core.Interfaces; + +namespace Ventas.Infrastructure.Repositories; + +public class CatalogoRepository : ICatalogoRepository +{ + private readonly string _connectionString; + + public CatalogoRepository(string connectionString) + { + _connectionString = connectionString; + } + + public async Task>> QuerySpAsync(string sp, object parameters) + { + using var connection = new NpgsqlConnection(_connectionString); + var rows = await connection.QueryAsync(sp, parameters, commandType: System.Data.CommandType.StoredProcedure); + return rows.Select(r => (Dictionary)(IDictionary)r!); + } + + public async Task ExecuteSpAsync(string sp, object parameters) + { + using var connection = new NpgsqlConnection(_connectionString); + await connection.ExecuteAsync(sp, parameters, commandType: System.Data.CommandType.StoredProcedure); + return "ok"; + } + + public async Task QuerySingleSpAsync(string sp, object parameters) + { + using var connection = new NpgsqlConnection(_connectionString); + return await connection.QuerySingleOrDefaultAsync(sp, parameters, + commandType: System.Data.CommandType.StoredProcedure); + } +} diff --git a/backend/src/Ventas.Infrastructure/Repositories/LeadRepository.cs b/backend/src/Ventas.Infrastructure/Repositories/LeadRepository.cs index 5fe17da..36666e9 100644 --- a/backend/src/Ventas.Infrastructure/Repositories/LeadRepository.cs +++ b/backend/src/Ventas.Infrastructure/Repositories/LeadRepository.cs @@ -104,7 +104,7 @@ public class LeadRepository : ILeadRepository using var connection = new NpgsqlConnection(_connectionString); await connection.ExecuteAsync( "sige_sam_v3.GrabaActividadesLead", - new { leadid = leadId, tipo = dto.Tipo, descripcion = dto.Descripcion, usuarioid = "" }, + new { leadid = leadId, tipo = dto.Tipo, descripcion = dto.Descripcion, usuarioid = dto.UsuarioId }, commandType: System.Data.CommandType.StoredProcedure); return "ok"; } diff --git a/backend/src/Ventas.Infrastructure/Repositories/UsuarioRepository.cs b/backend/src/Ventas.Infrastructure/Repositories/UsuarioRepository.cs index fd0855e..de18ed8 100644 --- a/backend/src/Ventas.Infrastructure/Repositories/UsuarioRepository.cs +++ b/backend/src/Ventas.Infrastructure/Repositories/UsuarioRepository.cs @@ -1,5 +1,6 @@ using Dapper; using Npgsql; +using Ventas.Core.DTOs; using Ventas.Core.Interfaces; namespace Ventas.Infrastructure.Repositories; @@ -13,33 +14,68 @@ public class UsuarioRepository : IUsuarioRepository _connectionString = connectionString; } - public async Task BuscarAsync(string usuario, string clave) + public async Task BuscarAsync(string usuario, string clave) { using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QueryAsync( + var data = await connection.QueryAsync( "sam.BuscarUsuario", new { userid = usuario, passid = clave }, commandType: System.Data.CommandType.StoredProcedure); - return result.Any() ? "ok" : ""; + + var user = data.FirstOrDefault(); + if (user == null) return null; + + var dict = (IDictionary)user; + dict.TryGetValue("Nombres", out var nombres); + dict.TryGetValue("idSede", out var sede); + return new LoginResponse + { + Nombre = nombres?.ToString() ?? "", + Sede = sede?.ToString() + }; } - public async Task InfoAsync(string usuario) + public async Task InfoAsync(string usuario) { using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QueryAsync( + var data = await connection.QueryAsync( "sige_sam_v3.BuscarUsuario", new { usuarioid = usuario }, commandType: System.Data.CommandType.StoredProcedure); - return result.Any() ? "ok" : ""; + + var user = data.FirstOrDefault(); + if (user == null) return null; + + var dict = (IDictionary)user; + dict.TryGetValue("Nombres", out var nombres); + dict.TryGetValue("idSede", out var sede); + return new LoginResponse + { + Nombre = nombres?.ToString() ?? "", + Sede = sede?.ToString() + }; } - public async Task PerfilAsync(string usuario) + public async Task PerfilAsync(string usuario) { using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QueryAsync( + var data = await connection.QueryAsync( "sige_sam_v3.BuscarPerfilUsuario", new { usuario }, commandType: System.Data.CommandType.StoredProcedure); - return result.Any() ? "ok" : ""; + + var user = data.FirstOrDefault(); + if (user == null) return null; + + var dict = (IDictionary)user; + dict.TryGetValue("Nombres", out var nombres); + dict.TryGetValue("idSede", out var sede); + dict.TryGetValue("Perfil", out var perfil); + return new LoginResponse + { + Nombre = nombres?.ToString() ?? "", + Sede = sede?.ToString(), + Perfil = perfil?.ToString() + }; } } diff --git a/backend/src/Ventas.Services/AlumnoService.cs b/backend/src/Ventas.Services/AlumnoService.cs index bd994a0..2aafd7a 100644 --- a/backend/src/Ventas.Services/AlumnoService.cs +++ b/backend/src/Ventas.Services/AlumnoService.cs @@ -1,5 +1,3 @@ -using Dapper; -using Npgsql; using Ventas.Core.Interfaces; namespace Ventas.Services; @@ -7,57 +5,50 @@ namespace Ventas.Services; public class AlumnoService { private readonly IAlumnoRepository _alumnoRepository; - private readonly string _connectionString; + private readonly ICatalogoRepository _catalogo; - public AlumnoService(IAlumnoRepository alumnoRepository, string connectionString) + public AlumnoService(IAlumnoRepository alumnoRepository, ICatalogoRepository catalogo) { _alumnoRepository = alumnoRepository; - _connectionString = connectionString; + _catalogo = catalogo; } - private async Task>> QuerySpAsync(string sp, object parameters) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync(sp, parameters, commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public Task>> BuscarAsync(string tipoBusqueda, string nombre) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarAlumnos", new { tipobusqueda = tipoBusqueda, nombrealumno = nombre }); - public async Task>> BuscarAsync(string tipoBusqueda, string nombre) - => await QuerySpAsync("sige_sam_v3.BuscarAlumnos", new { tipobusqueda = tipoBusqueda, nombrealumno = nombre }); - - public async Task IngresarV2Async(string rut, string nombre, string paterno, string materno, string fecha, string fono, string mail, int ocupacion, string profeOficio) - => await _alumnoRepository.IngresarV2Async(rut, nombre, paterno, materno, "SIN DIRECCION", "1", fecha, fono, mail, ocupacion, profeOficio); + public async Task IngresarV2Async(string rut, string nombre, string paterno, string materno, string direccion, string comuna, string fecha, string fono, string mail, int ocupacion, string profeOficio) + => await _alumnoRepository.IngresarV2Async(rut, nombre, paterno, materno, direccion, comuna, fecha, fono, mail, ocupacion, profeOficio); public async Task IngresarApoderadoAsync(string rutApoderado, string rutAlumno, string nombre, string paterno, string materno, string direccion, string comuna, int nacionalidad, string fono, string mail) => await _alumnoRepository.IngresarApoderadoAsync(rutApoderado, rutAlumno, nombre, paterno, materno, direccion, comuna, nacionalidad, fono, mail); - public async Task>> BuscarApoderadoAsync(string tipoBusqueda, string nombre) - => await QuerySpAsync("sige_sam_v3.BuscarApoderado", new { tipobusqueda = tipoBusqueda, nombreapoderado = nombre }); + public Task>> BuscarApoderadoAsync(string tipoBusqueda, string nombre) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarApoderado", new { tipobusqueda = tipoBusqueda, nombreapoderado = nombre }); - public async Task>> OcupacionAsync() - => await QuerySpAsync("sige_sam_v3.BuscarOcupaciones", new { }); + public Task>> OcupacionAsync() + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarOcupaciones", new { }); - public async Task>> BuscarContratosAsync(string id) - => await QuerySpAsync("sam.BuscarAlumnoContratoPersona", new { alumnoid = id }); + public Task>> BuscarContratosAsync(string id) + => _catalogo.QuerySpAsync("sam.BuscarAlumnoContratoPersona", new { alumnoid = id }); - public async Task>> BuscarBloqueoAsync(string idAlumno) - => await QuerySpAsync("sige_sam_v3.BuscarBloqueoFinazas", new { idcliente = idAlumno }); + public Task>> BuscarBloqueoAsync(string idAlumno) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarBloqueoFinazas", new { idcliente = idAlumno }); - public async Task>> BuscarAntiguedadAsync(string idAlumno) - => await QuerySpAsync("sige_sam_v3.AlumnoAntiguedad", new { alumnoid = idAlumno }); + public Task>> BuscarAntiguedadAsync(string idAlumno) + => _catalogo.QuerySpAsync("sige_sam_v3.AlumnoAntiguedad", new { alumnoid = idAlumno }); - public async Task>> BuscarFormasPagoAsync(int boleta) - => await QuerySpAsync("sige_sam_v3.AlumnoFormaPagoContrato", new { boleta }); + public Task>> BuscarFormasPagoAsync(int boleta) + => _catalogo.QuerySpAsync("sige_sam_v3.AlumnoFormaPagoContrato", new { boleta }); - public async Task>> BuscarAnexosContratoAsync(string alumnoId, string contratoId) - => await QuerySpAsync("sige_sam_v3.AlumnoBuscarAnexos", new { alumnoid = alumnoId, contrato = contratoId }); + public Task>> BuscarAnexosContratoAsync(string alumnoId, string contratoId) + => _catalogo.QuerySpAsync("sige_sam_v3.AlumnoBuscarAnexos", new { alumnoid = alumnoId, contrato = contratoId }); - public async Task>> BuscarColegiosAsync(string nombre) - => await QuerySpAsync("sam.BuscarColegios", new { nombrelike = nombre }); + public Task>> BuscarColegiosAsync(string nombre) + => _catalogo.QuerySpAsync("sam.BuscarColegios", new { nombrelike = nombre }); - public async Task>> BuscarProfesionesAsync(string nombre) - => await QuerySpAsync("sam.BuscarProfesiones", new { nombrelike = nombre }); + public Task>> BuscarProfesionesAsync(string nombre) + => _catalogo.QuerySpAsync("sam.BuscarProfesiones", new { nombrelike = nombre }); - public async Task>> BuscarComunasXnombreAsync(string nombre) - => await QuerySpAsync("sam.BuscarComunasXnombre", new { nombrelike = nombre }); + public Task>> BuscarComunasXnombreAsync(string nombre) + => _catalogo.QuerySpAsync("sam.BuscarComunasXnombre", new { nombrelike = nombre }); } diff --git a/backend/src/Ventas.Services/ArqueoService.cs b/backend/src/Ventas.Services/ArqueoService.cs index 1e8ed8c..88c3731 100644 --- a/backend/src/Ventas.Services/ArqueoService.cs +++ b/backend/src/Ventas.Services/ArqueoService.cs @@ -1,34 +1,19 @@ -using Dapper; -using Npgsql; +using Ventas.Core.Interfaces; namespace Ventas.Services; public class ArqueoService { - private readonly string _connectionString; + private readonly IArqueoRepository _arqueoRepository; - public ArqueoService(string connectionString) + public ArqueoService(IArqueoRepository arqueoRepository) { - _connectionString = connectionString; + _arqueoRepository = arqueoRepository; } - public async Task>> TodosHoyAsync(DateTime fecha) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.ArqueoHoy", - new { fechaarqueo = fecha }, - commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public Task>> TodosHoyAsync(DateTime fecha) + => _arqueoRepository.TodosHoyAsync(fecha); - public async Task>> HoyAsync(string usuarioId, DateTime fecha) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.ArqueoEjecutivo", - new { usuarioid = usuarioId, fechaarqueo = fecha }, - commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public Task>> HoyAsync(string usuarioId, DateTime fecha) + => _arqueoRepository.HoyAsync(usuarioId, fecha); } diff --git a/backend/src/Ventas.Services/CatalogoService.cs b/backend/src/Ventas.Services/CatalogoService.cs new file mode 100644 index 0000000..5ae37d5 --- /dev/null +++ b/backend/src/Ventas.Services/CatalogoService.cs @@ -0,0 +1,92 @@ +using Ventas.Core.Interfaces; + +namespace Ventas.Services; + +public class CatalogoService +{ + private readonly ICatalogoRepository _repo; + + public CatalogoService(ICatalogoRepository repo) + { + _repo = repo; + } + + // Curso + public Task>> CursoBuscarAsync(string tipo, string nombre) + => _repo.QuerySpAsync("sige_sam_v3.BuscarCurso", new { tipobusqueda = tipo, cursonombre = nombre }); + public Task>> CursoHorarioAsync(int sede, int curso) + => _repo.QuerySpAsync("sam.WEB_Horarios_ecommerce", new { cursoid = curso, sedeid = sede }); + public Task>> CursoFechasAsync(int curso, int sede) + => _repo.QuerySpAsync("sige_sam_v3.EcommerceFechas", new { cursoid = curso, sedeid = sede }); + public Task>> CursoAperturaAsync(string tipo, int curso, int periodo, int year, int prod, int sede, int jornada, int asignacion, DateTime fecha) + => _repo.QuerySpAsync("sige_sam_v3.BuscarCursosAperturados", + new { tipobusqueda = tipo, codigocurso = curso, periodo, yearperiodo = year, producto = prod, sede, jornada, asignacion = asignacion, fechatermino = fecha }); + + // Sede + public Task>> SedeBuscarAsync(string tipo, string nombre) + => _repo.QuerySpAsync("sige_sam_v3.BuscarSedes", new { tipobusqueda = tipo, sedenombre = nombre }); + + // Region + public Task>> RegionBuscarAsync(string tipo, string nombre) + => _repo.QuerySpAsync("sige_sam_v3.BuscarRegion", new { tipobusqueda = tipo, nombre }); + + // Jornada + public Task>> JornadaBuscarAsync(string tipo, string nombre) + => _repo.QuerySpAsync("sige_sam_v3.BuscarJornada", new { tipobusqueda = tipo, jornadanombre = nombre }); + + // Programa + public Task>> ProgramaBuscarAsync(string tipo, string nombre) + => _repo.QuerySpAsync("sige_sam_v3.BuscarProgramas", new { tipobusqueda = tipo, nombreprograma = nombre }); + + // Sala + public Task>> SalaBuscarAsync(string tipo, string nombre, string sede) + => _repo.QuerySpAsync("sige_sam_v3.BuscarSala", new { tipobusqueda = tipo, salanombre = nombre, sedenombre = sede }); + public Task SalaOcupacionAsync(int sedeId, int jornadaId, int salaId, string fecha, int horario, string dia, string hora) + => _repo.QuerySingleSpAsync("sige_sam_v3.BuscarSalaOcupada", new { sede = sedeId, jornada = jornadaId, fecha, sala = salaId, horario, diacorto = dia, varhora = hora }); + + // Tarifa + public Task>> TarifaBuscarAsync(int producto, int programa, int jornada, int sede, string fecha) + => _repo.QuerySpAsync("sige_sam_v3.BuscarTarifa", new { producto, programa, jornada, sede, fecha }); + public Task>> TarifaPromocionAsync(int tarifaId, int cantCursos) + => _repo.QuerySpAsync("sige_sam_v3.BuscarTarifaPromocion", new { tarifa = tarifaId, cantcursos = cantCursos }); + + // Horario + public Task>> HorarioBuscarAsync(string tipo, string varA, string varB) + => _repo.QuerySpAsync("Empresa_HorarioBuscar", new { tipo, varz = varA, vary = varB }); + + // Descuento + public Task>> DescuentoBuscarAsync(string tipo, int sede, int programa, int horario) + => _repo.QuerySpAsync("sige_sam_v3.BuscarDescuentos", new { tipobusqueda = tipo, sedeid = sede, programaid = programa, horarioid = horario }); + public Task>> DescuentoSummerAsync(int cantidad) + => _repo.QuerySpAsync("sige_sam_v3.BuscarDesctoSummer", new { cantidad }); + public Task DescuentoIngresarAsync(int cotizacionId, int descuentoId, int tipoDescuento, int nuevoMonto) + => _repo.ExecuteSpAsync("sige_sam_v3.DescuentoCotizacion", new { cotiid = cotizacionId, desctoid = descuentoId, tipoid = tipoDescuento, nuevototal = nuevoMonto }); + + // Documento + public Task DocumentoIngresarOCAsync(string interno, int contratoId, int tipoId, string glosa, string ubicacion, string usuario) + => _repo.ExecuteSpAsync("Empresa_IngresoOrdenCompra", new { numeroin = interno, contid = contratoId, tipodoc = tipoId, glosa, orig = ubicacion, vendedor = usuario }); + public Task DocumentoIngresarSNCAsync(string interno, string alumno, int contratoId, string glosa, string usuario) + => _repo.ExecuteSpAsync("Empresa_IngresoInscripcionSence", new { numsence = interno, cont = contratoId, alumnoid = alumno, obsv = glosa, vendedorid = usuario }); + + // Propuesta + public Task PropuestaIngresarAsync(int tipo, int estado, int venta, string vendedor, DateTime fecha, int monto, string otic, string libro) + => _repo.QuerySingleSpAsync("Empresa_IngresoPropuestaV2", new { tipo, estado, venta, vendedor, fecha, monto, otic, libro }); + public Task>> PropuestaDatosAsync(string busqueda, int prop, int cotz, int cont) + => _repo.QuerySpAsync("ModuloEmpresa_PropuestaCrystalReport", new { tipo = busqueda, prop, cotz, cont }); + + // Empresa + public Task>> EmpresaBuscarAsync(string busqueda, string rut, string varB, int varC) + => _repo.QuerySpAsync("ModuloEmpresa_BusquedaEmpresa", new { tipo = busqueda, varz = rut, vary = varB, varx = varC }); + public Task>> EmpresaTiposAsync(string busqueda) + => _repo.QuerySpAsync("Empresa_BuscarTiposEmpresas", new { tipo = busqueda }); + public Task EmpresaIngresarAsync(string rut, string nombre, string direccion, string comuna, int tipo, string giro, string contacto, string fono, string mail, string origen) + => _repo.ExecuteSpAsync("IngresarEmpresaV2", new { rutempresa = rut, razonsocial = nombre, drccnempresa = direccion, comunaid = comuna, tipoid = tipo, gironombre = giro, contactoempresa = contacto, fonocontacto = fono, mailcontacto = mail, originemp = origen }); + + // Usuario + public Task>> UsuarioInfoAsync(string id) + => _repo.QuerySpAsync("sige_sam_v3.BuscarUsuario", new { usuarioid = id }); + public Task>> UsuarioPerfilAsync(string id) + => _repo.QuerySpAsync("sige_sam_v3.BuscarPerfilUsuario", new { usuario = id }); + public Task>> VendedoresActivosAsync() + => _repo.QuerySpAsync("sige_sam_v3.BuscarVendedoresActivos", new { }); +} diff --git a/backend/src/Ventas.Services/ContratoService.cs b/backend/src/Ventas.Services/ContratoService.cs index 0210b95..b70c8d7 100644 --- a/backend/src/Ventas.Services/ContratoService.cs +++ b/backend/src/Ventas.Services/ContratoService.cs @@ -1,5 +1,3 @@ -using Dapper; -using Npgsql; using Ventas.Core.Interfaces; namespace Ventas.Services; @@ -7,80 +5,49 @@ namespace Ventas.Services; public class ContratoService { private readonly IContratoRepository _contratoRepository; - private readonly string _connectionString; + private readonly ICatalogoRepository _catalogo; - public ContratoService(IContratoRepository contratoRepository, string connectionString) + public ContratoService(IContratoRepository contratoRepository, ICatalogoRepository catalogo) { _contratoRepository = contratoRepository; - _connectionString = connectionString; + _catalogo = catalogo; } - private async Task>> QuerySpAsync(string sp, object parameters) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync(sp, parameters, commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } - - public async Task IngresarAsync(int cotizacionId, string fechaContrato, int boletaId, int vendedorId) - => await _contratoRepository.IngresarAsync(cotizacionId, 1, fechaContrato, boletaId, vendedorId); + public async Task IngresarAsync(int cotizacionId, int boletaCKT, string fechaContrato, int boletaId, int vendedorId) + => await _contratoRepository.IngresarAsync(cotizacionId, boletaCKT, fechaContrato, boletaId, vendedorId); public async Task IngresarDetalleAsync(int contratoId, string empresaId, string alumnoId, string cursoId, string fecha, int vendedor, int registroAcademico, int alumnoTipo) => await _contratoRepository.IngresarDetalleAsync(contratoId, empresaId, alumnoId, cursoId, fecha, vendedor, registroAcademico, alumnoTipo); - public async Task>> PdfContratoAsync(int contrato) - => await QuerySpAsync("sige_sam_v3.PDFContrato", new { contrato }); + public Task>> PdfContratoAsync(int contrato) + => _catalogo.QuerySpAsync("sige_sam_v3.PDFContrato", new { contrato }); - public async Task>> PdfContratoJornadasAsync(int contrato) - => await QuerySpAsync("sige_sam_v3.PDFContratoJornadas", new { contrato }); + public Task>> PdfContratoJornadasAsync(int contrato) + => _catalogo.QuerySpAsync("sige_sam_v3.PDFContratoJornadas", new { contrato }); - public async Task>> PdfContratoProgramasCursosAsync(int contrato) - => await QuerySpAsync("sige_sam_v3.PDFContratoProgramasCursos", new { contrato }); + public Task>> PdfContratoProgramasCursosAsync(int contrato) + => _catalogo.QuerySpAsync("sige_sam_v3.PDFContratoProgramasCursos", new { contrato }); - public async Task>> PdfContratoSedesAsync(int contrato) - => await QuerySpAsync("sige_sam_v3.PDFContratoSedes", new { contrato }); + public Task>> PdfContratoSedesAsync(int contrato) + => _catalogo.QuerySpAsync("sige_sam_v3.PDFContratoSedes", new { contrato }); - public async Task>> BuscarInformacionAsync(int contrato) - => await QuerySpAsync("sige_sam_v3.BuscarInfoContrato", new { contratoid = contrato }); + public Task>> BuscarInformacionAsync(int contrato) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarInfoContrato", new { contratoid = contrato }); public async Task IngresarContratoEmpresaAsync(int cotizacionId, string empresaId, int tipoVenta, int facturaId, int cantCursos, int vendedorId) - { - using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QuerySingleOrDefaultAsync( - "IngresarContratoEmpresa", - new { cotizacionid = cotizacionId, empresaid = empresaId, tipoventaid = tipoVenta, facturaid = facturaId, cantidadcursos = cantCursos, vendedorid = vendedorId }, - commandType: System.Data.CommandType.StoredProcedure); - return result ?? "ok"; - } + => await _catalogo.QuerySingleSpAsync("IngresarContratoEmpresa", + new { cotizacionid = cotizacionId, empresaid = empresaId, tipoventaid = tipoVenta, facturaid = facturaId, cantidadcursos = cantCursos, vendedorid = vendedorId }) ?? "ok"; public async Task IngresarContratoCerradoAsync(int prop, string rut, int tipoVenta, string vendedorId) - { - using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QuerySingleOrDefaultAsync( - "Empresa_IngresarContratoV2", - new { prop, rut, tipo = tipoVenta, vendedor = vendedorId }, - commandType: System.Data.CommandType.StoredProcedure); - return result ?? "ok"; - } + => await _catalogo.QuerySingleSpAsync("Empresa_IngresarContratoV2", + new { prop, rut, tipo = tipoVenta, vendedor = vendedorId }) ?? "ok"; public async Task IngresarFirmaPendienteAsync(int contratoId) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("Empresa_IngresarContratoFirma", new { cont = contratoId }, commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + => await _catalogo.ExecuteSpAsync("Empresa_IngresarContratoFirma", new { cont = contratoId }); public async Task ActualizarEstadoContratoAsync(string tipo, int contId, string varA, int varB) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("Empresa_ActualizaContrato", new { tipo, contrato = contId, varz = varA, vary = varB }, commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + => await _catalogo.ExecuteSpAsync("Empresa_ActualizaContrato", new { tipo, contrato = contId, varz = varA, vary = varB }); public async Task ActualizarFirmaContratoAsync(string tipo, int contrato, int firmado) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("Empresa_ActualizaFirmaContrato", new { tipoeleccion = tipo, cont = contrato, fir = firmado }, commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + => await _catalogo.ExecuteSpAsync("Empresa_ActualizaFirmaContrato", new { tipoeleccion = tipo, cont = contrato, fir = firmado }); } diff --git a/backend/src/Ventas.Services/CotizacionService.cs b/backend/src/Ventas.Services/CotizacionService.cs index 061df4a..1436f4a 100644 --- a/backend/src/Ventas.Services/CotizacionService.cs +++ b/backend/src/Ventas.Services/CotizacionService.cs @@ -1,5 +1,3 @@ -using Dapper; -using Npgsql; using Ventas.Core.Interfaces; namespace Ventas.Services; @@ -7,53 +5,36 @@ namespace Ventas.Services; public class CotizacionService { private readonly ICotizacionRepository _cotizacionRepository; - private readonly string _connectionString; + private readonly ICatalogoRepository _catalogo; - public CotizacionService(ICotizacionRepository cotizacionRepository, string connectionString) + public CotizacionService(ICotizacionRepository cotizacionRepository, ICatalogoRepository catalogo) { _cotizacionRepository = cotizacionRepository; - _connectionString = connectionString; + _catalogo = catalogo; } - private async Task>> QuerySpAsync(string sp, object parameters) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync(sp, parameters, commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } - - public async Task IngresarAsync(string apoderadoId, string vendedorId, int descuento, int tipoDescuento, string fecha, int monto, string validez, int leadId) - => await _cotizacionRepository.PersonaIngresarAsync(apoderadoId, vendedorId, 1, descuento, tipoDescuento, fecha, 1, 1, monto, validez, leadId); + public async Task IngresarAsync(string apoderadoId, string vendedorId, int solicitudDescuento, int descuento, int tipoDescuento, string fecha, int alumnos, int curso, int monto, string validez, int leadId) + => await _cotizacionRepository.PersonaIngresarAsync(apoderadoId, vendedorId, solicitudDescuento, descuento, tipoDescuento, fecha, alumnos, curso, monto, validez, leadId); public async Task IngresarDetalleAsync(int cotizacion, string alumnoId, int cursoId, int cantidad, int tarifa) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("sige_sam_v3.IngresarCotizacionDetalle", - new { cotizaion = cotizacion, alumno = alumnoId, codigocurso = cursoId, cantidad, tarifa }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + => await _catalogo.ExecuteSpAsync("sige_sam_v3.IngresarCotizacionDetalle", + new { cotizaion = cotizacion, alumno = alumnoId, codigocurso = cursoId, cantidad, tarifa }); public async Task DetalleSinCursoAsync(int cotizacion, string alumnoId, string apoderadoId, int programaId, int cantidad, int tarifa, int sedeId) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("sige_sam_v3.IngresarAnexoCotiSinCurso", - new { cotiid = cotizacion, alumnid = alumnoId, apoid = apoderadoId, programid = programaId, cursos = cantidad, tarifaid = tarifa, idsede = sedeId }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + => await _catalogo.ExecuteSpAsync("sige_sam_v3.IngresarAnexoCotiSinCurso", + new { cotiid = cotizacion, alumnid = alumnoId, apoid = apoderadoId, programid = programaId, cursos = cantidad, tarifaid = tarifa, idsede = sedeId }); - public async Task>> BuscarAsync(int lead) - => await QuerySpAsync("sige_sam_v3.BuscarCotizacionLead", new { leadid = lead }); + public Task>> BuscarAsync(int lead) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarCotizacionLead", new { leadid = lead }); - public async Task>> BuscarSinCursoAsync(int lead) - => await QuerySpAsync("sige_sam_v3.BuscarCotizacionesSinCurso", new { leadid = lead }); + public Task>> BuscarSinCursoAsync(int lead) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarCotizacionesSinCurso", new { leadid = lead }); - public async Task>> BuscarInfoAsync(string tipoBusqueda, string nombre) - => await QuerySpAsync("sige_sam_v3.BuscarCotizacion", new { tipobusqueda = tipoBusqueda, nombre, fecha = DateTime.Now.ToString("yyyy-MM-dd") }); + public Task>> BuscarInfoAsync(string tipoBusqueda, string nombre) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarCotizacion", new { tipobusqueda = tipoBusqueda, nombre, fecha = DateTime.Now.ToString("yyyy-MM-dd") }); - public async Task>> DetalleAsync(int cotizacion) - => await QuerySpAsync("sige_sam_v3.BuscarCotizacionDetalle", new { cotizacion }); + public Task>> DetalleAsync(int cotizacion) + => _catalogo.QuerySpAsync("sige_sam_v3.BuscarCotizacionDetalle", new { cotizacion }); public async Task PersonaPagarAsync(int cotizacion) => await _cotizacionRepository.PersonaPagarAsync(cotizacion); @@ -62,19 +43,9 @@ public class CotizacionService => await _cotizacionRepository.DesactivarAsync(cotizacion); public async Task CotizacionEmpIngresoAsync(string empresaId, string vendedor, int alumnos, int curso, int empresaMonto, int oticMonto, int alumnoMonto, int cotizacionTipo, DateTime validez, int descuentoId, int estadoId, string oticId, string motivo) - { - using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QuerySingleOrDefaultAsync( - "Empresa_IngresarCotizacionEmpresaV2", - new { rutempresa = empresaId, vendedor, cantidadcursos = curso, cantidadalumnos = alumnos, montpempresa = empresaMonto, montootic = oticMonto, montoalm = alumnoMonto, tipocotz = cotizacionTipo, validez, iddescuento = descuentoId, idestado = estadoId, oticid = oticId, motivo }, - commandType: System.Data.CommandType.StoredProcedure); - return result ?? "ok"; - } + => await _catalogo.QuerySingleSpAsync("Empresa_IngresarCotizacionEmpresaV2", + new { rutempresa = empresaId, vendedor, cantidadcursos = curso, cantidadalumnos = alumnos, montpempresa = empresaMonto, montootic = oticMonto, montoalm = alumnoMonto, tipocotz = cotizacionTipo, validez, iddescuento = descuentoId, idestado = estadoId, oticid = oticId, motivo }) ?? "ok"; public async Task ActualizaEstadoCotizacionAsync(string tipo, int cotzId, string varA, int varB) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync("Empresa_ActualizaCotizacion", new { tipo, cotizacion = cotzId, varz = varA, vary = varB }, commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + => await _catalogo.ExecuteSpAsync("Empresa_ActualizaCotizacion", new { tipo, cotizacion = cotzId, varz = varA, vary = varB }); } diff --git a/backend/src/Ventas.Services/EmpresaReportService.cs b/backend/src/Ventas.Services/EmpresaReportService.cs index 56fba71..db6e475 100644 --- a/backend/src/Ventas.Services/EmpresaReportService.cs +++ b/backend/src/Ventas.Services/EmpresaReportService.cs @@ -1,5 +1,3 @@ -using Dapper; -using Npgsql; using QuestPDF.Fluent; using QuestPDF.Helpers; using QuestPDF.Infrastructure; @@ -10,22 +8,12 @@ namespace Ventas.Services; public class EmpresaReportService { private readonly IInformeRepository _informeRepository; - private readonly string _connectionString; + private readonly ICatalogoRepository _catalogo; - public EmpresaReportService(IInformeRepository informeRepository, string connectionString) + public EmpresaReportService(IInformeRepository informeRepository, ICatalogoRepository catalogo) { _informeRepository = informeRepository; - _connectionString = connectionString; - } - - private async Task>> ContratoCrysAsync(string tipo, int cont) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "Empresa_ContratoCrys", - new { tipo, cont }, - commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); + _catalogo = catalogo; } private static string GetString(Dictionary row, string key) => @@ -33,10 +21,10 @@ public class EmpresaReportService public async Task ContratoAbiertoPdfAsync(int contratoId) { - var dt01 = await ContratoCrysAsync("CONTRATOREIMPRESION", contratoId); - var dt02 = await ContratoCrysAsync("DETALLECURSO", contratoId); - var dt03 = await ContratoCrysAsync("HORARIO", contratoId); - var dt04 = await ContratoCrysAsync("ALUMNO", contratoId); + var dt01 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "CONTRATOREIMPRESION", cont = contratoId }); + var dt02 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "DETALLECURSO", cont = contratoId }); + var dt03 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "HORARIO", cont = contratoId }); + var dt04 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "ALUMNO", cont = contratoId }); var header = dt01.FirstOrDefault(); if (header == null) return []; @@ -288,11 +276,10 @@ public class EmpresaReportService }); } - // Variantes CAEMP/CAEMPSNC/CAEMPV2 — mismo SP, layout con/sin SENCE public async Task ContratoAbiertoSinSencePdfAsync(int contratoId) { - var dt01 = await ContratoCrysAsync("CONTRATOREIMPRESION", contratoId); - var dt02 = await ContratoCrysAsync("DETALLECURSO", contratoId); + var dt01 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "CONTRATOREIMPRESION", cont = contratoId }); + var dt02 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "DETALLECURSO", cont = contratoId }); var header = dt01.FirstOrDefault(); if (header == null) return []; @@ -324,8 +311,8 @@ public class EmpresaReportService public async Task ContratoAbiertoConSencePdfAsync(int contratoId) { - var dt01 = await ContratoCrysAsync("CONTRATOREIMPRESION", contratoId); - var dt02 = await ContratoCrysAsync("DETALLECURSO", contratoId); + var dt01 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "CONTRATOREIMPRESION", cont = contratoId }); + var dt02 = await _catalogo.QuerySpAsync("Empresa_ContratoCrys", new { tipo = "DETALLECURSO", cont = contratoId }); var header = dt01.FirstOrDefault(); if (header == null) return []; diff --git a/backend/src/Ventas.Services/InformeService.cs b/backend/src/Ventas.Services/InformeService.cs index 07876c3..4ddc386 100644 --- a/backend/src/Ventas.Services/InformeService.cs +++ b/backend/src/Ventas.Services/InformeService.cs @@ -28,4 +28,7 @@ public class InformeService public async Task>> InformeGeneralAsync(string busqueda, string varA, string varB) => await _informeRepository.InformeGeneralAsync(busqueda, varA, varB); + + public async Task>> EjecutarCrystalSpAsync(string tipo, int prop, int cotz, int cont) + => await _informeRepository.EjecutarCrystalSpAsync(tipo, prop, cotz, cont); } diff --git a/backend/src/Ventas.Services/LeadService.cs b/backend/src/Ventas.Services/LeadService.cs index 2ec4919..c411944 100644 --- a/backend/src/Ventas.Services/LeadService.cs +++ b/backend/src/Ventas.Services/LeadService.cs @@ -1,160 +1,62 @@ -using Dapper; -using Npgsql; using Ventas.Core.DTOs; +using Ventas.Core.Interfaces; namespace Ventas.Services; public class LeadService { - private readonly string _connectionString; + private readonly ILeadRepository _leadRepository; + private readonly ILeadQueryRepository _leadQueryRepository; - public LeadService(string connectionString) + public LeadService(ILeadRepository leadRepository, ILeadQueryRepository leadQueryRepository) { - _connectionString = connectionString; + _leadRepository = leadRepository; + _leadQueryRepository = leadQueryRepository; } - public async Task>> BuscarAsync(int ejecutivo, int estado, int dias) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.BuscarLeadV3", - new { ejecutivo, estadolead = estado, filtro = dias }, - commandType: System.Data.CommandType.StoredProcedure); + public Task>> BuscarAsync(int ejecutivo, int estado, int dias) + => _leadQueryRepository.BuscarAsync(ejecutivo, estado, dias); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public Task>> BuscarIDAsync(int id) + => _leadQueryRepository.BuscarIDAsync(id); - public async Task>> BuscarIDAsync(int id) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.BuscarLeadID", - new { id }, - commandType: System.Data.CommandType.StoredProcedure); + public Task>> BuscarNuevosAsync(int ejecutivo) + => _leadQueryRepository.BuscarNuevosAsync(ejecutivo); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public Task IngresarAsync(LeadCreateDto dto) + => _leadRepository.IngresarAsync(dto); - public async Task>> BuscarNuevosAsync(int ejecutivo) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.BuscarLeadNuevos", - new { ejecutivo }, - commandType: System.Data.CommandType.StoredProcedure); + public Task IngresarV2Async(LeadCreateDto dto) + => _leadRepository.IngresarV2Async(dto); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public Task IngresarPagoAsync(int lead, int coti, string pago, int monto, string cod, string dig, int cuota) + => _leadRepository.IngresarPagoAsync(new PagoLeadDto + { + LeadId = lead, CotizacionId = coti, FormaPago = pago, + Monto = monto, CodigoAutorizacion = cod, DigitoTarjeta = dig, Cuotas = cuota + }); - public async Task IngresarAsync(LeadCreateDto dto) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync( - "sige_sam_v3.GrabaLead", - new { nombrelead = dto.Nombre, maillead = dto.Mail, telefonolead = dto.Telefono, productolead = dto.Producto, contactolead = dto.Contacto, ejecutivoid = dto.EjecutivoId }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + public Task ActualizarProductoAsync(int leadId, string producto) + => _leadRepository.ActualizarProductoAsync(leadId, producto); - public async Task IngresarV2Async(LeadCreateDto dto) - { - using var connection = new NpgsqlConnection(_connectionString); - var result = await connection.QuerySingleOrDefaultAsync( - "sige_sam_v3.GrabaLead", - new { nombrelead = dto.Nombre, maillead = dto.Mail, telefonolead = dto.Telefono, productolead = dto.Producto, contactolead = dto.Contacto, ejecutivoid = dto.EjecutivoId }, - commandType: System.Data.CommandType.StoredProcedure); - return result ?? "ok"; - } + public Task>> MontosAsync(int ejecutivo) + => _leadQueryRepository.MontosAsync(ejecutivo); - public async Task IngresarPagoAsync(int lead, int coti, string pago, int monto, string cod, string dig, int cuota) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync( - "sige_sam_v3.GrabaPagoLead", - new { leadid = lead, cotiid = coti, formapago = pago, valor = monto, codauto = cod, digtar = dig, cantcouta = cuota }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + public Task>> ActividadesAsync(int leadId, string tipo) + => _leadQueryRepository.ActividadesAsync(leadId, tipo); - public async Task ActualizarProductoAsync(int leadId, string producto) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync( - "sam.ActualuzarLeadProducto", - new { leadid = leadId, productlead = producto }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + public Task IngresarActividadAsync(int leadId, string tipo, string descripcion, string usuarioId) + => _leadRepository.IngresarActividadAsync(leadId, new ActividadCreateDto { Tipo = tipo, Descripcion = descripcion, UsuarioId = usuarioId }); - public async Task>> MontosAsync(int ejecutivo) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.BuscarLeadMontos", - new { ejecutivo }, - commandType: System.Data.CommandType.StoredProcedure); + public Task EstadoUpdateAsync(int leadId, int estadoId) + => _leadRepository.EstadoUpdateAsync(leadId, estadoId); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } + public Task>> MotivosPerdidoAsync() + => _leadQueryRepository.MotivosPerdidoAsync(); - public async Task>> ActividadesAsync(int leadId, string tipo) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.BuscarActividadesLead", - new { id = leadId, tipoactividad = tipo }, - commandType: System.Data.CommandType.StoredProcedure); + public Task IngresarLeadPerdidoAsync(int leadId, int motivo, int estado) + => _leadRepository.IngresarLeadPerdidoAsync(leadId, motivo, estado); - return rows.Select(r => (Dictionary)(IDictionary)r!); - } - - public async Task IngresarActividadAsync(int leadId, string tipo, string descripcion, string usuarioId) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync( - "sige_sam_v3.GrabaActividadesLead", - new { leadid = leadId, tipo, descripcion, usuarioid = usuarioId }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } - - public async Task EstadoUpdateAsync(int leadId, int estadoId) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync( - "sige_sam_v3.ActualizarEstadoLead", - new { leadid = leadId, estadolead = estadoId }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } - - public async Task>> MotivosPerdidoAsync() - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync( - "sige_sam_v3.BuscarMotivoLeadPerdido", - commandType: System.Data.CommandType.StoredProcedure); - - return rows.Select(r => (Dictionary)(IDictionary)r!); - } - - public async Task IngresarLeadPerdidoAsync(int leadId, int motivo, int estado) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync( - "sige_sam_v3.Lead_Ingresar_Perdido", - new { leadid = leadId, motivo, estado }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } - - public async Task ActualizarContactoAsync(int leadId, string nombre, string mail, string fono, string rut) - { - using var connection = new NpgsqlConnection(_connectionString); - await connection.ExecuteAsync( - "sige_sam_v3.ActualizaLeadContacto", - new { leadid = leadId, nombrecontacto = nombre, mailcontacto = mail, fonocontacto = fono, rutcontacto = rut }, - commandType: System.Data.CommandType.StoredProcedure); - return "ok"; - } + public Task ActualizarContactoAsync(int leadId, string nombre, string mail, string fono, string rut) + => _leadRepository.ActualizarContactoAsync(leadId, new ContactoUpdateDto { Nombre = nombre, Mail = mail, Telefono = fono, Rut = rut }); } diff --git a/backend/src/Ventas.Services/ReportService.cs b/backend/src/Ventas.Services/ReportService.cs index 106187b..98ed9c6 100644 --- a/backend/src/Ventas.Services/ReportService.cs +++ b/backend/src/Ventas.Services/ReportService.cs @@ -1,8 +1,7 @@ -using Dapper; -using Npgsql; using QuestPDF.Fluent; using QuestPDF.Helpers; using QuestPDF.Infrastructure; +using Ventas.Core.Interfaces; namespace Ventas.Services; @@ -10,20 +9,13 @@ public class ReportService { private readonly ContratoService _contratoService; private readonly CotizacionService _cotizacionService; - private readonly string _connectionString; + private readonly ICatalogoRepository _catalogo; - public ReportService(ContratoService contratoService, CotizacionService cotizacionService, string connectionString) + public ReportService(ContratoService contratoService, CotizacionService cotizacionService, ICatalogoRepository catalogo) { _contratoService = contratoService; _cotizacionService = cotizacionService; - _connectionString = connectionString; - } - - private async Task>> QuerySpAsync(string sp, object parameters) - { - using var connection = new NpgsqlConnection(_connectionString); - var rows = await connection.QueryAsync(sp, parameters, commandType: System.Data.CommandType.StoredProcedure); - return rows.Select(r => (Dictionary)(IDictionary)r!); + _catalogo = catalogo; } public async Task GenerarContratoPdfAsync(int contratoId) @@ -362,7 +354,7 @@ public class ReportService public async Task GenerarAnexoPdfAsync(int contratoId, int anexoId) { - var rows = await QuerySpAsync("sige_sam_v3.PDFContratoDetalle", new { contrato = contratoId, detalle = anexoId }); + var rows = await _catalogo.QuerySpAsync("sige_sam_v3.PDFContratoDetalle", new { contrato = contratoId, detalle = anexoId }); var row = rows.FirstOrDefault(); if (row == null) return []; @@ -411,7 +403,7 @@ public class ReportService public async Task GenerarPresupuestoPdfAsync(int presupuestoId) { - var rows = await QuerySpAsync("sige_sam_v3.BuscarCotizacionPDF", new { cotizacionid = presupuestoId }); + var rows = await _catalogo.QuerySpAsync("sige_sam_v3.BuscarCotizacionPDF", new { cotizacionid = presupuestoId }); var row = rows.FirstOrDefault(); if (row == null) return []; diff --git a/backend/src/Ventas.Services/UsuarioService.cs b/backend/src/Ventas.Services/UsuarioService.cs index 9a22f5d..70e220f 100644 --- a/backend/src/Ventas.Services/UsuarioService.cs +++ b/backend/src/Ventas.Services/UsuarioService.cs @@ -1,5 +1,3 @@ -using Dapper; -using Npgsql; using Ventas.Core.DTOs; using Ventas.Core.Interfaces; @@ -8,50 +6,15 @@ namespace Ventas.Services; public class UsuarioService { private readonly IUsuarioRepository _usuarioRepository; - private readonly string _connectionString; - public UsuarioService(IUsuarioRepository usuarioRepository, string connectionString) + public UsuarioService(IUsuarioRepository usuarioRepository) { _usuarioRepository = usuarioRepository; - _connectionString = connectionString; } - public async Task LoginAsync(LoginRequest request) - { - using var connection = new NpgsqlConnection(_connectionString); - var data = await connection.QueryAsync( - "sam.BuscarUsuario", - new { userid = request.Rut, passid = request.Clave }, - commandType: System.Data.CommandType.StoredProcedure); + public Task LoginAsync(LoginRequest request) + => _usuarioRepository.BuscarAsync(request.Rut, request.Clave); - var user = data.FirstOrDefault(); - if (user == null) return null; - - var dict = (IDictionary)user; - return new LoginResponse - { - Nombre = dict["Nombres"]?.ToString() ?? "", - Sede = dict["idSede"]?.ToString() - }; - } - - public async Task PerfilAsync(string usuarioId) - { - using var connection = new NpgsqlConnection(_connectionString); - var data = await connection.QueryAsync( - "sige_sam_v3.BuscarPerfilUsuario", - new { usuario = usuarioId }, - commandType: System.Data.CommandType.StoredProcedure); - - var user = data.FirstOrDefault(); - if (user == null) return null; - - var dict = (IDictionary)user; - return new LoginResponse - { - Nombre = dict["Nombres"]?.ToString() ?? "", - Sede = dict["idSede"]?.ToString(), - Perfil = dict["Perfil"]?.ToString() - }; - } + public Task PerfilAsync(string usuarioId) + => _usuarioRepository.PerfilAsync(usuarioId); } diff --git a/backend/src/Ventas.Services/Ventas.Services.csproj b/backend/src/Ventas.Services/Ventas.Services.csproj index 9fdf17a..1e6250c 100644 --- a/backend/src/Ventas.Services/Ventas.Services.csproj +++ b/backend/src/Ventas.Services/Ventas.Services.csproj @@ -5,6 +5,10 @@ + + + + net10.0 enable