feat: complete fase 1 - all controllers, services, middleware

- Added Ejecutivo.cs entity
- ArqueoService + ArqueoController (arqueos por fecha/usuario)
- 13 missing controllers: Curso, Descuento, Documento, Empresa, Horario,
  Jornada, Programa, Propuesta, Region, Sala, Sede, Tarifa, Usuario
- JwtMiddleware.cs for cookie/token validation
- SpComplexQueries.cs for Dapper multi-resultset
- ArqueoService registered in DI
- Build: 0 errors
- Total: 21 controllers, 8 services, 7 repos, 21 entities
This commit is contained in:
2026-07-08 10:26:20 -04:00
parent 1b1baaf6bf
commit c1e35445f6
20 changed files with 695 additions and 24 deletions
@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ventas.Services;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ArqueoController : ControllerBase
{
private readonly ArqueoService _arqueoService;
public ArqueoController(ArqueoService arqueoService)
{
_arqueoService = arqueoService;
}
[HttpGet("todos")]
public async Task<IActionResult> TodosHoy([FromQuery] DateTime fecha)
{
var result = await _arqueoService.TodosHoyAsync(fecha);
return Ok(result);
}
[HttpGet("usuario")]
public async Task<IActionResult> Hoy([FromQuery] string usuarioId, [FromQuery] DateTime fecha)
{
var result = await _arqueoService.HoyAsync(usuarioId, fecha);
return Ok(result);
}
}
@@ -0,0 +1,47 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class CursoController : ControllerBase
{
private readonly string _connectionString;
public CursoController(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("Default")!;
}
private async Task<IEnumerable<Dictionary<string, object>>> 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<string, object>)(IDictionary<string, object>)r!);
}
[HttpGet]
public async Task<IActionResult> Buscar([FromQuery] string tipoBusqueda, [FromQuery] string nombre)
=> Ok(await QuerySpAsync("sige_sam_v3.BuscarCurso", new { tipobusqueda = tipoBusqueda, cursonombre = nombre }));
[HttpGet("horario")]
public async Task<IActionResult> BuscarHorario([FromQuery] int sede, [FromQuery] int curso)
=> Ok(await QuerySpAsync("sam.WEB_Horarios_ecommerce", new { cursoid = curso, sedeid = sede }));
[HttpGet("fechas-disponibles")]
public async Task<IActionResult> FechaDisponibles([FromQuery] int curso, [FromQuery] int sede)
=> Ok(await QuerySpAsync("sige_sam_v3.EcommerceFechas", new { cursoid = curso, sedeid = sede }));
[HttpGet("apertura")]
public async Task<IActionResult> 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 }));
}
@@ -0,0 +1,49 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class DescuentoController : ControllerBase
{
private readonly string _connectionString;
public DescuentoController(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("Default")!;
}
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpGet("summer")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpPost]
public async Task<IActionResult> Ingresar([FromQuery] int cotizacionId, [FromQuery] int descuentoId, [FromQuery] int tipoDescuento, [FromQuery] int nuevoMonto)
{
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" });
}
}
@@ -0,0 +1,60 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class DocumentoController : ControllerBase
{
private readonly string _connectionString;
public DocumentoController(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("Default")!;
}
[HttpPost("orden-compra")]
public async Task<IActionResult> IngresaOC([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" });
}
[HttpPost("sence")]
public async Task<IActionResult> IngresaSNC([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" });
}
}
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;
}
@@ -0,0 +1,66 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class EmpresaController : ControllerBase
{
private readonly string _connectionString;
public EmpresaController(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("Default")!;
}
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpGet("tipos")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpPost]
public async Task<IActionResult> 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" });
}
}
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;
}
@@ -0,0 +1,26 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class HorarioController : ControllerBase
{
private readonly string _connectionString;
public HorarioController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet("bloques")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
}
@@ -0,0 +1,26 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class JornadaController : ControllerBase
{
private readonly string _connectionString;
public JornadaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
}
@@ -0,0 +1,26 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ProgramaController : ControllerBase
{
private readonly string _connectionString;
public ProgramaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
}
@@ -0,0 +1,51 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class PropuestaController : ControllerBase
{
private readonly string _connectionString;
public PropuestaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpPost]
public async Task<IActionResult> Ingresar([FromBody] PropuestaIngresoRequest request)
{
using var connection = new NpgsqlConnection(_connectionString);
var result = await connection.QuerySingleOrDefaultAsync<string>(
"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);
return Ok(new { id = result });
}
[HttpGet("datos")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)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;
}
@@ -0,0 +1,26 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class RegionController : ControllerBase
{
private readonly string _connectionString;
public RegionController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
}
@@ -0,0 +1,38 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class SalaController : ControllerBase
{
private readonly string _connectionString;
public SalaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpGet("ocupacion")]
public async Task<IActionResult> 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<string>(
"sige_sam_v3.BuscarSalaOcupada",
new { sede = sedeId, jornada = jornadaId, fecha = fechaInicio, sala = salaId, horario, diacorto = dia, varhora = hora },
commandType: System.Data.CommandType.StoredProcedure);
return Ok(new { ocupado = !string.IsNullOrEmpty(result), curso = result });
}
}
@@ -0,0 +1,26 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class SedeController : ControllerBase
{
private readonly string _connectionString;
public SedeController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
}
@@ -0,0 +1,36 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class TarifaController : ControllerBase
{
private readonly string _connectionString;
public TarifaController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpGet("promocion")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
}
@@ -0,0 +1,45 @@
using Dapper;
using Npgsql;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Ventas.API.Controllers;
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UsuarioController : ControllerBase
{
private readonly string _connectionString;
public UsuarioController(IConfiguration configuration) => _connectionString = configuration.GetConnectionString("Default")!;
[HttpGet("{id}")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpGet("{id}/perfil")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
[HttpGet("vendedores")]
public async Task<IActionResult> 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<string, object>)(IDictionary<string, object>)r!));
}
}
@@ -0,0 +1,45 @@
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);
}
}
+2
View File
@@ -42,6 +42,8 @@ builder.Services.AddScoped<CotizacionService>(sp =>
new CotizacionService(sp.GetRequiredService<ICotizacionRepository>(), connectionString));
builder.Services.AddScoped<AlumnoService>(sp =>
new AlumnoService(sp.GetRequiredService<IAlumnoRepository>(), connectionString));
builder.Services.AddScoped<ArqueoService>(sp =>
new ArqueoService(connectionString));
builder.Services.AddScoped<InformeService>();
builder.Services.AddScoped<ReportService>();
builder.Services.AddScoped<EmpresaReportService>(sp =>
@@ -0,0 +1,13 @@
namespace Ventas.Core.Entities;
public class Ejecutivo
{
public string Id { get; set; } = string.Empty;
public string Nombre { get; set; } = string.Empty;
public string? Paterno { get; set; }
public string? Materno { get; set; }
public string? Mail { get; set; }
public string? Fono1 { get; set; }
public string? Fono2 { get; set; }
public bool? Activo { get; set; }
}
@@ -0,0 +1,26 @@
using Dapper;
using Npgsql;
namespace Ventas.Infrastructure.Dapper;
public class SpComplexQueries
{
private readonly string _connectionString;
public SpComplexQueries(string connectionString)
{
_connectionString = connectionString;
}
public async Task<(IEnumerable<T1>, IEnumerable<T2>)> QueryMultipleAsync<T1, T2>(string sp, object parameters)
{
using var connection = new NpgsqlConnection(_connectionString);
using var multi = await connection.QueryMultipleAsync(sp, parameters,
commandType: System.Data.CommandType.StoredProcedure);
var result1 = await multi.ReadAsync<T1>();
var result2 = await multi.ReadAsync<T2>();
return (result1, result2);
}
}
@@ -0,0 +1,34 @@
using Dapper;
using Npgsql;
namespace Ventas.Services;
public class ArqueoService
{
private readonly string _connectionString;
public ArqueoService(string connectionString)
{
_connectionString = connectionString;
}
public async Task<IEnumerable<Dictionary<string, object>>> 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<string, object>)(IDictionary<string, object>)r!);
}
public async Task<IEnumerable<Dictionary<string, object>>> 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<string, object>)(IDictionary<string, object>)r!);
}
}