Compare commits
181 Commits
062cc05fd0
...
feat/cierr
| Author | SHA1 | Date | |
|---|---|---|---|
| 37c16686b7 | |||
| 24eaf18fd9 | |||
| 7e274ef114 | |||
| 5212e31a03 | |||
| 9201d7222b | |||
| fc27b4b43e | |||
| 35e8d803b9 | |||
| 8e1b8d2326 | |||
| bc19e184aa | |||
| 29109cff13 | |||
| 7f1fadfc84 | |||
| 74f07df960 | |||
| 6ceb1477ae | |||
| c049c1e544 | |||
| 8c7278ceae | |||
| e8215f8586 | |||
| bf7d7c22ef | |||
| 2c584e9383 | |||
| e123dae182 | |||
| c27dc2a0ba | |||
| 24b1c07342 | |||
| cb64bbc1f5 | |||
| 057310ca47 | |||
| e95c851e5b | |||
| 038faefd35 | |||
| da50c052f1 | |||
| 5781713b13 | |||
| 9f8d577265 | |||
| b594a48fde | |||
| 2e7d1e36be | |||
| dd2277fce2 | |||
| 9412556fa8 | |||
| 8c194b8441 | |||
| 1a288fcfa5 | |||
| 7dc0940001 | |||
| 5a806eda38 | |||
| 21c5c1d7d9 | |||
| 899e0a173f | |||
| 9cfe9d012e | |||
| 9e248efc84 | |||
| 84187a66df | |||
| b14c5de1b4 | |||
| d62ca7feb3 | |||
| f09c795fb0 | |||
| 19e7192a16 | |||
| 7e4d3282fb | |||
| 28c1b88a92 | |||
| 052141a45b | |||
| 9e8ccf6cfb | |||
| 9c225845c2 | |||
| f46dd82e27 | |||
| c251a0adf4 | |||
| 3e1ac6f742 | |||
| a35a3a66ea | |||
| c96d259892 | |||
| 95aa09d62a | |||
| dc52c9aff2 | |||
| d60ec7ffd7 | |||
| 03cda5cdbe | |||
| c6aec21e70 | |||
| a1a185c7b6 | |||
| 6921effab0 | |||
| cea51ee93c | |||
| ea225d650e | |||
| ff02cef2ca | |||
| 3c522a33af | |||
| b553affe7f | |||
| ab232c481d | |||
| 6a1d935a61 | |||
| 68376291da | |||
| 26856f26bf | |||
| 230332568f | |||
| 99d3db68d9 | |||
| b5a68d1825 | |||
| de54e5e200 | |||
| 673fd55037 | |||
| edb8a5e56c | |||
| fd11ef9005 | |||
| 229eb937f5 | |||
| a5bcbefa52 | |||
| 1373bcf9ca | |||
| 3a0f0a4bf8 | |||
| 16f991e04b | |||
| 26ffc7c0b2 | |||
| 35f62c3322 | |||
| a80a6f964f | |||
| b4b4f8b322 | |||
| 60a27621c1 | |||
| 221c41dc7d | |||
| 8561c84d71 | |||
| d30a0033f7 | |||
| bf275c1cf2 | |||
| 716707cd9f | |||
| f97e8ead15 | |||
| 703b8766b1 | |||
| 4b94377827 | |||
| 975a1e6d26 | |||
| 8591945eb4 | |||
| 5da5a0edea | |||
| 88c0762962 | |||
| f4601b7520 | |||
| dc1be0a073 | |||
| b957a3ef5b | |||
| 5df3f661e0 | |||
| b4b596efd9 | |||
| c07a4aa0f4 | |||
| f0f3c2b771 | |||
| 373449ba48 | |||
| 6d6ec22258 | |||
| 19ea4b23a0 | |||
| d514864986 | |||
| 29ba94e425 | |||
| c7d75ce76d | |||
| 6a2729e25b | |||
| 41282b61cd | |||
| bf91f9dc7c | |||
| 673fde163d | |||
| 88c9f22108 | |||
| 2f5a159650 | |||
| 08a7c27e08 | |||
| 4448f02df0 | |||
| 7e84c3f74c | |||
| 662da26ce8 | |||
| 0ef4e2d8f0 | |||
| 55ec8b5612 | |||
| bdcf8c60b7 | |||
| 481fce8115 | |||
| 1d9e23cc66 | |||
| 5d2c577c5e | |||
| 9e268e7fd4 | |||
| ee9e125b17 | |||
| 722c6ee4b2 | |||
| 0ea909db23 | |||
| 5af737fdfe | |||
| cd7b51b29a | |||
| adef45c466 | |||
| 6bafe0541d | |||
| a544fd7438 | |||
| 20d04b947b | |||
| 34e98b283f | |||
| a7c8944e78 | |||
| e84a6fb531 | |||
| e39c8a9491 | |||
| 8da73278db | |||
| ea2ee0c2fa | |||
| 4c5d920021 | |||
| 84332c947c | |||
| 7b73bb3acf | |||
| c36a742c00 | |||
| 27edd88f63 | |||
| 3c8a66c09b | |||
| 906f73640c | |||
| 5bb3d064e4 | |||
| 55765f9846 | |||
| 66c091eb79 | |||
| 47b8b47265 | |||
| 47bc88a248 | |||
| 6941de5276 | |||
| f841252783 | |||
| 2febe9967b | |||
| 3b21890797 | |||
| ccf1647a3d | |||
| 3ff5197637 | |||
| 0bc455450a | |||
| 56eb65dbdf | |||
| ca729bd875 | |||
| b4a219795a | |||
| 4b95de9ba2 | |||
| 8f488405ee | |||
| 373766a415 | |||
| 1526579b66 | |||
| 72f55b72d8 | |||
| 21f4facb31 | |||
| 0b8096e734 | |||
| 4e7ba4e5b2 | |||
| 97b0efa3dd | |||
| cec471b4b1 | |||
| b04a3b99bf | |||
| 437b1e8864 | |||
| 35e24ab7d2 | |||
| 8fb94f8cef |
71
.gitea/workflows/deploy.yml
Normal file
71
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
name: Optimized Build and Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
remote-build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Run Optimized CI/CD Process on Host via SSH
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Configura SSH (sin cambios)
|
||||||
|
apt-get update -qq && apt-get install -y openssh-client git
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.PROD_SERVER_SSH_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan -H ${{ secrets.PROD_SERVER_HOST }} >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
# Ejecuta en el host remoto
|
||||||
|
ssh ${{ secrets.PROD_SERVER_USER }}@${{ secrets.PROD_SERVER_HOST }} << 'EOSSH'
|
||||||
|
set -e
|
||||||
|
echo "--- INICIO DEL DESPLIEGUE OPTIMIZADO ---"
|
||||||
|
|
||||||
|
# 1. Preparar entorno
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
REPO_OWNER="dmolinari"
|
||||||
|
REPO_NAME="gestionintegralweb"
|
||||||
|
GITEA_REPO_PATH="/var/lib/docker/volumes/gitea-stack_gitea-data/_data/git/repositories/${REPO_OWNER}/${REPO_NAME}.git"
|
||||||
|
|
||||||
|
echo "Clonando repositorio desde: $GITEA_REPO_PATH ..."
|
||||||
|
git clone "$GITEA_REPO_PATH" "$TEMP_DIR"
|
||||||
|
cd "$TEMP_DIR"
|
||||||
|
git checkout "${{ gitea.sha }}"
|
||||||
|
|
||||||
|
# 2. Construcción paralela
|
||||||
|
build_image() {
|
||||||
|
local dockerfile=$1
|
||||||
|
local image_name=$2
|
||||||
|
local context=$3
|
||||||
|
|
||||||
|
echo "Construyendo $image_name..."
|
||||||
|
docker build \
|
||||||
|
-t "$image_name" \
|
||||||
|
-f "$dockerfile" \
|
||||||
|
"$context"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Construyendo imágenes en paralelo..."
|
||||||
|
(build_image "Backend/GestionIntegral.Api/Dockerfile" "dmolinari/gestionintegralweb-backend:latest" ".") &
|
||||||
|
(build_image "Frontend/Dockerfile" "dmolinari/gestionintegralweb-frontend:latest" ".") &
|
||||||
|
wait
|
||||||
|
|
||||||
|
# 3. Despliegue con Docker Compose
|
||||||
|
cd /opt/gestion-integral
|
||||||
|
export DB_SA_PASSWORD='${{ secrets.DB_SA_PASSWORD_SECRET }}'
|
||||||
|
|
||||||
|
echo "Recreando servicios de la aplicación..."
|
||||||
|
docker compose up -d --force-recreate
|
||||||
|
|
||||||
|
# 4. Limpieza
|
||||||
|
echo "Realizando limpieza..."
|
||||||
|
rm -rf "$TEMP_DIR"
|
||||||
|
docker image prune -f --filter "dangling=true"
|
||||||
|
|
||||||
|
echo "--- DESPLIEGUE COMPLETADO CON ÉXITO ---"
|
||||||
|
EOSSH
|
||||||
165
.gitignore
vendored
Normal file
165
.gitignore
vendored
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
# ===================================================================
|
||||||
|
# Archivo .gitignore para un repositorio con Backend ASP.NET y Frontend React/Vite
|
||||||
|
# ===================================================================
|
||||||
|
|
||||||
|
# Dependencias y paquetes locales
|
||||||
|
# -------------------------------
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
dist-ssr/
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Archivos de log
|
||||||
|
# -------------------------------
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Variables de entorno
|
||||||
|
# -------------------------------
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# Archivos de caché y reportes de herramientas
|
||||||
|
# ---------------------------------------------
|
||||||
|
.eslintcache
|
||||||
|
.stylelintcache
|
||||||
|
.npm/
|
||||||
|
.pnpm-store/
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# SECCIÓN PARA PROYECTOS ASP.NET CORE (Backend)
|
||||||
|
# ===================================================================
|
||||||
|
|
||||||
|
# Archivos y carpetas generados por Visual Studio y Rider
|
||||||
|
# -------------------------------------------------------
|
||||||
|
*.sln.DotSettings.user
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.vs/
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
vs.lock.json
|
||||||
|
*.csproj.user
|
||||||
|
*.vcxproj.filters
|
||||||
|
*.pubxml
|
||||||
|
*.pubxml.user
|
||||||
|
|
||||||
|
# Carpetas de compilación y publicación
|
||||||
|
# --------------------------------------
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
build/
|
||||||
|
bld/
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebug[Pp]ublic/
|
||||||
|
[Rr]elease[Pp]ublic/
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ss]uccess.txt
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
**/[Bb]in
|
||||||
|
**/[Oo]bj
|
||||||
|
**/[Dd]ebug
|
||||||
|
**/[Rr]elease
|
||||||
|
**/[Ll]ogs
|
||||||
|
**/[Pp]ackages
|
||||||
|
*.nupkg
|
||||||
|
*.snupkg
|
||||||
|
|
||||||
|
# Archivos de configuración locales de usuario y secrets
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# (appsettings.Development.json a veces se sube, pero si contiene secretos, no debería)
|
||||||
|
appsettings.Development.json
|
||||||
|
secrets.json
|
||||||
|
user-secrets.json
|
||||||
|
*.secrets.json
|
||||||
|
|
||||||
|
# Caché y logs de Resharper y Rider
|
||||||
|
# ----------------------------------
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Archivos de Test
|
||||||
|
# -----------------
|
||||||
|
TestResults/
|
||||||
|
*.trx
|
||||||
|
|
||||||
|
# Archivos de publicación de base de datos
|
||||||
|
# -----------------------------------------
|
||||||
|
*.dacpac
|
||||||
|
*.dbschema
|
||||||
|
*.dbmdl
|
||||||
|
|
||||||
|
# Otros
|
||||||
|
# -----
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_i.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.vsix
|
||||||
|
*.xaml.cs
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# SECCIÓN PARA PROYECTOS REACT/VITE (Frontend)
|
||||||
|
# ===================================================================
|
||||||
|
|
||||||
|
# Archivos de caché y logs específicos de Vite/React
|
||||||
|
# ---------------------------------------------------
|
||||||
|
.DS_Store
|
||||||
|
.cache/
|
||||||
|
.history/
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Editor-specific files
|
||||||
|
# ---------------------
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
|
*.orig
|
||||||
|
|
||||||
|
# Reportes
|
||||||
|
# --------
|
||||||
|
junit.xml
|
||||||
|
|
||||||
|
# Evitar subir imágenes/assets que deberían estar en el CDN en producción, si aplica.
|
||||||
|
# Si tus assets están en el repo, ignora esto.
|
||||||
|
# public/assets/production/
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fin del archivo .gitignore
|
||||||
|
# ===================================================================
|
||||||
|
Backend/SQL
|
||||||
|
.atl
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using GestionIntegral.Api.Dtos.Anomalia;
|
||||||
|
using GestionIntegral.Api.Services.Anomalia;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Anomalia
|
||||||
|
{
|
||||||
|
[Route("api/alertas")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class AlertasController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IAlertaService _alertaService;
|
||||||
|
|
||||||
|
public AlertasController(IAlertaService alertaService)
|
||||||
|
{
|
||||||
|
_alertaService = alertaService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/alertas
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<AlertaGenericaDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetAlertasNoLeidas()
|
||||||
|
{
|
||||||
|
var alertas = await _alertaService.ObtenerAlertasNoLeidasAsync();
|
||||||
|
return Ok(alertas);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/alertas/{idAlerta}/marcar-leida
|
||||||
|
[HttpPost("{idAlerta:int}/marcar-leida")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> MarcarComoLeida(int idAlerta)
|
||||||
|
{
|
||||||
|
var (exito, error) = await _alertaService.MarcarComoLeidaAsync(idAlerta);
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
return NotFound(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/alertas/marcar-grupo-leido
|
||||||
|
[HttpPost("marcar-grupo-leido")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<IActionResult> MarcarGrupoLeido([FromBody] MarcarGrupoLeidoRequestDto request)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
return BadRequest(ModelState);
|
||||||
|
}
|
||||||
|
var (exito, error) = await _alertaService.MarcarGrupoComoLeidoAsync(request.TipoAlerta, request.IdEntidad);
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DTO para el cuerpo del request de marcar grupo
|
||||||
|
public class MarcarGrupoLeidoRequestDto
|
||||||
|
{
|
||||||
|
[System.ComponentModel.DataAnnotations.Required]
|
||||||
|
public string TipoAlerta { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[System.ComponentModel.DataAnnotations.Required]
|
||||||
|
public int IdEntidad { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,738 @@
|
|||||||
|
using GestionIntegral.Api.Services.Usuarios;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Security.Claims; // Para ClaimTypes
|
||||||
|
using GestionIntegral.Api.Services.Contables; // Para IPagoDistribuidorService, etc.
|
||||||
|
using GestionIntegral.Api.Services.Distribucion;
|
||||||
|
using GestionIntegral.Api.Dtos.Auditoria;
|
||||||
|
using GestionIntegral.Api.Dtos.Zonas;
|
||||||
|
using GestionIntegral.Api.Dtos.Distribucion;
|
||||||
|
using GestionIntegral.Api.Services.Impresion;
|
||||||
|
using GestionIntegral.Api.Dtos.Impresion;
|
||||||
|
using GestionIntegral.Api.Dtos.Usuarios;
|
||||||
|
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/auditoria")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class AuditoriaController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IUsuarioService _usuarioService;
|
||||||
|
private readonly IPagoDistribuidorService _pagoDistribuidorService;
|
||||||
|
private readonly INotaCreditoDebitoService _notaCreditoDebitoService;
|
||||||
|
private readonly IEntradaSalidaDistService _esDistService;
|
||||||
|
private readonly IDistribuidorService _distribuidorService;
|
||||||
|
private readonly IEntradaSalidaCanillaService _esCanillaService;
|
||||||
|
private readonly INovedadCanillaService _novedadCanillaService;
|
||||||
|
private readonly ICanillaService _canillaService;
|
||||||
|
private readonly ISaldoService _saldoService;
|
||||||
|
private readonly ITipoPagoService _tipoPagoService;
|
||||||
|
private readonly IEmpresaService _empresaService;
|
||||||
|
private readonly IZonaService _zonaService;
|
||||||
|
private readonly IOtroDestinoService _otroDestinoService;
|
||||||
|
private readonly IPublicacionService _publicacionService;
|
||||||
|
private readonly IPubliSeccionService _publiSeccionService;
|
||||||
|
private readonly IPrecioService _precioService;
|
||||||
|
private readonly IRecargoZonaService _recargoZonaService;
|
||||||
|
private readonly IPorcPagoService _porcPagoService;
|
||||||
|
private readonly IPorcMonCanillaService _porcMonCanillaService;
|
||||||
|
private readonly IControlDevolucionesService _controlDevolucionesService;
|
||||||
|
private readonly ITipoBobinaService _tipoBobinaService;
|
||||||
|
private readonly IEstadoBobinaService _estadoBobinaService;
|
||||||
|
private readonly IPlantaService _plantaService;
|
||||||
|
private readonly IStockBobinaService _stockBobinaService;
|
||||||
|
private readonly ITiradaService _tiradaService;
|
||||||
|
private readonly IPerfilService _perfilService;
|
||||||
|
private readonly IPermisoService _permisoService;
|
||||||
|
private readonly ICambioParadaService _cambioParadaService;
|
||||||
|
private readonly ICierreCuentaCorrienteService _cierreCcService;
|
||||||
|
private readonly ILogger<AuditoriaController> _logger;
|
||||||
|
|
||||||
|
// Permiso general para ver cualquier auditoría.
|
||||||
|
// Podrías tener permisos más granulares por tipo de auditoría si es necesario.
|
||||||
|
private const string PermisoVerAuditoria = "AU_GENERAL_VIEW"; // Define este permiso
|
||||||
|
|
||||||
|
public AuditoriaController(
|
||||||
|
IUsuarioService usuarioService,
|
||||||
|
IPagoDistribuidorService pagoDistribuidorService,
|
||||||
|
INotaCreditoDebitoService notaCreditoDebitoService,
|
||||||
|
IEntradaSalidaDistService esDistService,
|
||||||
|
IDistribuidorService distribuidorService,
|
||||||
|
IEntradaSalidaCanillaService esCanillaService,
|
||||||
|
INovedadCanillaService novedadCanillaService,
|
||||||
|
ICanillaService canillaService,
|
||||||
|
ISaldoService saldoService,
|
||||||
|
ITipoPagoService tipoPagoService,
|
||||||
|
IEmpresaService empresaService,
|
||||||
|
IZonaService zonaService,
|
||||||
|
IOtroDestinoService otroDestinoService,
|
||||||
|
IPublicacionService publicacionService,
|
||||||
|
IPubliSeccionService publiSeccionService,
|
||||||
|
IPrecioService precioService,
|
||||||
|
IRecargoZonaService recargoZonaService,
|
||||||
|
IPorcPagoService porcPagoService,
|
||||||
|
IPorcMonCanillaService porcMonCanillaService,
|
||||||
|
IControlDevolucionesService controlDevolucionesService,
|
||||||
|
ITipoBobinaService tipoBobinaService,
|
||||||
|
IEstadoBobinaService estadoBobinaService,
|
||||||
|
IPlantaService plantaService,
|
||||||
|
IStockBobinaService stockBobinaService,
|
||||||
|
ITiradaService tiradaService,
|
||||||
|
IPerfilService perfilService,
|
||||||
|
IPermisoService permisoService,
|
||||||
|
ICambioParadaService cambioParadaService,
|
||||||
|
ICierreCuentaCorrienteService cierreCcService,
|
||||||
|
ILogger<AuditoriaController> logger)
|
||||||
|
{
|
||||||
|
_usuarioService = usuarioService;
|
||||||
|
_pagoDistribuidorService = pagoDistribuidorService;
|
||||||
|
_notaCreditoDebitoService = notaCreditoDebitoService;
|
||||||
|
_esDistService = esDistService;
|
||||||
|
_distribuidorService = distribuidorService;
|
||||||
|
_esCanillaService = esCanillaService;
|
||||||
|
_novedadCanillaService = novedadCanillaService;
|
||||||
|
_canillaService = canillaService;
|
||||||
|
_saldoService = saldoService;
|
||||||
|
_tipoPagoService = tipoPagoService;
|
||||||
|
_empresaService = empresaService;
|
||||||
|
_zonaService = zonaService;
|
||||||
|
_otroDestinoService = otroDestinoService;
|
||||||
|
_publicacionService = publicacionService;
|
||||||
|
_publiSeccionService = publiSeccionService;
|
||||||
|
_precioService = precioService;
|
||||||
|
_recargoZonaService = recargoZonaService;
|
||||||
|
_porcPagoService = porcPagoService;
|
||||||
|
_porcMonCanillaService = porcMonCanillaService;
|
||||||
|
_controlDevolucionesService = controlDevolucionesService;
|
||||||
|
_tipoBobinaService = tipoBobinaService;
|
||||||
|
_estadoBobinaService = estadoBobinaService;
|
||||||
|
_plantaService = plantaService;
|
||||||
|
_stockBobinaService = stockBobinaService;
|
||||||
|
_tiradaService = tiradaService;
|
||||||
|
_perfilService = perfilService;
|
||||||
|
_cambioParadaService = cambioParadaService;
|
||||||
|
_permisoService = permisoService;
|
||||||
|
_cierreCcService = cierreCcService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
private int? GetCurrentUserId() // Podría no ser necesario aquí si solo filtramos por usuario modificador
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("pagos-distribuidores")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PagoDistribuidorHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPagosDistribuidor(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPagoAfectado) // Parámetro para filtrar por un ID de pago específico
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid(); // O un permiso más específico si lo creas
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _pagoDistribuidorService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPagoAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PagoDistribuidorHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de pagos de distribuidores.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de pagos.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("notas-credito-debito")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<NotaCreditoDebitoHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialNotasCD(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idNotaAfectada) // ID de la nota original
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _notaCreditoDebitoService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idNotaAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<NotaCreditoDebitoHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de notas C/D.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de notas C/D.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("entradas-salidas-dist")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EntradaSalidaDistHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialEntradasSalidasDist(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idParteAfectada) // ID del movimiento original
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _esDistService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idParteAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<EntradaSalidaDistHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de E/S Distribuidores.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de E/S Distribuidores.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("entradas-salidas-canilla")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EntradaSalidaCanillaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialEntradasSalidasCanilla(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idParteAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _esCanillaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idParteAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<EntradaSalidaCanillaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de E/S Canillitas.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de E/S Canillitas.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("novedades-canilla")] // Endpoint consistente con el servicio frontend
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<NovedadCanillaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialNovedadesCanilla(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idNovedadAfectada) // ID de la novedad original
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _novedadCanillaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idNovedadAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<NovedadCanillaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Novedades de Canillitas.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Novedades de Canillitas.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("ajustes-saldo")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<SaldoAjusteHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialAjustesSaldo(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico,
|
||||||
|
[FromQuery] string? destino, [FromQuery] int? idDestino, [FromQuery] int? idEmpresa)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid(); // O un permiso más específico si lo creas
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _saldoService.ObtenerHistorialAjustesAsync(fechaDesde, fechaHasta, idUsuarioModifico, destino, idDestino, idEmpresa);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<SaldoAjusteHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de ajustes de saldo.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de ajustes de saldo.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("tipos-pago")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<TipoPagoHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialTiposPago(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idTipoPagoAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Asumiendo que _tipoPagoService está inyectado
|
||||||
|
var historial = await _tipoPagoService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idTipoPagoAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<TipoPagoHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Tipos de Pago.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Tipos de Pago.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("canillitas-maestro")] // Endpoint para el historial del maestro de canillitas
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<CanillaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialCanillitasMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idCanillaAfectado) // ID del canillita original
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _canillaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idCanillaAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<CanillaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Canillitas (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Canillitas (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("distribuidores-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<DistribuidorHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialDistribuidoresMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idDistribuidorAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _distribuidorService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idDistribuidorAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<DistribuidorHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Distribuidores (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Distribuidores (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("empresas-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EmpresaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialEmpresasMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idEmpresaAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Asumiendo que _empresaService está inyectado
|
||||||
|
var historial = await _empresaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idEmpresaAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<EmpresaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Empresas (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Empresas (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("zonas-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<ZonaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialZonasMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idZonaAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Asumiendo que _zonaService está inyectado
|
||||||
|
var historial = await _zonaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idZonaAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<ZonaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Zonas (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Zonas (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("otros-destinos-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<OtroDestinoHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialOtrosDestinosMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idOtroDestinoAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _otroDestinoService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idOtroDestinoAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<OtroDestinoHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Otros Destinos (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Otros Destinos (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("publicaciones-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PublicacionHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPublicacionesMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPublicacionAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _publicacionService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPublicacionAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PublicacionHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Publicaciones (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Publicaciones (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("publi-secciones-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PubliSeccionHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPubliSeccionesMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idSeccionAfectada, [FromQuery] int? idPublicacionAfectada) // Nuevos filtros
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _publiSeccionService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idSeccionAfectada, idPublicacionAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PubliSeccionHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Secciones de Publicación.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Secciones de Publicación.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("precios-publicacion-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PrecioHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPreciosMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPrecioAfectado, [FromQuery] int? idPublicacionAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _precioService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPrecioAfectado, idPublicacionAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PrecioHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Precios de Publicación.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Precios de Publicación.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("recargos-zona-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<RecargoZonaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialRecargosZonaMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idRecargoAfectado, [FromQuery] int? idPublicacionAfectada, [FromQuery] int? idZonaAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _recargoZonaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idRecargoAfectado, idPublicacionAfectada, idZonaAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<RecargoZonaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Recargos por Zona.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Recargos por Zona.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("porc-pago-dist-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PorcPagoHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPorcPagoDistMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPorcentajeAfectado, [FromQuery] int? idPublicacionAfectada, [FromQuery] int? idDistribuidorAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _porcPagoService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPorcentajeAfectado, idPublicacionAfectada, idDistribuidorAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PorcPagoHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Porcentajes de Pago (Dist).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Porcentajes de Pago (Dist).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("porc-mon-canilla-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PorcMonCanillaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPorcMonCanillaMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPorcMonAfectado, [FromQuery] int? idPublicacionAfectada, [FromQuery] int? idCanillaAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _porcMonCanillaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPorcMonAfectado, idPublicacionAfectada, idCanillaAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PorcMonCanillaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Porc/Mon Canillita.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Porc/Mon Canillita.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("control-devoluciones-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<ControlDevolucionesHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialControlDevolucionesMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idControlAfectado, [FromQuery] int? idEmpresaAfectada, [FromQuery] DateTime? fechaAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _controlDevolucionesService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idControlAfectado, idEmpresaAfectada, fechaAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<ControlDevolucionesHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Control de Devoluciones.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Control de Devoluciones.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("tipos-bobina-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<TipoBobinaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialTiposBobinaMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idTipoBobinaAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _tipoBobinaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idTipoBobinaAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<TipoBobinaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Tipos de Bobina.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Tipos de Bobina.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("estados-bobina-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EstadoBobinaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialEstadosBobinaMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idEstadoBobinaAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _estadoBobinaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idEstadoBobinaAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<EstadoBobinaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Estados de Bobina.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Estados de Bobina.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("plantas-impresion-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PlantaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPlantasMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPlantaAfectada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _plantaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPlantaAfectada);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PlantaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Plantas de Impresión.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Plantas de Impresión.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("stock-bobinas-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<StockBobinaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialStockBobinasMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idBobinaAfectada, [FromQuery] int? idTipoBobinaFiltro,
|
||||||
|
[FromQuery] int? idPlantaFiltro, [FromQuery] int? idEstadoBobinaFiltro)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _stockBobinaService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idBobinaAfectada, idTipoBobinaFiltro, idPlantaFiltro, idEstadoBobinaFiltro);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<StockBobinaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Stock de Bobinas.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Stock de Bobinas.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("reg-tiradas-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<RegTiradaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialRegTiradasMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idRegistroAfectado, [FromQuery] int? idPublicacionFiltro,
|
||||||
|
[FromQuery] int? idPlantaFiltro, [FromQuery] DateTime? fechaTiradaFiltro)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _tiradaService.ObtenerRegTiradasHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idRegistroAfectado, idPublicacionFiltro, idPlantaFiltro, fechaTiradaFiltro);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<RegTiradaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Registro de Tiradas.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Registro de Tiradas.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("reg-secciones-tirada-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<RegSeccionTiradaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialRegSeccionesTiradaMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idTiradaAfectada, [FromQuery] int? idPublicacionFiltro,
|
||||||
|
[FromQuery] int? idSeccionFiltro, [FromQuery] int? idPlantaFiltro, [FromQuery] DateTime? fechaTiradaFiltro)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _tiradaService.ObtenerRegSeccionesTiradaHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idTiradaAfectada, idPublicacionFiltro, idSeccionFiltro, idPlantaFiltro, fechaTiradaFiltro);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<RegSeccionTiradaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Secciones de Tirada.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Secciones de Tirada.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("perfiles-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PerfilHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPerfilesMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPerfilAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _perfilService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPerfilAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PerfilHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Perfiles (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Perfiles (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("permisos-maestro")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PermisoHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPermisosMaestro(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPermisoAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _permisoService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPermisoAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PermisoHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Permisos (Maestro).");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Permisos (Maestro).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("permisos-perfiles-historial")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PermisosPerfilesHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialPermisosPerfiles(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idPerfilAfectado, [FromQuery] int? idPermisoAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _perfilService.ObtenerPermisosAsignadosHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idPerfilAfectado, idPermisoAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<PermisosPerfilesHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Asignación de Permisos.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Asignación de Permisos.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("cierres-cuenta-corriente")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<CierreCuentaCorrienteHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialCierresCuentaCorriente(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idCierreAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _cierreCcService.ObtenerHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idCierreAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<CierreCuentaCorrienteHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Cierres de Cuenta Corriente.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Cierres de Cuenta Corriente.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("cambios-parada-canilla")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<CambioParadaHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialCambiosParada(
|
||||||
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] int? idUsuarioModifico, [FromQuery] string? tipoModificacion,
|
||||||
|
[FromQuery] int? idCanillaAfectado)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerAuditoria)) return Forbid();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var historial = await _cambioParadaService.ObtenerCambiosParadaHistorialAsync(fechaDesde, fechaHasta, idUsuarioModifico, tipoModificacion, idCanillaAfectado);
|
||||||
|
return Ok(historial ?? Enumerable.Empty<CambioParadaHistorialDto>());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error obteniendo historial de Cambios de Parada.");
|
||||||
|
return StatusCode(500, "Error interno al obtener historial de Cambios de Parada.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Comunicaciones;
|
||||||
|
using GestionIntegral.Api.Services.Comunicaciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Comunicaciones
|
||||||
|
{
|
||||||
|
[Route("api/lotes-envio")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class LotesEnvioController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IEmailLogService _emailLogService;
|
||||||
|
|
||||||
|
public LotesEnvioController(IEmailLogService emailLogService)
|
||||||
|
{
|
||||||
|
_emailLogService = emailLogService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/lotes-envio/123/detalles
|
||||||
|
[HttpGet("{idLote:int}/detalles")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EmailLogDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> GetDetallesLote(int idLote)
|
||||||
|
{
|
||||||
|
// Reutilizamos un permiso existente, ya que esta es una función de auditoría relacionada.
|
||||||
|
var tienePermiso = User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == "SU006");
|
||||||
|
if (!tienePermiso)
|
||||||
|
{
|
||||||
|
return Forbid();
|
||||||
|
}
|
||||||
|
|
||||||
|
var detalles = await _emailLogService.ObtenerDetallesPorLoteId(idLote);
|
||||||
|
|
||||||
|
// Devolvemos OK con un array vacío si no hay resultados, el frontend lo manejará.
|
||||||
|
return Ok(detalles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Auditoria;
|
||||||
|
using GestionIntegral.Api.Dtos.Contables;
|
||||||
|
using GestionIntegral.Api.Services.Contables;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Contables
|
||||||
|
{
|
||||||
|
[Route("api/cierres-cc")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class CierresCuentaCorrienteController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ICierreCuentaCorrienteService _cierreService;
|
||||||
|
private readonly ILogger<CierresCuentaCorrienteController> _logger;
|
||||||
|
|
||||||
|
// Permisos asignables a perfiles. La reapertura es exclusiva de SuperAdmin
|
||||||
|
// y se valida con User.IsInRole('SuperAdmin') — no tiene código en gral_Permisos.
|
||||||
|
private const string PermisoCrear = "CC001";
|
||||||
|
private const string PermisoVer = "CC003";
|
||||||
|
|
||||||
|
public CierresCuentaCorrienteController(
|
||||||
|
ICierreCuentaCorrienteService cierreService,
|
||||||
|
ILogger<CierresCuentaCorrienteController> logger)
|
||||||
|
{
|
||||||
|
_cierreService = cierreService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) =>
|
||||||
|
User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
|
||||||
|
private bool EsSuperAdmin() => User.IsInRole("SuperAdmin");
|
||||||
|
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId))
|
||||||
|
return userId;
|
||||||
|
_logger.LogWarning("No se pudo obtener el UserId del token JWT en CierresCuentaCorrienteController.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/cierres-cc
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(CierreCuentaCorrienteDto), StatusCodes.Status201Created)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status409Conflict)]
|
||||||
|
public async Task<IActionResult> Crear([FromBody] CrearCierreDto dto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoCrear)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (cierre, errorCode, errorMessage) = await _cierreService.CrearCierreAsync(dto, userId.Value);
|
||||||
|
|
||||||
|
if (errorCode != null)
|
||||||
|
{
|
||||||
|
int status = errorCode switch
|
||||||
|
{
|
||||||
|
"CIERRE_FECHA_ANTERIOR_A_ULTIMO" => StatusCodes.Status409Conflict,
|
||||||
|
"CIERRE_ERROR_INTERNO" => StatusCodes.Status500InternalServerError,
|
||||||
|
_ => StatusCodes.Status400BadRequest
|
||||||
|
};
|
||||||
|
return StatusCode(status, new { codigo = errorCode, mensaje = errorMessage });
|
||||||
|
}
|
||||||
|
|
||||||
|
return StatusCode(StatusCodes.Status201Created, cierre);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/cierres-cc/{idCierre}/reabrir
|
||||||
|
[HttpPost("{idCierre:int}/reabrir")]
|
||||||
|
[ProducesResponseType(typeof(CierreCuentaCorrienteDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status409Conflict)]
|
||||||
|
public async Task<IActionResult> Reabrir(int idCierre, [FromBody] ReabrirCierreDto dto)
|
||||||
|
{
|
||||||
|
if (!EsSuperAdmin())
|
||||||
|
return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (cierre, errorCode, errorMessage) = await _cierreService.ReabrirCierreAsync(idCierre, dto, userId.Value, esSuperAdmin: true);
|
||||||
|
|
||||||
|
if (errorCode != null)
|
||||||
|
{
|
||||||
|
int status = errorCode switch
|
||||||
|
{
|
||||||
|
"CIERRE_NO_ENCONTRADO" => StatusCodes.Status404NotFound,
|
||||||
|
"CIERRE_PERMISO_DENEGADO" => StatusCodes.Status403Forbidden,
|
||||||
|
"CIERRE_HAY_POSTERIORES_VIGENTES" => StatusCodes.Status409Conflict,
|
||||||
|
"CIERRE_YA_ANULADO" => StatusCodes.Status409Conflict,
|
||||||
|
"CIERRE_ERROR_INTERNO" => StatusCodes.Status500InternalServerError,
|
||||||
|
_ => StatusCodes.Status400BadRequest
|
||||||
|
};
|
||||||
|
return StatusCode(status, new { codigo = errorCode, mensaje = errorMessage });
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(cierre);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/cierres-cc?idDistribuidor=&idEmpresa=&estado=&fechaCorteDesde=&fechaCorteHasta=
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<CierreCuentaCorrienteDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetAll(
|
||||||
|
[FromQuery] int? idDistribuidor,
|
||||||
|
[FromQuery] int? idEmpresa,
|
||||||
|
[FromQuery] string? estado,
|
||||||
|
[FromQuery] DateTime? fechaCorteDesde,
|
||||||
|
[FromQuery] DateTime? fechaCorteHasta)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
|
var cierres = await _cierreService.GetAllAsync(idDistribuidor, idEmpresa, estado, fechaCorteDesde, fechaCorteHasta);
|
||||||
|
return Ok(cierres);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/cierres-cc/{idCierre}
|
||||||
|
[HttpGet("{idCierre:int}")]
|
||||||
|
[ProducesResponseType(typeof(CierreCuentaCorrienteDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> GetById(int idCierre)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
|
var cierre = await _cierreService.GetByIdAsync(idCierre);
|
||||||
|
if (cierre == null) return NotFound(new { message = $"Cierre #{idCierre} no encontrado." });
|
||||||
|
return Ok(cierre);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/cierres-cc/ultimo?idDistribuidor=&idEmpresa=
|
||||||
|
// Atajo del frontend para autorrellenar "Desde último cierre" en filtros del reporte.
|
||||||
|
// Acepta CC003 (gestión de cierres) o RR001 (acceso al reporte que CONTIENE este atajo):
|
||||||
|
// operadores con solo el permiso del reporte deben poder usar el atajo desde la pantalla del reporte.
|
||||||
|
[HttpGet("ultimo")]
|
||||||
|
[ProducesResponseType(typeof(UltimoCierreDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> GetUltimoVigente(
|
||||||
|
[FromQuery] int idDistribuidor,
|
||||||
|
[FromQuery] int idEmpresa)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVer) && !TienePermiso("RR001")) return Forbid();
|
||||||
|
var ultimo = await _cierreService.GetUltimoVigenteAsync(idDistribuidor, idEmpresa);
|
||||||
|
if (ultimo == null) return NotFound(new { message = "No hay cierres vigentes para el distribuidor en la empresa indicada." });
|
||||||
|
return Ok(ultimo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/cierres-cc/{idCierre}/historial
|
||||||
|
[HttpGet("{idCierre:int}/historial")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<CierreCuentaCorrienteHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetHistorial(int idCierre)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
|
var historial = await _cierreService.GetHistorialAsync(idCierre);
|
||||||
|
return Ok(historial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Contables;
|
||||||
|
using GestionIntegral.Api.Services.Contables;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Contables
|
||||||
|
{
|
||||||
|
[Route("api/saldos")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize] // Requiere autenticación para todos los endpoints
|
||||||
|
public class SaldosController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ISaldoService _saldoService;
|
||||||
|
private readonly ILogger<SaldosController> _logger;
|
||||||
|
|
||||||
|
// Permiso para ver saldos. El ajuste manual es exclusivo de SuperAdmin (no se valida un permiso asignable).
|
||||||
|
private const string PermisoVerSaldos = "CS001";
|
||||||
|
|
||||||
|
|
||||||
|
public SaldosController(ISaldoService saldoService, ILogger<SaldosController> logger)
|
||||||
|
{
|
||||||
|
_saldoService = saldoService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAccRequerido)
|
||||||
|
{
|
||||||
|
if (User.IsInRole("SuperAdmin")) return true;
|
||||||
|
return User.HasClaim(c => c.Type == "permission" && c.Value == codAccRequerido);
|
||||||
|
}
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
_logger.LogWarning("No se pudo obtener el UserId del token JWT en SaldosController.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/saldos
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<SaldoGestionDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetSaldosGestion(
|
||||||
|
[FromQuery] string? destino,
|
||||||
|
[FromQuery] int? idDestino,
|
||||||
|
[FromQuery] int? idEmpresa)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVerSaldos)) // Usar el nuevo permiso
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Acceso denegado a GetSaldosGestion para Usuario ID {userId}", GetCurrentUserId() ?? 0);
|
||||||
|
return Forbid();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var saldos = await _saldoService.ObtenerSaldosParaGestionAsync(destino, idDestino, idEmpresa);
|
||||||
|
return Ok(saldos);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener saldos para gestión.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener saldos.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/saldos/ajustar
|
||||||
|
[HttpPost("ajustar")]
|
||||||
|
[ProducesResponseType(typeof(SaldoGestionDto), StatusCodes.Status200OK)] // Devuelve el saldo actualizado
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)] // Solo SuperAdmin o con permiso específico
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> AjustarSaldoManualmente([FromBody] AjusteSaldoRequestDto ajusteDto)
|
||||||
|
{
|
||||||
|
// El ajuste manual de saldo es operación crítica: solo SuperAdmin. No se admite vía permiso asignable.
|
||||||
|
if (!User.IsInRole("SuperAdmin"))
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Intento no autorizado de ajustar saldo por Usuario ID {userId}", GetCurrentUserId() ?? 0);
|
||||||
|
return Forbid("Solo SuperAdmin puede ajustar saldos manualmente.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var idUsuario = GetCurrentUserId();
|
||||||
|
if (idUsuario == null) return Unauthorized("No se pudo identificar al usuario.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var (exito, error, saldoActualizado) = await _saldoService.RealizarAjusteManualSaldoAsync(ajusteDto, idUsuario.Value);
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("No se encontró un saldo existente"))
|
||||||
|
return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error ?? "Error desconocido al ajustar el saldo." });
|
||||||
|
}
|
||||||
|
return Ok(saldoActualizado);
|
||||||
|
}
|
||||||
|
catch (BloqueoPorPeriodoCerradoException)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error crítico al ajustar saldo manualmente.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al procesar el ajuste de saldo.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Distribucion;
|
||||||
|
using GestionIntegral.Api.Services.Distribucion;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Distribucion
|
||||||
|
{
|
||||||
|
[Route("api/canillas/{idCanilla}/paradas")] // Anidado bajo canillas
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class CambiosParadaController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ICambioParadaService _paradaService;
|
||||||
|
private readonly ILogger<CambiosParadaController> _logger;
|
||||||
|
private const string PermisoGestionarParadas = "CG007";
|
||||||
|
|
||||||
|
public CambiosParadaController(ICambioParadaService paradaService, ILogger<CambiosParadaController> logger)
|
||||||
|
{
|
||||||
|
_paradaService = paradaService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
_logger.LogWarning("No se pudo obtener el UserId del token JWT en CambiosParadaController.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/canillas/{idCanilla}/paradas
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<CambioParadaDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetParadasPorCanilla(int idCanilla)
|
||||||
|
{
|
||||||
|
// Podría usarse CG001 (Ver Canilla) o CG007 para ver el historial de paradas
|
||||||
|
if (!TienePermiso("CG001") && !TienePermiso(PermisoGestionarParadas)) return Forbid();
|
||||||
|
|
||||||
|
var paradas = await _paradaService.ObtenerPorCanillaAsync(idCanilla);
|
||||||
|
return Ok(paradas);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/canillas/{idCanilla}/paradas
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(CambioParadaDto), StatusCodes.Status201Created)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> CreateParada(int idCanilla, [FromBody] CreateCambioParadaDto createDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarParadas)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (paradaDto, error) = await _paradaService.CrearNuevaParadaAsync(idCanilla, createDto, userId.Value);
|
||||||
|
if (error != null) return BadRequest(new { message = error });
|
||||||
|
if (paradaDto == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear la parada.");
|
||||||
|
|
||||||
|
// La ruta para "GetById" podría estar en otro controlador si decides separar los endpoints de "paradas individuales"
|
||||||
|
// Por ahora, asumimos que habrá un endpoint para obtener una parada por su ID de registro.
|
||||||
|
return CreatedAtAction(nameof(GetParadaById), new { idCanilla = idCanilla, idRegistroParada = paradaDto.IdRegistro }, paradaDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/canillas/{idCanilla}/paradas/{idRegistroParada} (o api/paradas/{idRegistroParada})
|
||||||
|
// Este endpoint es opcional, pero útil si necesitas obtener una parada específica por su ID de registro
|
||||||
|
[HttpGet("{idRegistroParada:int}", Name = "GetParadaById")]
|
||||||
|
[ProducesResponseType(typeof(CambioParadaDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> GetParadaById(int idCanilla, int idRegistroParada) // idCanilla es parte de la ruta base
|
||||||
|
{
|
||||||
|
if (!TienePermiso("CG001") && !TienePermiso(PermisoGestionarParadas)) return Forbid();
|
||||||
|
var parada = await _paradaService.ObtenerPorIdAsync(idRegistroParada);
|
||||||
|
if (parada == null || parada.IdCanilla != idCanilla) return NotFound(new { message = "Registro de parada no encontrado para este canillita."});
|
||||||
|
return Ok(parada);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// PUT: api/paradas/{idRegistroParada}/cerrar (Ruta ejemplo para cerrar una parada)
|
||||||
|
// O podrías usar PUT api/canillas/{idCanilla}/paradas/{idRegistroParada} y que el DTO solo tenga VigenciaH
|
||||||
|
[HttpPut("~/api/paradas/{idRegistroParada}/cerrar")] // Ruta a nivel raíz para paradas si se edita por IdRegistro
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> CerrarVigenciaParada(int idRegistroParada, [FromBody] UpdateCambioParadaDto updateDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarParadas)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _paradaService.CerrarParadaAsync(idRegistroParada, updateDto, userId.Value);
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/paradas/{idRegistroParada}
|
||||||
|
[HttpDelete("~/api/paradas/{idRegistroParada}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> DeleteParada(int idRegistroParada)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarParadas)) return Forbid();
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _paradaService.EliminarParadaAsync(idRegistroParada, userId.Value);
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,13 +47,22 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IEnumerable<CanillaDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<CanillaDto>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
public async Task<IActionResult> GetAllCanillas([FromQuery] string? nomApe, [FromQuery] int? legajo, [FromQuery] bool? soloActivos = true)
|
public async Task<IActionResult> GetAllCanillas([FromQuery] string? nomApe, [FromQuery] int? legajo, [FromQuery] bool? esAccionista, [FromQuery] bool? soloActivos = true)
|
||||||
{
|
{
|
||||||
if (!TienePermiso(PermisoVer)) return Forbid();
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
var canillas = await _canillaService.ObtenerTodosAsync(nomApe, legajo, soloActivos);
|
var canillitas = await _canillaService.ObtenerTodosAsync(nomApe, legajo, soloActivos, esAccionista);
|
||||||
return Ok(canillas);
|
return Ok(canillitas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<CanillaDropdownDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetAllDropdownCanillas([FromQuery] bool? esAccionista, [FromQuery] bool? soloActivos = true)
|
||||||
|
{
|
||||||
|
var canillitas = await _canillaService.ObtenerTodosDropdownAsync(esAccionista, soloActivos);
|
||||||
|
return Ok(canillitas);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// GET: api/canillas/{id}
|
// GET: api/canillas/{id}
|
||||||
[HttpGet("{id:int}", Name = "GetCanillaById")]
|
[HttpGet("{id:int}", Name = "GetCanillaById")]
|
||||||
[ProducesResponseType(typeof(CanillaDto), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(CanillaDto), StatusCodes.Status200OK)]
|
||||||
|
|||||||
@@ -40,10 +40,19 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IEnumerable<DistribuidorDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<DistribuidorDto>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
public async Task<IActionResult> GetAllDistribuidores([FromQuery] string? nombre, [FromQuery] string? nroDoc)
|
public async Task<IActionResult> GetAllDistribuidores([FromQuery] string? nombre, [FromQuery] string? nroDoc, [FromQuery] bool? soloActivos = true)
|
||||||
{
|
{
|
||||||
if (!TienePermiso(PermisoVer)) return Forbid();
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
var distribuidores = await _distribuidorService.ObtenerTodosAsync(nombre, nroDoc);
|
var distribuidores = await _distribuidorService.ObtenerTodosAsync(nombre, nroDoc, soloActivos);
|
||||||
|
return Ok(distribuidores);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<DistribuidorDropdownDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetAllDropdownDistribuidores([FromQuery] bool? soloActivos = true)
|
||||||
|
{
|
||||||
|
var distribuidores = await _distribuidorService.GetAllDropdownAsync(soloActivos);
|
||||||
return Ok(distribuidores);
|
return Ok(distribuidores);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +68,17 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
return Ok(distribuidor);
|
return Ok(distribuidor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}/lookup", Name = "GetDistribuidorLookupById")]
|
||||||
|
[ProducesResponseType(typeof(DistribuidorLookupDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ObtenerLookupPorIdAsync(int id)
|
||||||
|
{
|
||||||
|
var distribuidor = await _distribuidorService.ObtenerLookupPorIdAsync(id);
|
||||||
|
if (distribuidor == null) return NotFound();
|
||||||
|
return Ok(distribuidor);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(typeof(DistribuidorDto), StatusCodes.Status201Created)]
|
[ProducesResponseType(typeof(DistribuidorDto), StatusCodes.Status201Created)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
@@ -97,6 +117,27 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPut("{id:int}/toggle-baja")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ToggleBajaDistribuidor(int id, [FromBody] ToggleBajaDistribuidorDto dto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoModificar)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _distribuidorService.ToggleBajaAsync(id, dto.DarDeBaja, dto.FechaBaja, userId.Value);
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error == "Distribuidor no encontrado.") return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
[HttpDelete("{id:int}")]
|
[HttpDelete("{id:int}")]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
|||||||
@@ -74,6 +74,25 @@ namespace GestionIntegral.Api.Controllers // Ajusta el namespace si es necesario
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/empresas/dropdown
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EmpresaDropdownDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> GetEmpresasDropdown()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var empresas = await _empresaService.ObtenerParaDropdown();
|
||||||
|
return Ok(empresas);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener todas las Empresas.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener las empresas.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GET: api/empresas/{id}
|
// GET: api/empresas/{id}
|
||||||
// Permiso Requerido: DE001 (Ver Empresas)
|
// Permiso Requerido: DE001 (Ver Empresas)
|
||||||
[HttpGet("{id:int}", Name = "GetEmpresaById")]
|
[HttpGet("{id:int}", Name = "GetEmpresaById")]
|
||||||
@@ -101,6 +120,29 @@ namespace GestionIntegral.Api.Controllers // Ajusta el namespace si es necesario
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id:int}/lookup", Name = "GetEmpresaLookupById")]
|
||||||
|
[ProducesResponseType(typeof(EmpresaDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> ObtenerLookupPorIdAsync(int id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var empresa = await _empresaService.ObtenerLookupPorIdAsync(id);
|
||||||
|
if (empresa == null)
|
||||||
|
{
|
||||||
|
return NotFound(new { message = $"Empresa con ID {id} no encontrada." });
|
||||||
|
}
|
||||||
|
return Ok(empresa);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener Empresa por ID: {Id}", id);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener la empresa.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// POST: api/empresas
|
// POST: api/empresas
|
||||||
// Permiso Requerido: DE002 (Agregar Empresas)
|
// Permiso Requerido: DE002 (Agregar Empresas)
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
|||||||
@@ -0,0 +1,212 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Distribucion;
|
||||||
|
using GestionIntegral.Api.Services.Distribucion;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Distribucion
|
||||||
|
{
|
||||||
|
[Route("api/novedadescanilla")] // Ruta base más genérica para las novedades
|
||||||
|
[ApiController]
|
||||||
|
[Authorize] // Todas las acciones requieren autenticación
|
||||||
|
public class NovedadesCanillaController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly INovedadCanillaService _novedadService;
|
||||||
|
private readonly ILogger<NovedadesCanillaController> _logger;
|
||||||
|
|
||||||
|
public NovedadesCanillaController(INovedadCanillaService novedadService, ILogger<NovedadesCanillaController> logger)
|
||||||
|
{
|
||||||
|
_novedadService = novedadService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Helper para verificar permisos ---
|
||||||
|
private bool TienePermiso(string codAccRequerido)
|
||||||
|
{
|
||||||
|
if (User.IsInRole("SuperAdmin")) return true;
|
||||||
|
return User.HasClaim(c => c.Type == "permission" && c.Value == codAccRequerido);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Helper para obtener User ID ---
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
var userIdClaim = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub");
|
||||||
|
if (int.TryParse(userIdClaim, out int userId))
|
||||||
|
{
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
_logger.LogWarning("No se pudo obtener el UserId del token JWT en NovedadesCanillaController.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/novedadescanilla/porcanilla/{idCanilla}
|
||||||
|
// Obtiene todas las novedades para un canillita específico, opcionalmente filtrado por fecha.
|
||||||
|
// Permiso: CG001 (Ver Canillas) o CG006 (Gestionar Novedades).
|
||||||
|
// Si CG006 es "Permite la Carga/Modificación", entonces CG001 podría ser más apropiado solo para ver.
|
||||||
|
// Vamos a usar CG001 para ver. Si se quiere más granularidad, se puede crear un permiso "Ver Novedades".
|
||||||
|
[HttpGet("porcanilla/{idCanilla:int}")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<NovedadCanillaDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> GetNovedadesPorCanilla(int idCanilla, [FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta)
|
||||||
|
{
|
||||||
|
if (!TienePermiso("CG001") && !TienePermiso("CG006")) // Necesita al menos uno de los dos
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Acceso denegado a GetNovedadesPorCanilla para el usuario {UserId} y canillita {IdCanilla}", GetCurrentUserId() ?? 0, idCanilla);
|
||||||
|
return Forbid();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var novedades = await _novedadService.ObtenerPorCanillaAsync(idCanilla, fechaDesde, fechaHasta);
|
||||||
|
return Ok(novedades);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener novedades para Canillita ID: {IdCanilla}", idCanilla);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener las novedades.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/novedadescanilla/{idNovedad}
|
||||||
|
// Obtiene una novedad específica por su ID.
|
||||||
|
// Permiso: CG001 o CG006
|
||||||
|
[HttpGet("{idNovedad:int}", Name = "GetNovedadCanillaById")]
|
||||||
|
[ProducesResponseType(typeof(NovedadCanillaDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> GetNovedadCanillaById(int idNovedad)
|
||||||
|
{
|
||||||
|
if (!TienePermiso("CG001") && !TienePermiso("CG006")) return Forbid();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var novedad = await _novedadService.ObtenerPorIdAsync(idNovedad);
|
||||||
|
if (novedad == null)
|
||||||
|
{
|
||||||
|
return NotFound(new { message = $"Novedad con ID {idNovedad} no encontrada." });
|
||||||
|
}
|
||||||
|
return Ok(novedad);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener NovedadCanilla por ID: {IdNovedad}", idNovedad);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener la novedad.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// POST: api/novedadescanilla
|
||||||
|
// Crea una nueva novedad. El IdCanilla viene en el DTO.
|
||||||
|
// Permiso: CG006 (Permite la Carga/Modificación de Novedades)
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(NovedadCanillaDto), StatusCodes.Status201Created)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> CreateNovedadCanilla([FromBody] CreateNovedadCanillaDto createDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso("CG006")) return Forbid();
|
||||||
|
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var idUsuario = GetCurrentUserId();
|
||||||
|
if (idUsuario == null) return Unauthorized("No se pudo obtener el ID del usuario del token.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var (novedadCreada, error) = await _novedadService.CrearAsync(createDto, idUsuario.Value);
|
||||||
|
|
||||||
|
if (error != null) return BadRequest(new { message = error });
|
||||||
|
if (novedadCreada == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear la novedad.");
|
||||||
|
|
||||||
|
// Devuelve la ruta al recurso creado y el recurso mismo
|
||||||
|
return CreatedAtRoute("GetNovedadCanillaById", new { idNovedad = novedadCreada.IdNovedad }, novedadCreada);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al crear NovedadCanilla para Canilla ID: {IdCanilla} por Usuario ID: {UsuarioId}", createDto.IdCanilla, idUsuario);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al crear la novedad.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: api/novedadescanilla/{idNovedad}
|
||||||
|
// Actualiza una novedad existente.
|
||||||
|
// Permiso: CG006
|
||||||
|
[HttpPut("{idNovedad:int}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> UpdateNovedadCanilla(int idNovedad, [FromBody] UpdateNovedadCanillaDto updateDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso("CG006")) return Forbid();
|
||||||
|
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var idUsuario = GetCurrentUserId();
|
||||||
|
if (idUsuario == null) return Unauthorized("No se pudo obtener el ID del usuario del token.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var (exito, error) = await _novedadService.ActualizarAsync(idNovedad, updateDto, idUsuario.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error == "Novedad no encontrada.") return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al actualizar NovedadCanilla ID: {IdNovedad} por Usuario ID: {UsuarioId}", idNovedad, idUsuario);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al actualizar la novedad.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/novedadescanilla/{idNovedad}
|
||||||
|
// Elimina una novedad.
|
||||||
|
// Permiso: CG006 (Asumiendo que el mismo permiso para Carga/Modificación incluye eliminación)
|
||||||
|
// Si la eliminación es un permiso separado (ej: CG00X), ajústalo.
|
||||||
|
[HttpDelete("{idNovedad:int}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> DeleteNovedadCanilla(int idNovedad)
|
||||||
|
{
|
||||||
|
if (!TienePermiso("CG006")) return Forbid();
|
||||||
|
|
||||||
|
var idUsuario = GetCurrentUserId();
|
||||||
|
if (idUsuario == null) return Unauthorized("No se pudo obtener el ID del usuario del token.");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var (exito, error) = await _novedadService.EliminarAsync(idNovedad, idUsuario.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error == "Novedad no encontrada.") return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error }); // Podría ser otro error, como "no se pudo eliminar"
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al eliminar NovedadCanilla ID: {IdNovedad} por Usuario ID: {UsuarioId}", idNovedad, idUsuario);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al eliminar la novedad.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,6 +64,23 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<OtroDestinoDropdownDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> GetAllOtrosDestinosDropdown()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var destinos = await _otroDestinoService.ObtenerTodosDropdownAsync();
|
||||||
|
return Ok(destinos);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener Otros Destinos para dropdown.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener la lista de destinos.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GET: api/otrosdestinos/{id}
|
// GET: api/otrosdestinos/{id}
|
||||||
[HttpGet("{id:int}", Name = "GetOtroDestinoById")]
|
[HttpGet("{id:int}", Name = "GetOtroDestinoById")]
|
||||||
[ProducesResponseType(typeof(OtroDestinoDto), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(OtroDestinoDto), StatusCodes.Status200OK)]
|
||||||
|
|||||||
@@ -38,16 +38,37 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/publicaciones
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IEnumerable<PublicacionDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<PublicacionDto>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
public async Task<IActionResult> GetAllPublicaciones([FromQuery] string? nombre, [FromQuery] int? idEmpresa, [FromQuery] bool? soloHabilitadas = true)
|
public async Task<IActionResult> GetAllPublicaciones([FromQuery] string? nombre, [FromQuery] int? idEmpresa, [FromQuery] bool? soloHabilitadas)
|
||||||
{
|
{
|
||||||
if (!TienePermiso(PermisoVer)) return Forbid();
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
var publicaciones = await _publicacionService.ObtenerTodasAsync(nombre, idEmpresa, soloHabilitadas);
|
var publicaciones = await _publicacionService.ObtenerTodasAsync(nombre, idEmpresa, soloHabilitadas);
|
||||||
return Ok(publicaciones);
|
return Ok(publicaciones);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/publicaciones/dropdown
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PublicacionDropdownDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
// No se verifica permiso DP001, solo requiere autenticación general ([Authorize] del controlador)
|
||||||
|
public async Task<IActionResult> GetPublicacionesForDropdown([FromQuery] bool? soloHabilitadas)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var publicaciones = await _publicacionService.ObtenerParaDropdownAsync(soloHabilitadas);
|
||||||
|
return Ok(publicaciones);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener publicaciones para dropdown.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener publicaciones para selección.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/publicaciones/{id}
|
||||||
[HttpGet("{id:int}", Name = "GetPublicacionById")]
|
[HttpGet("{id:int}", Name = "GetPublicacionById")]
|
||||||
[ProducesResponseType(typeof(PublicacionDto), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(PublicacionDto), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
@@ -60,6 +81,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
return Ok(publicacion);
|
return Ok(publicacion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// POST: api/publicaciones
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(typeof(PublicacionDto), StatusCodes.Status201Created)]
|
[ProducesResponseType(typeof(PublicacionDto), StatusCodes.Status201Created)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
@@ -77,6 +99,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
return CreatedAtRoute("GetPublicacionById", new { id = dto.IdPublicacion }, dto);
|
return CreatedAtRoute("GetPublicacionById", new { id = dto.IdPublicacion }, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PUT: api/publicaciones/{id}
|
||||||
[HttpPut("{id:int}")]
|
[HttpPut("{id:int}")]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
@@ -98,6 +121,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DELETE: api/publicaciones/{id}
|
||||||
[HttpDelete("{id:int}")]
|
[HttpDelete("{id:int}")]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
@@ -118,7 +142,7 @@ namespace GestionIntegral.Api.Controllers.Distribucion
|
|||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endpoint para obtener las configuraciones de días para una publicación
|
// Endpoint para obtener la configuración de días de publicación para una publicación específica
|
||||||
[HttpGet("{idPublicacion:int}/dias-semana")]
|
[HttpGet("{idPublicacion:int}/dias-semana")]
|
||||||
[ProducesResponseType(typeof(IEnumerable<PublicacionDiaSemanaDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<PublicacionDiaSemanaDto>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
|||||||
@@ -67,6 +67,23 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/estadosbobina/dropdown
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EstadoBobinaDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetAllDropdownEstadosBobina()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var estados = await _estadoBobinaService.ObtenerTodosDropdownAsync();
|
||||||
|
return Ok(estados);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener todos los Estados de Bobina.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener los estados de bobina.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GET: api/estadosbobina/{id}
|
// GET: api/estadosbobina/{id}
|
||||||
[HttpGet("{id:int}", Name = "GetEstadoBobinaById")]
|
[HttpGet("{id:int}", Name = "GetEstadoBobinaById")]
|
||||||
[ProducesResponseType(typeof(EstadoBobinaDto), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(EstadoBobinaDto), StatusCodes.Status200OK)]
|
||||||
|
|||||||
@@ -71,6 +71,25 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/plantas/dropdown
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PlantaDropdownDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
// NO chequeo TienePermiso("IP001")(requiere autenticación)
|
||||||
|
public async Task<IActionResult> GetPlantasForDropdown()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var plantas = await _plantaService.ObtenerParaDropdownAsync();
|
||||||
|
return Ok(plantas);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener plantas para dropdown.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener plantas para selección.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GET: api/plantas/{id}
|
// GET: api/plantas/{id}
|
||||||
// Permiso: IP001 (Ver Plantas)
|
// Permiso: IP001 (Ver Plantas)
|
||||||
[HttpGet("{id:int}", Name = "GetPlantaById")]
|
[HttpGet("{id:int}", Name = "GetPlantaById")]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using GestionIntegral.Api.Dtos.Impresion;
|
|||||||
using GestionIntegral.Api.Services.Impresion;
|
using GestionIntegral.Api.Services.Impresion;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -40,6 +41,7 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/stockbobinas
|
||||||
// GET: api/stockbobinas
|
// GET: api/stockbobinas
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IEnumerable<StockBobinaDto>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<StockBobinaDto>), StatusCodes.Status200OK)]
|
||||||
@@ -47,12 +49,23 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
public async Task<IActionResult> GetAllStockBobinas(
|
public async Task<IActionResult> GetAllStockBobinas(
|
||||||
[FromQuery] int? idTipoBobina, [FromQuery] string? nroBobina, [FromQuery] int? idPlanta,
|
[FromQuery] int? idTipoBobina, [FromQuery] string? nroBobina, [FromQuery] int? idPlanta,
|
||||||
[FromQuery] int? idEstadoBobina, [FromQuery] string? remito,
|
[FromQuery] int? idEstadoBobina, [FromQuery] string? remito,
|
||||||
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta)
|
[FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta,
|
||||||
|
[FromQuery] DateTime? fechaEstadoDesde, [FromQuery] DateTime? fechaEstadoHasta) // <--- Nuevos parámetros agregados
|
||||||
{
|
{
|
||||||
if (!TienePermiso(PermisoVerStock)) return Forbid();
|
if (!TienePermiso(PermisoVerStock)) return Forbid();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var bobinas = await _stockBobinaService.ObtenerTodosAsync(idTipoBobina, nroBobina, idPlanta, idEstadoBobina, remito, fechaDesde, fechaHasta);
|
var bobinas = await _stockBobinaService.ObtenerTodosAsync(
|
||||||
|
idTipoBobina,
|
||||||
|
nroBobina,
|
||||||
|
idPlanta,
|
||||||
|
idEstadoBobina,
|
||||||
|
remito,
|
||||||
|
fechaDesde,
|
||||||
|
fechaHasta,
|
||||||
|
fechaEstadoDesde,
|
||||||
|
fechaEstadoHasta
|
||||||
|
);
|
||||||
return Ok(bobinas);
|
return Ok(bobinas);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -124,11 +137,15 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
public async Task<IActionResult> CambiarEstadoBobina(int idBobina, [FromBody] CambiarEstadoBobinaDto cambiarEstadoDto)
|
public async Task<IActionResult> CambiarEstadoBobina(int idBobina, [FromBody] CambiarEstadoBobinaDto cambiarEstadoDto)
|
||||||
{
|
{
|
||||||
if (!TienePermiso(PermisoCambiarEstado)) return Forbid();
|
if (!TienePermiso(PermisoCambiarEstado)) return Forbid();
|
||||||
if (!ModelState.IsValid) return BadRequest(ModelState);
|
if (!ModelState.IsValid) return BadRequest(ModelState); // Validaciones de DTO (Required, Range, etc.)
|
||||||
var userId = GetCurrentUserId();
|
var userId = GetCurrentUserId();
|
||||||
if (userId == null) return Unauthorized();
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
// Validación adicional en el controlador para el caso "En Uso"
|
// La validación de que IdPublicacion/IdSeccion son requeridos para estado "En Uso"
|
||||||
|
// ahora está más robusta en el servicio. Se puede quitar del controlador
|
||||||
|
// si se prefiere que el servicio sea la única fuente de verdad para esa lógica.
|
||||||
|
// Si la mantenés acá, es una validación temprana.
|
||||||
|
/*
|
||||||
if (cambiarEstadoDto.NuevoEstadoId == 2) // Asumiendo 2 = En Uso
|
if (cambiarEstadoDto.NuevoEstadoId == 2) // Asumiendo 2 = En Uso
|
||||||
{
|
{
|
||||||
if (!cambiarEstadoDto.IdPublicacion.HasValue || cambiarEstadoDto.IdPublicacion.Value <= 0)
|
if (!cambiarEstadoDto.IdPublicacion.HasValue || cambiarEstadoDto.IdPublicacion.Value <= 0)
|
||||||
@@ -136,12 +153,13 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
if (!cambiarEstadoDto.IdSeccion.HasValue || cambiarEstadoDto.IdSeccion.Value <=0)
|
if (!cambiarEstadoDto.IdSeccion.HasValue || cambiarEstadoDto.IdSeccion.Value <=0)
|
||||||
return BadRequest(new { message = "Se requiere IdSeccion para el estado 'En Uso'."});
|
return BadRequest(new { message = "Se requiere IdSeccion para el estado 'En Uso'."});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
var (exito, error) = await _stockBobinaService.CambiarEstadoBobinaAsync(idBobina, cambiarEstadoDto, userId.Value);
|
var (exito, error) = await _stockBobinaService.CambiarEstadoBobinaAsync(idBobina, cambiarEstadoDto, userId.Value);
|
||||||
if (!exito)
|
if (!exito)
|
||||||
{
|
{
|
||||||
if (error == "Bobina no encontrada.") return NotFound(new { message = error });
|
if (error == "Bobina no encontrada.") return NotFound(new { message = error });
|
||||||
|
// Otros errores específicos del servicio (ej. flujo de estado no permitido) vienen como BadRequest
|
||||||
return BadRequest(new { message = error });
|
return BadRequest(new { message = error });
|
||||||
}
|
}
|
||||||
return NoContent();
|
return NoContent();
|
||||||
@@ -167,5 +185,72 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
}
|
}
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/stockbobinas/verificar-remito
|
||||||
|
[HttpGet("verificar-remito")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<StockBobinaDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
// CAMBIO: Hacer fechaRemito opcional (nullable)
|
||||||
|
public async Task<IActionResult> VerificarRemito([FromQuery, BindRequired] int idPlanta, [FromQuery, BindRequired] string remito, [FromQuery] DateTime? fechaRemito)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoIngresarBobina)) return Forbid();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Pasamos el parámetro nullable al servicio
|
||||||
|
var bobinasExistentes = await _stockBobinaService.VerificarRemitoExistenteAsync(idPlanta, remito, fechaRemito);
|
||||||
|
return Ok(bobinasExistentes);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al verificar remito {Remito} para planta {IdPlanta}", remito, idPlanta);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al verificar el remito.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("actualizar-fecha-remito")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> ActualizarFechaRemitoLote([FromBody] UpdateFechaRemitoLoteDto dto)
|
||||||
|
{
|
||||||
|
// Reutilizamos el permiso de modificar datos, ya que es una corrección.
|
||||||
|
if (!TienePermiso(PermisoModificarDatos)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _stockBobinaService.ActualizarFechaRemitoLoteAsync(dto, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/stockbobinas/lote
|
||||||
|
[HttpPost("lote")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> IngresarLoteBobinas([FromBody] CreateStockBobinaLoteDto loteDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoIngresarBobina)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _stockBobinaService.IngresarBobinaLoteAsync(loteDto, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoContent(); // 204 es una buena respuesta para un lote procesado exitosamente sin devolver contenido.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,6 +62,25 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET: api/tiposbobina/dropdown
|
||||||
|
[HttpGet("dropdown")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<TipoBobinaDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
|
public async Task<IActionResult> GetAllTiposBobina()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tiposBobina = await _tipoBobinaService.ObtenerTodosDropdownAsync();
|
||||||
|
return Ok(tiposBobina);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener todos los Tipos de Bobina.");
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener los tipos de bobina.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GET: api/tiposbobina/{id}
|
// GET: api/tiposbobina/{id}
|
||||||
// Permiso: IB006 (Ver Tipos Bobinas)
|
// Permiso: IB006 (Ver Tipos Bobinas)
|
||||||
[HttpGet("{id:int}", Name = "GetTipoBobinaById")]
|
[HttpGet("{id:int}", Name = "GetTipoBobinaById")]
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
// Permisos para Tiradas (IT001 a IT003)
|
// Permisos para Tiradas (IT001 a IT003)
|
||||||
private const string PermisoVerTiradas = "IT001";
|
private const string PermisoVerTiradas = "IT001";
|
||||||
private const string PermisoRegistrarTirada = "IT002";
|
private const string PermisoRegistrarTirada = "IT002";
|
||||||
private const string PermisoEliminarTirada = "IT003"; // Asumo que se refiere a eliminar una tirada completa (cabecera y detalles)
|
private const string PermisoEliminarTirada = "IT003";
|
||||||
|
private const string PermisoModificarTirada = "IT004";
|
||||||
|
|
||||||
public TiradasController(ITiradaService tiradaService, ILogger<TiradasController> logger)
|
public TiradasController(ITiradaService tiradaService, ILogger<TiradasController> logger)
|
||||||
{
|
{
|
||||||
@@ -83,6 +84,43 @@ namespace GestionIntegral.Api.Controllers.Impresion
|
|||||||
return StatusCode(StatusCodes.Status201Created, tiradaCreada);
|
return StatusCode(StatusCodes.Status201Created, tiradaCreada);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPut]
|
||||||
|
[ProducesResponseType(typeof(TiradaDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ModificarTirada(
|
||||||
|
[FromQuery, BindRequired] DateTime fecha,
|
||||||
|
[FromQuery, BindRequired] int idPublicacion,
|
||||||
|
[FromQuery, BindRequired] int idPlanta,
|
||||||
|
[FromBody] UpdateTiradaRequestDto updateDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoModificarTirada)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (tiradaActualizada, error) = await _tiradaService.ModificarTiradaCompletaAsync(fecha, idPublicacion, idPlanta, updateDto, userId.Value);
|
||||||
|
|
||||||
|
if (error != null)
|
||||||
|
{
|
||||||
|
// Chequear si el error es porque no se encontró la tirada.
|
||||||
|
if (error.StartsWith("No se encontró la tirada"))
|
||||||
|
{
|
||||||
|
return NotFound(new { message = error });
|
||||||
|
}
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tiradaActualizada == null)
|
||||||
|
{
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al modificar la tirada.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(tiradaActualizada);
|
||||||
|
}
|
||||||
|
|
||||||
// DELETE: api/tiradas
|
// DELETE: api/tiradas
|
||||||
// Se identifica la tirada a eliminar por su combinación única de Fecha, IdPublicacion, IdPlanta
|
// Se identifica la tirada a eliminar por su combinación única de Fecha, IdPublicacion, IdPlanta
|
||||||
[HttpDelete]
|
[HttpDelete]
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ComparativaConsumoBobinasDocument : IDocument
|
||||||
|
{
|
||||||
|
public ComparativaConsumoBobinasViewModel Model { get; }
|
||||||
|
|
||||||
|
public ComparativaConsumoBobinasDocument(ComparativaConsumoBobinasViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Consumo de Bobinas - Comparativa Mensual").SemiBold().FontSize(14);
|
||||||
|
|
||||||
|
string subTitle = Model.EsConsolidado ? "Consolidado" : $"Planta: {Model.NombrePlanta}";
|
||||||
|
column.Item().AlignCenter().Text(subTitle).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
// Le damos una proporción menor al texto de la izquierda (que es corto y fijo).
|
||||||
|
row.RelativeItem(1).Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha del Reporte: ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaReporte);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Le damos una proporción mayor al texto de la derecha (que es largo y variable).
|
||||||
|
// El factor "2" significa que tendrá el doble de espacio disponible que el item con factor "1".
|
||||||
|
row.RelativeItem(2).AlignRight().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Meses: ").SemiBold().FontSize(12);
|
||||||
|
text.Span($"{Model.MesA} (Mes A) contra {Model.MesB} (Mes B)").FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(3); // Tipo Bobina
|
||||||
|
columns.RelativeColumn(1); columns.RelativeColumn(1); columns.RelativeColumn(1); // Grupo Cantidad
|
||||||
|
columns.RelativeColumn(1); columns.RelativeColumn(1); columns.RelativeColumn(1); // Grupo Kilos
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
// Fila 1 del Encabezado
|
||||||
|
header.Cell().RowSpan(2).Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignMiddle().Text("Tipo Bobina").SemiBold();
|
||||||
|
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Cantidad Bobinas").SemiBold();
|
||||||
|
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Kilos Utilizados").SemiBold();
|
||||||
|
|
||||||
|
// Fila 2 del Encabezado
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Mes A").SemiBold();
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Mes B").SemiBold();
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Diferencia").SemiBold();
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Kg Mes A").SemiBold();
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Kg Mes B").SemiBold();
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Diferencia").SemiBold();
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Detalles.OrderBy(x => x.TipoBobina))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.TipoBobina);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.BobinasUtilizadasMesA.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.BobinasUtilizadasMesB.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.DiferenciaBobinasUtilizadas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.KilosUtilizadosMesA.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.KilosUtilizadosMesB.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.DiferenciaKilosUtilizados.ToString("N0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de Totales
|
||||||
|
var style = TextStyle.Default.SemiBold();
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span("Totales").Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.BobinasUtilizadasMesA).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.BobinasUtilizadasMesB).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.DiferenciaBobinasUtilizadas).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.KilosUtilizadosMesA).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.KilosUtilizadosMesB).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.DiferenciaKilosUtilizados).ToString("N0")).Style(style));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ConsumoBobinasPublicacionDocument : IDocument
|
||||||
|
{
|
||||||
|
public ConsumoBobinasPublicacionViewModel Model { get; }
|
||||||
|
|
||||||
|
public ConsumoBobinasPublicacionDocument(ConsumoBobinasPublicacionViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1.5f, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Consumo de Bobinas por Publicaciones").SemiBold().FontSize(14);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha del Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2); // Planta
|
||||||
|
columns.RelativeColumn(3); // Publicación
|
||||||
|
columns.RelativeColumn(1.5f); // Kilos
|
||||||
|
columns.RelativeColumn(1.5f); // Cant. Bobinas
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Planta");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Publicación");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Kilos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Bobinas");
|
||||||
|
});
|
||||||
|
|
||||||
|
var gruposPorPlanta = Model.Detalles.GroupBy(p => p.NombrePlanta);
|
||||||
|
|
||||||
|
foreach (var grupoPlanta in gruposPorPlanta)
|
||||||
|
{
|
||||||
|
var primeraFilaDePlanta = true;
|
||||||
|
foreach (var detalle in grupoPlanta.OrderBy(d => d.NombrePublicacion))
|
||||||
|
{
|
||||||
|
// Celda de Planta (solo en la primera fila del grupo)
|
||||||
|
if (primeraFilaDePlanta)
|
||||||
|
{
|
||||||
|
table.Cell().RowSpan((uint)grupoPlanta.Count()).Border(1).Padding(3).AlignTop().Text(grupoPlanta.Key).SemiBold();
|
||||||
|
primeraFilaDePlanta = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3).Text(detalle.NombrePublicacion);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(detalle.TotalKilos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(detalle.CantidadBobinas.ToString("N0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de Totales Generales
|
||||||
|
var totalGeneralKilos = Model.Detalles.Sum(d => d.TotalKilos);
|
||||||
|
var totalGeneralBobinas = Model.Detalles.Sum(d => d.CantidadBobinas);
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(2).BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text("Totales").ExtraBold();
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text(t => t.Span(totalGeneralKilos.ToString("N0")).ExtraBold());
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text(t => t.Span(totalGeneralBobinas.ToString("N0")).ExtraBold());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes;
|
||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ConsumoBobinasSeccionDocument : IDocument
|
||||||
|
{
|
||||||
|
public ConsumoBobinasSeccionViewModel Model { get; }
|
||||||
|
|
||||||
|
public ConsumoBobinasSeccionDocument(ConsumoBobinasSeccionViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1.5f, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Consumo de Bobinas por Secciones").SemiBold().FontSize(14);
|
||||||
|
|
||||||
|
string subTitle = Model.EsConsolidado ? "Consolidado" : $"Planta: {Model.NombrePlanta}";
|
||||||
|
column.Item().AlignCenter().Text(subTitle).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha del Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Encabezado de la tabla principal
|
||||||
|
column.Item().PaddingTop(10).BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem(1.5f).Text("Publicación").SemiBold();
|
||||||
|
row.RelativeItem(1.5f).Text("Sección").SemiBold();
|
||||||
|
row.RelativeItem(3).Text("Bobina").SemiBold();
|
||||||
|
row.RelativeItem(1).AlignRight().Text("Cant. Bobinas").SemiBold();
|
||||||
|
row.RelativeItem(1).AlignRight().Text("Kilos").SemiBold();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
var gruposPorPublicacion = Model.Detalles.GroupBy(p => p.NombrePublicacion);
|
||||||
|
|
||||||
|
foreach (var grupoPub in gruposPorPublicacion)
|
||||||
|
{
|
||||||
|
column.Item().Element(c => ComposePublicacionSection(c, grupoPub));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de Totales Generales al final
|
||||||
|
var totalGeneralBobinas = Model.Detalles.Sum(d => d.CantidadBobinas);
|
||||||
|
var totalGeneralKilos = Model.Detalles.Sum(d => d.TotalKilos);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(10).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem(6).AlignRight().Text("Total General").ExtraBold().FontSize(12);
|
||||||
|
row.RelativeItem(1).AlignRight().Text(totalGeneralBobinas.ToString("N0")).ExtraBold().FontSize(12);
|
||||||
|
row.RelativeItem(1).AlignRight().Text(totalGeneralKilos.ToString("N0")).ExtraBold().FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- COMPONENTE PARA UNA PUBLICACIÓN ENTERA ---
|
||||||
|
void ComposePublicacionSection(IContainer container, IGrouping<string, ConsumoBobinasSeccionDto> grupoPub)
|
||||||
|
{
|
||||||
|
container.Row(row =>
|
||||||
|
{
|
||||||
|
// Columna 1: Nombre de la Publicación
|
||||||
|
row.RelativeItem(1.5f).BorderBottom(1).BorderLeft(1).BorderRight(1).BorderColor(Colors.Grey.Medium).Padding(3).Text(grupoPub.Key).SemiBold();
|
||||||
|
|
||||||
|
// Columna 2: Contiene todas las sub-tablas de secciones
|
||||||
|
row.RelativeItem(6.5f).Column(seccionesColumn =>
|
||||||
|
{
|
||||||
|
var gruposPorSeccion = grupoPub.GroupBy(s => s.NombreSeccion);
|
||||||
|
foreach(var grupoSec in gruposPorSeccion)
|
||||||
|
{
|
||||||
|
seccionesColumn.Item().Element(c => ComposeSeccionTable(c, grupoSec));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- COMPONENTE PARA LA TABLA DE UNA SECCIÓN ---
|
||||||
|
void ComposeSeccionTable(IContainer container, IGrouping<string, ConsumoBobinasSeccionDto> grupoSec)
|
||||||
|
{
|
||||||
|
container.Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(1.5f); // Sección
|
||||||
|
columns.RelativeColumn(3); // Bobina
|
||||||
|
columns.RelativeColumn(1); // Cantidad
|
||||||
|
columns.RelativeColumn(1); // Kilos
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filas de detalle
|
||||||
|
foreach (var detalle in grupoSec.OrderBy(d => d.NombreBobina))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).Text(grupoSec.Key);
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).Text(detalle.NombreBobina);
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(detalle.CantidadBobinas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(detalle.TotalKilos.ToString("N0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de total de la sección
|
||||||
|
var totalCantSeccion = grupoSec.Sum(d => d.CantidadBobinas);
|
||||||
|
var totalKilosSeccion = grupoSec.Sum(d => d.TotalKilos);
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(2).Border(1).BorderColor(Colors.Grey.Medium).AlignRight().Padding(3).Text("Total Sección").SemiBold();
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(t => t.Span(totalCantSeccion.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(t => t.Span(totalKilosSeccion.ToString("N0")).SemiBold());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ControlDevolucionesDocument : IDocument
|
||||||
|
{
|
||||||
|
public ControlDevolucionesViewModel Model { get; }
|
||||||
|
|
||||||
|
public ControlDevolucionesDocument(ControlDevolucionesViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(11));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("Control de Devoluciones").SemiBold().FontSize(16);
|
||||||
|
column.Item().AlignCenter().Text("Canillas / Accionistas").FontSize(13);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
// << CAMBIO: Reducido el padding superior de 1cm a 5mm >>
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Column(column =>
|
||||||
|
{
|
||||||
|
// << CAMBIO: Reducido el espaciado principal entre elementos de 15 a 10 puntos >>
|
||||||
|
column.Spacing(10);
|
||||||
|
|
||||||
|
column.Item().Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha Consultada: ").SemiBold();
|
||||||
|
text.Span(Model.FechaConsultada);
|
||||||
|
});
|
||||||
|
row.RelativeItem().AlignRight().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Cantidad Canillas: ").SemiBold();
|
||||||
|
text.Span(Model.CantidadCanillas.ToString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
column.Item().PaddingTop(3).Border(1).Background(Colors.Grey.Lighten3).AlignCenter().Padding(2).Text(Model.NombreEmpresa).SemiBold();
|
||||||
|
|
||||||
|
column.Item().Border(1).Padding(8).Column(innerCol => // << CAMBIO: Padding reducido de 10 a 8 >>
|
||||||
|
{
|
||||||
|
// << CAMBIO: Reducido el espaciado interno de 5 a 4 >>
|
||||||
|
innerCol.Spacing(4);
|
||||||
|
|
||||||
|
innerCol.Item().BorderBottom(1, Unit.Point).BorderColor(Colors.Grey.Medium).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text("Ingresados por Remito:").SemiBold();
|
||||||
|
row.RelativeItem().AlignRight().Text(Model.TotalIngresadosPorRemito.ToString("N0"));
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Detalles)
|
||||||
|
{
|
||||||
|
var totalSeccion = item.Devueltos - item.Llevados;
|
||||||
|
// << CAMBIO: Reducido el padding superior de 5 a 3 >>
|
||||||
|
innerCol.Item().PaddingTop(3).Row(row =>
|
||||||
|
{
|
||||||
|
row.ConstantItem(100).Text(item.Tipo).SemiBold();
|
||||||
|
|
||||||
|
row.RelativeItem().Column(sub =>
|
||||||
|
{
|
||||||
|
sub.Spacing(2);
|
||||||
|
sub.Item().Row(r => {
|
||||||
|
r.RelativeItem().Text("Llevados");
|
||||||
|
r.RelativeItem().AlignRight().Text($"-{item.Llevados:N0}");
|
||||||
|
});
|
||||||
|
sub.Item().Row(r => {
|
||||||
|
r.RelativeItem().Text("Devueltos");
|
||||||
|
r.RelativeItem().AlignRight().Text($"{item.Devueltos:N0}");
|
||||||
|
});
|
||||||
|
// << CAMBIO: Reducido el padding superior de 2 a 1 >>
|
||||||
|
sub.Item().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(1).Row(r => {
|
||||||
|
r.RelativeItem().Text(t => t.Span("Total").SemiBold());
|
||||||
|
r.RelativeItem().AlignRight().Text(t => t.Span(totalSeccion.ToString("N0")).SemiBold());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// << CAMBIO: Reducido el padding superior de 10 a 8 >>
|
||||||
|
column.Item().PaddingTop(8).Column(finalCol =>
|
||||||
|
{
|
||||||
|
finalCol.Spacing(2);
|
||||||
|
|
||||||
|
Action<RowDescriptor, string, string, bool> AddTotalRow = (row, label, value, isBold) =>
|
||||||
|
{
|
||||||
|
var text = row.RelativeItem().Text(label);
|
||||||
|
if (isBold) text.SemiBold();
|
||||||
|
|
||||||
|
var valueText = row.ConstantItem(80).AlignRight().Text(value);
|
||||||
|
if (isBold) valueText.SemiBold();
|
||||||
|
};
|
||||||
|
|
||||||
|
// << CAMBIO: Reducido el padding superior de 2 a 1 en las siguientes líneas >>
|
||||||
|
finalCol.Item().BorderTop(2f).BorderColor(Colors.Black).PaddingTop(1).Row(row => AddTotalRow(row, "Total Devolución a la Fecha", Model.TotalDevolucionALaFecha.ToString("N0"), false));
|
||||||
|
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(1).Row(row => AddTotalRow(row, "Total Devolución Días Anteriores", Model.TotalDevolucionDiasAnteriores.ToString("N0"), false));
|
||||||
|
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(1).Row(row => AddTotalRow(row, "Total Devolución", Model.TotalDevolucionGeneral.ToString("N0"), false));
|
||||||
|
// << CAMBIO: Reducido el padding superior de 5 a 3 >>
|
||||||
|
finalCol.Item().BorderTop(2f).BorderColor(Colors.Black).PaddingTop(3).Row(row => AddTotalRow(row, "Sin Cargo", Model.TotalSinCargo.ToString("N0"), false));
|
||||||
|
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(1).Row(row => AddTotalRow(row, "Sobrantes", $"-{Model.TotalSobrantes.ToString("N0")}", false));
|
||||||
|
// << CAMBIO: Reducido el padding superior de 5 a 3 >>
|
||||||
|
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).BorderBottom(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(3).Row(row => AddTotalRow(row, "Diferencia", Model.DiferenciaFinal.ToString("N0"), true));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,255 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class CuentasDistribuidorDocument : IDocument
|
||||||
|
{
|
||||||
|
public CuentasDistribuidorViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR", false)
|
||||||
|
{
|
||||||
|
NumberFormat = { CurrencySymbol = "$" }
|
||||||
|
};
|
||||||
|
|
||||||
|
public CuentasDistribuidorDocument(CuentasDistribuidorViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); x.Span(" de "); x.TotalPages(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text($"Fecha de Reporte {Model.FechaReporte}");
|
||||||
|
row.RelativeItem().AlignCenter().Text("Cuenta De Distribuidor").SemiBold().FontSize(14);
|
||||||
|
row.RelativeItem();
|
||||||
|
});
|
||||||
|
|
||||||
|
column.Item().AlignCenter().Text(Model.NombreDistribuidor).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem(2);
|
||||||
|
row.RelativeItem(8).AlignCenter().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha Consultada: Desde ").SemiBold();
|
||||||
|
text.Span(Model.FechaDesde);
|
||||||
|
text.Span(" Hasta ").SemiBold();
|
||||||
|
text.Span(Model.FechaHasta);
|
||||||
|
});
|
||||||
|
row.RelativeItem(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(20);
|
||||||
|
|
||||||
|
if (Model.Movimientos.Any()) column.Item().Element(ComposeMovimientosTable);
|
||||||
|
if (Model.Pagos.Any()) column.Item().Element(ComposePagosTable);
|
||||||
|
if (Model.DebitosCreditos.Any()) column.Item().Element(ComposeDebCredTable);
|
||||||
|
|
||||||
|
column.Item().Element(ComposeResumenPeriodo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeMovimientosTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(5).Text("Movimientos").SemiBold().FontSize(11);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(60);
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
columns.ConstantColumn(50);
|
||||||
|
columns.ConstantColumn(50);
|
||||||
|
columns.RelativeColumn(1.5f);
|
||||||
|
columns.RelativeColumn(1.5f);
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicacion");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Remito");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Cantidad");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Debe");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Haber");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fila Saldo Inicial al inicio de la primera tabla — ancla del acumulado
|
||||||
|
table.Cell().ColumnSpan(6).Border(1).Padding(2).Text(t => t.Span("Saldo Inicial").SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(Model.SaldoInicial.ToString("C", CultureAr)).SemiBold());
|
||||||
|
|
||||||
|
decimal saldoAcumulado = Model.SaldoInicial;
|
||||||
|
foreach (var item in Model.Movimientos.OrderBy(m => m.Fecha))
|
||||||
|
{
|
||||||
|
saldoAcumulado += (item.Debe - item.Haber);
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Fecha.ToString("dd/MM/yyyy"));
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Remito);
|
||||||
|
table.Cell().Border(1).Padding(2).AlignCenter().Text(item.Cantidad.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Debe.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Haber.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(saldoAcumulado.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(4).Border(1).AlignRight().Padding(2).Text(t => t.Span("Totales").SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Movimientos.Sum(x => x.Debe).ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Movimientos.Sum(x => x.Haber).ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(saldoAcumulado.ToString("C", CultureAr)).SemiBold());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposePagosTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(5).Text("Pagos").SemiBold().FontSize(12);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(60);
|
||||||
|
columns.RelativeColumn(1.5f);
|
||||||
|
columns.ConstantColumn(50);
|
||||||
|
columns.RelativeColumn(1.5f);
|
||||||
|
columns.RelativeColumn(1.5f);
|
||||||
|
columns.RelativeColumn(1.5f);
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Recibo");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Debe");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Haber");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Detalle");
|
||||||
|
});
|
||||||
|
|
||||||
|
decimal saldoAcumulado = Model.SaldoInicial + Model.TotalMovimientos;
|
||||||
|
foreach (var item in Model.Pagos.OrderBy(p => p.Fecha).ThenBy(p => p.Recibo))
|
||||||
|
{
|
||||||
|
saldoAcumulado += (item.Debe - item.Haber);
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Fecha.ToString("dd/MM/yyyy"));
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Recibo.ToString());
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Tipo);
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Debe.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Haber.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(saldoAcumulado.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Detalle);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(3).Border(1).AlignRight().Padding(2).Text(t => t.Span("Totales").SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Pagos.Sum(x => x.Debe).ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Pagos.Sum(x => x.Haber).ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(saldoAcumulado.ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().Border(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeDebCredTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(5).Text("Débitos / Créditos").SemiBold().FontSize(12);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(65);
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
columns.RelativeColumn(1);
|
||||||
|
columns.RelativeColumn(1);
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Referencia");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Debe");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Haber");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||||
|
});
|
||||||
|
|
||||||
|
decimal saldoAcumulado = Model.SaldoInicial + Model.TotalMovimientos + Model.TotalPagos;
|
||||||
|
foreach (var item in Model.DebitosCreditos.OrderBy(dc => dc.Fecha))
|
||||||
|
{
|
||||||
|
saldoAcumulado += (item.Debe - item.Haber);
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Fecha.ToString("dd/MM/yyyy"));
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Referencia);
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Debe.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Haber.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(saldoAcumulado.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(2).Border(1).AlignRight().Padding(2).Text(t => t.Span("Totales").SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.DebitosCreditos.Sum(x => x.Debe).ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.DebitosCreditos.Sum(x => x.Haber).ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(saldoAcumulado.ToString("C", CultureAr)).SemiBold());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeResumenPeriodo(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).AlignLeft().Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Border(1).Padding(5).Width(300, Unit.Point).Column(col =>
|
||||||
|
{
|
||||||
|
col.Spacing(5);
|
||||||
|
col.Item().Text("Datos totales del periodo consultado").SemiBold();
|
||||||
|
Action<RowDescriptor, string, decimal> AddResumenRow = (row, label, value) =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(label);
|
||||||
|
row.ConstantItem(120).AlignRight().Text(value.ToString("C", CultureAr));
|
||||||
|
};
|
||||||
|
col.Item().Row(row => AddResumenRow(row, "Saldo Inicial", Model.SaldoInicial));
|
||||||
|
col.Item().Row(row => AddResumenRow(row, "Movimientos", Model.TotalMovimientos));
|
||||||
|
col.Item().Row(row => AddResumenRow(row, "Débitos/Créditos", Model.TotalDebitosCreditos));
|
||||||
|
col.Item().Row(row => AddResumenRow(row, "Pagos", Model.TotalPagos));
|
||||||
|
col.Item().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(5).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text("Saldo Final").SemiBold();
|
||||||
|
row.ConstantItem(120).AlignRight().Text(t => t.Span(Model.SaldoFinal.ToString("C", CultureAr)).SemiBold());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes;
|
||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class DistribucionCanillasDocument : IDocument
|
||||||
|
{
|
||||||
|
public DistribucionCanillasViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||||
|
|
||||||
|
public DistribucionCanillasDocument(DistribucionCanillasViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Row(row => {
|
||||||
|
row.RelativeItem().Text("Listado de Distribución: Canillas / Accionistas").FontSize(12);
|
||||||
|
row.RelativeItem().AlignRight().Text(text => {
|
||||||
|
text.Span("Fecha Consultada ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaConsultada).FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
column.Item().PaddingTop(5).Row(row => {
|
||||||
|
row.RelativeItem().Text(text => {
|
||||||
|
text.Span("Fecha de Generación del Reporte ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaReporte);
|
||||||
|
});
|
||||||
|
row.RelativeItem().AlignRight().Text(text => {
|
||||||
|
text.Span("Empresa ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.Empresa).FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(15);
|
||||||
|
|
||||||
|
if(Model.Canillas.Any())
|
||||||
|
column.Item().Element(c => ComposeTablaDetallada(c, "Canillas", Model.Canillas));
|
||||||
|
|
||||||
|
if(Model.CanillasAccionistas.Any())
|
||||||
|
column.Item().Element(c => ComposeTablaDetallada(c, "Accionistas", Model.CanillasAccionistas));
|
||||||
|
|
||||||
|
if(Model.CanillasLiquidadasOtraFecha.Any())
|
||||||
|
column.Item().Element(c => ComposeTablaLiquidacion(c, "Liquidación de movimientos de otras fechas canillas", Model.CanillasLiquidadasOtraFecha));
|
||||||
|
|
||||||
|
if(Model.CanillasAccionistasLiquidadasOtraFecha.Any())
|
||||||
|
column.Item().Element(c => ComposeTablaLiquidacion(c, "Liquidación de movimientos de otras fechas accionistas", Model.CanillasAccionistasLiquidadasOtraFecha));
|
||||||
|
|
||||||
|
if(Model.CanillasTodos.Any())
|
||||||
|
column.Item().Element(c => ComposeTablaTotales(c, "Recuento de Publicaciones", Model.CanillasTodos));
|
||||||
|
|
||||||
|
if(Model.RemitoIngresado > 0)
|
||||||
|
column.Item().Element(ComposeResumenDevoluciones);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeTablaDetallada(IContainer container, string title, IEnumerable<DetalleDistribucionCanillaDto> data)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(4).Text(title).SemiBold().FontSize(11);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(3); columns.RelativeColumn(3);
|
||||||
|
columns.RelativeColumn(1); columns.RelativeColumn(1);
|
||||||
|
columns.RelativeColumn(1); columns.RelativeColumn(1.2f);
|
||||||
|
});
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Vendedor");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||||
|
});
|
||||||
|
foreach (var grupoCanilla in data.GroupBy(c => c.Canilla))
|
||||||
|
{
|
||||||
|
var primeraFila = true;
|
||||||
|
// El RowSpan es el número de publicaciones + la fila de total
|
||||||
|
var totalFilasGrupo = grupoCanilla.Count() + 1;
|
||||||
|
foreach (var item in grupoCanilla.OrderBy(p => p.Publicacion))
|
||||||
|
{
|
||||||
|
if (primeraFila)
|
||||||
|
{
|
||||||
|
table.Cell().RowSpan((uint)totalFilasGrupo).Border(1).Padding(2).AlignTop().Text(item.Canilla);
|
||||||
|
primeraFila = false;
|
||||||
|
}
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida - item.TotalCantEntrada).ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
// Subtotal por canilla
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text("Totales").SemiBold();
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalCantSalida).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalCantEntrada).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalRendir).ToString("C", CultureAr)).SemiBold());
|
||||||
|
}
|
||||||
|
|
||||||
|
var boldStyle = TextStyle.Default.ExtraBold();
|
||||||
|
table.Cell().ColumnSpan(2).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total " + title).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeTablaLiquidacion(IContainer container, string title, IEnumerable<DetalleDistribucionCanillaDto> data)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(4).Text(title).SemiBold().FontSize(11);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(3); columns.RelativeColumn(1.5f);
|
||||||
|
columns.RelativeColumn(3); columns.RelativeColumn(1);
|
||||||
|
columns.RelativeColumn(1); columns.RelativeColumn(1);
|
||||||
|
columns.RelativeColumn(1.2f);
|
||||||
|
});
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Vendedor");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||||
|
});
|
||||||
|
foreach(var item in data.OrderBy(d => d.Canilla).ThenBy(d => d.Fecha))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Canilla);
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Fecha?.ToString("dd/MM/yyyy") ?? "");
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida - item.TotalCantEntrada).ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
var boldStyle = TextStyle.Default.ExtraBold();
|
||||||
|
table.Cell().ColumnSpan(3).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total").Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeTablaTotales(IContainer container, string title, IEnumerable<DetalleDistribucionCanillaAllDto> data)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(4).Text(title).SemiBold().FontSize(11);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2); columns.RelativeColumn(3);
|
||||||
|
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.2f);
|
||||||
|
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.5f);
|
||||||
|
});
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo Vendedor");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||||
|
});
|
||||||
|
foreach(var item in data.OrderBy(d => d.TipoVendedor).ThenBy(d => d.Publicacion))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.TipoVendedor);
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida-item.TotalCantEntrada).ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
var boldStyle = TextStyle.Default.ExtraBold();
|
||||||
|
table.Cell().ColumnSpan(2).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total General").Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeResumenDevoluciones(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5).Column(column => {
|
||||||
|
column.Item().Row(row => {
|
||||||
|
row.Spacing(15);
|
||||||
|
row.AutoItem().Text(text => { text.Span("Remito: ").SemiBold().FontSize(11); text.Span(Model.RemitoIngresado.ToString("N0")).FontSize(11); });
|
||||||
|
row.AutoItem().Text(text => { text.Span("Devolución: ").SemiBold().FontSize(11); text.Span(Model.DevolucionTotal.ToString("N0")).FontSize(11); });
|
||||||
|
row.AutoItem().Text(text => { text.Span("Venta: ").SemiBold().FontSize(11); text.Span(Model.VentaTotal.ToString("N0")).FontSize(11); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class DistribucionCanillasTotalesDocument : IDocument
|
||||||
|
{
|
||||||
|
public DistribucionCanillasViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||||
|
|
||||||
|
public DistribucionCanillasTotalesDocument(DistribucionCanillasViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Row(row => {
|
||||||
|
row.RelativeItem().Text("Listado de Distribución: Canillas / Accionistas (Totales)").FontSize(12);
|
||||||
|
row.RelativeItem().AlignRight().Text(text => {
|
||||||
|
text.Span("Fecha Consultada ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaConsultada).FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
column.Item().PaddingTop(5).Row(row => {
|
||||||
|
row.RelativeItem().Text(text => {
|
||||||
|
text.Span("Fecha de Generación del Reporte ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaReporte).FontSize(12);
|
||||||
|
});
|
||||||
|
row.RelativeItem().AlignRight().Text(text => {
|
||||||
|
text.Span("Empresa ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.Empresa).FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(15);
|
||||||
|
|
||||||
|
if(Model.CanillasTodos.Any())
|
||||||
|
column.Item().Element(ComposeTablaTotales);
|
||||||
|
|
||||||
|
if(Model.RemitoIngresado > 0)
|
||||||
|
column.Item().Element(ComposeResumenDevoluciones);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeTablaTotales(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(4).Text("Recuento de Publicaciones").SemiBold().FontSize(11);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2); columns.RelativeColumn(3);
|
||||||
|
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.2f);
|
||||||
|
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.5f);
|
||||||
|
});
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo Vendedor");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||||
|
});
|
||||||
|
foreach(var item in Model.CanillasTodos.OrderBy(d => d.TipoVendedor).ThenBy(d => d.Publicacion))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.TipoVendedor);
|
||||||
|
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida-item.TotalCantEntrada).ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
var boldStyle = TextStyle.Default.ExtraBold();
|
||||||
|
table.Cell().ColumnSpan(2).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total General").Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeResumenDevoluciones(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(10).Column(column => {
|
||||||
|
column.Item().Row(row => {
|
||||||
|
row.Spacing(15);
|
||||||
|
row.AutoItem().Text(text => { text.Span("Remito: ").SemiBold(); text.Span(Model.RemitoIngresado.ToString("N0")); });
|
||||||
|
row.AutoItem().Text(text => { text.Span("Devolución: ").SemiBold(); text.Span(Model.DevolucionTotal.ToString("N0")); });
|
||||||
|
row.AutoItem().Text(text => { text.Span("Venta: ").SemiBold(); text.Span(Model.VentaTotal.ToString("N0")); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class DistribucionSuscripcionesDocument : IDocument
|
||||||
|
{
|
||||||
|
public DistribucionSuscripcionesViewModel Model { get; }
|
||||||
|
|
||||||
|
public DistribucionSuscripcionesDocument(DistribucionSuscripcionesViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Column(col =>
|
||||||
|
{
|
||||||
|
col.Item().Text("Reporte de Distribución de Suscripciones").SemiBold().FontSize(14);
|
||||||
|
col.Item().Text($"Período: {Model.FechaDesde} al {Model.FechaHasta}").FontSize(11);
|
||||||
|
});
|
||||||
|
row.ConstantItem(150).AlignRight().Text($"Generado: {Model.FechaGeneracion}");
|
||||||
|
});
|
||||||
|
column.Item().PaddingTop(5).BorderBottom(1).BorderColor(Colors.Grey.Lighten2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(10).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(20); // Espacio entre elementos principales (sección de altas y sección de bajas)
|
||||||
|
|
||||||
|
// --- Sección 1: Altas y Activas ---
|
||||||
|
column.Item().Column(colAltas =>
|
||||||
|
{
|
||||||
|
colAltas.Item().Text("Altas y Suscripciones Activas en el Período").Bold().FontSize(14).Underline();
|
||||||
|
colAltas.Item().PaddingBottom(10).Text("Listado de suscriptores que deben recibir entregas en el período seleccionado.");
|
||||||
|
|
||||||
|
if (!Model.DatosAgrupadosAltas.Any())
|
||||||
|
{
|
||||||
|
colAltas.Item().PaddingTop(10).Text("No se encontraron suscripciones activas para este período.").Italic();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var empresa in Model.DatosAgrupadosAltas)
|
||||||
|
{
|
||||||
|
colAltas.Item().Element(c => ComposeTablaEmpresa(c, empresa, esBaja: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- Sección 2: Bajas ---
|
||||||
|
if (Model.DatosAgrupadosBajas.Any())
|
||||||
|
{
|
||||||
|
column.Item().PageBreak(); // Salto de página para separar las secciones
|
||||||
|
column.Item().Column(colBajas =>
|
||||||
|
{
|
||||||
|
colBajas.Item().Text("Bajas de Suscripciones en el Período").Bold().FontSize(14).Underline().FontColor(Colors.Red.Medium);
|
||||||
|
colBajas.Item().PaddingBottom(10).Text("Listado de suscriptores cuya suscripción finalizó. NO se les debe entregar a partir de su 'Fecha de Baja'.");
|
||||||
|
|
||||||
|
foreach (var empresa in Model.DatosAgrupadosBajas)
|
||||||
|
{
|
||||||
|
colBajas.Item().Element(c => ComposeTablaEmpresa(c, empresa, esBaja: true));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeTablaEmpresa(IContainer container, GrupoEmpresa empresa, bool esBaja)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
// Cabecera de la EMPRESA (ej. EL DIA)
|
||||||
|
column.Item().Background(Colors.Grey.Lighten2).Padding(5).Text(empresa.NombreEmpresa).Bold().FontSize(12);
|
||||||
|
|
||||||
|
// Contenedor para las tablas de las publicaciones de esta empresa
|
||||||
|
column.Item().PaddingTop(5).Column(colPub =>
|
||||||
|
{
|
||||||
|
colPub.Spacing(10); // Espacio entre cada tabla de publicación
|
||||||
|
foreach (var publicacion in empresa.Publicaciones)
|
||||||
|
{
|
||||||
|
colPub.Item().Element(c => ComposeTablaPublicacion(c, publicacion, esBaja));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeTablaPublicacion(IContainer container, GrupoPublicacion publicacion, bool esBaja)
|
||||||
|
{
|
||||||
|
// Se envuelve la tabla en una columna para poder ponerle un título simple arriba.
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingLeft(2).PaddingBottom(2).Text(publicacion.NombrePublicacion).SemiBold().FontSize(10);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2.5f); // Nombre
|
||||||
|
columns.RelativeColumn(3); // Dirección
|
||||||
|
columns.RelativeColumn(1.5f); // Teléfono
|
||||||
|
columns.ConstantColumn(65); // Fecha Inicio / Baja
|
||||||
|
columns.RelativeColumn(1.5f); // Días
|
||||||
|
columns.RelativeColumn(2.5f); // Observaciones
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().BorderBottom(1).Padding(2).Text("Suscriptor").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).Padding(2).Text("Dirección").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).Padding(2).Text("Teléfono").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).Padding(2).Text(esBaja ? "Fecha de Baja" : "Fecha Inicio").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).Padding(2).Text("Días Entrega").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).Padding(2).Text("Observaciones").SemiBold();
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in publicacion.Suscripciones)
|
||||||
|
{
|
||||||
|
table.Cell().Padding(2).Text(item.NombreSuscriptor);
|
||||||
|
table.Cell().Padding(2).Text(item.Direccion);
|
||||||
|
table.Cell().Padding(2).Text(item.Telefono ?? "-");
|
||||||
|
var fecha = esBaja ? item.FechaFin : item.FechaInicio;
|
||||||
|
table.Cell().Padding(2).Text(fecha?.ToString("dd/MM/yyyy") ?? "-");
|
||||||
|
table.Cell().Padding(2).Text(item.DiasEntrega);
|
||||||
|
table.Cell().Padding(2).Text(item.Observaciones ?? "-");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ExistenciaPapelConsolidadoDocument : IDocument
|
||||||
|
{
|
||||||
|
public ExistenciaPapelConsolidadoViewModel Model { get; }
|
||||||
|
|
||||||
|
public ExistenciaPapelConsolidadoDocument(ExistenciaPapelConsolidadoViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.PageColor(Colors.White);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
|
||||||
|
page.Footer()
|
||||||
|
.AlignCenter()
|
||||||
|
.Text(x =>
|
||||||
|
{
|
||||||
|
x.Span("Página ");
|
||||||
|
x.CurrentPageNumber();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Existencias de Papel").SemiBold().FontSize(14);
|
||||||
|
// La versión consolidada no muestra la planta, sino el texto "Consolidado"
|
||||||
|
column.Item().AlignCenter().Text("Consolidado").FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Column(col =>
|
||||||
|
{
|
||||||
|
col.Item().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha del Reporte: ").SemiBold();
|
||||||
|
text.Span(Model.FechaReporte);
|
||||||
|
});
|
||||||
|
col.Item().Text($"Periodo Consultado: Desde {Model.FechaDesde} Hasta {Model.FechaHasta}");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.ConstantColumn(65);
|
||||||
|
columns.ConstantColumn(70);
|
||||||
|
columns.ConstantColumn(85);
|
||||||
|
columns.ConstantColumn(65);
|
||||||
|
columns.ConstantColumn(80);
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Tipo de Bobina");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Stock");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Kg. Stock");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Consumo (Kg)");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Días Disp.");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Fin Estimado");
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Existencias)
|
||||||
|
{
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.TipoBobina);
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.BobinasEnStock?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.TotalKilosEnStock?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.ConsumoAcumulado?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.PromedioDiasDisponibles?.ToString("N0") ?? "N/A");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignCenter().Text(item.FechaEstimacionFinStock?.ToString("dd/MM/yyyy") ?? "N/A");
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalBobinas = Model.Existencias.Sum(e => e.BobinasEnStock ?? 0);
|
||||||
|
var totalKilos = Model.Existencias.Sum(e => e.TotalKilosEnStock ?? 0);
|
||||||
|
var totalConsumo = Model.Existencias.Sum(e => e.ConsumoAcumulado ?? 0);
|
||||||
|
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span("Totales").SemiBold());
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalBobinas.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalKilos.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalConsumo.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().ColumnSpan(2).BorderTop(1).BorderColor(Colors.Grey.Lighten2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
// Usamos una clase parcial para organizar mejor el código, aunque no es estrictamente necesario aquí.
|
||||||
|
public class ExistenciaPapelDocument : IDocument
|
||||||
|
{
|
||||||
|
// Usamos una propiedad pública con 'init' en lugar de un campo privado.
|
||||||
|
// Esto es más limpio y funciona mejor con el análisis de código.
|
||||||
|
public ExistenciaPapelViewModel Model { get; }
|
||||||
|
|
||||||
|
public ExistenciaPapelDocument(ExistenciaPapelViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.PageColor(Colors.White);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
|
||||||
|
page.Footer()
|
||||||
|
.AlignCenter()
|
||||||
|
.Text(x =>
|
||||||
|
{
|
||||||
|
x.Span("Página ");
|
||||||
|
x.CurrentPageNumber();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ahora los métodos usan 'Model' (la propiedad pública) en lugar de '_model'.
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Existencias de Papel").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text($"Planta: {Model.NombrePlanta}").FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Column(col =>
|
||||||
|
{
|
||||||
|
col.Item().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha del Reporte: ").SemiBold();
|
||||||
|
text.Span(Model.FechaReporte);
|
||||||
|
});
|
||||||
|
col.Item().Text($"Periodo Consultado: Desde {Model.FechaDesde} Hasta {Model.FechaHasta}");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.ConstantColumn(65);
|
||||||
|
columns.ConstantColumn(70);
|
||||||
|
columns.ConstantColumn(85);
|
||||||
|
columns.ConstantColumn(65);
|
||||||
|
columns.ConstantColumn(80);
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Tipo de Bobina");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Stock");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Kg. Stock");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Consumo (Kg)");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Días Disp.");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Fin Estimado");
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Existencias)
|
||||||
|
{
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.TipoBobina);
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.BobinasEnStock?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.TotalKilosEnStock?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.ConsumoAcumulado?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.PromedioDiasDisponibles?.ToString("N0") ?? "N/A");
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignCenter().Text(item.FechaEstimacionFinStock?.ToString("dd/MM/yyyy") ?? "N/A");
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalBobinas = Model.Existencias.Sum(e => e.BobinasEnStock ?? 0);
|
||||||
|
var totalKilos = Model.Existencias.Sum(e => e.TotalKilosEnStock ?? 0);
|
||||||
|
var totalConsumo = Model.Existencias.Sum(e => e.ConsumoAcumulado ?? 0);
|
||||||
|
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span("Totales").SemiBold());
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalBobinas.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalKilos.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalConsumo.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().ColumnSpan(2).BorderTop(1).BorderColor(Colors.Grey.Lighten2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class FacturasPublicidadDocument : IDocument
|
||||||
|
{
|
||||||
|
public FacturasPublicidadViewModel Model { get; }
|
||||||
|
|
||||||
|
public FacturasPublicidadDocument(FacturasPublicidadViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
// Se envuelve todo el contenido del header en una única Columna.
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
// El primer item de la columna es la fila con los títulos.
|
||||||
|
column.Item().Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Column(col =>
|
||||||
|
{
|
||||||
|
col.Item().Text($"Reporte de Suscripciones a Facturar").SemiBold().FontSize(14);
|
||||||
|
col.Item().Text($"Período: {Model.Periodo}").FontSize(11);
|
||||||
|
});
|
||||||
|
|
||||||
|
row.ConstantItem(150).AlignRight().Column(col => {
|
||||||
|
col.Item().AlignRight().Text($"Fecha de Generación:");
|
||||||
|
col.Item().AlignRight().Text(Model.FechaGeneracion);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// El segundo item de la columna es el separador.
|
||||||
|
column.Item().PaddingTop(5).BorderBottom(1).BorderColor(Colors.Grey.Lighten2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(10).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(20);
|
||||||
|
|
||||||
|
foreach (var empresaData in Model.DatosPorEmpresa)
|
||||||
|
{
|
||||||
|
column.Item().Element(c => ComposeTablaPorEmpresa(c, empresaData));
|
||||||
|
}
|
||||||
|
|
||||||
|
column.Item().AlignRight().PaddingTop(15).Text($"Total General a Facturar: {Model.TotalGeneral.ToString("C", new CultureInfo("es-AR"))}").Bold().FontSize(12);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeTablaPorEmpresa(IContainer container, DatosEmpresaViewModel empresaData)
|
||||||
|
{
|
||||||
|
container.Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(3); // Nombre Suscriptor
|
||||||
|
columns.ConstantColumn(100); // Documento
|
||||||
|
columns.ConstantColumn(100, Unit.Point); // Importe
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().ColumnSpan(3).Background(Colors.Grey.Lighten2)
|
||||||
|
.Padding(5).Text(empresaData.NombreEmpresa).Bold().FontSize(12);
|
||||||
|
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten3).Padding(2).Text("Suscriptor").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten3).Padding(2).Text("Documento").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Importe a Facturar").SemiBold();
|
||||||
|
});
|
||||||
|
|
||||||
|
var facturasPorSuscriptor = empresaData.Facturas.GroupBy(f => f.NombreSuscriptor);
|
||||||
|
|
||||||
|
foreach (var grupoSuscriptor in facturasPorSuscriptor.OrderBy(g => g.Key))
|
||||||
|
{
|
||||||
|
foreach(var item in grupoSuscriptor)
|
||||||
|
{
|
||||||
|
table.Cell().Padding(2).Text(item.NombreSuscriptor);
|
||||||
|
table.Cell().Padding(2).Text($"{item.TipoDocumento} {item.NroDocumento}");
|
||||||
|
table.Cell().Padding(2).AlignRight().Text(item.ImporteFinal.ToString("C", new CultureInfo("es-AR")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(grupoSuscriptor.Count() > 1)
|
||||||
|
{
|
||||||
|
var subtotal = grupoSuscriptor.Sum(i => i.ImporteFinal);
|
||||||
|
table.Cell().ColumnSpan(2).AlignRight().Padding(2).Text($"Subtotal {grupoSuscriptor.Key}:").Italic();
|
||||||
|
table.Cell().AlignRight().Padding(2).Text(subtotal.ToString("C", new CultureInfo("es-AR"))).Italic().SemiBold();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(2).BorderTop(1).BorderColor(Colors.Grey.Darken1).AlignRight()
|
||||||
|
.PaddingTop(5).Text("Total Empresa:").Bold();
|
||||||
|
table.Cell().BorderTop(1).BorderColor(Colors.Grey.Darken1).AlignRight()
|
||||||
|
.PaddingTop(5).Text(empresaData.TotalEmpresa.ToString("C", new CultureInfo("es-AR"))).Bold();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class LiquidacionCanillaDocument : IDocument
|
||||||
|
{
|
||||||
|
public LiquidacionCanillaViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||||
|
|
||||||
|
public LiquidacionCanillaDocument(LiquidacionCanillaViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Size(PageSizes.A4);
|
||||||
|
page.Margin(5, Unit.Millimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
|
||||||
|
page.Content().Column(mainColumn =>
|
||||||
|
{
|
||||||
|
mainColumn.Item()
|
||||||
|
.AlignCenter()
|
||||||
|
.Width(PageSizes.A6.Width)
|
||||||
|
.Height(PageSizes.A6.Height)
|
||||||
|
.Column(a6ContentColumn =>
|
||||||
|
{
|
||||||
|
a6ContentColumn.Item().PaddingRight(10, Unit.Millimetre).PaddingLeft(10, Unit.Millimetre).Column(content =>
|
||||||
|
{
|
||||||
|
content.Item().Element(ComposeHeader);
|
||||||
|
content.Item().Element(ComposeContent);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Text("EL DIA S.A.I.C. y F.");
|
||||||
|
column.Item().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Liquidación venta de diarios del: ");
|
||||||
|
text.Span(Model.FechaLiquidacion);
|
||||||
|
});
|
||||||
|
column.Item().PaddingTop(5).Text($"Vendedor: {Model.NombreVendedor}").SemiBold();
|
||||||
|
column.Item().PaddingTop(10);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(15);
|
||||||
|
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
columns.RelativeColumn(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Detalles.OrderBy(d => d.Publicacion))
|
||||||
|
{
|
||||||
|
var vendidos = item.TotalCantSalida - item.TotalCantEntrada;
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(3).Text(item.Publicacion).SemiBold();
|
||||||
|
|
||||||
|
table.Cell();
|
||||||
|
table.Cell().Text("Retirados");
|
||||||
|
table.Cell().AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||||
|
|
||||||
|
table.Cell();
|
||||||
|
table.Cell().Text("Devueltos");
|
||||||
|
table.Cell().AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||||
|
|
||||||
|
table.Cell();
|
||||||
|
table.Cell().Text("Vendidos");
|
||||||
|
table.Cell().AlignRight().Text(vendidos.ToString("N0"));
|
||||||
|
|
||||||
|
table.Cell();
|
||||||
|
table.Cell().Text("Precio Unitario");
|
||||||
|
table.Cell().AlignRight().Text(item.PrecioEjemplar.ToString("C", CultureAr));
|
||||||
|
|
||||||
|
table.Cell();
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(2).Text(t => t.Span("Importe Vendido").SemiBold());
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(2).AlignRight().Text(t => t.Span(item.TotalRendir.ToString("C", CultureAr)).SemiBold());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
column.Item().BorderTop(2).BorderColor(Colors.Black).PaddingTop(4).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text("Total A Rendir").SemiBold().FontSize(10);
|
||||||
|
row.RelativeItem().AlignRight().Text(text => text.Span(Model.TotalARendir.ToString("C", CultureAr)).SemiBold().FontSize(10));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!Model.EsAccionista && Model.Ganancias.Any())
|
||||||
|
{
|
||||||
|
column.Item().PaddingTop(10).Element(ComposeGananciasTable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeGananciasTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Text("Comisiones Acreditadas").SemiBold().FontSize(11);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2);
|
||||||
|
columns.RelativeColumn(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Ganancias)
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Lighten2).Padding(3).Text(item.Publicacion);
|
||||||
|
table.Cell().Border(1).BorderColor(Colors.Grey.Lighten2).Padding(3).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).Text("Total Comisiones").SemiBold();
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text(t => t.Span(Model.TotalComisiones.ToString("C", CultureAr)).SemiBold());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ListadoDistCanMensualDiariosDocument : IDocument
|
||||||
|
{
|
||||||
|
public ListadoDistCanMensualDiariosViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||||
|
|
||||||
|
public ListadoDistCanMensualDiariosDocument(ListadoDistCanMensualDiariosViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text($"Ventas por {Model.TipoDestinatario} desde el {Model.FechaDesde} hasta el {Model.FechaHasta}").SemiBold().FontSize(12);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
// APLICAMOS LA SOLUCIÓN AQUÍ: .AlignTop()
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).AlignTop().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(3); // Nombre
|
||||||
|
columns.ConstantColumn(50); // El Día
|
||||||
|
columns.ConstantColumn(50); // El Plata
|
||||||
|
columns.ConstantColumn(60); // Vendidos
|
||||||
|
columns.RelativeColumn(1.5f); // Imp. El Día
|
||||||
|
columns.RelativeColumn(1.5f); // Imp. El Plata
|
||||||
|
columns.RelativeColumn(1.5f); // Importe Total
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).Text("Nombre").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignCenter().Text("El Día").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignCenter().Text("El Plata").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignCenter().Text("Vendidos").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignRight().Text("Imp. El Día").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignRight().Text("Imp. El Plata").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignRight().Text("Importe Total").SemiBold();
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Detalles.OrderBy(d => d.Canilla))
|
||||||
|
{
|
||||||
|
table.Cell().Padding(3).PaddingRight(10).Text(item.Canilla);
|
||||||
|
table.Cell().Padding(3).AlignCenter().Text(item.ElDia?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Padding(3).AlignCenter().Text(item.ElPlata?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Padding(3).AlignCenter().Text(item.Vendidos?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Padding(3).AlignRight().Text(item.ImporteElDia?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||||
|
table.Cell().Padding(3).AlignRight().Text(item.ImporteElPlata?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||||
|
table.Cell().Padding(3).AlignRight().Text(item.ImporteTotal?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de Totales
|
||||||
|
var totalElDia = Model.Detalles.Sum(x => x.ElDia ?? 0);
|
||||||
|
var totalElPlata = Model.Detalles.Sum(x => x.ElPlata ?? 0);
|
||||||
|
var totalVendidos = Model.Detalles.Sum(x => x.Vendidos ?? 0);
|
||||||
|
var totalImpElDia = Model.Detalles.Sum(x => x.ImporteElDia ?? 0);
|
||||||
|
var totalImpElPlata = Model.Detalles.Sum(x => x.ImporteElPlata ?? 0);
|
||||||
|
var totalImpTotal = Model.Detalles.Sum(x => x.ImporteTotal ?? 0);
|
||||||
|
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).Text("Totales").SemiBold();
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignCenter().Text(t => t.Span(totalElDia.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignCenter().Text(t => t.Span(totalElPlata.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignCenter().Text(t => t.Span(totalVendidos.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignRight().Text(t => t.Span(totalImpElDia.ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignRight().Text(t => t.Span(totalImpElPlata.ToString("C", CultureAr)).SemiBold());
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignRight().Text(t => t.Span(totalImpTotal.ToString("C", CultureAr)).SemiBold());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ListadoDistCanMensualDocument : IDocument
|
||||||
|
{
|
||||||
|
public ListadoDistCanMensualViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||||
|
|
||||||
|
public ListadoDistCanMensualDocument(ListadoDistCanMensualViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1.5f, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("Listado de Distribución Mensual").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text(Model.TipoDestinatario).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(10);
|
||||||
|
|
||||||
|
// Agrupamos los datos por Canilla
|
||||||
|
var gruposPorCanilla = Model.Detalles.GroupBy(d => d.Canilla);
|
||||||
|
|
||||||
|
// Creamos una tabla principal que contendrá todo
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2.5f); // Canilla / Publicación
|
||||||
|
columns.RelativeColumn(); // Llevados
|
||||||
|
columns.RelativeColumn(); // Devueltos
|
||||||
|
columns.RelativeColumn(1.2f); // Importe
|
||||||
|
});
|
||||||
|
|
||||||
|
// Encabezado principal de la tabla
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).Text("Canilla / Publicación").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Llevados").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Devueltos").SemiBold();
|
||||||
|
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Importe").SemiBold();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Iteramos sobre cada grupo de canilla
|
||||||
|
foreach (var grupo in gruposPorCanilla)
|
||||||
|
{
|
||||||
|
// Fila del nombre del Canilla
|
||||||
|
table.Cell().ColumnSpan(4).PaddingTop(8).Text(grupo.Key).SemiBold();
|
||||||
|
|
||||||
|
// Filas de detalle para ese canilla
|
||||||
|
foreach (var detalle in grupo)
|
||||||
|
{
|
||||||
|
table.Cell().PaddingLeft(15).Padding(2).Text(detalle.Publicacion);
|
||||||
|
table.Cell().Padding(2).AlignRight().Text(detalle.TotalCantSalida?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Padding(2).AlignRight().Text(detalle.TotalCantEntrada?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Padding(2).AlignRight().Text(detalle.TotalRendir?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de total por canilla
|
||||||
|
var totalRendirCanilla = grupo.Sum(d => d.TotalRendir ?? 0);
|
||||||
|
table.Cell().ColumnSpan(3).BorderTop(1.5f).BorderColor(Colors.Black).AlignRight().Padding(2).Text("A Rendir").SemiBold();
|
||||||
|
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).AlignRight().Padding(2).Text(t => t.Span(totalRendirCanilla.ToString("C", CultureAr)).SemiBold());
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Fila de TOTALES GENERALES ---
|
||||||
|
var totalGeneralLlevados = Model.Detalles.Sum(d => d.TotalCantSalida ?? 0);
|
||||||
|
var totalGeneralDevueltos = Model.Detalles.Sum(d => d.TotalCantEntrada ?? 0);
|
||||||
|
var totalGeneralRendir = Model.Detalles.Sum(d => d.TotalRendir ?? 0);
|
||||||
|
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).Text("TOTALES").ExtraBold();
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralLlevados.ToString("N0")).ExtraBold());
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralDevueltos.ToString("N0")).ExtraBold());
|
||||||
|
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralRendir.ToString("C", CultureAr)).ExtraBold());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ListadoDistCanillasImporteDocument : IDocument
|
||||||
|
{
|
||||||
|
public ListadoDistCanillasImporteViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||||
|
|
||||||
|
public ListadoDistCanillasImporteDocument(ListadoDistCanillasImporteViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1.5f, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("Listado de Distribución con Importes").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text(Model.TipoDestinatario).FontSize(12);
|
||||||
|
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(); // Fecha
|
||||||
|
columns.RelativeColumn(); // Llevados
|
||||||
|
columns.RelativeColumn(); // Devueltos
|
||||||
|
columns.RelativeColumn(); // Vendidos
|
||||||
|
columns.RelativeColumn(1.5f); // Importe Publicación
|
||||||
|
columns.RelativeColumn(1.5f); // A Rendir
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Fecha");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Vendidos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Imp. Publicación");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("A Rendir");
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Detalles)
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Fecha);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Llevados.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Devueltos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Vendidos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalRendirPublicacion.ToString("C", CultureAr));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalRendirGeneral.ToString("C", CultureAr));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de Totales
|
||||||
|
var totalLlevados = Model.Detalles.Sum(x => x.Llevados);
|
||||||
|
var totalDevueltos = Model.Detalles.Sum(x => x.Devueltos);
|
||||||
|
var totalVendidos = Model.Detalles.Sum(x => x.Vendidos);
|
||||||
|
var totalRendirPub = Model.Detalles.Sum(x => x.TotalRendirPublicacion);
|
||||||
|
var totalRendirGral = Model.Detalles.Sum(x => x.TotalRendirGeneral);
|
||||||
|
|
||||||
|
var boldStyle = TextStyle.Default.SemiBold();
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3); // Celda vacía
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalLlevados.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalDevueltos.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalVendidos.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalRendirPub.ToString("C", CultureAr)).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalRendirGral.ToString("C", CultureAr)).Style(boldStyle));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ListadoDistribucionCanillasDocument : IDocument
|
||||||
|
{
|
||||||
|
public ListadoDistribucionCanillasViewModel Model { get; }
|
||||||
|
|
||||||
|
public ListadoDistribucionCanillasDocument(ListadoDistribucionCanillasViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("Listado de Distribución - Canillitas").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(8, Unit.Millimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(15);
|
||||||
|
|
||||||
|
column.Item().Text("Distribución").SemiBold().FontSize(12);
|
||||||
|
column.Item().Element(ComposeDetalleDiarioTable);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre);
|
||||||
|
|
||||||
|
column.Item().Text("Promedios").SemiBold().FontSize(12);
|
||||||
|
column.Item().Element(ComposePromediosTable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeDetalleDiarioTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(50); // Día
|
||||||
|
columns.RelativeColumn(); // Llevados
|
||||||
|
columns.RelativeColumn(); // Devueltos
|
||||||
|
columns.RelativeColumn(); // Venta Neta
|
||||||
|
columns.RelativeColumn(2); // Promedio (columna vacía en el original)
|
||||||
|
columns.RelativeColumn(2); // % Devolución
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Venta Neta");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Promedio");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||||
|
});
|
||||||
|
|
||||||
|
decimal ventaNetaAcumulada = 0;
|
||||||
|
int conteoDias = 0;
|
||||||
|
|
||||||
|
foreach (var item in Model.DetalleDiario.OrderBy(x => x.Dia))
|
||||||
|
{
|
||||||
|
var ventaNetaDia = item.Llevados - item.Devueltos;
|
||||||
|
ventaNetaAcumulada += ventaNetaDia;
|
||||||
|
conteoDias++;
|
||||||
|
var promedio = ventaNetaAcumulada / conteoDias;
|
||||||
|
var porcDevolucion = item.Llevados > 0 ? (decimal)item.Devueltos * 100 / item.Llevados : 0;
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Dia.ToString());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Llevados.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Devueltos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(ventaNetaDia.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(promedio.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalVentaNeta = Model.TotalesDetalleDiario.Llevados - Model.TotalesDetalleDiario.Devueltos;
|
||||||
|
var totalPorcDevolucion = Model.TotalesDetalleDiario.Llevados > 0 ? (decimal)Model.TotalesDetalleDiario.Devueltos * 100 / Model.TotalesDetalleDiario.Llevados : 0;
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3); // Celda vacía
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.TotalesDetalleDiario.Llevados.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.TotalesDetalleDiario.Devueltos.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalVentaNeta.ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span((ventaNetaAcumulada / (conteoDias > 0 ? conteoDias : 1)).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalPorcDevolucion.ToString("F2")).SemiBold());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposePromediosTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingBottom(5).Text("Promedios por Día de Semana").SemiBold().FontSize(11);
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(1.5f);
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn(1.2f);
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día Semana");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Días");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Ventas");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||||
|
});
|
||||||
|
|
||||||
|
var dayOrder = new Dictionary<string, int> { { "Lunes", 1 }, { "Martes", 2 }, { "Miércoles", 3 }, { "Jueves", 4 }, { "Viernes", 5 }, { "Sábado", 6 }, { "Domingo", 7 } };
|
||||||
|
|
||||||
|
foreach (var item in Model.PromediosPorDia.OrderBy(d => dayOrder.GetValueOrDefault(d.Dia, 99)))
|
||||||
|
{
|
||||||
|
var porcDevolucion = item.Promedio_Llevados > 0 ? (decimal)item.Promedio_Devueltos * 100 / item.Promedio_Llevados : 0;
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Dia);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Cant.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Llevados.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Devueltos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Ventas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2") + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- SECCIÓN AÑADIDA PARA LA FILA "GENERAL" ---
|
||||||
|
var general = Model.PromedioGeneral;
|
||||||
|
if (general != null)
|
||||||
|
{
|
||||||
|
var boldStyle = TextStyle.Default.SemiBold();
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3).Text(text => text.Span(general.Dia).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Cant.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Promedio_Llevados.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Promedio_Devueltos.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Promedio_Ventas.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.PorcentajeDevolucionGeneral.ToString("F2") + "%").Style(boldStyle));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ListadoDistribucionDistribuidoresDocument : IDocument
|
||||||
|
{
|
||||||
|
public ListadoDistribucionDistribuidoresViewModel Model { get; }
|
||||||
|
|
||||||
|
public ListadoDistribucionDistribuidoresDocument(ListadoDistribucionDistribuidoresViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("Listado de Distribución").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text(Model.NombreDistribuidor).FontSize(12);
|
||||||
|
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(11);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(8, Unit.Millimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(15);
|
||||||
|
column.Item().Text("Distribución").SemiBold().FontSize(12);
|
||||||
|
column.Item().Element(ComposeDetalleDiarioTable);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre);
|
||||||
|
|
||||||
|
column.Item().Text("Promedios").SemiBold().FontSize(12);
|
||||||
|
column.Item().Element(ComposePromediosTable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeDetalleDiarioTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(50); columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn(); columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn(2); columns.RelativeColumn(2);
|
||||||
|
});
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Venta Neta");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Promedio");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||||
|
});
|
||||||
|
|
||||||
|
decimal ventaNetaAcumulada = 0;
|
||||||
|
int conteoDias = 0;
|
||||||
|
|
||||||
|
foreach (var item in Model.DetalleDiario.OrderBy(x => x.Dia))
|
||||||
|
{
|
||||||
|
var llevados = item.Llevados ?? 0;
|
||||||
|
var devueltos = item.Devueltos ?? 0;
|
||||||
|
var ventaNetaDia = llevados - devueltos;
|
||||||
|
if (llevados > 0)
|
||||||
|
{
|
||||||
|
ventaNetaAcumulada += ventaNetaDia;
|
||||||
|
conteoDias++;
|
||||||
|
}
|
||||||
|
var promedio = conteoDias > 0 ? ventaNetaAcumulada / conteoDias : 0;
|
||||||
|
var porcDevolucion = llevados > 0 ? (decimal)devueltos * 100 / llevados : 0;
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Dia.ToString());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(llevados.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(devueltos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(ventaNetaDia.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(promedio.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2") + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalLlevados = Model.DetalleDiario.Sum(i => i.Llevados ?? 0);
|
||||||
|
var totalDevueltos = Model.DetalleDiario.Sum(i => i.Devueltos ?? 0);
|
||||||
|
var totalVentaNeta = totalLlevados - totalDevueltos;
|
||||||
|
var totalPorcDevolucion = totalLlevados > 0 ? (decimal)totalDevueltos * 100 / totalLlevados : 0;
|
||||||
|
|
||||||
|
var boldStyle = TextStyle.Default.SemiBold();
|
||||||
|
table.Cell().Border(1).Padding(3);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalLlevados.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalDevueltos.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalVentaNeta.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span((ventaNetaAcumulada / (conteoDias > 0 ? conteoDias : 1)).ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalPorcDevolucion.ToString("F2") + "%").Style(boldStyle));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposePromediosTable(IContainer container)
|
||||||
|
{
|
||||||
|
var dayOrder = new Dictionary<string, int> { { "Lunes", 1 }, { "Martes", 2 }, { "Miércoles", 3 }, { "Jueves", 4 }, { "Viernes", 5 }, { "Sábado", 6 }, { "Domingo", 7 } };
|
||||||
|
|
||||||
|
container.Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(1.5f); columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn(); columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn(); columns.RelativeColumn(1.2f);
|
||||||
|
});
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Días");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Ventas");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||||
|
});
|
||||||
|
foreach (var item in Model.PromediosPorDia.Where(p => p.Dia != "General").OrderBy(d => dayOrder.GetValueOrDefault(d.Dia, 99)))
|
||||||
|
{
|
||||||
|
var llevados = item.Promedio_Llevados ?? 0;
|
||||||
|
var devueltos = item.Promedio_Devueltos ?? 0;
|
||||||
|
var porcDevolucion = llevados > 0 ? (decimal)devueltos * 100 / llevados : 0;
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Dia);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Cant?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(llevados.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(devueltos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Ventas?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2") + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FILA GENERAL ---
|
||||||
|
var general = Model.PromedioGeneral;
|
||||||
|
if (general != null)
|
||||||
|
{
|
||||||
|
var boldStyle = TextStyle.Default.SemiBold();
|
||||||
|
var avgPercentage = Model.PromediosPorDia
|
||||||
|
.Where(p => p.Dia != "General" && (p.Promedio_Llevados ?? 0) > 0)
|
||||||
|
.Average(p => (decimal)(p.Promedio_Devueltos ?? 0) * 100 / (p.Promedio_Llevados ?? 1));
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3).Text(t => t.Span(general.Dia).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Cant?.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Promedio_Llevados?.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Promedio_Devueltos?.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Promedio_Ventas?.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(avgPercentage.ToString("F2") + "%").Style(boldStyle));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class ListadoDistribucionGeneralDocument : IDocument
|
||||||
|
{
|
||||||
|
public ListadoDistribucionGeneralViewModel Model { get; }
|
||||||
|
|
||||||
|
public ListadoDistribucionGeneralDocument(ListadoDistribucionGeneralViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("Listado de Distribución General Mensual").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(1, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Mes Consultado: ").SemiBold(); text.Span(Model.MesConsultado); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Millimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(20);
|
||||||
|
|
||||||
|
if (Model.ResumenMensual.Any())
|
||||||
|
{
|
||||||
|
column.Item().Element(ComposeResumenTable);
|
||||||
|
}
|
||||||
|
if (Model.PromediosPorDia.Any())
|
||||||
|
{
|
||||||
|
column.Item().Element(ComposePromediosTable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeResumenTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(60);
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Tirada");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Sin Cargo");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Perdidos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Vendidos");
|
||||||
|
});
|
||||||
|
|
||||||
|
var dayAbbreviations = new Dictionary<System.DayOfWeek, string>
|
||||||
|
{
|
||||||
|
{ System.DayOfWeek.Sunday, "Dom" },
|
||||||
|
{ System.DayOfWeek.Monday, "Lun" },
|
||||||
|
{ System.DayOfWeek.Tuesday, "Mar" },
|
||||||
|
{ System.DayOfWeek.Wednesday, "Mie" },
|
||||||
|
{ System.DayOfWeek.Thursday, "Jue" },
|
||||||
|
{ System.DayOfWeek.Friday, "Vie" },
|
||||||
|
{ System.DayOfWeek.Saturday, "Sab" }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var item in Model.ResumenMensual.OrderBy(x => x.Fecha))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(3).Text($"{dayAbbreviations[item.Fecha.DayOfWeek]} {item.Fecha.Day}");
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.CantidadTirada.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.SinCargo.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Perdidos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Llevados.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Devueltos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Vendidos.ToString("N0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(3);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.CantidadTirada).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.SinCargo).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Perdidos).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Llevados).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Devueltos).ToString("N0")).SemiBold());
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Vendidos).ToString("N0")).SemiBold());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposePromediosTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
// --- TÍTULO DE LA TABLA DE PROMEDIOS ---
|
||||||
|
column.Item().PaddingBottom(5).AlignCenter().Text("Promedios Diarios de Distribución").SemiBold();
|
||||||
|
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(1.2f);
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
columns.RelativeColumn();
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Días");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Tirada");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Sin Cargo");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Perdidos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Vendidos");
|
||||||
|
});
|
||||||
|
|
||||||
|
var dayOrder = new Dictionary<string, int> { { "Lunes", 1 }, { "Martes", 2 }, { "Miércoles", 3 }, { "Jueves", 4 }, { "Viernes", 5 }, { "Sábado", 6 }, { "Domingo", 7 } };
|
||||||
|
|
||||||
|
// Mostramos los promedios por día de la semana
|
||||||
|
foreach (var item in Model.PromediosPorDia.OrderBy(d => dayOrder.GetValueOrDefault(d.Dia, 99)))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Dia);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.CantidadDias.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioTirada.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioSinCargo.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioPerdidos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioLlevados.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioDevueltos.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioVendidos.ToString("N0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- FILA GENERAL CON DATOS CALCULADOS DEL VIEWMODEL ---
|
||||||
|
var general = Model.PromedioGeneral;
|
||||||
|
if (general != null)
|
||||||
|
{
|
||||||
|
var boldStyle = TextStyle.Default.SemiBold();
|
||||||
|
table.Cell().Border(1).Padding(3).Text(text => text.Span(general.Dia).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.CantidadDias.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioTirada.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioSinCargo.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioPerdidos.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioLlevados.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioDevueltos.ToString("N0")).Style(boldStyle));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioVendidos.ToString("N0")).Style(boldStyle));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class MovimientoBobinasDocument : IDocument
|
||||||
|
{
|
||||||
|
public MovimientoBobinasViewModel Model { get; }
|
||||||
|
|
||||||
|
public MovimientoBobinasDocument(MovimientoBobinasViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Page(page =>
|
||||||
|
{
|
||||||
|
// Configuramos la página en modo apaisado (landscape)
|
||||||
|
page.Size(PageSizes.A4.Landscape());
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(9)); // Un poco más pequeño por la cantidad de columnas
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
|
||||||
|
page.Footer()
|
||||||
|
.AlignCenter()
|
||||||
|
.Text(x =>
|
||||||
|
{
|
||||||
|
x.Span("Página ");
|
||||||
|
x.CurrentPageNumber();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Movimiento de Bobinas").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text($"Planta: {Model.NombrePlanta}").FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Column(col =>
|
||||||
|
{
|
||||||
|
col.Item().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha del Reporte: ").SemiBold();
|
||||||
|
text.Span(Model.FechaReporte);
|
||||||
|
});
|
||||||
|
col.Item().Text($"Periodo Consultado: Desde {Model.FechaDesde} Hasta {Model.FechaHasta}");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||||
|
{
|
||||||
|
// Definimos 11 columnas. Usamos una combinación de relativas y constantes
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2.5f); // Tipo
|
||||||
|
columns.ConstantColumn(50); // Cant. Inicial
|
||||||
|
columns.ConstantColumn(60); // Kg Iniciales
|
||||||
|
columns.ConstantColumn(50); // Compradas
|
||||||
|
columns.ConstantColumn(60); // Kg Comprados
|
||||||
|
columns.ConstantColumn(50); // Consumidas
|
||||||
|
columns.ConstantColumn(60); // Kg Consumidos
|
||||||
|
columns.ConstantColumn(50); // Dañadas
|
||||||
|
columns.ConstantColumn(60); // Kg Dañados
|
||||||
|
columns.ConstantColumn(50); // Cant. Final
|
||||||
|
columns.ConstantColumn(60); // Kg Final
|
||||||
|
});
|
||||||
|
|
||||||
|
// Encabezado de la tabla
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
// Celda por celda para control total
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Cant. Inicial");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Inicial");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Compradas");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Comprados");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Consumidas");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Consumidos");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Dañadas");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Dañados");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Cant. Final");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Final");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filas de datos
|
||||||
|
foreach (var item in Model.Movimientos)
|
||||||
|
{
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).Text(item.TipoBobina);
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasIniciales.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosIniciales.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasCompradas.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosComprados.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasConsumidas.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosConsumidos.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasDaniadas.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosDaniados.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasFinales.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosFinales.ToString("N0"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class MovimientoBobinasEstadoDocument : IDocument
|
||||||
|
{
|
||||||
|
public MovimientoBobinasEstadoViewModel Model { get; }
|
||||||
|
|
||||||
|
public MovimientoBobinasEstadoDocument(MovimientoBobinasEstadoViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
|
||||||
|
page.Footer()
|
||||||
|
.AlignCenter()
|
||||||
|
.Text(x =>
|
||||||
|
{
|
||||||
|
x.Span("Página ");
|
||||||
|
x.CurrentPageNumber();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Movimiento de Bobinas por Estados").SemiBold().FontSize(14);
|
||||||
|
column.Item().AlignCenter().Text($"Planta: {Model.NombrePlanta}").FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Column(col =>
|
||||||
|
{
|
||||||
|
col.Item().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha del Reporte: ").SemiBold();
|
||||||
|
text.Span(Model.FechaReporte);
|
||||||
|
});
|
||||||
|
col.Item().Text($"Periodo Consultado: Desde {Model.FechaDesde} Hasta {Model.FechaHasta}");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||||
|
{
|
||||||
|
// Primera tabla: Detalle de Movimientos
|
||||||
|
column.Item().Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(3); // Tipo Bobina
|
||||||
|
columns.RelativeColumn(2); // Remito
|
||||||
|
columns.ConstantColumn(80); // Fecha
|
||||||
|
columns.ConstantColumn(60); // Cantidad
|
||||||
|
columns.RelativeColumn(2); // Tipo Movimiento
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Tipo Bobina");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("N° Remito");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Fecha Mov.");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cantidad");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Tipo Movimiento");
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Detalles)
|
||||||
|
{
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.TipoBobina);
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.NumeroRemito);
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignCenter().Text(item.FechaMovimiento.ToString("dd/MM/yyyy"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.Cantidad.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.TipoMovimiento);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Espacio entre tablas
|
||||||
|
column.Item().PaddingTop(1, Unit.Centimetre);
|
||||||
|
|
||||||
|
// Segunda tabla: Totales
|
||||||
|
column.Item().AlignLeft().Table(table => // Alineamos la tabla a la izquierda para que no ocupe todo el ancho
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(120); // Tipo Movimiento
|
||||||
|
columns.ConstantColumn(80); // Total Bobinas
|
||||||
|
columns.ConstantColumn(80); // Total Kilos
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Totales por Movimiento");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Bobinas");
|
||||||
|
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Kilos");
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var total in Model.Totales)
|
||||||
|
{
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(total.TipoMovimiento);
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(total.TotalBobinas.ToString("N0"));
|
||||||
|
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(total.TotalKilos.ToString("N0"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class NovedadesCanillasDocument : IDocument
|
||||||
|
{
|
||||||
|
public NovedadesCanillasViewModel Model { get; }
|
||||||
|
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||||
|
|
||||||
|
public NovedadesCanillasDocument(NovedadesCanillasViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1.5f, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("Listado de Novedades - Canillas").SemiBold().FontSize(16);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||||
|
});
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5).Border(1).Background(Colors.Grey.Lighten3).AlignCenter().Padding(2).Text(Model.NombreEmpresa).SemiBold();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(20);
|
||||||
|
|
||||||
|
if (Model.ResumenCanillas.Any())
|
||||||
|
{
|
||||||
|
column.Item().Element(ComposeResumenTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Model.DetallesNovedades.Any())
|
||||||
|
{
|
||||||
|
column.Item().Element(ComposeDetallesNovedadesTable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeResumenTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(3); // Canilla
|
||||||
|
columns.RelativeColumn(1); // Legajo
|
||||||
|
columns.RelativeColumn(1); // Faltas
|
||||||
|
columns.RelativeColumn(1); // Francos
|
||||||
|
columns.RelativeColumn(1.5f); // Comisiones
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Canilla");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Legajo");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Faltas");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Francos");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Comisiones");
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.ResumenCanillas.OrderBy(x => x.Canilla))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Canilla);
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.Legajo?.ToString() ?? "-");
|
||||||
|
table.Cell().Border(1).Padding(3).AlignCenter().Text(item.Faltas?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Border(1).Padding(3).AlignCenter().Text(item.Francos?.ToString("N0") ?? "0");
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalRendir?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de Totales
|
||||||
|
table.Cell().ColumnSpan(4).Border(1).Padding(3).AlignRight().Text("Total").SemiBold();
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.ResumenCanillas.Sum(x => x.TotalRendir ?? 0).ToString("C", CultureAr)).SemiBold());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeDetallesNovedadesTable(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().PaddingTop(10).Text("Otras Novedades").SemiBold().FontSize(12);
|
||||||
|
column.Item().PaddingTop(5).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2); // Nombre
|
||||||
|
columns.ConstantColumn(80); // Fecha
|
||||||
|
columns.RelativeColumn(4); // Detalle
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Nombre");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Fecha");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Detalle");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Agrupamos por canillita para mostrar su nombre una sola vez
|
||||||
|
foreach (var grupo in Model.DetallesNovedades.GroupBy(x => x.NomApe))
|
||||||
|
{
|
||||||
|
// Celda con el nombre del canillita, abarcando todas las filas de sus novedades
|
||||||
|
table.Cell().RowSpan((uint)grupo.Count()).Border(1).Padding(3).Text(grupo.Key);
|
||||||
|
|
||||||
|
// Iteramos sobre las novedades del grupo
|
||||||
|
foreach (var detalle in grupo.OrderBy(d => d.Fecha))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(3).Text(detalle.Fecha.ToString("dd/MM/yyyy"));
|
||||||
|
table.Cell().Border(1).Padding(3).Text(detalle.Detalle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class TiradasPublicacionesSeccionesDocument : IDocument
|
||||||
|
{
|
||||||
|
public TiradasPublicacionesSeccionesViewModel Model { get; }
|
||||||
|
|
||||||
|
public TiradasPublicacionesSeccionesDocument(TiradasPublicacionesSeccionesViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("Reporte de Tiradas por Publicación Mensual").SemiBold().FontSize(14);
|
||||||
|
|
||||||
|
// Título secundario dinámico
|
||||||
|
string subTitle = Model.EsConsolidado
|
||||||
|
? $"Consolidado - Publicación: {Model.NombrePublicacion}"
|
||||||
|
: $"Planta: {Model.NombrePlanta} - Publicación: {Model.NombrePublicacion}";
|
||||||
|
column.Item().AlignCenter().Text(subTitle).FontSize(12);
|
||||||
|
|
||||||
|
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||||
|
{
|
||||||
|
row.RelativeItem().Text(text => { text.Span("Fecha del Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||||
|
row.RelativeItem().AlignRight().Text(text => { text.Span("Mes Consultado: ").SemiBold(); text.Span(Model.MesConsultado); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.RelativeColumn(2.5f); // Nombre Seccion
|
||||||
|
columns.RelativeColumn(1.5f); // Páginas Impresas
|
||||||
|
columns.RelativeColumn(1); // Total Ediciones
|
||||||
|
columns.RelativeColumn(1.5f); // Pág. Por Edición
|
||||||
|
columns.RelativeColumn(1.2f); // Total Ejemplares
|
||||||
|
columns.RelativeColumn(1.5f); // Pág. Ejemplar
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Nombre Sección");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Páginas Impresas");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Ediciones");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Pág/Edición");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Ejemplares");
|
||||||
|
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Pág/Ejemplar");
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.Detalles.OrderBy(x => x.NombreSeccion))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(3).Text(item.NombreSeccion);
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalPaginasImpresas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.CantidadTiradas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalPaginasEjemplares.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalEjemplares.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioPaginasPorEjemplar.ToString("N0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fila de Totales
|
||||||
|
var style = TextStyle.Default.SemiBold();
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span("Totales").Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.TotalPaginasImpresas).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.CantidadTiradas).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.TotalPaginasEjemplares).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.TotalEjemplares).ToString("N0")).Style(style));
|
||||||
|
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.PromedioPaginasPorEjemplar).ToString("N0")).Style(style));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class VentaMensualSecretariaElDiaDocument : IDocument
|
||||||
|
{
|
||||||
|
public VentaMensualSecretariaElDiaViewModel Model { get; }
|
||||||
|
|
||||||
|
public VentaMensualSecretariaElDiaDocument(VentaMensualSecretariaElDiaViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(11));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("VENTA DIARIO EL DÍA").SemiBold().FontSize(16);
|
||||||
|
|
||||||
|
column.Item().AlignCenter().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha Consultada: Desde ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaDesde).FontSize(12);
|
||||||
|
text.Span(" Hasta ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaHasta).FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(50); // Día
|
||||||
|
columns.RelativeColumn(); // Canillas
|
||||||
|
columns.RelativeColumn(); // Tirajes
|
||||||
|
columns.RelativeColumn(); // Ventas
|
||||||
|
columns.RelativeColumn(); // Accionistas
|
||||||
|
columns.RelativeColumn(); // Total Coop.
|
||||||
|
columns.RelativeColumn(); // Total Gral.
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("DÍA").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("CANILLAS").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TIRAJES").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("VENTAS").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("ACCIONISTAS").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TOTAL COOPERATIVA").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TOTAL").FontColor(Colors.White).SemiBold());
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.VentasDiarias.OrderBy(x => x.Dia))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Dia.ToString());
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.CantidadCanillas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Tirajes.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Ventas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Accionistas.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TotalCooperativa.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.TotalGeneral.ToString("N0")).SemiBold());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class VentaMensualSecretariaElPlataDocument : IDocument
|
||||||
|
{
|
||||||
|
public VentaMensualSecretariaElPlataViewModel Model { get; }
|
||||||
|
|
||||||
|
public VentaMensualSecretariaElPlataDocument(VentaMensualSecretariaElPlataViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(11));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
column.Item().AlignCenter().Text("VENTA DIARIO EL PLATA").SemiBold().FontSize(16);
|
||||||
|
|
||||||
|
column.Item().AlignCenter().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha Consultada: Desde ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaDesde).FontSize(12);
|
||||||
|
text.Span(" Hasta ").SemiBold().FontSize(12);
|
||||||
|
text.Span(Model.FechaHasta).FontSize(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(50); // Día
|
||||||
|
columns.RelativeColumn(); // Tirada Coop
|
||||||
|
columns.RelativeColumn(); // Devolución Coop
|
||||||
|
columns.RelativeColumn(); // Venta Coop
|
||||||
|
columns.RelativeColumn(); // Tirada Canillas
|
||||||
|
columns.RelativeColumn(); // Venta Canillas
|
||||||
|
columns.RelativeColumn(); // Total
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("DÍA").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TIRADA COOP.").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("DEVOLUCIÓN COOP.").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("VENTA COOP.").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TIRADA CANILLAS").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("VENTA CANILLAS (TOTAL)").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TOTAL").FontColor(Colors.White).SemiBold());
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in Model.VentasDiarias.OrderBy(x => x.Dia))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Dia.ToString());
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaCoop.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionCoop.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.VentaCoop.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaCan.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.VentaCan.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.Total.ToString("N0")).SemiBold());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||||
|
using QuestPDF.Elements.Table;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||||
|
{
|
||||||
|
public class VentaMensualSecretariaTirDevoDocument : IDocument
|
||||||
|
{
|
||||||
|
public VentaMensualSecretariaTirDevoViewModel Model { get; }
|
||||||
|
|
||||||
|
public VentaMensualSecretariaTirDevoDocument(VentaMensualSecretariaTirDevoViewModel model)
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||||
|
|
||||||
|
public void Compose(IDocumentContainer container)
|
||||||
|
{
|
||||||
|
container.Page(page =>
|
||||||
|
{
|
||||||
|
// CORRECCIÓN: Se aplica Landscape() al tamaño de página.
|
||||||
|
page.Size(PageSizes.A4.Landscape());
|
||||||
|
page.Margin(1, Unit.Centimetre);
|
||||||
|
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(12));
|
||||||
|
|
||||||
|
page.Header().Element(ComposeHeader);
|
||||||
|
page.Content().Element(ComposeContent);
|
||||||
|
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeHeader(IContainer container)
|
||||||
|
{
|
||||||
|
container.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().AlignCenter().Text("TIRADA Y DEVOLUCIÓN").SemiBold().FontSize(18);
|
||||||
|
column.Item().AlignCenter().Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("Fecha Consultada: Desde ").SemiBold().FontSize(14);
|
||||||
|
text.Span(Model.FechaDesde).FontSize(14);
|
||||||
|
text.Span(" Hasta ").SemiBold().FontSize(14);
|
||||||
|
text.Span(Model.FechaHasta).FontSize(14);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeContent(IContainer container)
|
||||||
|
{
|
||||||
|
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||||
|
{
|
||||||
|
table.ColumnsDefinition(columns =>
|
||||||
|
{
|
||||||
|
columns.ConstantColumn(40);
|
||||||
|
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // EL DÍA
|
||||||
|
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // POPULAR
|
||||||
|
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // CLARÍN
|
||||||
|
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // LA NACIÓN
|
||||||
|
});
|
||||||
|
|
||||||
|
table.Header(header =>
|
||||||
|
{
|
||||||
|
// CORRECCIÓN: La sintaxis de VerticalAlign es un método.
|
||||||
|
header.Cell().RowSpan(2).Border(1).Background(Colors.Black).AlignCenter().AlignMiddle().Text(text => text.Span("Día").FontColor(Colors.White).SemiBold());
|
||||||
|
|
||||||
|
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("EL DÍA").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("POPULAR").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("CLARÍN").FontColor(Colors.White).SemiBold());
|
||||||
|
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("LA NACIÓN").FontColor(Colors.White).SemiBold());
|
||||||
|
|
||||||
|
// CORRECCIÓN: Se define una función local para crear y estilizar las celdas del sub-encabezado.
|
||||||
|
// Esto evita el error de "multiple child elements".
|
||||||
|
void SubHeaderCell(ITableCellContainer cell, string text)
|
||||||
|
{
|
||||||
|
cell.Border(1)
|
||||||
|
.Background(Colors.Black)
|
||||||
|
.AlignCenter()
|
||||||
|
.Text(txt => txt.Span(text).FontColor(Colors.White).SemiBold());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var _ in Enumerable.Range(0, 4))
|
||||||
|
{
|
||||||
|
SubHeaderCell(header.Cell(), "TIRADA");
|
||||||
|
SubHeaderCell(header.Cell(), "DEVOLUC");
|
||||||
|
SubHeaderCell(header.Cell(), "VENTA");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filas de datos (sin cambios)
|
||||||
|
foreach (var item in Model.VentasDiarias.OrderBy(x => x.Dia))
|
||||||
|
{
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Dia.ToString());
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaCoop.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionCoop.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaCoop.ToString("N0")).SemiBold());
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaPopular.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionPopular.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaPopular.ToString("N0")).SemiBold());
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaClarin.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionClarin.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaClarin.ToString("N0")).SemiBold());
|
||||||
|
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaNacion.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionNacion.ToString("N0"));
|
||||||
|
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaNacion.ToString("N0")).SemiBold());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,779 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
|
|
||||||
<AutoRefresh>0</AutoRefresh>
|
|
||||||
<DataSources>
|
|
||||||
<DataSource Name="DSConsumoBobinas">
|
|
||||||
<ConnectionProperties>
|
|
||||||
<DataProvider>System.Data.DataSet</DataProvider>
|
|
||||||
<ConnectString>/* Local Connection */</ConnectString>
|
|
||||||
</ConnectionProperties>
|
|
||||||
<rd:DataSourceID>2bf94014-b80d-4047-9164-c0b5ad337361</rd:DataSourceID>
|
|
||||||
</DataSource>
|
|
||||||
</DataSources>
|
|
||||||
<DataSets>
|
|
||||||
<DataSet Name="DSConsumoBobinasPublicacion">
|
|
||||||
<Query>
|
|
||||||
<DataSourceName>DSConsumoBobinas</DataSourceName>
|
|
||||||
<CommandText>/* Local Query */</CommandText>
|
|
||||||
</Query>
|
|
||||||
<Fields>
|
|
||||||
<Field Name="NombrePlanta">
|
|
||||||
<DataField>NombrePlanta</DataField>
|
|
||||||
<rd:TypeName>System.String</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="NombrePublicacion">
|
|
||||||
<DataField>NombrePublicacion</DataField>
|
|
||||||
<rd:TypeName>System.String</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalKilos">
|
|
||||||
<DataField>TotalKilos</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="CantidadBobinas">
|
|
||||||
<DataField>CantidadBobinas</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
</Fields>
|
|
||||||
<rd:DataSetInfo>
|
|
||||||
<rd:DataSetName>DSConsumoBobinas</rd:DataSetName>
|
|
||||||
<rd:SchemaPath>C:\Users\dmolinari\source\repos\Cobol-VBNet\Reportes\DSConsumoBobinas.xsd</rd:SchemaPath>
|
|
||||||
<rd:TableName>SP_BobinasUtilizadasPorPublicacion</rd:TableName>
|
|
||||||
<rd:TableAdapterFillMethod>Fill</rd:TableAdapterFillMethod>
|
|
||||||
<rd:TableAdapterGetDataMethod>GetData</rd:TableAdapterGetDataMethod>
|
|
||||||
<rd:TableAdapterName>SP_BobinasUtilizadasPorPublicacionTableAdapter</rd:TableAdapterName>
|
|
||||||
</rd:DataSetInfo>
|
|
||||||
</DataSet>
|
|
||||||
</DataSets>
|
|
||||||
<ReportSections>
|
|
||||||
<ReportSection>
|
|
||||||
<Body>
|
|
||||||
<ReportItems>
|
|
||||||
<Tablix Name="Tablix1">
|
|
||||||
<TablixBody>
|
|
||||||
<TablixColumns>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>6cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>5cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>4cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
</TablixColumns>
|
|
||||||
<TablixRows>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox11">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Publicación</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>roboto</FontFamily>
|
|
||||||
<FontSize>11pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox11</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox13">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Kilos</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>roboto</FontFamily>
|
|
||||||
<FontSize>11pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox13</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox15">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Cant.Bobinas</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>roboto</FontFamily>
|
|
||||||
<FontSize>11pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox15</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="NombrePublicacion">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!NombrePublicacion.Value</Value>
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>NombrePublicacion</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TotalKilos">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalKilos.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<Format>#,0</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TotalKilos</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="CantidadBobinas">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!CantidadBobinas.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<Format>#,0</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>CantidadBobinas</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox48">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Totales </Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>roboto</FontFamily>
|
|
||||||
<FontSize>11pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Right</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox48</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox50">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!TotalKilos.Value)</Value>
|
|
||||||
<Style>
|
|
||||||
<Format>#,0</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox50</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox51">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!CantidadBobinas.Value)</Value>
|
|
||||||
<Style>
|
|
||||||
<Format>#,0</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox51</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
</TablixRows>
|
|
||||||
</TablixBody>
|
|
||||||
<TablixColumnHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixColumnHierarchy>
|
|
||||||
<TablixRowHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember>
|
|
||||||
<TablixHeader>
|
|
||||||
<Size>4cm</Size>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox17">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Planta</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>roboto</FontFamily>
|
|
||||||
<FontSize>11pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox17</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixHeader>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
<KeepWithGroup>After</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<Group Name="NombrePlanta">
|
|
||||||
<GroupExpressions>
|
|
||||||
<GroupExpression>=Fields!NombrePlanta.Value</GroupExpression>
|
|
||||||
</GroupExpressions>
|
|
||||||
</Group>
|
|
||||||
<SortExpressions>
|
|
||||||
<SortExpression>
|
|
||||||
<Value>=Fields!NombrePlanta.Value</Value>
|
|
||||||
</SortExpression>
|
|
||||||
</SortExpressions>
|
|
||||||
<TablixHeader>
|
|
||||||
<Size>4cm</Size>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="NombrePlanta1">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!NombrePlanta.Value</Value>
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>NombrePlanta1</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixHeader>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember>
|
|
||||||
<Group Name="Detalles" />
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<KeepWithGroup>Before</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixMember>
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixRowHierarchy>
|
|
||||||
<DataSetName>DSConsumoBobinasPublicacion</DataSetName>
|
|
||||||
<Top>0.14111cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>1.8cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</Tablix>
|
|
||||||
</ReportItems>
|
|
||||||
<Height>0.80957in</Height>
|
|
||||||
<Style />
|
|
||||||
</Body>
|
|
||||||
<Width>21cm</Width>
|
|
||||||
<Page>
|
|
||||||
<PageHeader>
|
|
||||||
<Height>1.91974cm</Height>
|
|
||||||
<PrintOnFirstPage>true</PrintOnFirstPage>
|
|
||||||
<PrintOnLastPage>true</PrintOnLastPage>
|
|
||||||
<ReportItems>
|
|
||||||
<Textbox Name="Textbox41">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Reporte de Consumo de Bobinas por Publicaciones</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>0.28998cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.72912cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox43">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Fecha del Reporte</Value>
|
|
||||||
<Style>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.16692cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.64974cm</Height>
|
|
||||||
<Width>3.43896cm</Width>
|
|
||||||
<ZIndex>1</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox49">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Globals!ExecutionTime).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.16692cm</Top>
|
|
||||||
<Left>4.00151cm</Left>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<Width>2.60584cm</Width>
|
|
||||||
<ZIndex>2</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox71">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Fecha Consultada: Desde</Value>
|
|
||||||
<Style>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.17052cm</Top>
|
|
||||||
<Left>6.64968cm</Left>
|
|
||||||
<Height>0.64974cm</Height>
|
|
||||||
<Width>4.5cm</Width>
|
|
||||||
<ZIndex>3</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox72">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Parameters!FechaDesde.Value).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.2058cm</Top>
|
|
||||||
<Left>11.0676cm</Left>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<Width>2.52646cm</Width>
|
|
||||||
<ZIndex>4</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox76">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Hasta</Value>
|
|
||||||
<Style>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.17052cm</Top>
|
|
||||||
<Left>13.31184cm</Left>
|
|
||||||
<Height>0.64974cm</Height>
|
|
||||||
<Width>1.13709cm</Width>
|
|
||||||
<ZIndex>5</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox77">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Parameters!FechaHasta.Value).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.17052cm</Top>
|
|
||||||
<Left>14.44892cm</Left>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<Width>2.52646cm</Width>
|
|
||||||
<ZIndex>6</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</ReportItems>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</PageHeader>
|
|
||||||
<PageHeight>29.7cm</PageHeight>
|
|
||||||
<PageWidth>21cm</PageWidth>
|
|
||||||
<LeftMargin>0cm</LeftMargin>
|
|
||||||
<RightMargin>0cm</RightMargin>
|
|
||||||
<TopMargin>0.5cm</TopMargin>
|
|
||||||
<BottomMargin>0.5cm</BottomMargin>
|
|
||||||
<ColumnSpacing>0.13cm</ColumnSpacing>
|
|
||||||
<Style />
|
|
||||||
</Page>
|
|
||||||
</ReportSection>
|
|
||||||
</ReportSections>
|
|
||||||
<ReportParameters>
|
|
||||||
<ReportParameter Name="FechaDesde">
|
|
||||||
<DataType>DateTime</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
<ReportParameter Name="FechaHasta">
|
|
||||||
<DataType>DateTime</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
</ReportParameters>
|
|
||||||
<ReportParametersLayout>
|
|
||||||
<GridLayoutDefinition>
|
|
||||||
<NumberOfColumns>4</NumberOfColumns>
|
|
||||||
<NumberOfRows>2</NumberOfRows>
|
|
||||||
<CellDefinitions>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>0</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>FechaDesde</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>1</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>FechaHasta</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
</CellDefinitions>
|
|
||||||
</GridLayoutDefinition>
|
|
||||||
</ReportParametersLayout>
|
|
||||||
<rd:ReportUnitType>Cm</rd:ReportUnitType>
|
|
||||||
<rd:ReportID>4e743a44-a248-48fe-9b28-03d7da14e6e5</rd:ReportID>
|
|
||||||
</Report>
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,992 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
|
|
||||||
<AutoRefresh>0</AutoRefresh>
|
|
||||||
<DataSources>
|
|
||||||
<DataSource Name="DSLiquidacionCanillas">
|
|
||||||
<ConnectionProperties>
|
|
||||||
<DataProvider>System.Data.DataSet</DataProvider>
|
|
||||||
<ConnectString>/* Local Connection */</ConnectString>
|
|
||||||
</ConnectionProperties>
|
|
||||||
<rd:DataSourceID>ee328c50-edc3-4726-92dc-19ec72ac5a56</rd:DataSourceID>
|
|
||||||
</DataSource>
|
|
||||||
</DataSources>
|
|
||||||
<DataSets>
|
|
||||||
<DataSet Name="DSLiquidacionCanillas">
|
|
||||||
<Query>
|
|
||||||
<DataSourceName>DSLiquidacionCanillas</DataSourceName>
|
|
||||||
<CommandText>/* Local Query */</CommandText>
|
|
||||||
</Query>
|
|
||||||
<Fields>
|
|
||||||
<Field Name="Publicacion">
|
|
||||||
<DataField>Publicacion</DataField>
|
|
||||||
<rd:TypeName>System.String</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="Canilla">
|
|
||||||
<DataField>Canilla</DataField>
|
|
||||||
<rd:TypeName>System.String</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalCantSalida">
|
|
||||||
<DataField>TotalCantSalida</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalCantEntrada">
|
|
||||||
<DataField>TotalCantEntrada</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalRendir">
|
|
||||||
<DataField>TotalRendir</DataField>
|
|
||||||
<rd:TypeName>System.Decimal</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="PrecioEjemplar">
|
|
||||||
<DataField>PrecioEjemplar</DataField>
|
|
||||||
<rd:TypeName>System.Decimal</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
</Fields>
|
|
||||||
<rd:DataSetInfo>
|
|
||||||
<rd:DataSetName>DSLiquidacionCanillas</rd:DataSetName>
|
|
||||||
<rd:SchemaPath>C:\Users\dmolinari\source\repos\Cobol-VBNet\Reportes\DSLiquidacionCanillas.xsd</rd:SchemaPath>
|
|
||||||
<rd:TableName>SP_DistCanillasLiquidacion</rd:TableName>
|
|
||||||
<rd:TableAdapterFillMethod>Fill</rd:TableAdapterFillMethod>
|
|
||||||
<rd:TableAdapterGetDataMethod>GetData</rd:TableAdapterGetDataMethod>
|
|
||||||
<rd:TableAdapterName>SP_DistCanillasLiquidacionTableAdapter</rd:TableAdapterName>
|
|
||||||
</rd:DataSetInfo>
|
|
||||||
</DataSet>
|
|
||||||
</DataSets>
|
|
||||||
<ReportSections>
|
|
||||||
<ReportSection>
|
|
||||||
<Body>
|
|
||||||
<ReportItems>
|
|
||||||
<Tablix Name="Tablix1">
|
|
||||||
<TablixBody>
|
|
||||||
<TablixColumns>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3.53124cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3.10854cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3.55834cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
</TablixColumns>
|
|
||||||
<TablixRows>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox38">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>="Vendedor: " & First(Fields!Canilla.Value, "DSLiquidacionCanillas")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox38</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<ColSpan>3</ColSpan>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell />
|
|
||||||
<TablixCell />
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Publicacion">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!Publicacion.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Publicacion</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox13">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Retirados</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox13</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TotalCantSalida">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalCantSalida.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TotalCantSalida</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox7">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value />
|
|
||||||
<Style>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox7</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</TopBorder>
|
|
||||||
<BottomBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</BottomBorder>
|
|
||||||
<LeftBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</LeftBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox14">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Devueltos</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox14</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox12">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalCantEntrada.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox8</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox27">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value />
|
|
||||||
<Style>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox27</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</TopBorder>
|
|
||||||
<BottomBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</BottomBorder>
|
|
||||||
<LeftBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</LeftBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox28">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Vendidos</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox28</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox29">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalCantSalida.Value-Fields!TotalCantEntrada.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox29</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox33">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value />
|
|
||||||
<Style>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox33</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</TopBorder>
|
|
||||||
<BottomBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</BottomBorder>
|
|
||||||
<LeftBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</LeftBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox30">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Precio Unitario</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox30</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox32">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!PrecioEjemplar.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
<Format>'$'#,0.00;'$'-#,0.00</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox32</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
<rd:FormatSymbolCulture>es-AR</rd:FormatSymbolCulture>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox35">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value />
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox35</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</TopBorder>
|
|
||||||
<BottomBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</BottomBorder>
|
|
||||||
<LeftBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</LeftBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox36">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Importe Vendido</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox36</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Color>Black</Color>
|
|
||||||
<Width>2pt</Width>
|
|
||||||
</TopBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox37">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalRendir.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Format>'$'#,0.00;'$'-#,0.00</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox37</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Color>Black</Color>
|
|
||||||
<Width>2pt</Width>
|
|
||||||
</TopBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
<rd:FormatSymbolCulture>es-AR</rd:FormatSymbolCulture>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox1">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value />
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox1</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</TopBorder>
|
|
||||||
<BottomBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</BottomBorder>
|
|
||||||
<LeftBorder>
|
|
||||||
<Style>None</Style>
|
|
||||||
</LeftBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox2">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Total A Rendir</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox2</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Color>Black</Color>
|
|
||||||
<Width>2pt</Width>
|
|
||||||
</TopBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox4">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!TotalRendir.Value, "DSLiquidacionCanillas")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Format>'$'#,0.00;'$'-#,0.00</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox4</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<TopBorder>
|
|
||||||
<Color>Black</Color>
|
|
||||||
<Width>2pt</Width>
|
|
||||||
</TopBorder>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
<rd:FormatSymbolCulture>es-AR</rd:FormatSymbolCulture>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
</TablixRows>
|
|
||||||
</TablixBody>
|
|
||||||
<TablixColumnHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixColumnHierarchy>
|
|
||||||
<TablixRowHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember>
|
|
||||||
<KeepWithGroup>After</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<Group Name="Publicacion">
|
|
||||||
<GroupExpressions>
|
|
||||||
<GroupExpression>=Fields!Publicacion.Value</GroupExpression>
|
|
||||||
</GroupExpressions>
|
|
||||||
</Group>
|
|
||||||
<SortExpressions>
|
|
||||||
<SortExpression>
|
|
||||||
<Value>=Fields!Publicacion.Value</Value>
|
|
||||||
</SortExpression>
|
|
||||||
</SortExpressions>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<KeepWithGroup>Before</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixRowHierarchy>
|
|
||||||
<DataSetName>DSLiquidacionCanillas</DataSetName>
|
|
||||||
<Top>1.07592cm</Top>
|
|
||||||
<Left>2.09225cm</Left>
|
|
||||||
<Height>3.5cm</Height>
|
|
||||||
<Width>10.19813cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</Tablix>
|
|
||||||
<Textbox Name="Textbox39">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>EL DIA S.A.I.C. y F.</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox39</rd:DefaultName>
|
|
||||||
<Top>0.01025cm</Top>
|
|
||||||
<Left>2.09225cm</Left>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<Width>10.19813cm</Width>
|
|
||||||
<ZIndex>1</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox40">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Liquidación venta de diarios del:</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox39</rd:DefaultName>
|
|
||||||
<Top>0.53236cm</Top>
|
|
||||||
<Left>2.09225cm</Left>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<Width>4.43198cm</Width>
|
|
||||||
<ZIndex>2</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox41">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Parameters!FechaLiqui.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>8pt</FontSize>
|
|
||||||
<Format>dd/MM/yyy</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>0.53236cm</Top>
|
|
||||||
<Left>6.44662cm</Left>
|
|
||||||
<Height>0.5cm</Height>
|
|
||||||
<Width>3.86292cm</Width>
|
|
||||||
<ZIndex>3</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</ReportItems>
|
|
||||||
<Height>4.66667cm</Height>
|
|
||||||
<Style />
|
|
||||||
</Body>
|
|
||||||
<Width>14.8cm</Width>
|
|
||||||
<Page>
|
|
||||||
<PageHeight>21cm</PageHeight>
|
|
||||||
<PageWidth>14.8cm</PageWidth>
|
|
||||||
<LeftMargin>0cm</LeftMargin>
|
|
||||||
<RightMargin>0cm</RightMargin>
|
|
||||||
<TopMargin>0.5cm</TopMargin>
|
|
||||||
<BottomMargin>0.5cm</BottomMargin>
|
|
||||||
<ColumnSpacing>0.13cm</ColumnSpacing>
|
|
||||||
<Style />
|
|
||||||
</Page>
|
|
||||||
</ReportSection>
|
|
||||||
</ReportSections>
|
|
||||||
<ReportParameters>
|
|
||||||
<ReportParameter Name="FechaLiqui">
|
|
||||||
<DataType>DateTime</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
</ReportParameters>
|
|
||||||
<ReportParametersLayout>
|
|
||||||
<GridLayoutDefinition>
|
|
||||||
<NumberOfColumns>4</NumberOfColumns>
|
|
||||||
<NumberOfRows>2</NumberOfRows>
|
|
||||||
<CellDefinitions>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>0</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>FechaLiqui</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
</CellDefinitions>
|
|
||||||
</GridLayoutDefinition>
|
|
||||||
</ReportParametersLayout>
|
|
||||||
<rd:ReportUnitType>Cm</rd:ReportUnitType>
|
|
||||||
<rd:ReportID>3bfdc2c9-c7dc-47b8-b2b1-3512fa773a78</rd:ReportID>
|
|
||||||
</Report>
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,994 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
|
|
||||||
<AutoRefresh>0</AutoRefresh>
|
|
||||||
<DataSources>
|
|
||||||
<DataSource Name="DSConsumoBobinas">
|
|
||||||
<ConnectionProperties>
|
|
||||||
<DataProvider>System.Data.DataSet</DataProvider>
|
|
||||||
<ConnectString>/* Local Connection */</ConnectString>
|
|
||||||
</ConnectionProperties>
|
|
||||||
<rd:DataSourceID>7c4f9d40-0118-4f83-ae46-6a1b074be5d7</rd:DataSourceID>
|
|
||||||
</DataSource>
|
|
||||||
</DataSources>
|
|
||||||
<DataSets>
|
|
||||||
<DataSet Name="DSTiradasPublicacionesSecciones">
|
|
||||||
<Query>
|
|
||||||
<DataSourceName>DSConsumoBobinas</DataSourceName>
|
|
||||||
<CommandText>/* Local Query */</CommandText>
|
|
||||||
</Query>
|
|
||||||
<Fields>
|
|
||||||
<Field Name="NombreSeccion">
|
|
||||||
<DataField>NombreSeccion</DataField>
|
|
||||||
<rd:TypeName>System.String</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalPaginasImpresas">
|
|
||||||
<DataField>TotalPaginasImpresas</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="CantidadTiradas">
|
|
||||||
<DataField>CantidadTiradas</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalPaginasEjemplares">
|
|
||||||
<DataField>TotalPaginasEjemplares</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalEjemplares">
|
|
||||||
<DataField>TotalEjemplares</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="PromedioPaginasPorEjemplar">
|
|
||||||
<DataField>PromedioPaginasPorEjemplar</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
</Fields>
|
|
||||||
<rd:DataSetInfo>
|
|
||||||
<rd:DataSetName>DSConsumoBobinas</rd:DataSetName>
|
|
||||||
<rd:SchemaPath>C:\Users\dmolinari\source\repos\Cobol-VBNet\Reportes\DSConsumoBobinas.xsd</rd:SchemaPath>
|
|
||||||
<rd:TableName>SP_TiradasPublicacionesSecciones</rd:TableName>
|
|
||||||
<rd:TableAdapterFillMethod>Fill</rd:TableAdapterFillMethod>
|
|
||||||
<rd:TableAdapterGetDataMethod>GetData</rd:TableAdapterGetDataMethod>
|
|
||||||
<rd:TableAdapterName>SP_TiradasPublicacionesSeccionesTableAdapter</rd:TableAdapterName>
|
|
||||||
</rd:DataSetInfo>
|
|
||||||
</DataSet>
|
|
||||||
</DataSets>
|
|
||||||
<ReportSections>
|
|
||||||
<ReportSection>
|
|
||||||
<Body>
|
|
||||||
<ReportItems>
|
|
||||||
<Tablix Name="Tablix1">
|
|
||||||
<TablixBody>
|
|
||||||
<TablixColumns>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>5.5cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.5cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.5cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.5cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
</TablixColumns>
|
|
||||||
<TablixRows>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox9">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Nombre </Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox9</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox11">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Total Páginas Impresas</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox11</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox13">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Total Ediciones</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox13</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox15">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Pág. Por Edición (Promedio)</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox15</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox17">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Total Ejemplares</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox17</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox19">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Pág. Ejemplar (Promedio)</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox19</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="NombreSeccion">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!NombreSeccion.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>NombreSeccion</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TotalPaginasImpresas">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalPaginasImpresas.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TotalPaginasImpresas</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="CantidadTiradas">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!CantidadTiradas.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>CantidadTiradas</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TotalPaginasEjemplares">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalPaginasEjemplares.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TotalPaginasEjemplares</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TotalEjemplares">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalEjemplares.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TotalEjemplares</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="PromedioPaginasPorEjemplar">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!PromedioPaginasPorEjemplar.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>9pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>PromedioPaginasPorEjemplar</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox21">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Totales </Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Right</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox21</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox22">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!TotalPaginasImpresas.Value, "DSTiradasPublicacionesSecciones")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox22</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox23">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!CantidadTiradas.Value, "DSTiradasPublicacionesSecciones")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox23</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox24">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!TotalPaginasEjemplares.Value, "DSTiradasPublicacionesSecciones")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox24</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox25">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!TotalEjemplares.Value, "DSTiradasPublicacionesSecciones")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox25</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox26">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Sum(Fields!PromedioPaginasPorEjemplar.Value, "DSTiradasPublicacionesSecciones")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox26</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
</TablixRows>
|
|
||||||
</TablixBody>
|
|
||||||
<TablixColumnHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixColumnHierarchy>
|
|
||||||
<TablixRowHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember>
|
|
||||||
<KeepWithGroup>After</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<Group Name="Detalles" />
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<KeepWithGroup>Before</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixRowHierarchy>
|
|
||||||
<DataSetName>DSTiradasPublicacionesSecciones</DataSetName>
|
|
||||||
<Top>0.14111cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>1.8cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</Tablix>
|
|
||||||
</ReportItems>
|
|
||||||
<Height>0.84039in</Height>
|
|
||||||
<Style />
|
|
||||||
</Body>
|
|
||||||
<Width>21cm</Width>
|
|
||||||
<Page>
|
|
||||||
<PageHeader>
|
|
||||||
<Height>2.55474cm</Height>
|
|
||||||
<PrintOnFirstPage>true</PrintOnFirstPage>
|
|
||||||
<PrintOnLastPage>true</PrintOnLastPage>
|
|
||||||
<ReportItems>
|
|
||||||
<Textbox Name="Textbox41">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Reporte de Tiradas por Publicación Mensual</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>0.27552cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.72912cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox42">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>="Consolidados - Publicación: " & Parameters!NomPubli.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.07428cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.64975cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<ZIndex>1</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox43">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Fecha del Reporte</Value>
|
|
||||||
<Style>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.78746cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.64974cm</Height>
|
|
||||||
<Width>3.43896cm</Width>
|
|
||||||
<ZIndex>2</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox49">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Globals!ExecutionTime).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.78746cm</Top>
|
|
||||||
<Left>4.00151cm</Left>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<Width>2.60584cm</Width>
|
|
||||||
<ZIndex>3</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox71">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Mes Consultado:</Value>
|
|
||||||
<Style>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.81998cm</Top>
|
|
||||||
<Left>6.60123cm</Left>
|
|
||||||
<Height>0.64974cm</Height>
|
|
||||||
<Width>3.25646cm</Width>
|
|
||||||
<ZIndex>4</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox72">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Parameters!Mes.Value</Value>
|
|
||||||
<Style />
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.85526cm</Top>
|
|
||||||
<Left>9.74915cm</Left>
|
|
||||||
<Height>0.6cm</Height>
|
|
||||||
<Width>7.02438cm</Width>
|
|
||||||
<ZIndex>5</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</ReportItems>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</PageHeader>
|
|
||||||
<PageHeight>29.7cm</PageHeight>
|
|
||||||
<PageWidth>21cm</PageWidth>
|
|
||||||
<LeftMargin>0cm</LeftMargin>
|
|
||||||
<RightMargin>0cm</RightMargin>
|
|
||||||
<TopMargin>0.5cm</TopMargin>
|
|
||||||
<BottomMargin>0.5cm</BottomMargin>
|
|
||||||
<ColumnSpacing>0.13cm</ColumnSpacing>
|
|
||||||
<Style />
|
|
||||||
</Page>
|
|
||||||
</ReportSection>
|
|
||||||
</ReportSections>
|
|
||||||
<ReportParameters>
|
|
||||||
<ReportParameter Name="Mes">
|
|
||||||
<DataType>String</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
<ReportParameter Name="NomPubli">
|
|
||||||
<DataType>String</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
</ReportParameters>
|
|
||||||
<ReportParametersLayout>
|
|
||||||
<GridLayoutDefinition>
|
|
||||||
<NumberOfColumns>4</NumberOfColumns>
|
|
||||||
<NumberOfRows>2</NumberOfRows>
|
|
||||||
<CellDefinitions>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>0</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>Mes</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>2</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>NomPubli</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
</CellDefinitions>
|
|
||||||
</GridLayoutDefinition>
|
|
||||||
</ReportParametersLayout>
|
|
||||||
<rd:ReportUnitType>Cm</rd:ReportUnitType>
|
|
||||||
<rd:ReportID>41f590aa-e80a-45c7-8c64-d8fe8117f5ff</rd:ReportID>
|
|
||||||
</Report>
|
|
||||||
@@ -1,879 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
|
|
||||||
<AutoRefresh>0</AutoRefresh>
|
|
||||||
<DataSources>
|
|
||||||
<DataSource Name="DSListadoDistribucion">
|
|
||||||
<ConnectionProperties>
|
|
||||||
<DataProvider>System.Data.DataSet</DataProvider>
|
|
||||||
<ConnectString>/* Local Connection */</ConnectString>
|
|
||||||
</ConnectionProperties>
|
|
||||||
<rd:DataSourceID>afdb4b97-a9ea-4bab-b77b-a7c9e72d6fac</rd:DataSourceID>
|
|
||||||
</DataSource>
|
|
||||||
</DataSources>
|
|
||||||
<DataSets>
|
|
||||||
<DataSet Name="DSListadoDistribucion">
|
|
||||||
<Query>
|
|
||||||
<DataSourceName>DSListadoDistribucion</DataSourceName>
|
|
||||||
<CommandText>/* Local Query */</CommandText>
|
|
||||||
</Query>
|
|
||||||
<Fields>
|
|
||||||
<Field Name="Dia">
|
|
||||||
<DataField>Dia</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="CantidadCanillas">
|
|
||||||
<DataField>CantidadCanillas</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="Tirajes">
|
|
||||||
<DataField>Tirajes</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="Ventas">
|
|
||||||
<DataField>Ventas</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="Accionistas">
|
|
||||||
<DataField>Accionistas</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalCooperativa">
|
|
||||||
<DataField>TotalCooperativa</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TotalGeneral">
|
|
||||||
<DataField>TotalGeneral</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
</Fields>
|
|
||||||
<rd:DataSetInfo>
|
|
||||||
<rd:DataSetName>DSListadoDistribucion</rd:DataSetName>
|
|
||||||
<rd:SchemaPath>C:\Users\dmolinari\source\repos\Cobol-VBNet\Reportes\DSListadoDistribucion.xsd</rd:SchemaPath>
|
|
||||||
<rd:TableName>SP_VentaMensualSecretariaElDia</rd:TableName>
|
|
||||||
<rd:TableAdapterFillMethod>Fill</rd:TableAdapterFillMethod>
|
|
||||||
<rd:TableAdapterGetDataMethod>GetData</rd:TableAdapterGetDataMethod>
|
|
||||||
<rd:TableAdapterName>SP_VentaMensualSecretariaElDiaTableAdapter</rd:TableAdapterName>
|
|
||||||
</rd:DataSetInfo>
|
|
||||||
</DataSet>
|
|
||||||
</DataSets>
|
|
||||||
<ReportSections>
|
|
||||||
<ReportSection>
|
|
||||||
<Body>
|
|
||||||
<ReportItems>
|
|
||||||
<Tablix Name="Tablix1">
|
|
||||||
<TablixBody>
|
|
||||||
<TablixColumns>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>1.5475cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.9525cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.85687cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.5cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3.37313cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3.27cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.5cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
</TablixColumns>
|
|
||||||
<TablixRows>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>1.20854cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox5">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>DÍA</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox5</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox7">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>CANILLAS</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox7</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox9">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>TIRAJES</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox9</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox1">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>VENTAS</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox1</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox3">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>ACCIONISTAS</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox3</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox6">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>TOTAL COOPERATIVA</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox6</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox10">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>TOTAL</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox10</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.75875cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Dia">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!Dia.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Dia</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Llevados">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!CantidadCanillas.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Llevados</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Devueltos">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!Tirajes.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Devueltos</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Ventas">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!Ventas.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Ventas</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Accionistas">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!Accionistas.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Accionistas</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TotalCooperativa">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalCooperativa.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TotalCooperativa</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TotalGeneral">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TotalGeneral.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TotalGeneral</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
</TablixRows>
|
|
||||||
</TablixBody>
|
|
||||||
<TablixColumnHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixColumnHierarchy>
|
|
||||||
<TablixRowHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember>
|
|
||||||
<KeepWithGroup>After</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<Group Name="Detalles" />
|
|
||||||
</TablixMember>
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixRowHierarchy>
|
|
||||||
<DataSetName>DSListadoDistribucion</DataSetName>
|
|
||||||
<Top>0.14139cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>1.96729cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</Tablix>
|
|
||||||
</ReportItems>
|
|
||||||
<Height>0.88228in</Height>
|
|
||||||
<Style />
|
|
||||||
</Body>
|
|
||||||
<Width>20.70896cm</Width>
|
|
||||||
<Page>
|
|
||||||
<PageHeader>
|
|
||||||
<Height>1.89329cm</Height>
|
|
||||||
<PrintOnFirstPage>true</PrintOnFirstPage>
|
|
||||||
<PrintOnLastPage>true</PrintOnLastPage>
|
|
||||||
<ReportItems>
|
|
||||||
<Textbox Name="Textbox41">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>VENTA DIARIO EL DÍA</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>16pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>0.15522cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.72912cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox55">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Fecha Consultada: Desde</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.07181cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.78267cm</Height>
|
|
||||||
<Width>7.14583cm</Width>
|
|
||||||
<ZIndex>1</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox56">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Parameters!FechaDesde.Value).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.10709cm</Top>
|
|
||||||
<Left>6.94192cm</Left>
|
|
||||||
<Height>0.73293cm</Height>
|
|
||||||
<Width>2.77341cm</Width>
|
|
||||||
<ZIndex>2</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox57">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Hasta</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.07181cm</Top>
|
|
||||||
<Left>10.13866cm</Left>
|
|
||||||
<Height>0.78267cm</Height>
|
|
||||||
<Width>1.56784cm</Width>
|
|
||||||
<ZIndex>3</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox58">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Parameters!FechaHasta.Value).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.10709cm</Top>
|
|
||||||
<Left>11.91074cm</Left>
|
|
||||||
<Height>0.73293cm</Height>
|
|
||||||
<Width>3.02917cm</Width>
|
|
||||||
<ZIndex>4</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</ReportItems>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</PageHeader>
|
|
||||||
<PageHeight>29.7cm</PageHeight>
|
|
||||||
<PageWidth>21cm</PageWidth>
|
|
||||||
<LeftMargin>0cm</LeftMargin>
|
|
||||||
<RightMargin>0cm</RightMargin>
|
|
||||||
<TopMargin>0.5cm</TopMargin>
|
|
||||||
<BottomMargin>0.5cm</BottomMargin>
|
|
||||||
<ColumnSpacing>0.13cm</ColumnSpacing>
|
|
||||||
<Style />
|
|
||||||
</Page>
|
|
||||||
</ReportSection>
|
|
||||||
</ReportSections>
|
|
||||||
<ReportParameters>
|
|
||||||
<ReportParameter Name="FechaDesde">
|
|
||||||
<DataType>DateTime</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
<ReportParameter Name="FechaHasta">
|
|
||||||
<DataType>DateTime</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
</ReportParameters>
|
|
||||||
<ReportParametersLayout>
|
|
||||||
<GridLayoutDefinition>
|
|
||||||
<NumberOfColumns>4</NumberOfColumns>
|
|
||||||
<NumberOfRows>2</NumberOfRows>
|
|
||||||
<CellDefinitions>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>2</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>FechaDesde</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>3</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>FechaHasta</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
</CellDefinitions>
|
|
||||||
</GridLayoutDefinition>
|
|
||||||
</ReportParametersLayout>
|
|
||||||
<rd:ReportUnitType>Cm</rd:ReportUnitType>
|
|
||||||
<rd:ReportID>8cf8fb7a-ec4d-4153-8fb0-a21a9e443a88</rd:ReportID>
|
|
||||||
</Report>
|
|
||||||
@@ -1,879 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
|
|
||||||
<AutoRefresh>0</AutoRefresh>
|
|
||||||
<DataSources>
|
|
||||||
<DataSource Name="DSListadoDistribucion">
|
|
||||||
<ConnectionProperties>
|
|
||||||
<DataProvider>System.Data.DataSet</DataProvider>
|
|
||||||
<ConnectString>/* Local Connection */</ConnectString>
|
|
||||||
</ConnectionProperties>
|
|
||||||
<rd:DataSourceID>afdb4b97-a9ea-4bab-b77b-a7c9e72d6fac</rd:DataSourceID>
|
|
||||||
</DataSource>
|
|
||||||
</DataSources>
|
|
||||||
<DataSets>
|
|
||||||
<DataSet Name="DSListadoDistribucion">
|
|
||||||
<Query>
|
|
||||||
<DataSourceName>DSListadoDistribucion</DataSourceName>
|
|
||||||
<CommandText>/* Local Query */</CommandText>
|
|
||||||
</Query>
|
|
||||||
<Fields>
|
|
||||||
<Field Name="TiradaCoop">
|
|
||||||
<DataField>TiradaCoop</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="DevolucionCoop">
|
|
||||||
<DataField>DevolucionCoop</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="VentaCoop">
|
|
||||||
<DataField>VentaCoop</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="TiradaCan">
|
|
||||||
<DataField>TiradaCan</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="VentaCan">
|
|
||||||
<DataField>VentaCan</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="Total">
|
|
||||||
<DataField>Total</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
<Field Name="Dia">
|
|
||||||
<DataField>Dia</DataField>
|
|
||||||
<rd:TypeName>System.Int32</rd:TypeName>
|
|
||||||
</Field>
|
|
||||||
</Fields>
|
|
||||||
<rd:DataSetInfo>
|
|
||||||
<rd:DataSetName>DSListadoDistribucion</rd:DataSetName>
|
|
||||||
<rd:SchemaPath>C:\Users\dmolinari\source\repos\Cobol-VBNet\Reportes\DSListadoDistribucion.xsd</rd:SchemaPath>
|
|
||||||
<rd:TableName>SP_VentaMensualSecretariaElPlata</rd:TableName>
|
|
||||||
<rd:TableAdapterFillMethod>Fill</rd:TableAdapterFillMethod>
|
|
||||||
<rd:TableAdapterGetDataMethod>GetData</rd:TableAdapterGetDataMethod>
|
|
||||||
<rd:TableAdapterName>SP_VentaMensualSecretariaElPlataTableAdapter</rd:TableAdapterName>
|
|
||||||
</rd:DataSetInfo>
|
|
||||||
</DataSet>
|
|
||||||
</DataSets>
|
|
||||||
<ReportSections>
|
|
||||||
<ReportSection>
|
|
||||||
<Body>
|
|
||||||
<ReportItems>
|
|
||||||
<Tablix Name="Tablix1">
|
|
||||||
<TablixBody>
|
|
||||||
<TablixColumns>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>1.5475cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.9525cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>3.34396cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.79104cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.76459cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.75645cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
<TablixColumn>
|
|
||||||
<Width>2.84396cm</Width>
|
|
||||||
</TablixColumn>
|
|
||||||
</TablixColumns>
|
|
||||||
<TablixRows>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>1.63187cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox2">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Día</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox2</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox7">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>TIRADA</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox7</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox9">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>DEVOLUCIÓN COOP.</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox9</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox1">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>VENTA COOP.</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox1</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox3">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>TIRADA CANILLAS</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox3</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox6">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>VENTA CANILLAS (TOTAL)</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox6</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Textbox10">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>TOTAL</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>12pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
<Color>White</Color>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox10</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Color>LightGrey</Color>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<BackgroundColor>Black</BackgroundColor>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
<TablixRow>
|
|
||||||
<Height>0.75875cm</Height>
|
|
||||||
<TablixCells>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Dia1">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!Dia.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Dia1</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TiradaCoop">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TiradaCoop.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TiradaCoop</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="DevolucionCoop">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!DevolucionCoop.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<Format>#,0;(#,0)</Format>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>DevolucionCoop</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="VentaCoop">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!VentaCoop.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>VentaCoop</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="TiradaCan">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!TiradaCan.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>TiradaCan</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="VentaCan">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!VentaCan.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>VentaCan</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
<TablixCell>
|
|
||||||
<CellContents>
|
|
||||||
<Textbox Name="Total">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=Fields!Total.Value</Value>
|
|
||||||
<Style>
|
|
||||||
<FontFamily>Roboto</FontFamily>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Total</rd:DefaultName>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>Solid</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</CellContents>
|
|
||||||
</TablixCell>
|
|
||||||
</TablixCells>
|
|
||||||
</TablixRow>
|
|
||||||
</TablixRows>
|
|
||||||
</TablixBody>
|
|
||||||
<TablixColumnHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
<TablixMember />
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixColumnHierarchy>
|
|
||||||
<TablixRowHierarchy>
|
|
||||||
<TablixMembers>
|
|
||||||
<TablixMember>
|
|
||||||
<KeepWithGroup>After</KeepWithGroup>
|
|
||||||
</TablixMember>
|
|
||||||
<TablixMember>
|
|
||||||
<Group Name="Detalles" />
|
|
||||||
</TablixMember>
|
|
||||||
</TablixMembers>
|
|
||||||
</TablixRowHierarchy>
|
|
||||||
<DataSetName>DSListadoDistribucion</DataSetName>
|
|
||||||
<Top>0.14139cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>2.39062cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</Tablix>
|
|
||||||
</ReportItems>
|
|
||||||
<Height>1.03853in</Height>
|
|
||||||
<Style />
|
|
||||||
</Body>
|
|
||||||
<Width>20.39921cm</Width>
|
|
||||||
<Page>
|
|
||||||
<PageHeader>
|
|
||||||
<Height>1.89329cm</Height>
|
|
||||||
<PrintOnFirstPage>true</PrintOnFirstPage>
|
|
||||||
<PrintOnLastPage>true</PrintOnLastPage>
|
|
||||||
<ReportItems>
|
|
||||||
<Textbox Name="Textbox41">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>VENTA DIARIO EL PLATA</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>16pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Center</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>0.15875cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.72912cm</Height>
|
|
||||||
<Width>19cm</Width>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox55">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Fecha Consultada: Desde</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.07534cm</Top>
|
|
||||||
<Left>0.619cm</Left>
|
|
||||||
<Height>0.78267cm</Height>
|
|
||||||
<Width>7.14583cm</Width>
|
|
||||||
<ZIndex>1</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox56">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Parameters!FechaDesde.Value).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.11062cm</Top>
|
|
||||||
<Left>6.94192cm</Left>
|
|
||||||
<Height>0.73293cm</Height>
|
|
||||||
<Width>2.77341cm</Width>
|
|
||||||
<ZIndex>2</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox57">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>Hasta</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
<FontWeight>Bold</FontWeight>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style>
|
|
||||||
<TextAlign>Left</TextAlign>
|
|
||||||
</Style>
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox41</rd:DefaultName>
|
|
||||||
<Top>1.07534cm</Top>
|
|
||||||
<Left>10.13866cm</Left>
|
|
||||||
<Height>0.78267cm</Height>
|
|
||||||
<Width>1.56784cm</Width>
|
|
||||||
<ZIndex>3</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
<Textbox Name="Textbox58">
|
|
||||||
<CanGrow>true</CanGrow>
|
|
||||||
<KeepTogether>true</KeepTogether>
|
|
||||||
<Paragraphs>
|
|
||||||
<Paragraph>
|
|
||||||
<TextRuns>
|
|
||||||
<TextRun>
|
|
||||||
<Value>=CDate(Parameters!FechaHasta.Value).ToString("dd/MM/yyyy")</Value>
|
|
||||||
<Style>
|
|
||||||
<FontSize>14pt</FontSize>
|
|
||||||
</Style>
|
|
||||||
</TextRun>
|
|
||||||
</TextRuns>
|
|
||||||
<Style />
|
|
||||||
</Paragraph>
|
|
||||||
</Paragraphs>
|
|
||||||
<rd:DefaultName>Textbox49</rd:DefaultName>
|
|
||||||
<Top>1.11062cm</Top>
|
|
||||||
<Left>11.91074cm</Left>
|
|
||||||
<Height>0.73293cm</Height>
|
|
||||||
<Width>3.02917cm</Width>
|
|
||||||
<ZIndex>4</ZIndex>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
<VerticalAlign>Middle</VerticalAlign>
|
|
||||||
<PaddingLeft>2pt</PaddingLeft>
|
|
||||||
<PaddingRight>2pt</PaddingRight>
|
|
||||||
<PaddingTop>2pt</PaddingTop>
|
|
||||||
<PaddingBottom>2pt</PaddingBottom>
|
|
||||||
</Style>
|
|
||||||
</Textbox>
|
|
||||||
</ReportItems>
|
|
||||||
<Style>
|
|
||||||
<Border>
|
|
||||||
<Style>None</Style>
|
|
||||||
</Border>
|
|
||||||
</Style>
|
|
||||||
</PageHeader>
|
|
||||||
<PageHeight>29.7cm</PageHeight>
|
|
||||||
<PageWidth>21cm</PageWidth>
|
|
||||||
<LeftMargin>0cm</LeftMargin>
|
|
||||||
<RightMargin>0cm</RightMargin>
|
|
||||||
<TopMargin>0.5cm</TopMargin>
|
|
||||||
<BottomMargin>0.5cm</BottomMargin>
|
|
||||||
<ColumnSpacing>0.13cm</ColumnSpacing>
|
|
||||||
<Style />
|
|
||||||
</Page>
|
|
||||||
</ReportSection>
|
|
||||||
</ReportSections>
|
|
||||||
<ReportParameters>
|
|
||||||
<ReportParameter Name="FechaDesde">
|
|
||||||
<DataType>DateTime</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
<ReportParameter Name="FechaHasta">
|
|
||||||
<DataType>DateTime</DataType>
|
|
||||||
<Prompt>ReportParameter1</Prompt>
|
|
||||||
</ReportParameter>
|
|
||||||
</ReportParameters>
|
|
||||||
<ReportParametersLayout>
|
|
||||||
<GridLayoutDefinition>
|
|
||||||
<NumberOfColumns>4</NumberOfColumns>
|
|
||||||
<NumberOfRows>2</NumberOfRows>
|
|
||||||
<CellDefinitions>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>2</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>FechaDesde</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
<CellDefinition>
|
|
||||||
<ColumnIndex>3</ColumnIndex>
|
|
||||||
<RowIndex>0</RowIndex>
|
|
||||||
<ParameterName>FechaHasta</ParameterName>
|
|
||||||
</CellDefinition>
|
|
||||||
</CellDefinitions>
|
|
||||||
</GridLayoutDefinition>
|
|
||||||
</ReportParametersLayout>
|
|
||||||
<rd:ReportUnitType>Cm</rd:ReportUnitType>
|
|
||||||
<rd:ReportID>8cf8fb7a-ec4d-4153-8fb0-a21a9e443a88</rd:ReportID>
|
|
||||||
</Report>
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Suscripciones;
|
||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/ajustes")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class AjustesController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IAjusteService _ajusteService;
|
||||||
|
private readonly ILogger<AjustesController> _logger;
|
||||||
|
|
||||||
|
// Permiso a crear en BD
|
||||||
|
private const string PermisoGestionarAjustes = "SU011";
|
||||||
|
|
||||||
|
public AjustesController(IAjusteService ajusteService, ILogger<AjustesController> logger)
|
||||||
|
{
|
||||||
|
_ajusteService = ajusteService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/suscriptores/{idSuscriptor}/ajustes
|
||||||
|
[HttpGet("~/api/suscriptores/{idSuscriptor:int}/ajustes")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<AjusteDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetAjustesPorSuscriptor(int idSuscriptor, [FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarAjustes)) return Forbid();
|
||||||
|
var ajustes = await _ajusteService.ObtenerAjustesPorSuscriptor(idSuscriptor, fechaDesde, fechaHasta);
|
||||||
|
return Ok(ajustes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/ajustes
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(AjusteDto), StatusCodes.Status201Created)]
|
||||||
|
public async Task<IActionResult> CreateAjuste([FromBody] CreateAjusteDto createDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarAjustes)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (dto, error) = await _ajusteService.CrearAjusteManual(createDto, userId.Value);
|
||||||
|
|
||||||
|
if (error != null) return BadRequest(new { message = error });
|
||||||
|
if (dto == null) return StatusCode(500, "Error al crear el ajuste.");
|
||||||
|
|
||||||
|
// Devolvemos el objeto creado con un 201
|
||||||
|
return StatusCode(201, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/ajustes/{id}/anular
|
||||||
|
[HttpPost("{id:int}/anular")]
|
||||||
|
public async Task<IActionResult> Anular(int id)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarAjustes)) return Forbid();
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _ajusteService.AnularAjuste(id, userId.Value);
|
||||||
|
if (!exito) return BadRequest(new { message = error });
|
||||||
|
|
||||||
|
return Ok(new { message = "Ajuste anulado correctamente." });
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: api/ajustes/{id}
|
||||||
|
[HttpPut("{id:int}")]
|
||||||
|
public async Task<IActionResult> UpdateAjuste(int id, [FromBody] UpdateAjusteDto updateDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarAjustes)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var (exito, error) = await _ajusteService.ActualizarAjuste(id, updateDto);
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
// Archivo: GestionIntegral.Api/Controllers/Suscripciones/DebitosController.cs
|
||||||
|
|
||||||
|
using GestionIntegral.Api.Dtos.Suscripciones;
|
||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/debitos")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class DebitosController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IDebitoAutomaticoService _debitoService;
|
||||||
|
private readonly ILogger<DebitosController> _logger;
|
||||||
|
|
||||||
|
// Permiso para generar archivos de débito (a crear en BD)
|
||||||
|
private const string PermisoGenerarDebitos = "SU007";
|
||||||
|
|
||||||
|
public DebitosController(IDebitoAutomaticoService debitoService, ILogger<DebitosController> logger)
|
||||||
|
{
|
||||||
|
_debitoService = debitoService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/debitos/{anio}/{mes}/generar-archivo
|
||||||
|
[HttpPost("{anio:int}/{mes:int}/generar-archivo")]
|
||||||
|
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> GenerarArchivo(int anio, int mes)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGenerarDebitos)) return Forbid();
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (contenido, nombreArchivo, error) = await _debitoService.GenerarArchivoPagoDirecto(anio, mes, userId.Value);
|
||||||
|
|
||||||
|
if (error != null)
|
||||||
|
{
|
||||||
|
// Si el error es "No se encontraron facturas", es un 404. Otros son 400.
|
||||||
|
if (error.Contains("No se encontraron"))
|
||||||
|
{
|
||||||
|
return NotFound(new { message = error });
|
||||||
|
}
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(contenido) || string.IsNullOrEmpty(nombreArchivo))
|
||||||
|
{
|
||||||
|
return StatusCode(500, new { message = "El servicio no pudo generar el contenido del archivo correctamente." });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Devolver el archivo para descarga
|
||||||
|
var fileBytes = Encoding.UTF8.GetBytes(contenido);
|
||||||
|
return File(fileBytes, "text/plain", nombreArchivo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/debitos/procesar-respuesta
|
||||||
|
[HttpPost("procesar-respuesta")]
|
||||||
|
[ProducesResponseType(typeof(ProcesamientoLoteResponseDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<IActionResult> ProcesarArchivoRespuesta(IFormFile archivo)
|
||||||
|
{
|
||||||
|
// Usamos el mismo permiso de generar débitos para procesar la respuesta.
|
||||||
|
if (!TienePermiso(PermisoGenerarDebitos)) return Forbid();
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var resultado = await _debitoService.ProcesarArchivoRespuesta(archivo, userId.Value);
|
||||||
|
|
||||||
|
if (resultado.Errores.Any() && resultado.PagosAprobados == 0 && resultado.PagosRechazados == 0)
|
||||||
|
{
|
||||||
|
return BadRequest(resultado);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(resultado);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Comunicaciones;
|
||||||
|
using GestionIntegral.Api.Services.Comunicaciones;
|
||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/facturacion")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class FacturacionController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IFacturacionService _facturacionService;
|
||||||
|
private readonly ILogger<FacturacionController> _logger;
|
||||||
|
private readonly IEmailLogService _emailLogService;
|
||||||
|
private const string PermisoGestionarFacturacion = "SU006";
|
||||||
|
private const string PermisoEnviarEmail = "SU009";
|
||||||
|
|
||||||
|
public FacturacionController(IFacturacionService facturacionService, ILogger<FacturacionController> logger, IEmailLogService emailLogService)
|
||||||
|
{
|
||||||
|
_facturacionService = facturacionService;
|
||||||
|
_logger = logger;
|
||||||
|
_emailLogService = emailLogService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
_logger.LogWarning("No se pudo obtener el UserId del token JWT en FacturacionController.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{idFactura:int}/numero-factura")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
public async Task<IActionResult> UpdateNumeroFactura(int idFactura, [FromBody] string numeroFactura)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid();
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _facturacionService.ActualizarNumeroFactura(idFactura, numeroFactura, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no existe")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{idFactura:int}/enviar-factura-pdf")]
|
||||||
|
public async Task<IActionResult> EnviarFacturaPdf(int idFactura)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoEnviarEmail)) return Forbid();
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
var (exito, error, emailDestino) = await _facturacionService.EnviarFacturaPdfPorEmail(idFactura, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
|
||||||
|
var mensajeExito = $"El email con la factura PDF se ha enviado correctamente a {emailDestino}.";
|
||||||
|
return Ok(new { message = mensajeExito });
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{anio:int}/{mes:int}")]
|
||||||
|
public async Task<IActionResult> GetFacturas(
|
||||||
|
int anio, int mes,
|
||||||
|
[FromQuery] string? nombreSuscriptor,
|
||||||
|
[FromQuery] string? estadoPago,
|
||||||
|
[FromQuery] string? estadoFacturacion,
|
||||||
|
[FromQuery] string? tipoFactura)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid();
|
||||||
|
if (anio < 2020 || mes < 1 || mes > 12) return BadRequest(new { message = "El período no es válido." });
|
||||||
|
|
||||||
|
var resumenes = await _facturacionService.ObtenerResumenesDeCuentaPorPeriodo(anio, mes, nombreSuscriptor, estadoPago, estadoFacturacion, tipoFactura);
|
||||||
|
return Ok(resumenes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{anio:int}/{mes:int}")]
|
||||||
|
public async Task<IActionResult> GenerarFacturacion(int anio, int mes)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid();
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
if (anio < 2020 || mes < 1 || mes > 12) return BadRequest(new { message = "El año y el mes proporcionados no son válidos." });
|
||||||
|
|
||||||
|
var (exito, mensaje, resultadoEnvio) = await _facturacionService.GenerarFacturacionMensual(anio, mes, userId.Value);
|
||||||
|
|
||||||
|
if (!exito) return StatusCode(StatusCodes.Status500InternalServerError, new { message = mensaje });
|
||||||
|
|
||||||
|
return Ok(new { message = mensaje, resultadoEnvio });
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("historial-lotes-envio")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<LoteDeEnvioHistorialDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialLotesEnvio([FromQuery] int? anio, [FromQuery] int? mes)
|
||||||
|
{
|
||||||
|
if (!TienePermiso("SU006")) return Forbid();
|
||||||
|
var historial = await _facturacionService.ObtenerHistorialLotesEnvio(anio, mes);
|
||||||
|
return Ok(historial);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endpoint para el historial de envíos de una factura individual
|
||||||
|
[HttpGet("{idFactura:int}/historial-envios")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<EmailLogDto>), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GetHistorialEnvios(int idFactura)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarFacturacion)) return Forbid(); // Reutilizamos el permiso
|
||||||
|
|
||||||
|
// Construimos la referencia que se guarda en el log
|
||||||
|
string referencia = $"Factura-{idFactura}";
|
||||||
|
var historial = await _emailLogService.ObtenerHistorialPorReferencia(referencia);
|
||||||
|
|
||||||
|
return Ok(historial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/formaspago")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize] // Solo usuarios logueados pueden ver esto
|
||||||
|
public class FormasDePagoController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IFormaPagoService _formaPagoService;
|
||||||
|
|
||||||
|
public FormasDePagoController(IFormaPagoService formaPagoService)
|
||||||
|
{
|
||||||
|
_formaPagoService = formaPagoService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/formaspago
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAll()
|
||||||
|
{
|
||||||
|
var formasDePago = await _formaPagoService.ObtenerTodos();
|
||||||
|
return Ok(formasDePago);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Suscripciones;
|
||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/pagos")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class PagosController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IPagoService _pagoService;
|
||||||
|
private readonly ILogger<PagosController> _logger;
|
||||||
|
|
||||||
|
// Permiso para registrar pagos manuales (a crear en BD)
|
||||||
|
private const string PermisoRegistrarPago = "SU008";
|
||||||
|
|
||||||
|
public PagosController(IPagoService pagoService, ILogger<PagosController> logger)
|
||||||
|
{
|
||||||
|
_pagoService = pagoService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/facturas/{idFactura}/pagos
|
||||||
|
[HttpGet("~/api/facturas/{idFactura:int}/pagos")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<PagoDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetPagosPorFactura(int idFactura)
|
||||||
|
{
|
||||||
|
// Se podría usar un permiso de "Ver Facturación"
|
||||||
|
if (!TienePermiso("SU006")) return Forbid();
|
||||||
|
|
||||||
|
var pagos = await _pagoService.ObtenerPagosPorFacturaId(idFactura);
|
||||||
|
return Ok(pagos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/pagos
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(PagoDto), StatusCodes.Status201Created)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> RegistrarPago([FromBody] CreatePagoDto createDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoRegistrarPago)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (dto, error) = await _pagoService.RegistrarPagoManual(createDto, userId.Value);
|
||||||
|
|
||||||
|
if (error != null) return BadRequest(new { message = error });
|
||||||
|
if (dto == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al registrar el pago.");
|
||||||
|
|
||||||
|
// No tenemos un "GetById" para pagos, así que devolvemos el objeto con un 201.
|
||||||
|
return StatusCode(201, dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Suscripciones;
|
||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/promociones")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class PromocionesController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IPromocionService _promocionService;
|
||||||
|
private readonly ILogger<PromocionesController> _logger;
|
||||||
|
|
||||||
|
// Permiso a crear en BD
|
||||||
|
private const string PermisoGestionarPromociones = "SU010";
|
||||||
|
|
||||||
|
public PromocionesController(IPromocionService promocionService, ILogger<PromocionesController> logger)
|
||||||
|
{
|
||||||
|
_promocionService = promocionService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/promociones
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetAll([FromQuery] bool soloActivas = true)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarPromociones)) return Forbid();
|
||||||
|
var promociones = await _promocionService.ObtenerTodas(soloActivas);
|
||||||
|
return Ok(promociones);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/promociones/{id}
|
||||||
|
[HttpGet("{id:int}", Name = "GetPromocionById")]
|
||||||
|
public async Task<IActionResult> GetById(int id)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarPromociones)) return Forbid();
|
||||||
|
var promocion = await _promocionService.ObtenerPorId(id);
|
||||||
|
if (promocion == null) return NotFound();
|
||||||
|
return Ok(promocion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/promociones
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> Create([FromBody] CreatePromocionDto createDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarPromociones)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (dto, error) = await _promocionService.Crear(createDto, userId.Value);
|
||||||
|
|
||||||
|
if (error != null) return BadRequest(new { message = error });
|
||||||
|
if (dto == null) return StatusCode(500, "Error al crear la promoción.");
|
||||||
|
|
||||||
|
return CreatedAtRoute("GetPromocionById", new { id = dto.IdPromocion }, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: api/promociones/{id}
|
||||||
|
[HttpPut("{id:int}")]
|
||||||
|
public async Task<IActionResult> Update(int id, [FromBody] UpdatePromocionDto updateDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarPromociones)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _promocionService.Actualizar(id, updateDto, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrada")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
// Archivo: GestionIntegral.Api/Controllers/Suscripciones/SuscripcionesController.cs
|
||||||
|
|
||||||
|
using GestionIntegral.Api.Dtos.Suscripciones;
|
||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/suscripciones")] // Ruta base para acciones sobre una suscripción específica
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class SuscripcionesController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ISuscripcionService _suscripcionService;
|
||||||
|
private readonly ILogger<SuscripcionesController> _logger;
|
||||||
|
|
||||||
|
// Permisos (nuevos, a crear en la BD)
|
||||||
|
private const string PermisoGestionarSuscripciones = "SU005";
|
||||||
|
|
||||||
|
public SuscripcionesController(ISuscripcionService suscripcionService, ILogger<SuscripcionesController> logger)
|
||||||
|
{
|
||||||
|
_suscripcionService = suscripcionService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
_logger.LogWarning("No se pudo obtener el UserId del token JWT en SuscripcionesController.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endpoint anidado para obtener las suscripciones de un suscriptor
|
||||||
|
// GET: api/suscriptores/{idSuscriptor}/suscripciones
|
||||||
|
[HttpGet("~/api/suscriptores/{idSuscriptor:int}/suscripciones")]
|
||||||
|
public async Task<IActionResult> GetBySuscriptor(int idSuscriptor)
|
||||||
|
{
|
||||||
|
// Se podría usar el permiso de ver suscriptores (SU001) o el de gestionar suscripciones (SU005)
|
||||||
|
if (!TienePermiso("SU001")) return Forbid();
|
||||||
|
|
||||||
|
var suscripciones = await _suscripcionService.ObtenerPorSuscriptorId(idSuscriptor);
|
||||||
|
return Ok(suscripciones);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/suscripciones/{id}
|
||||||
|
[HttpGet("{id:int}", Name = "GetSuscripcionById")]
|
||||||
|
public async Task<IActionResult> GetById(int id)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarSuscripciones)) return Forbid();
|
||||||
|
var suscripcion = await _suscripcionService.ObtenerPorId(id);
|
||||||
|
if (suscripcion == null) return NotFound();
|
||||||
|
return Ok(suscripcion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/suscripciones
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> Create([FromBody] CreateSuscripcionDto createDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarSuscripciones)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (dto, error) = await _suscripcionService.Crear(createDto, userId.Value);
|
||||||
|
|
||||||
|
if (error != null) return BadRequest(new { message = error });
|
||||||
|
if (dto == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear la suscripción.");
|
||||||
|
|
||||||
|
return CreatedAtRoute("GetSuscripcionById", new { id = dto.IdSuscripcion }, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: api/suscripciones/{id}
|
||||||
|
[HttpPut("{id:int}")]
|
||||||
|
public async Task<IActionResult> Update(int id, [FromBody] UpdateSuscripcionDto updateDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarSuscripciones)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _suscripcionService.Actualizar(id, updateDto, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrada")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/suscripciones/{idSuscripcion}/promociones
|
||||||
|
[HttpGet("{idSuscripcion:int}/promociones")]
|
||||||
|
public async Task<IActionResult> GetPromocionesAsignadas(int idSuscripcion)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarSuscripciones)) return Forbid();
|
||||||
|
var promos = await _suscripcionService.ObtenerPromocionesAsignadas(idSuscripcion);
|
||||||
|
return Ok(promos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/suscripciones/{idSuscripcion}/promociones-disponibles
|
||||||
|
[HttpGet("{idSuscripcion:int}/promociones-disponibles")]
|
||||||
|
public async Task<IActionResult> GetPromocionesDisponibles(int idSuscripcion)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarSuscripciones)) return Forbid();
|
||||||
|
var promos = await _suscripcionService.ObtenerPromocionesDisponibles(idSuscripcion);
|
||||||
|
return Ok(promos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/suscripciones/{idSuscripcion}/promociones
|
||||||
|
[HttpPost("{idSuscripcion:int}/promociones")]
|
||||||
|
public async Task<IActionResult> AsignarPromocion(int idSuscripcion, [FromBody] AsignarPromocionDto dto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarSuscripciones)) return Forbid();
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _suscripcionService.AsignarPromocion(idSuscripcion, dto, userId.Value);
|
||||||
|
if (!exito) return BadRequest(new { message = error });
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/suscripciones/{idSuscripcion}/promociones/{idPromocion}
|
||||||
|
[HttpDelete("{idSuscripcion:int}/promociones/{idPromocion:int}")]
|
||||||
|
public async Task<IActionResult> QuitarPromocion(int idSuscripcion, int idPromocion)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoGestionarSuscripciones)) return Forbid();
|
||||||
|
var (exito, error) = await _suscripcionService.QuitarPromocion(idSuscripcion, idPromocion);
|
||||||
|
if (!exito) return BadRequest(new { message = error });
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Suscripciones;
|
||||||
|
using GestionIntegral.Api.Services.Suscripciones;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Controllers.Suscripciones
|
||||||
|
{
|
||||||
|
[Route("api/suscriptores")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class SuscriptoresController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ISuscriptorService _suscriptorService;
|
||||||
|
private readonly ILogger<SuscriptoresController> _logger;
|
||||||
|
|
||||||
|
// Permisos para Suscriptores
|
||||||
|
private const string PermisoVer = "SU001";
|
||||||
|
private const string PermisoCrear = "SU002";
|
||||||
|
private const string PermisoModificar = "SU003";
|
||||||
|
private const string PermisoActivarDesactivar = "SU004";
|
||||||
|
|
||||||
|
public SuscriptoresController(ISuscriptorService suscriptorService, ILogger<SuscriptoresController> logger)
|
||||||
|
{
|
||||||
|
_suscriptorService = suscriptorService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc);
|
||||||
|
|
||||||
|
private int? GetCurrentUserId()
|
||||||
|
{
|
||||||
|
if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId;
|
||||||
|
_logger.LogWarning("No se pudo obtener el UserId del token JWT en SuscriptoresController.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/suscriptores
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<SuscriptorDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetAll([FromQuery] string? nombre, [FromQuery] string? nroDoc, [FromQuery] bool soloActivos = true)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
|
var suscriptores = await _suscriptorService.ObtenerTodos(nombre, nroDoc, soloActivos);
|
||||||
|
return Ok(suscriptores);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET: api/suscriptores/{id}
|
||||||
|
[HttpGet("{id:int}", Name = "GetSuscriptorById")]
|
||||||
|
[ProducesResponseType(typeof(SuscriptorDto), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> GetById(int id)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoVer)) return Forbid();
|
||||||
|
var suscriptor = await _suscriptorService.ObtenerPorId(id);
|
||||||
|
if (suscriptor == null) return NotFound();
|
||||||
|
return Ok(suscriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/suscriptores
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(SuscriptorDto), StatusCodes.Status201Created)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> Create([FromBody] CreateSuscriptorDto createDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoCrear)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (dto, error) = await _suscriptorService.Crear(createDto, userId.Value);
|
||||||
|
|
||||||
|
if (error != null) return BadRequest(new { message = error });
|
||||||
|
if (dto == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear el suscriptor.");
|
||||||
|
|
||||||
|
return CreatedAtRoute("GetSuscriptorById", new { id = dto.IdSuscriptor }, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT: api/suscriptores/{id}
|
||||||
|
[HttpPut("{id:int}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> Update(int id, [FromBody] UpdateSuscriptorDto updateDto)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoModificar)) return Forbid();
|
||||||
|
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _suscriptorService.Actualizar(id, updateDto, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE: api/suscriptores/{id} (Desactivar)
|
||||||
|
[HttpDelete("{id:int}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> Deactivate(int id)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoActivarDesactivar)) return Forbid();
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _suscriptorService.Desactivar(id, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST: api/suscriptores/{id}/activar
|
||||||
|
[HttpPost("{id:int}/activar")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> Activate(int id)
|
||||||
|
{
|
||||||
|
if (!TienePermiso(PermisoActivarDesactivar)) return Forbid();
|
||||||
|
|
||||||
|
var userId = GetCurrentUserId();
|
||||||
|
if (userId == null) return Unauthorized();
|
||||||
|
|
||||||
|
var (exito, error) = await _suscriptorService.Activar(id, userId.Value);
|
||||||
|
|
||||||
|
if (!exito)
|
||||||
|
{
|
||||||
|
if (error != null && error.Contains("no encontrado")) return NotFound(new { message = error });
|
||||||
|
return BadRequest(new { message = error });
|
||||||
|
}
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using Dapper;
|
||||||
|
using GestionIntegral.Api.Models.Comunicaciones;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Data.Repositories.Comunicaciones
|
||||||
|
{
|
||||||
|
public class EmailLogRepository : IEmailLogRepository
|
||||||
|
{
|
||||||
|
private readonly DbConnectionFactory _connectionFactory;
|
||||||
|
private readonly ILogger<EmailLogRepository> _logger;
|
||||||
|
public EmailLogRepository(DbConnectionFactory connectionFactory, ILogger<EmailLogRepository> logger)
|
||||||
|
{
|
||||||
|
_connectionFactory = connectionFactory;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CreateAsync(EmailLog log)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
INSERT INTO dbo.com_EmailLogs
|
||||||
|
(FechaEnvio, DestinatarioEmail, Asunto, Estado, Error, IdUsuarioDisparo, Origen, ReferenciaId, IdLoteDeEnvio)
|
||||||
|
VALUES
|
||||||
|
(@FechaEnvio, @DestinatarioEmail, @Asunto, @Estado, @Error, @IdUsuarioDisparo, @Origen, @ReferenciaId, @IdLoteDeEnvio);";
|
||||||
|
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
await connection.ExecuteAsync(sql, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<EmailLog>> GetByReferenceAsync(string referenciaId)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
SELECT * FROM dbo.com_EmailLogs
|
||||||
|
WHERE ReferenciaId = @ReferenciaId
|
||||||
|
ORDER BY FechaEnvio DESC;";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QueryAsync<EmailLog>(sql, new { ReferenciaId = referenciaId });
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener logs de email por ReferenciaId: {ReferenciaId}", referenciaId);
|
||||||
|
return Enumerable.Empty<EmailLog>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<EmailLog>> GetByLoteIdAsync(int idLoteDeEnvio)
|
||||||
|
{
|
||||||
|
// Ordenamos por Estado descendente para que los 'Fallidos' aparezcan primero
|
||||||
|
const string sql = @"
|
||||||
|
SELECT * FROM dbo.com_EmailLogs
|
||||||
|
WHERE IdLoteDeEnvio = @IdLoteDeEnvio
|
||||||
|
ORDER BY Estado DESC, FechaEnvio DESC;";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QueryAsync<EmailLog>(sql, new { IdLoteDeEnvio = idLoteDeEnvio });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener logs de email por IdLoteDeEnvio: {IdLoteDeEnvio}", idLoteDeEnvio);
|
||||||
|
return Enumerable.Empty<EmailLog>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using GestionIntegral.Api.Models.Comunicaciones;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Data.Repositories.Comunicaciones
|
||||||
|
{
|
||||||
|
public interface IEmailLogRepository
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Guarda un nuevo registro de log de email en la base de datos.
|
||||||
|
/// </summary>
|
||||||
|
Task CreateAsync(EmailLog log);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Obtiene todos los registros de log de email que coinciden con una referencia específica.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="referenciaId">El identificador de la entidad (ej. "Factura-59").</param>
|
||||||
|
/// <returns>Una colección de registros de log de email.</returns>
|
||||||
|
Task<IEnumerable<EmailLog>> GetByReferenceAsync(string referenciaId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Obtiene todos los registros de log de email que pertenecen a un lote de envío masivo.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idLoteDeEnvio">El ID del lote de envío.</param>
|
||||||
|
/// <returns>Una colección de registros de log de email.</returns>
|
||||||
|
Task<IEnumerable<EmailLog>> GetByLoteIdAsync(int idLoteDeEnvio);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using GestionIntegral.Api.Models.Comunicaciones;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Data.Repositories.Comunicaciones
|
||||||
|
{
|
||||||
|
public interface ILoteDeEnvioRepository
|
||||||
|
{
|
||||||
|
Task<LoteDeEnvio> CreateAsync(LoteDeEnvio lote);
|
||||||
|
Task<bool> UpdateAsync(LoteDeEnvio lote);
|
||||||
|
Task<IEnumerable<LoteDeEnvio>> GetAllAsync(int? anio, int? mes);
|
||||||
|
Task<LoteDeEnvio?> GetByIdAsync(int id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Text;
|
||||||
|
using Dapper;
|
||||||
|
using GestionIntegral.Api.Models.Comunicaciones;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Data.Repositories.Comunicaciones
|
||||||
|
{
|
||||||
|
public class LoteDeEnvioRepository : ILoteDeEnvioRepository
|
||||||
|
{
|
||||||
|
private readonly DbConnectionFactory _connectionFactory;
|
||||||
|
public LoteDeEnvioRepository(DbConnectionFactory connectionFactory)
|
||||||
|
{
|
||||||
|
_connectionFactory = connectionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<LoteDeEnvio> CreateAsync(LoteDeEnvio lote)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
INSERT INTO dbo.com_LotesDeEnvio (FechaInicio, Periodo, Origen, Estado, IdUsuarioDisparo)
|
||||||
|
OUTPUT INSERTED.*
|
||||||
|
VALUES (@FechaInicio, @Periodo, @Origen, @Estado, @IdUsuarioDisparo);";
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QuerySingleAsync<LoteDeEnvio>(sql, lote);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateAsync(LoteDeEnvio lote)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
UPDATE dbo.com_LotesDeEnvio SET
|
||||||
|
FechaFin = @FechaFin,
|
||||||
|
Estado = @Estado,
|
||||||
|
TotalCorreos = @TotalCorreos,
|
||||||
|
TotalEnviados = @TotalEnviados,
|
||||||
|
TotalFallidos = @TotalFallidos
|
||||||
|
WHERE IdLoteDeEnvio = @IdLoteDeEnvio;";
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
var rows = await connection.ExecuteAsync(sql, lote);
|
||||||
|
return rows == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<LoteDeEnvio>> GetAllAsync(int? anio, int? mes)
|
||||||
|
{
|
||||||
|
var sqlBuilder = new StringBuilder("SELECT * FROM dbo.com_LotesDeEnvio WHERE 1=1");
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (anio.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND YEAR(FechaInicio) = @Anio");
|
||||||
|
parameters.Add("Anio", anio.Value);
|
||||||
|
}
|
||||||
|
if (mes.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND MONTH(FechaInicio) = @Mes");
|
||||||
|
parameters.Add("Mes", mes.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY FechaInicio DESC;");
|
||||||
|
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QueryAsync<LoteDeEnvio>(sqlBuilder.ToString(), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<LoteDeEnvio?> GetByIdAsync(int id)
|
||||||
|
{
|
||||||
|
const string sql = "SELECT * FROM dbo.com_LotesDeEnvio WHERE IdLoteDeEnvio = @Id;";
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<LoteDeEnvio>(sql, new { Id = id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,435 @@
|
|||||||
|
using Dapper;
|
||||||
|
using GestionIntegral.Api.Dtos.Auditoria;
|
||||||
|
using GestionIntegral.Api.Dtos.Contables;
|
||||||
|
using GestionIntegral.Api.Models.Contables;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Data.Repositories.Contables
|
||||||
|
{
|
||||||
|
public class CierreCuentaCorrienteRepository : ICierreCuentaCorrienteRepository
|
||||||
|
{
|
||||||
|
private readonly DbConnectionFactory _cf;
|
||||||
|
private readonly ILogger<CierreCuentaCorrienteRepository> _log;
|
||||||
|
|
||||||
|
public CierreCuentaCorrienteRepository(DbConnectionFactory cf, ILogger<CierreCuentaCorrienteRepository> log)
|
||||||
|
{
|
||||||
|
_cf = cf;
|
||||||
|
_log = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aliases SELECT — mapean Id_X (SQL) → IdX (modelo C#).
|
||||||
|
private const string SelectModelBase = @"
|
||||||
|
SELECT
|
||||||
|
Id_Cierre AS IdCierre,
|
||||||
|
Id_Distribuidor AS IdDistribuidor,
|
||||||
|
Id_Empresa AS IdEmpresa,
|
||||||
|
FechaCorte,
|
||||||
|
FechaCierre,
|
||||||
|
SaldoCierre,
|
||||||
|
Estado,
|
||||||
|
Justificacion,
|
||||||
|
Id_Usuario_Cierre AS IdUsuarioCierre,
|
||||||
|
Id_Usuario_Anula AS IdUsuarioAnula,
|
||||||
|
FechaAnulacion,
|
||||||
|
Justificacion_Anulacion AS JustificacionAnulacion
|
||||||
|
FROM dbo.cue_CierresCuentaCorriente";
|
||||||
|
|
||||||
|
public async Task<CierreCuentaCorriente?> GetByIdAsync(int idCierre)
|
||||||
|
{
|
||||||
|
var sql = SelectModelBase + " WHERE Id_Cierre = @IdCierreParam;";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<CierreCuentaCorriente>(sql, new { IdCierreParam = idCierre });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error al obtener Cierre por ID: {IdCierre}", idCierre);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CierreCuentaCorriente?> GetUltimoCierreVigenteAsync(int idDistribuidor, int idEmpresa, IDbTransaction? transaction = null)
|
||||||
|
{
|
||||||
|
var sql = @"
|
||||||
|
SELECT TOP 1
|
||||||
|
Id_Cierre AS IdCierre,
|
||||||
|
Id_Distribuidor AS IdDistribuidor,
|
||||||
|
Id_Empresa AS IdEmpresa,
|
||||||
|
FechaCorte,
|
||||||
|
FechaCierre,
|
||||||
|
SaldoCierre,
|
||||||
|
Estado,
|
||||||
|
Justificacion,
|
||||||
|
Id_Usuario_Cierre AS IdUsuarioCierre,
|
||||||
|
Id_Usuario_Anula AS IdUsuarioAnula,
|
||||||
|
FechaAnulacion,
|
||||||
|
Justificacion_Anulacion AS JustificacionAnulacion
|
||||||
|
FROM dbo.cue_CierresCuentaCorriente
|
||||||
|
WHERE Id_Distribuidor = @IdDist
|
||||||
|
AND Id_Empresa = @IdEmp
|
||||||
|
AND Estado = 'Activo'
|
||||||
|
ORDER BY FechaCorte DESC, Id_Cierre DESC;";
|
||||||
|
|
||||||
|
var parameters = new { IdDist = idDistribuidor, IdEmp = idEmpresa };
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
return await transaction.Connection!.QuerySingleOrDefaultAsync<CierreCuentaCorriente>(sql, parameters, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<CierreCuentaCorriente>(sql, parameters);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error al obtener último cierre vigente Dist={IdDist} Emp={IdEmp}", idDistribuidor, idEmpresa);
|
||||||
|
if (transaction != null) throw;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CierreCuentaCorriente?> GetCierreVigenteParaFechaAsync(int idDistribuidor, int idEmpresa, DateTime fechaOperacion)
|
||||||
|
{
|
||||||
|
// Cae en período cerrado si existe un cierre Activo cuya FechaCorte sea >= fechaOperacion (la fecha está dentro del período cerrado).
|
||||||
|
// Se devuelve el más reciente (TOP 1 ORDER BY FechaCorte DESC) — el más restrictivo desde la perspectiva de la fecha consultada.
|
||||||
|
const string sql = @"
|
||||||
|
SELECT TOP 1
|
||||||
|
Id_Cierre AS IdCierre,
|
||||||
|
Id_Distribuidor AS IdDistribuidor,
|
||||||
|
Id_Empresa AS IdEmpresa,
|
||||||
|
FechaCorte,
|
||||||
|
FechaCierre,
|
||||||
|
SaldoCierre,
|
||||||
|
Estado,
|
||||||
|
Justificacion,
|
||||||
|
Id_Usuario_Cierre AS IdUsuarioCierre,
|
||||||
|
Id_Usuario_Anula AS IdUsuarioAnula,
|
||||||
|
FechaAnulacion,
|
||||||
|
Justificacion_Anulacion AS JustificacionAnulacion
|
||||||
|
FROM dbo.cue_CierresCuentaCorriente
|
||||||
|
WHERE Id_Distribuidor = @IdDist
|
||||||
|
AND Id_Empresa = @IdEmp
|
||||||
|
AND Estado = 'Activo'
|
||||||
|
AND FechaCorte >= @FechaOp
|
||||||
|
ORDER BY FechaCorte DESC, Id_Cierre DESC;";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<CierreCuentaCorriente>(sql, new
|
||||||
|
{
|
||||||
|
IdDist = idDistribuidor,
|
||||||
|
IdEmp = idEmpresa,
|
||||||
|
FechaOp = fechaOperacion.Date
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error en GetCierreVigenteParaFechaAsync Dist={IdDist} Emp={IdEmp} Fecha={Fecha}", idDistribuidor, idEmpresa, fechaOperacion);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> ExisteCierrePosteriorVigenteAsync(int idDistribuidor, int idEmpresa, DateTime fechaCorte, int? excluirIdCierre = null, IDbTransaction? transaction = null)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
SELECT CASE WHEN EXISTS (
|
||||||
|
SELECT 1 FROM dbo.cue_CierresCuentaCorriente
|
||||||
|
WHERE Id_Distribuidor = @IdDist
|
||||||
|
AND Id_Empresa = @IdEmp
|
||||||
|
AND Estado = 'Activo'
|
||||||
|
AND FechaCorte > @FechaCorte
|
||||||
|
AND (@Excluir IS NULL OR Id_Cierre <> @Excluir)
|
||||||
|
) THEN 1 ELSE 0 END;";
|
||||||
|
|
||||||
|
var parameters = new
|
||||||
|
{
|
||||||
|
IdDist = idDistribuidor,
|
||||||
|
IdEmp = idEmpresa,
|
||||||
|
FechaCorte = fechaCorte.Date,
|
||||||
|
Excluir = excluirIdCierre
|
||||||
|
};
|
||||||
|
|
||||||
|
if (transaction != null)
|
||||||
|
{
|
||||||
|
return await transaction.Connection!.ExecuteScalarAsync<bool>(sql, parameters, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
return await connection.ExecuteScalarAsync<bool>(sql, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateAsync(CierreCuentaCorriente cierre, int idUsuarioMod, IDbTransaction transaction)
|
||||||
|
{
|
||||||
|
const string sqlInsertMaster = @"
|
||||||
|
INSERT INTO dbo.cue_CierresCuentaCorriente
|
||||||
|
(Id_Distribuidor, Id_Empresa, FechaCorte, FechaCierre, SaldoCierre, Estado, Justificacion, Id_Usuario_Cierre)
|
||||||
|
VALUES
|
||||||
|
(@IdDistribuidor, @IdEmpresa, @FechaCorte, @FechaCierre, @SaldoCierre, @Estado, @Justificacion, @IdUsuarioCierre);
|
||||||
|
SELECT CAST(SCOPE_IDENTITY() AS INT);";
|
||||||
|
|
||||||
|
var idCierre = await transaction.Connection!.ExecuteScalarAsync<int>(sqlInsertMaster, new
|
||||||
|
{
|
||||||
|
cierre.IdDistribuidor,
|
||||||
|
cierre.IdEmpresa,
|
||||||
|
FechaCorte = cierre.FechaCorte.Date,
|
||||||
|
cierre.FechaCierre,
|
||||||
|
cierre.SaldoCierre,
|
||||||
|
cierre.Estado,
|
||||||
|
cierre.Justificacion,
|
||||||
|
cierre.IdUsuarioCierre
|
||||||
|
}, transaction);
|
||||||
|
|
||||||
|
if (idCierre <= 0) throw new DataException("No se pudo crear el cierre — SCOPE_IDENTITY no devolvió valor.");
|
||||||
|
|
||||||
|
const string sqlInsertHist = @"
|
||||||
|
INSERT INTO dbo.cue_CierresCuentaCorriente_H
|
||||||
|
(Id_Cierre, Id_Distribuidor, Id_Empresa, FechaCorte, FechaCierre, SaldoCierre,
|
||||||
|
Estado, Justificacion, Id_Usuario_Cierre,
|
||||||
|
Id_Usuario_Anula, FechaAnulacion, Justificacion_Anulacion,
|
||||||
|
TipoMod, Id_Usuario_Mod, FechaMod)
|
||||||
|
VALUES
|
||||||
|
(@IdCierre, @IdDistribuidor, @IdEmpresa, @FechaCorte, @FechaCierre, @SaldoCierre,
|
||||||
|
@Estado, @Justificacion, @IdUsuarioCierre,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
@TipoMod, @IdUsuarioMod, @FechaMod);";
|
||||||
|
|
||||||
|
await transaction.Connection!.ExecuteAsync(sqlInsertHist, new
|
||||||
|
{
|
||||||
|
IdCierre = idCierre,
|
||||||
|
cierre.IdDistribuidor,
|
||||||
|
cierre.IdEmpresa,
|
||||||
|
FechaCorte = cierre.FechaCorte.Date,
|
||||||
|
cierre.FechaCierre,
|
||||||
|
cierre.SaldoCierre,
|
||||||
|
cierre.Estado,
|
||||||
|
cierre.Justificacion,
|
||||||
|
cierre.IdUsuarioCierre,
|
||||||
|
TipoMod = "Creacion",
|
||||||
|
IdUsuarioMod = idUsuarioMod,
|
||||||
|
FechaMod = DateTime.Now
|
||||||
|
}, transaction);
|
||||||
|
|
||||||
|
return idCierre;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> AnularAsync(int idCierre, int idUsuarioAnula, string justificacionAnulacion, int idUsuarioMod, IDbTransaction transaction)
|
||||||
|
{
|
||||||
|
// UPDATE atómico: solo cambia Estado si está actualmente Activo. Evita doble anulación concurrente.
|
||||||
|
const string sqlUpdate = @"
|
||||||
|
UPDATE dbo.cue_CierresCuentaCorriente
|
||||||
|
SET Estado = 'Anulado',
|
||||||
|
Id_Usuario_Anula = @IdUsuarioAnula,
|
||||||
|
FechaAnulacion = @FechaAnulacion,
|
||||||
|
Justificacion_Anulacion = @JustificacionAnulacion
|
||||||
|
WHERE Id_Cierre = @IdCierre
|
||||||
|
AND Estado = 'Activo';";
|
||||||
|
|
||||||
|
var fechaAnulacion = DateTime.Now;
|
||||||
|
|
||||||
|
int affected = await transaction.Connection!.ExecuteAsync(sqlUpdate, new
|
||||||
|
{
|
||||||
|
IdCierre = idCierre,
|
||||||
|
IdUsuarioAnula = idUsuarioAnula,
|
||||||
|
FechaAnulacion = fechaAnulacion,
|
||||||
|
JustificacionAnulacion = justificacionAnulacion
|
||||||
|
}, transaction);
|
||||||
|
|
||||||
|
if (affected != 1) return false;
|
||||||
|
|
||||||
|
// Snapshot post-update para el _H. Trae los valores ya actualizados.
|
||||||
|
const string sqlSnapshot = SelectModelBase + " WHERE Id_Cierre = @IdCierre;";
|
||||||
|
var actualizado = await transaction.Connection!.QuerySingleAsync<CierreCuentaCorriente>(sqlSnapshot, new { IdCierre = idCierre }, transaction);
|
||||||
|
|
||||||
|
const string sqlInsertHist = @"
|
||||||
|
INSERT INTO dbo.cue_CierresCuentaCorriente_H
|
||||||
|
(Id_Cierre, Id_Distribuidor, Id_Empresa, FechaCorte, FechaCierre, SaldoCierre,
|
||||||
|
Estado, Justificacion, Id_Usuario_Cierre,
|
||||||
|
Id_Usuario_Anula, FechaAnulacion, Justificacion_Anulacion,
|
||||||
|
TipoMod, Id_Usuario_Mod, FechaMod)
|
||||||
|
VALUES
|
||||||
|
(@IdCierre, @IdDistribuidor, @IdEmpresa, @FechaCorte, @FechaCierre, @SaldoCierre,
|
||||||
|
@Estado, @Justificacion, @IdUsuarioCierre,
|
||||||
|
@IdUsuarioAnula, @FechaAnulacion, @JustificacionAnulacion,
|
||||||
|
@TipoMod, @IdUsuarioMod, @FechaMod);";
|
||||||
|
|
||||||
|
await transaction.Connection!.ExecuteAsync(sqlInsertHist, new
|
||||||
|
{
|
||||||
|
IdCierre = actualizado.IdCierre,
|
||||||
|
actualizado.IdDistribuidor,
|
||||||
|
actualizado.IdEmpresa,
|
||||||
|
FechaCorte = actualizado.FechaCorte.Date,
|
||||||
|
actualizado.FechaCierre,
|
||||||
|
actualizado.SaldoCierre,
|
||||||
|
actualizado.Estado,
|
||||||
|
actualizado.Justificacion,
|
||||||
|
actualizado.IdUsuarioCierre,
|
||||||
|
actualizado.IdUsuarioAnula,
|
||||||
|
actualizado.FechaAnulacion,
|
||||||
|
JustificacionAnulacion = actualizado.JustificacionAnulacion,
|
||||||
|
TipoMod = "Reapertura",
|
||||||
|
IdUsuarioMod = idUsuarioMod,
|
||||||
|
FechaMod = DateTime.Now
|
||||||
|
}, transaction);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<CierreCuentaCorrienteDto>> GetAllAsync(
|
||||||
|
int? idDistribuidor, int? idEmpresa, string? estado,
|
||||||
|
DateTime? fechaCorteDesde, DateTime? fechaCorteHasta)
|
||||||
|
{
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
c.Id_Cierre AS IdCierre,
|
||||||
|
c.Id_Distribuidor AS IdDistribuidor,
|
||||||
|
d.Nombre AS NombreDistribuidor,
|
||||||
|
c.Id_Empresa AS IdEmpresa,
|
||||||
|
e.Nombre AS NombreEmpresa,
|
||||||
|
CONVERT(varchar(10), c.FechaCorte, 23) AS FechaCorte,
|
||||||
|
c.FechaCierre,
|
||||||
|
c.SaldoCierre,
|
||||||
|
c.Estado,
|
||||||
|
c.Justificacion,
|
||||||
|
c.Id_Usuario_Cierre AS IdUsuarioCierre,
|
||||||
|
(uc.Nombre + ' ' + uc.Apellido) AS NombreUsuarioCierre,
|
||||||
|
c.Id_Usuario_Anula AS IdUsuarioAnula,
|
||||||
|
CASE WHEN ua.Id IS NULL THEN NULL ELSE (ua.Nombre + ' ' + ua.Apellido) END AS NombreUsuarioAnula,
|
||||||
|
c.FechaAnulacion,
|
||||||
|
c.Justificacion_Anulacion AS JustificacionAnulacion,
|
||||||
|
CAST(CASE WHEN c.Estado = 'Activo'
|
||||||
|
AND c.Id_Cierre = (
|
||||||
|
SELECT TOP 1 c2.Id_Cierre FROM dbo.cue_CierresCuentaCorriente c2
|
||||||
|
WHERE c2.Id_Distribuidor = c.Id_Distribuidor
|
||||||
|
AND c2.Id_Empresa = c.Id_Empresa
|
||||||
|
AND c2.Estado = 'Activo'
|
||||||
|
ORDER BY c2.FechaCorte DESC, c2.Id_Cierre DESC)
|
||||||
|
THEN 1 ELSE 0 END AS bit) AS EsUltimoVigente
|
||||||
|
FROM dbo.cue_CierresCuentaCorriente c
|
||||||
|
JOIN dbo.dist_dtDistribuidores d ON d.Id_Distribuidor = c.Id_Distribuidor
|
||||||
|
JOIN dbo.dist_dtEmpresas e ON e.Id_Empresa = c.Id_Empresa
|
||||||
|
JOIN dbo.gral_Usuarios uc ON uc.Id = c.Id_Usuario_Cierre
|
||||||
|
LEFT JOIN dbo.gral_Usuarios ua ON ua.Id = c.Id_Usuario_Anula
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
if (idDistribuidor.HasValue) { sqlBuilder.Append(" AND c.Id_Distribuidor = @IdDist"); parameters.Add("IdDist", idDistribuidor.Value); }
|
||||||
|
if (idEmpresa.HasValue) { sqlBuilder.Append(" AND c.Id_Empresa = @IdEmp"); parameters.Add("IdEmp", idEmpresa.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(estado)) { sqlBuilder.Append(" AND c.Estado = @Estado"); parameters.Add("Estado", estado); }
|
||||||
|
if (fechaCorteDesde.HasValue) { sqlBuilder.Append(" AND c.FechaCorte >= @FechaDesde"); parameters.Add("FechaDesde", fechaCorteDesde.Value.Date); }
|
||||||
|
if (fechaCorteHasta.HasValue) { sqlBuilder.Append(" AND c.FechaCorte <= @FechaHasta"); parameters.Add("FechaHasta", fechaCorteHasta.Value.Date); }
|
||||||
|
sqlBuilder.Append(" ORDER BY c.FechaCorte DESC, c.Id_Cierre DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
return await connection.QueryAsync<CierreCuentaCorrienteDto>(sqlBuilder.ToString(), parameters);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error en GetAllAsync de CierresCuentaCorriente.");
|
||||||
|
return Enumerable.Empty<CierreCuentaCorrienteDto>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<CierreCuentaCorrienteHistorialDto>> GetHistorialAsync(int idCierre)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
SELECT
|
||||||
|
h.Id_Historial,
|
||||||
|
h.Id_Cierre,
|
||||||
|
h.Id_Distribuidor,
|
||||||
|
h.Id_Empresa,
|
||||||
|
h.FechaCorte,
|
||||||
|
h.FechaCierre,
|
||||||
|
h.SaldoCierre,
|
||||||
|
h.Estado,
|
||||||
|
h.Justificacion,
|
||||||
|
h.Id_Usuario_Cierre,
|
||||||
|
h.Id_Usuario_Anula,
|
||||||
|
h.FechaAnulacion,
|
||||||
|
h.Justificacion_Anulacion,
|
||||||
|
h.TipoMod,
|
||||||
|
h.Id_Usuario_Mod,
|
||||||
|
(u.Nombre + ' ' + u.Apellido) AS NombreUsuarioModifico,
|
||||||
|
h.FechaMod
|
||||||
|
FROM dbo.cue_CierresCuentaCorriente_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON u.Id = h.Id_Usuario_Mod
|
||||||
|
WHERE h.Id_Cierre = @IdCierre
|
||||||
|
ORDER BY h.FechaMod ASC, h.Id_Historial ASC;";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
return await connection.QueryAsync<CierreCuentaCorrienteHistorialDto>(sql, new { IdCierre = idCierre });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error en GetHistorialAsync para Cierre ID {IdCierre}", idCierre);
|
||||||
|
return Enumerable.Empty<CierreCuentaCorrienteHistorialDto>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<CierreCuentaCorrienteHistorialDto>> ObtenerHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idCierreAfectado)
|
||||||
|
{
|
||||||
|
// FechaMod cubre el rango inclusive: [fechaDesde 00:00, fechaHasta+1día). Patrón consistente con otros ObtenerHistorial del proyecto.
|
||||||
|
var sql = @"
|
||||||
|
SELECT
|
||||||
|
h.Id_Historial,
|
||||||
|
h.Id_Cierre,
|
||||||
|
h.Id_Distribuidor,
|
||||||
|
h.Id_Empresa,
|
||||||
|
h.FechaCorte,
|
||||||
|
h.FechaCierre,
|
||||||
|
h.SaldoCierre,
|
||||||
|
h.Estado,
|
||||||
|
h.Justificacion,
|
||||||
|
h.Id_Usuario_Cierre,
|
||||||
|
h.Id_Usuario_Anula,
|
||||||
|
h.FechaAnulacion,
|
||||||
|
h.Justificacion_Anulacion,
|
||||||
|
h.TipoMod,
|
||||||
|
h.Id_Usuario_Mod,
|
||||||
|
(u.Nombre + ' ' + u.Apellido) AS NombreUsuarioModifico,
|
||||||
|
h.FechaMod
|
||||||
|
FROM dbo.cue_CierresCuentaCorriente_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON u.Id = h.Id_Usuario_Mod
|
||||||
|
WHERE 1 = 1
|
||||||
|
AND (@FechaDesde IS NULL OR h.FechaMod >= @FechaDesde)
|
||||||
|
AND (@FechaHasta IS NULL OR h.FechaMod < DATEADD(DAY, 1, @FechaHasta))
|
||||||
|
AND (@IdUsuarioMod IS NULL OR h.Id_Usuario_Mod = @IdUsuarioMod)
|
||||||
|
AND (@TipoMod IS NULL OR h.TipoMod = @TipoMod)
|
||||||
|
AND (@IdCierre IS NULL OR h.Id_Cierre = @IdCierre)
|
||||||
|
ORDER BY h.FechaMod DESC, h.Id_Historial DESC;";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
return await connection.QueryAsync<CierreCuentaCorrienteHistorialDto>(sql, new
|
||||||
|
{
|
||||||
|
FechaDesde = fechaDesde?.Date,
|
||||||
|
FechaHasta = fechaHasta?.Date,
|
||||||
|
IdUsuarioMod = idUsuarioModifico,
|
||||||
|
TipoMod = tipoModificacion,
|
||||||
|
IdCierre = idCierreAfectado
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error en ObtenerHistorialAsync (auditoría) de Cierres CC.");
|
||||||
|
return Enumerable.Empty<CierreCuentaCorrienteHistorialDto>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using GestionIntegral.Api.Dtos.Auditoria;
|
||||||
|
using GestionIntegral.Api.Dtos.Contables;
|
||||||
|
using GestionIntegral.Api.Models.Contables;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Data.Repositories.Contables
|
||||||
|
{
|
||||||
|
public interface ICierreCuentaCorrienteRepository
|
||||||
|
{
|
||||||
|
Task<CierreCuentaCorriente?> GetByIdAsync(int idCierre);
|
||||||
|
|
||||||
|
// Devuelve el último cierre con Estado = 'Activo' para el par (Distribuidor + Empresa).
|
||||||
|
// Acepta una transacción opcional para usarse dentro del flujo Crear/Reabrir.
|
||||||
|
Task<CierreCuentaCorriente?> GetUltimoCierreVigenteAsync(int idDistribuidor, int idEmpresa, IDbTransaction? transaction = null);
|
||||||
|
|
||||||
|
// Verifica si la fecha cae dentro de un período cerrado: existe un cierre Activo con FechaCorte >= fechaOperacion.
|
||||||
|
Task<CierreCuentaCorriente?> GetCierreVigenteParaFechaAsync(int idDistribuidor, int idEmpresa, DateTime fechaOperacion);
|
||||||
|
|
||||||
|
// True si existe otro cierre Activo con FechaCorte > fechaCorte (excluyendo opcionalmente un cierre puntual).
|
||||||
|
// Se usa al reabrir para forzar la cascada manual.
|
||||||
|
Task<bool> ExisteCierrePosteriorVigenteAsync(int idDistribuidor, int idEmpresa, DateTime fechaCorte, int? excluirIdCierre = null, IDbTransaction? transaction = null);
|
||||||
|
|
||||||
|
// Crea la fila maestra y registra la entrada inicial en _H con TipoMod='Creacion'. Devuelve el Id_Cierre generado.
|
||||||
|
Task<int> CreateAsync(CierreCuentaCorriente cierre, int idUsuarioMod, IDbTransaction transaction);
|
||||||
|
|
||||||
|
// Marca un cierre como Anulado (UPDATE atómico solo si Estado='Activo') y registra entrada en _H con TipoMod='Reapertura'.
|
||||||
|
// Devuelve true si se anuló (Estado pasó de Activo a Anulado), false si ya estaba anulado o no existía.
|
||||||
|
Task<bool> AnularAsync(int idCierre, int idUsuarioAnula, string justificacionAnulacion, int idUsuarioMod, IDbTransaction transaction);
|
||||||
|
|
||||||
|
Task<IEnumerable<CierreCuentaCorrienteDto>> GetAllAsync(
|
||||||
|
int? idDistribuidor, int? idEmpresa, string? estado,
|
||||||
|
DateTime? fechaCorteDesde, DateTime? fechaCorteHasta);
|
||||||
|
|
||||||
|
Task<IEnumerable<CierreCuentaCorrienteHistorialDto>> GetHistorialAsync(int idCierre);
|
||||||
|
|
||||||
|
// Auditoría general: filtra el historial cruzado de todos los cierres por rango de FechaMod, usuario, tipo, y opcional Id_Cierre.
|
||||||
|
Task<IEnumerable<CierreCuentaCorrienteHistorialDto>> ObtenerHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idCierreAfectado);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,9 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
Task<NotaCreditoDebito?> CreateAsync(NotaCreditoDebito nuevaNota, int idUsuario, IDbTransaction transaction);
|
Task<NotaCreditoDebito?> CreateAsync(NotaCreditoDebito nuevaNota, int idUsuario, IDbTransaction transaction);
|
||||||
Task<bool> UpdateAsync(NotaCreditoDebito notaAActualizar, int idUsuario, IDbTransaction transaction);
|
Task<bool> UpdateAsync(NotaCreditoDebito notaAActualizar, int idUsuario, IDbTransaction transaction);
|
||||||
Task<bool> DeleteAsync(int idNota, int idUsuario, IDbTransaction transaction);
|
Task<bool> DeleteAsync(int idNota, int idUsuario, IDbTransaction transaction);
|
||||||
// No se suele validar unicidad por referencia, ya que podría repetirse.
|
Task<IEnumerable<(NotaCreditoDebitoHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idNotaOriginal); // Para filtrar por una nota específica
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,10 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
Task<PagoDistribuidor?> CreateAsync(PagoDistribuidor nuevoPago, int idUsuario, IDbTransaction transaction);
|
Task<PagoDistribuidor?> CreateAsync(PagoDistribuidor nuevoPago, int idUsuario, IDbTransaction transaction);
|
||||||
Task<bool> UpdateAsync(PagoDistribuidor pagoAActualizar, int idUsuario, IDbTransaction transaction);
|
Task<bool> UpdateAsync(PagoDistribuidor pagoAActualizar, int idUsuario, IDbTransaction transaction);
|
||||||
Task<bool> DeleteAsync(int idPago, int idUsuario, IDbTransaction transaction);
|
Task<bool> DeleteAsync(int idPago, int idUsuario, IDbTransaction transaction);
|
||||||
Task<bool> ExistsByReciboAndTipoMovimientoAsync(int recibo, string tipoMovimiento, int? excludeIdPago = null);
|
Task<PagoDistribuidor?> GetByReciboAndTipoMovimientoAsync(int recibo, string tipoMovimiento, int? excludeIdPago = null);
|
||||||
|
Task<IEnumerable<(PagoDistribuidorHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idPagoOriginal); // Para filtrar por un pago específico
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Collections.Generic; // Para IEnumerable
|
using System.Collections.Generic; // Para IEnumerable
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using GestionIntegral.Api.Dtos.Contables; // Para SaldoGestionDto si lo usas aquí
|
||||||
|
using GestionIntegral.Api.Models.Contables; // Para Saldo, SaldoAjusteHistorial
|
||||||
|
|
||||||
namespace GestionIntegral.Api.Data.Repositories.Contables
|
namespace GestionIntegral.Api.Data.Repositories.Contables
|
||||||
{
|
{
|
||||||
@@ -15,5 +17,16 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
// Método para modificar saldo (lo teníamos como privado antes, ahora en el repo)
|
// Método para modificar saldo (lo teníamos como privado antes, ahora en el repo)
|
||||||
Task<bool> ModificarSaldoAsync(string destino, int idDestino, int idEmpresa, decimal montoAAgregar, IDbTransaction? transaction = null);
|
Task<bool> ModificarSaldoAsync(string destino, int idDestino, int idEmpresa, decimal montoAAgregar, IDbTransaction? transaction = null);
|
||||||
Task<bool> CheckIfSaldosExistForEmpresaAsync(int id);
|
Task<bool> CheckIfSaldosExistForEmpresaAsync(int id);
|
||||||
|
|
||||||
|
// Para obtener la lista de saldos para la página de gestión
|
||||||
|
Task<IEnumerable<Saldo>> GetSaldosParaGestionAsync(string? destinoFilter, int? idDestinoFilter, int? idEmpresaFilter);
|
||||||
|
// Para obtener un saldo específico (ya podría existir uno similar, o crearlo si es necesario)
|
||||||
|
Task<Saldo?> GetSaldoAsync(string destino, int idDestino, int idEmpresa, IDbTransaction? transaction = null);
|
||||||
|
// Para registrar el historial de ajuste
|
||||||
|
Task CreateSaldoAjusteHistorialAsync(SaldoAjusteHistorial historialEntry, IDbTransaction transaction);
|
||||||
|
Task<IEnumerable<(SaldoAjusteHistorial Historial, string NombreUsuarioModifico)>> GetHistorialAjustesAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico,
|
||||||
|
string? destino, int? idDestino, int? idEmpresa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,5 +13,9 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
Task<bool> DeleteAsync(int id, int idUsuario); // Devuelve true si fue exitoso
|
Task<bool> DeleteAsync(int id, int idUsuario); // Devuelve true si fue exitoso
|
||||||
Task<bool> ExistsByNameAsync(string nombre, int? excludeId = null);
|
Task<bool> ExistsByNameAsync(string nombre, int? excludeId = null);
|
||||||
Task<bool> IsInUseAsync(int id);
|
Task<bool> IsInUseAsync(int id);
|
||||||
|
Task<IEnumerable<(TipoPagoHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idTipoPagoOriginal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,11 +86,20 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
var inserted = await transaction.Connection!.QuerySingleAsync<NotaCreditoDebito>(sqlInsert, nuevaNota, transaction);
|
var inserted = await transaction.Connection!.QuerySingleAsync<NotaCreditoDebito>(sqlInsert, nuevaNota, transaction);
|
||||||
if (inserted == null || inserted.IdNota == 0) throw new DataException("Error al crear la nota o ID no generado.");
|
if (inserted == null || inserted.IdNota == 0) throw new DataException("Error al crear la nota o ID no generado.");
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdNotaHist = inserted.IdNota, DestinoHist = inserted.Destino, IdDestinoHist = inserted.IdDestino,
|
{
|
||||||
ReferenciaHist = inserted.Referencia, TipoHist = inserted.Tipo, FechaHist = inserted.Fecha, MontoHist = inserted.Monto,
|
IdNotaHist = inserted.IdNota,
|
||||||
ObservacionesHist = inserted.Observaciones, IdEmpresaHist = inserted.IdEmpresa,
|
DestinoHist = inserted.Destino,
|
||||||
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Creada"
|
IdDestinoHist = inserted.IdDestino,
|
||||||
|
ReferenciaHist = inserted.Referencia,
|
||||||
|
TipoHist = inserted.Tipo,
|
||||||
|
FechaHist = inserted.Fecha,
|
||||||
|
MontoHist = inserted.Monto,
|
||||||
|
ObservacionesHist = inserted.Observaciones,
|
||||||
|
IdEmpresaHist = inserted.IdEmpresa,
|
||||||
|
IdUsuarioHist = idUsuario,
|
||||||
|
FechaModHist = DateTime.Now,
|
||||||
|
TipoModHist = "Creada"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
return inserted;
|
return inserted;
|
||||||
}
|
}
|
||||||
@@ -112,14 +121,24 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
(Id_Nota, Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
(Id_Nota, Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdNotaHist, @DestinoHist, @IdDestinoHist, @ReferenciaHist, @TipoHist, @FechaHist, @MontoHist, @ObservacionesHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
VALUES (@IdNotaHist, @DestinoHist, @IdDestinoHist, @ReferenciaHist, @TipoHist, @FechaHist, @MontoHist, @ObservacionesHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdNotaHist = actual.IdNota, DestinoHist = actual.Destino, IdDestinoHist = actual.IdDestino, ReferenciaHist = actual.Referencia,
|
{
|
||||||
TipoHist = actual.Tipo, FechaHist = actual.Fecha, MontoHist = actual.Monto, // Valor ANTERIOR
|
IdNotaHist = actual.IdNota,
|
||||||
ObservacionesHist = actual.Observaciones, IdEmpresaHist = actual.IdEmpresa, // Valor ANTERIOR
|
DestinoHist = actual.Destino,
|
||||||
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Actualizada"
|
IdDestinoHist = actual.IdDestino,
|
||||||
|
ReferenciaHist = actual.Referencia,
|
||||||
|
TipoHist = actual.Tipo,
|
||||||
|
FechaHist = actual.Fecha,
|
||||||
|
MontoHist = actual.Monto, // Valor ANTERIOR
|
||||||
|
ObservacionesHist = actual.Observaciones,
|
||||||
|
IdEmpresaHist = actual.IdEmpresa, // Valor ANTERIOR
|
||||||
|
IdUsuarioHist = idUsuario,
|
||||||
|
FechaModHist = DateTime.Now,
|
||||||
|
TipoModHist = "Actualizada"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, new {
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, new
|
||||||
|
{
|
||||||
notaAActualizar.Monto,
|
notaAActualizar.Monto,
|
||||||
notaAActualizar.Observaciones,
|
notaAActualizar.Observaciones,
|
||||||
notaAActualizar.IdNota
|
notaAActualizar.IdNota
|
||||||
@@ -140,14 +159,67 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
(Id_Nota, Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
(Id_Nota, Destino, Id_Destino, Referencia, Tipo, Fecha, Monto, Observaciones, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdNotaHist, @DestinoHist, @IdDestinoHist, @ReferenciaHist, @TipoHist, @FechaHist, @MontoHist, @ObservacionesHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
VALUES (@IdNotaHist, @DestinoHist, @IdDestinoHist, @ReferenciaHist, @TipoHist, @FechaHist, @MontoHist, @ObservacionesHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdNotaHist = actual.IdNota, DestinoHist = actual.Destino, IdDestinoHist = actual.IdDestino, ReferenciaHist = actual.Referencia,
|
{
|
||||||
TipoHist = actual.Tipo, FechaHist = actual.Fecha, MontoHist = actual.Monto, ObservacionesHist = actual.Observaciones, IdEmpresaHist = actual.IdEmpresa,
|
IdNotaHist = actual.IdNota,
|
||||||
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Eliminada"
|
DestinoHist = actual.Destino,
|
||||||
|
IdDestinoHist = actual.IdDestino,
|
||||||
|
ReferenciaHist = actual.Referencia,
|
||||||
|
TipoHist = actual.Tipo,
|
||||||
|
FechaHist = actual.Fecha,
|
||||||
|
MontoHist = actual.Monto,
|
||||||
|
ObservacionesHist = actual.Observaciones,
|
||||||
|
IdEmpresaHist = actual.IdEmpresa,
|
||||||
|
IdUsuarioHist = idUsuario,
|
||||||
|
FechaModHist = DateTime.Now,
|
||||||
|
TipoModHist = "Eliminada"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdNotaParam = idNota }, transaction);
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdNotaParam = idNota }, transaction);
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(NotaCreditoDebitoHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idNotaOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Nota, h.Destino, h.Id_Destino, h.Referencia, h.Tipo, h.Fecha, h.Monto,
|
||||||
|
h.Observaciones, h.Id_Empresa,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.cue_CreditosDebitos_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idNotaOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Nota = @IdNotaOriginalParam"); parameters.Add("IdNotaOriginalParam", idNotaOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<NotaCreditoDebitoHistorico, string, (NotaCreditoDebitoHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error al obtener historial de Notas C/D.");
|
||||||
|
return Enumerable.Empty<(NotaCreditoDebitoHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,9 +70,10 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> ExistsByReciboAndTipoMovimientoAsync(int recibo, string tipoMovimiento, int? excludeIdPago = null)
|
public async Task<PagoDistribuidor?> GetByReciboAndTipoMovimientoAsync(int recibo, string tipoMovimiento, int? excludeIdPago = null)
|
||||||
{
|
{
|
||||||
var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.cue_PagosDistribuidor WHERE Recibo = @ReciboParam AND TipoMovimiento = @TipoMovParam");
|
var sqlBuilder = new StringBuilder(SelectQueryBase()); // Reutiliza la consulta base
|
||||||
|
sqlBuilder.Append(" WHERE Recibo = @ReciboParam AND TipoMovimiento = @TipoMovParam");
|
||||||
var parameters = new DynamicParameters();
|
var parameters = new DynamicParameters();
|
||||||
parameters.Add("ReciboParam", recibo);
|
parameters.Add("ReciboParam", recibo);
|
||||||
parameters.Add("TipoMovParam", tipoMovimiento);
|
parameters.Add("TipoMovParam", tipoMovimiento);
|
||||||
@@ -85,12 +86,12 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var connection = _cf.CreateConnection();
|
using var connection = _cf.CreateConnection();
|
||||||
return await connection.ExecuteScalarAsync<bool>(sqlBuilder.ToString(), parameters);
|
return await connection.QuerySingleOrDefaultAsync<PagoDistribuidor>(sqlBuilder.ToString(), parameters);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_log.LogError(ex, "Error en ExistsByReciboAndTipoMovimientoAsync. Recibo: {Recibo}, Tipo: {Tipo}", recibo, tipoMovimiento);
|
_log.LogError(ex, "Error en GetByReciboAndTipoMovimientoAsync. Recibo: {Recibo}, Tipo: {Tipo}", recibo, tipoMovimiento);
|
||||||
return true; // Asumir que existe en caso de error para prevenir duplicados
|
throw; // Relanzar para que el servicio lo maneje
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +110,20 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
var inserted = await transaction.Connection!.QuerySingleAsync<PagoDistribuidor>(sqlInsert, nuevoPago, transaction);
|
var inserted = await transaction.Connection!.QuerySingleAsync<PagoDistribuidor>(sqlInsert, nuevoPago, transaction);
|
||||||
if (inserted == null || inserted.IdPago == 0) throw new DataException("Error al crear pago o ID no generado.");
|
if (inserted == null || inserted.IdPago == 0) throw new DataException("Error al crear pago o ID no generado.");
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdPagoHist = inserted.IdPago, IdDistribuidorHist = inserted.IdDistribuidor, FechaHist = inserted.Fecha,
|
{
|
||||||
TipoMovimientoHist = inserted.TipoMovimiento, ReciboHist = inserted.Recibo, MontoHist = inserted.Monto,
|
IdPagoHist = inserted.IdPago,
|
||||||
IdTipoPagoHist = inserted.IdTipoPago, DetalleHist = inserted.Detalle, IdEmpresaHist = inserted.IdEmpresa,
|
IdDistribuidorHist = inserted.IdDistribuidor,
|
||||||
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Creado"
|
FechaHist = inserted.Fecha,
|
||||||
|
TipoMovimientoHist = inserted.TipoMovimiento,
|
||||||
|
ReciboHist = inserted.Recibo,
|
||||||
|
MontoHist = inserted.Monto,
|
||||||
|
IdTipoPagoHist = inserted.IdTipoPago,
|
||||||
|
DetalleHist = inserted.Detalle,
|
||||||
|
IdEmpresaHist = inserted.IdEmpresa,
|
||||||
|
IdUsuarioHist = idUsuario,
|
||||||
|
FechaModHist = DateTime.Now,
|
||||||
|
TipoModHist = "Creado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
return inserted;
|
return inserted;
|
||||||
}
|
}
|
||||||
@@ -137,11 +147,20 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
(Id_Pago, Id_Distribuidor, Fecha, TipoMovimiento, Recibo, Monto, Id_TipoPago, Detalle, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
(Id_Pago, Id_Distribuidor, Fecha, TipoMovimiento, Recibo, Monto, Id_TipoPago, Detalle, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdPagoHist, @IdDistribuidorHist, @FechaHist, @TipoMovimientoHist, @ReciboHist, @MontoHist, @IdTipoPagoHist, @DetalleHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
VALUES (@IdPagoHist, @IdDistribuidorHist, @FechaHist, @TipoMovimientoHist, @ReciboHist, @MontoHist, @IdTipoPagoHist, @DetalleHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdPagoHist = actual.IdPago, IdDistribuidorHist = actual.IdDistribuidor, FechaHist = actual.Fecha,
|
{
|
||||||
TipoMovimientoHist = actual.TipoMovimiento, ReciboHist = actual.Recibo, MontoHist = actual.Monto, // Valor ANTERIOR
|
IdPagoHist = actual.IdPago,
|
||||||
IdTipoPagoHist = actual.IdTipoPago, DetalleHist = actual.Detalle, IdEmpresaHist = actual.IdEmpresa, // Valores ANTERIORES
|
IdDistribuidorHist = actual.IdDistribuidor,
|
||||||
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Actualizado"
|
FechaHist = actual.Fecha,
|
||||||
|
TipoMovimientoHist = actual.TipoMovimiento,
|
||||||
|
ReciboHist = actual.Recibo,
|
||||||
|
MontoHist = actual.Monto, // Valor ANTERIOR
|
||||||
|
IdTipoPagoHist = actual.IdTipoPago,
|
||||||
|
DetalleHist = actual.Detalle,
|
||||||
|
IdEmpresaHist = actual.IdEmpresa, // Valores ANTERIORES
|
||||||
|
IdUsuarioHist = idUsuario,
|
||||||
|
FechaModHist = DateTime.Now,
|
||||||
|
TipoModHist = "Actualizado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, pagoAActualizar, transaction);
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, pagoAActualizar, transaction);
|
||||||
@@ -161,15 +180,67 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
(Id_Pago, Id_Distribuidor, Fecha, TipoMovimiento, Recibo, Monto, Id_TipoPago, Detalle, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
(Id_Pago, Id_Distribuidor, Fecha, TipoMovimiento, Recibo, Monto, Id_TipoPago, Detalle, Id_Empresa, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdPagoHist, @IdDistribuidorHist, @FechaHist, @TipoMovimientoHist, @ReciboHist, @MontoHist, @IdTipoPagoHist, @DetalleHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
VALUES (@IdPagoHist, @IdDistribuidorHist, @FechaHist, @TipoMovimientoHist, @ReciboHist, @MontoHist, @IdTipoPagoHist, @DetalleHist, @IdEmpresaHist, @IdUsuarioHist, @FechaModHist, @TipoModHist);";
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdPagoHist = actual.IdPago, IdDistribuidorHist = actual.IdDistribuidor, FechaHist = actual.Fecha,
|
{
|
||||||
TipoMovimientoHist = actual.TipoMovimiento, ReciboHist = actual.Recibo, MontoHist = actual.Monto,
|
IdPagoHist = actual.IdPago,
|
||||||
IdTipoPagoHist = actual.IdTipoPago, DetalleHist = actual.Detalle, IdEmpresaHist = actual.IdEmpresa,
|
IdDistribuidorHist = actual.IdDistribuidor,
|
||||||
IdUsuarioHist = idUsuario, FechaModHist = DateTime.Now, TipoModHist = "Eliminado"
|
FechaHist = actual.Fecha,
|
||||||
|
TipoMovimientoHist = actual.TipoMovimiento,
|
||||||
|
ReciboHist = actual.Recibo,
|
||||||
|
MontoHist = actual.Monto,
|
||||||
|
IdTipoPagoHist = actual.IdTipoPago,
|
||||||
|
DetalleHist = actual.Detalle,
|
||||||
|
IdEmpresaHist = actual.IdEmpresa,
|
||||||
|
IdUsuarioHist = idUsuario,
|
||||||
|
FechaModHist = DateTime.Now,
|
||||||
|
TipoModHist = "Eliminado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdPagoParam = idPago }, transaction);
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdPagoParam = idPago }, transaction);
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(PagoDistribuidorHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idPagoOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Pago, h.Id_Distribuidor, h.Fecha, h.TipoMovimiento, h.Recibo, h.Monto,
|
||||||
|
h.Id_TipoPago, h.Detalle, h.Id_Empresa,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.cue_PagosDistribuidor_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idPagoOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Pago = @IdPagoOriginalParam"); parameters.Add("IdPagoOriginalParam", idPagoOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<PagoDistribuidorHistorico, string, (PagoDistribuidorHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error al obtener historial de Pagos de Distribuidores.");
|
||||||
|
return Enumerable.Empty<(PagoDistribuidorHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,8 @@ using Microsoft.Extensions.Logging;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using GestionIntegral.Api.Models.Contables;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace GestionIntegral.Api.Data.Repositories.Contables
|
namespace GestionIntegral.Api.Data.Repositories.Contables
|
||||||
{
|
{
|
||||||
@@ -21,7 +23,7 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
|
|
||||||
public async Task<IEnumerable<int>> GetAllDistribuidorIdsAsync()
|
public async Task<IEnumerable<int>> GetAllDistribuidorIdsAsync()
|
||||||
{
|
{
|
||||||
var sql = "SELECT Id_Distribuidor FROM dbo.dist_dtDistribuidores";
|
var sql = "SELECT Id_Distribuidor FROM dbo.dist_dtDistribuidores WHERE Baja = 0";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var connection = _connectionFactory.CreateConnection())
|
using (var connection = _connectionFactory.CreateConnection())
|
||||||
@@ -73,44 +75,47 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
public async Task<bool> ModificarSaldoAsync(string destino, int idDestino, int idEmpresa, decimal montoAAgregar, IDbTransaction? transaction = null)
|
public async Task<bool> ModificarSaldoAsync(string destino, int idDestino, int idEmpresa, decimal montoAAgregar, IDbTransaction? transaction = null)
|
||||||
{
|
{
|
||||||
var sql = @"UPDATE dbo.cue_Saldos
|
var sql = @"UPDATE dbo.cue_Saldos
|
||||||
SET Monto = Monto + @MontoAAgregar
|
SET Monto = Monto + @MontoAAgregar,
|
||||||
|
FechaUltimaModificacion = @FechaActualizacion -- << AÑADIR
|
||||||
WHERE Destino = @Destino AND Id_Destino = @IdDestino AND Id_Empresa = @IdEmpresa;";
|
WHERE Destino = @Destino AND Id_Destino = @IdDestino AND Id_Empresa = @IdEmpresa;";
|
||||||
|
|
||||||
// Usar una variable para la conexión para poder aplicar el '!' si es necesario
|
|
||||||
IDbConnection connection = transaction?.Connection ?? _connectionFactory.CreateConnection();
|
IDbConnection connection = transaction?.Connection ?? _connectionFactory.CreateConnection();
|
||||||
bool ownConnection = transaction == null; // Saber si necesitamos cerrar la conexión nosotros
|
bool ownConnection = transaction == null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (ownConnection) await (connection as System.Data.Common.DbConnection)!.OpenAsync(); // Abrir solo si no hay transacción externa
|
if (ownConnection && connection.State != ConnectionState.Open)
|
||||||
|
{
|
||||||
|
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
|
||||||
|
}
|
||||||
|
|
||||||
var parameters = new {
|
var parameters = new
|
||||||
|
{
|
||||||
MontoAAgregar = montoAAgregar,
|
MontoAAgregar = montoAAgregar,
|
||||||
Destino = destino,
|
Destino = destino,
|
||||||
IdDestino = idDestino,
|
IdDestino = idDestino,
|
||||||
IdEmpresa = idEmpresa
|
IdEmpresa = idEmpresa,
|
||||||
|
FechaActualizacion = DateTime.Now // O DateTime.UtcNow si prefieres
|
||||||
};
|
};
|
||||||
// Aplicar '!' aquí también si viene de la transacción
|
|
||||||
int rowsAffected = await connection.ExecuteAsync(sql, parameters, transaction: transaction);
|
int rowsAffected = await connection.ExecuteAsync(sql, parameters, transaction: transaction);
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error al modificar saldo para {Destino} ID {IdDestino}, Empresa ID {IdEmpresa}.", destino, idDestino, idEmpresa);
|
_logger.LogError(ex, "Error al modificar saldo para {Destino} ID {IdDestino}, Empresa ID {IdEmpresa}.", destino, idDestino, idEmpresa);
|
||||||
if (transaction != null) throw; // Re-lanzar si estamos en una transacción externa
|
if (transaction != null) throw;
|
||||||
return false; // Devolver false si fue una operación aislada que falló
|
return false;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Cerrar la conexión solo si la abrimos nosotros (no había transacción externa)
|
|
||||||
if (ownConnection && connection.State == ConnectionState.Open)
|
if (ownConnection && connection.State == ConnectionState.Open)
|
||||||
{
|
{
|
||||||
await (connection as System.Data.Common.DbConnection)!.CloseAsync();
|
if (connection is System.Data.Common.DbConnection dbConn) await dbConn.CloseAsync(); else connection.Close();
|
||||||
}
|
}
|
||||||
// Disponer de la conexión si la creamos nosotros
|
if (ownConnection && connection is IDisposable d) d.Dispose(); // Mejorar dispose
|
||||||
if(ownConnection) (connection as IDisposable)?.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> CheckIfSaldosExistForEmpresaAsync(int idEmpresa)
|
public async Task<bool> CheckIfSaldosExistForEmpresaAsync(int idEmpresa)
|
||||||
{
|
{
|
||||||
var sql = "SELECT COUNT(1) FROM dbo.cue_Saldos WHERE Id_Empresa = @IdEmpresa";
|
var sql = "SELECT COUNT(1) FROM dbo.cue_Saldos WHERE Id_Empresa = @IdEmpresa";
|
||||||
@@ -130,5 +135,122 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
// O podrías devolver true para ser más conservador si la verificación es crítica.
|
// O podrías devolver true para ser más conservador si la verificación es crítica.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Saldo>> GetSaldosParaGestionAsync(string? destinoFilter, int? idDestinoFilter, int? idEmpresaFilter)
|
||||||
|
{
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT Id_Saldo AS IdSaldo, Destino, Id_Destino AS IdDestino, Monto, Id_Empresa AS IdEmpresa, FechaUltimaModificacion
|
||||||
|
FROM dbo.cue_Saldos s
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(destinoFilter))
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND s.Destino = @Destino");
|
||||||
|
parameters.Add("Destino", destinoFilter);
|
||||||
|
|
||||||
|
// Filtro para excluir distribuidores de baja si el tipo es Distribuidores
|
||||||
|
// No se aplica a Canillas por requerimiento explícito del usuario
|
||||||
|
if (destinoFilter == "Distribuidores")
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND EXISTS (SELECT 1 FROM dbo.dist_dtDistribuidores d WHERE d.Id_Distribuidor = s.Id_Destino AND d.Baja = 0)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Si no hay filtro de destino, aplicamos el filtro de baja solo para Distribuidores
|
||||||
|
sqlBuilder.Append(@" AND (
|
||||||
|
(s.Destino = 'Distribuidores' AND EXISTS (SELECT 1 FROM dbo.dist_dtDistribuidores d WHERE d.Id_Distribuidor = s.Id_Destino AND d.Baja = 0))
|
||||||
|
OR (s.Destino != 'Distribuidores')
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idDestinoFilter.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND s.Id_Destino = @IdDestino");
|
||||||
|
parameters.Add("IdDestino", idDestinoFilter.Value);
|
||||||
|
}
|
||||||
|
if (idEmpresaFilter.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND s.Id_Empresa = @IdEmpresa");
|
||||||
|
parameters.Add("IdEmpresa", idEmpresaFilter.Value);
|
||||||
|
}
|
||||||
|
sqlBuilder.Append(" ORDER BY s.Destino, s.Id_Empresa, s.Id_Destino;");
|
||||||
|
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QueryAsync<Saldo>(sqlBuilder.ToString(), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Saldo?> GetSaldoAsync(string destino, int idDestino, int idEmpresa, IDbTransaction? transaction = null)
|
||||||
|
{
|
||||||
|
const string sql = "SELECT Id_Saldo AS IdSaldo, Destino, Id_Destino AS IdDestino, Monto, Id_Empresa AS IdEmpresa, FechaUltimaModificacion FROM dbo.cue_Saldos WHERE Destino = @Destino AND Id_Destino = @IdDestino AND Id_Empresa = @IdEmpresa;";
|
||||||
|
var conn = transaction?.Connection ?? _connectionFactory.CreateConnection();
|
||||||
|
if (transaction == null && conn.State != ConnectionState.Open) { if (conn is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else conn.Open(); }
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await conn.QuerySingleOrDefaultAsync<Saldo>(sql, new { Destino = destino, IdDestino = idDestino, IdEmpresa = idEmpresa }, transaction);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (transaction == null && conn.State == ConnectionState.Open) { if (conn is System.Data.Common.DbConnection dbConn) await dbConn.CloseAsync(); else conn.Close(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CreateSaldoAjusteHistorialAsync(SaldoAjusteHistorial historialEntry, IDbTransaction transaction)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
INSERT INTO dbo.cue_SaldoAjustesHistorial
|
||||||
|
(Destino, Id_Destino, Id_Empresa, MontoAjuste, SaldoAnterior, SaldoNuevo, Justificacion, FechaAjuste, Id_UsuarioAjuste)
|
||||||
|
VALUES
|
||||||
|
(@Destino, @IdDestino, @IdEmpresa, @MontoAjuste, @SaldoAnterior, @SaldoNuevo, @Justificacion, @FechaAjuste, @IdUsuarioAjuste);";
|
||||||
|
|
||||||
|
await transaction.Connection!.ExecuteAsync(sql, historialEntry, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(SaldoAjusteHistorial Historial, string NombreUsuarioModifico)>> GetHistorialAjustesAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico,
|
||||||
|
string? destino, int? idDestino, int? idEmpresa)
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.IdSaldoAjusteHist, h.Destino, h.Id_Destino, h.Id_Empresa,
|
||||||
|
h.MontoAjuste, h.SaldoAnterior, h.SaldoNuevo, h.Justificacion,
|
||||||
|
h.FechaAjuste, h.Id_UsuarioAjuste,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.cue_SaldoAjustesHistorial h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_UsuarioAjuste = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaAjuste >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaAjuste <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_UsuarioAjuste = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(destino)) { sqlBuilder.Append(" AND h.Destino = @DestinoParam"); parameters.Add("DestinoParam", destino); }
|
||||||
|
if (idDestino.HasValue) { sqlBuilder.Append(" AND h.Id_Destino = @IdDestinoParam"); parameters.Add("IdDestinoParam", idDestino.Value); }
|
||||||
|
if (idEmpresa.HasValue) { sqlBuilder.Append(" AND h.Id_Empresa = @IdEmpresaParam"); parameters.Add("IdEmpresaParam", idEmpresa.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaAjuste DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<SaldoAjusteHistorial, string, (SaldoAjusteHistorial, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener historial de Ajustes de Saldo.");
|
||||||
|
return Enumerable.Empty<(SaldoAjusteHistorial, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ using Dapper;
|
|||||||
using GestionIntegral.Api.Models.Contables;
|
using GestionIntegral.Api.Models.Contables;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GestionIntegral.Api.Data.Repositories.Contables
|
namespace GestionIntegral.Api.Data.Repositories.Contables
|
||||||
@@ -284,5 +285,47 @@ namespace GestionIntegral.Api.Data.Repositories.Contables
|
|||||||
return true; // Asumir que está en uso si hay error para prevenir borrado incorrecto
|
return true; // Asumir que está en uso si hay error para prevenir borrado incorrecto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(TipoPagoHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idTipoPagoOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection(); // Asumiendo _cf es tu DbConnectionFactory
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_TipoPago, h.Nombre, h.Detalle,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.cue_dtTipopago_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idTipoPagoOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_TipoPago = @IdTipoPagoOriginalParam"); parameters.Add("IdTipoPagoOriginalParam", idTipoPagoOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<TipoPagoHistorico, string, (TipoPagoHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener historial de Tipos de Pago."); // Asumiendo _log
|
||||||
|
return Enumerable.Empty<(TipoPagoHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
using Dapper;
|
||||||
|
using GestionIntegral.Api.Models.Distribucion;
|
||||||
|
using Microsoft.Extensions.Logging; // Para ILogger
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text; // Para StringBuilder
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
||||||
|
{
|
||||||
|
public class CambioParadaRepository : ICambioParadaRepository
|
||||||
|
{
|
||||||
|
private readonly DbConnectionFactory _cf;
|
||||||
|
private readonly ILogger<CambioParadaRepository> _logger;
|
||||||
|
|
||||||
|
public CambioParadaRepository(DbConnectionFactory cf, ILogger<CambioParadaRepository> logger)
|
||||||
|
{
|
||||||
|
_cf = cf;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LogHistorialAsync(CambioParadaCanilla paradaOriginal, int idUsuario, string tipoMod, IDbConnection connection, IDbTransaction? transaction)
|
||||||
|
{
|
||||||
|
var historial = new CambioParadaCanillaHistorial
|
||||||
|
{
|
||||||
|
Id_Registro = paradaOriginal.IdRegistro,
|
||||||
|
Id_Canilla = paradaOriginal.IdCanilla,
|
||||||
|
Parada = paradaOriginal.Parada,
|
||||||
|
VigenciaD = paradaOriginal.VigenciaD,
|
||||||
|
VigenciaH = paradaOriginal.VigenciaH,
|
||||||
|
Id_Usuario = idUsuario,
|
||||||
|
FechaMod = DateTime.Now,
|
||||||
|
TipoMod = tipoMod
|
||||||
|
};
|
||||||
|
const string sqlHistorial = @"
|
||||||
|
INSERT INTO dbo.dist_CambiosParadasCanillas_H
|
||||||
|
(Id_Registro, Id_Canilla, Parada, VigenciaD, VigenciaH, Id_Usuario, FechaMod, TipoMod)
|
||||||
|
VALUES
|
||||||
|
(@Id_Registro, @Id_Canilla, @Parada, @VigenciaD, @VigenciaH, @Id_Usuario, @FechaMod, @TipoMod);";
|
||||||
|
await connection.ExecuteAsync(sqlHistorial, historial, transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<IEnumerable<CambioParadaCanilla>> GetByCanillaAsync(int idCanilla)
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
const string sql = @"
|
||||||
|
SELECT Id_Registro AS IdRegistro, Id_Canilla AS IdCanilla, Parada, VigenciaD, VigenciaH
|
||||||
|
FROM dbo.dist_CambiosParadasCanillas
|
||||||
|
WHERE Id_Canilla = @IdCanilla
|
||||||
|
ORDER BY VigenciaD DESC, Id_Registro DESC;";
|
||||||
|
return await connection.QueryAsync<CambioParadaCanilla>(sql, new { IdCanilla = idCanilla });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CambioParadaCanilla?> GetByIdAsync(int idRegistro)
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
const string sql = @"
|
||||||
|
SELECT Id_Registro AS IdRegistro, Id_Canilla AS IdCanilla, Parada, VigenciaD, VigenciaH
|
||||||
|
FROM dbo.dist_CambiosParadasCanillas
|
||||||
|
WHERE Id_Registro = @IdRegistro;";
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<CambioParadaCanilla>(sql, new { IdRegistro = idRegistro });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CambioParadaCanilla?> GetCurrentParadaAsync(int idCanilla, IDbTransaction? transaction = null)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
SELECT TOP 1 Id_Registro AS IdRegistro, Id_Canilla AS IdCanilla, Parada, VigenciaD, VigenciaH
|
||||||
|
FROM dbo.dist_CambiosParadasCanillas
|
||||||
|
WHERE Id_Canilla = @IdCanilla AND VigenciaH IS NULL
|
||||||
|
ORDER BY VigenciaD DESC, Id_Registro DESC;"; // Por si hay un error y quedaron varias abiertas
|
||||||
|
|
||||||
|
var conn = transaction?.Connection ?? _cf.CreateConnection();
|
||||||
|
bool manageConnection = transaction == null;
|
||||||
|
if (manageConnection && conn.State != ConnectionState.Open) { if (conn is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else conn.Open(); }
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await conn.QuerySingleOrDefaultAsync<CambioParadaCanilla>(sql, new { IdCanilla = idCanilla }, transaction);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (manageConnection && conn.State == ConnectionState.Open) { if (conn is System.Data.Common.DbConnection dbConn) await dbConn.CloseAsync(); else conn.Close(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<CambioParadaCanilla?> CreateAsync(CambioParadaCanilla nuevaParada, int idUsuario, IDbTransaction transaction)
|
||||||
|
{
|
||||||
|
const string sqlInsert = @"
|
||||||
|
INSERT INTO dbo.dist_CambiosParadasCanillas (Id_Canilla, Parada, VigenciaD, VigenciaH)
|
||||||
|
OUTPUT INSERTED.Id_Registro AS IdRegistro, INSERTED.Id_Canilla AS IdCanilla, INSERTED.Parada, INSERTED.VigenciaD, INSERTED.VigenciaH
|
||||||
|
VALUES (@IdCanilla, @Parada, @VigenciaD, @VigenciaH);";
|
||||||
|
|
||||||
|
// VigenciaH es null al crear una nueva parada activa
|
||||||
|
var inserted = await transaction.Connection!.QuerySingleAsync<CambioParadaCanilla>(sqlInsert,
|
||||||
|
new { nuevaParada.IdCanilla, nuevaParada.Parada, nuevaParada.VigenciaD, VigenciaH = (DateTime?)null },
|
||||||
|
transaction);
|
||||||
|
|
||||||
|
if (inserted == null || inserted.IdRegistro == 0) throw new DataException("Error al crear cambio de parada o ID no generado.");
|
||||||
|
|
||||||
|
await LogHistorialAsync(inserted, idUsuario, "Creada", transaction.Connection!, transaction);
|
||||||
|
return inserted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateVigenciaHAsync(int idRegistro, DateTime vigenciaH, int idUsuario, IDbTransaction transaction)
|
||||||
|
{
|
||||||
|
var paradaOriginal = await GetByIdAsync(idRegistro);
|
||||||
|
if (paradaOriginal == null) throw new KeyNotFoundException("Registro de parada no encontrado para actualizar VigenciaH.");
|
||||||
|
|
||||||
|
var paradaParaHistorial = new CambioParadaCanilla
|
||||||
|
{
|
||||||
|
IdRegistro = paradaOriginal.IdRegistro,
|
||||||
|
IdCanilla = paradaOriginal.IdCanilla,
|
||||||
|
Parada = paradaOriginal.Parada,
|
||||||
|
VigenciaD = paradaOriginal.VigenciaD,
|
||||||
|
VigenciaH = vigenciaH.Date
|
||||||
|
};
|
||||||
|
|
||||||
|
// Loggear el estado que QUEDARÁ en la tabla principal (con la VigenciaH actualizada)
|
||||||
|
// El TipoMod debería reflejar la acción. "Cerrada".
|
||||||
|
await LogHistorialAsync(paradaParaHistorial, idUsuario, "Cerrada", transaction.Connection!, transaction);
|
||||||
|
|
||||||
|
const string sqlUpdate = @"
|
||||||
|
UPDATE dbo.dist_CambiosParadasCanillas
|
||||||
|
SET VigenciaH = @VigenciaH
|
||||||
|
WHERE Id_Registro = @IdRegistro;";
|
||||||
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate,
|
||||||
|
new { VigenciaH = vigenciaH.Date, IdRegistro = idRegistro },
|
||||||
|
transaction);
|
||||||
|
|
||||||
|
return rowsAffected == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteAsync(int idRegistro, int idUsuario, IDbTransaction transaction)
|
||||||
|
{
|
||||||
|
var paradaOriginal = await GetByIdAsync(idRegistro);
|
||||||
|
if (paradaOriginal == null) throw new KeyNotFoundException("Registro de parada no encontrado para eliminar.");
|
||||||
|
|
||||||
|
// Loggear ANTES de eliminar
|
||||||
|
await LogHistorialAsync(paradaOriginal, idUsuario, "Eliminada", transaction.Connection!, transaction);
|
||||||
|
|
||||||
|
const string sqlDelete = "DELETE FROM dbo.dist_CambiosParadasCanillas WHERE Id_Registro = @IdRegistro;";
|
||||||
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdRegistro = idRegistro }, transaction);
|
||||||
|
return rowsAffected == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(CambioParadaCanillaHistorial Historial, string NombreUsuarioModifico, string NombreCanilla)>> GetCambiosParadaHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idCanillaOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Registro, h.Id_Canilla, h.Parada, h.VigenciaD, h.VigenciaH,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico,
|
||||||
|
c.NomApe AS NombreCanilla
|
||||||
|
FROM dbo.dist_CambiosParadasCanillas_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
JOIN dbo.dist_dtCanillas c ON h.Id_Canilla = c.Id_Canilla
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idCanillaOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Canilla = @IdCanillaOriginalParam"); parameters.Add("IdCanillaOriginalParam", idCanillaOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<CambioParadaCanillaHistorial, string, string, (CambioParadaCanillaHistorial, string, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userMod, canillaNombre) => (hist, userMod, canillaNombre),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico,NombreCanilla"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener historial de Cambios de Parada.");
|
||||||
|
return Enumerable.Empty<(CambioParadaCanillaHistorial, string, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dapper;
|
using Dapper;
|
||||||
|
using GestionIntegral.Api.Dtos.Distribucion;
|
||||||
using GestionIntegral.Api.Models.Distribucion;
|
using GestionIntegral.Api.Models.Distribucion;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System; // Para Exception
|
using System; // Para Exception
|
||||||
@@ -21,51 +22,87 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<(Canilla Canilla, string NombreZona, string NombreEmpresa)>> GetAllAsync(string? nomApeFilter, int? legajoFilter, bool? soloActivos)
|
public async Task<IEnumerable<(Canilla Canilla, string? NombreZona, string? NombreEmpresa)>> GetAllAsync(
|
||||||
|
string? nomApeFilter,
|
||||||
|
int? legajoFilter,
|
||||||
|
bool? esAccionista,
|
||||||
|
bool? soloActivos)
|
||||||
{
|
{
|
||||||
var sqlBuilder = new StringBuilder(@"
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
SELECT
|
var sqlBuilder = new System.Text.StringBuilder(@"
|
||||||
c.Id_Canilla AS IdCanilla, c.Legajo, c.NomApe, c.Parada, c.Id_Zona AS IdZona,
|
SELECT c.Id_Canilla AS IdCanilla, c.Legajo, c.NomApe, c.Parada, c.Id_Zona AS IdZona,
|
||||||
c.Accionista, c.Obs, c.Empresa, c.Baja, c.FechaBaja,
|
c.Accionista, c.Obs, c.Empresa, c.Baja, c.FechaBaja,
|
||||||
z.Nombre AS NombreZona,
|
z.Nombre AS NombreZona,
|
||||||
ISNULL(e.Nombre, 'N/A (Accionista)') AS NombreEmpresa
|
e.Nombre AS NombreEmpresa
|
||||||
FROM dbo.dist_dtCanillas c
|
FROM dbo.dist_dtCanillas c
|
||||||
INNER JOIN dbo.dist_dtZonas z ON c.Id_Zona = z.Id_Zona
|
LEFT JOIN dbo.dist_dtZonas z ON c.Id_Zona = z.Id_Zona
|
||||||
LEFT JOIN dbo.dist_dtEmpresas e ON c.Empresa = e.Id_Empresa
|
LEFT JOIN dbo.dist_dtEmpresas e ON c.Empresa = e.Id_Empresa
|
||||||
|
WHERE 1=1 "); // Cláusula base para añadir AND fácilmente
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(nomApeFilter))
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND c.NomApe LIKE @NomApeFilter ");
|
||||||
|
parameters.Add("NomApeFilter", $"%{nomApeFilter}%");
|
||||||
|
}
|
||||||
|
if (legajoFilter.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND c.Legajo = @LegajoFilter ");
|
||||||
|
parameters.Add("LegajoFilter", legajoFilter.Value);
|
||||||
|
}
|
||||||
|
if (soloActivos.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND c.Baja = @BajaStatus ");
|
||||||
|
parameters.Add("BajaStatus", !soloActivos.Value); // Si soloActivos es true, Baja debe ser false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esAccionista.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND c.Accionista = @EsAccionista ");
|
||||||
|
parameters.Add("EsAccionista", esAccionista.Value); // true para accionistas, false para no accionistas (canillitas)
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY c.NomApe;");
|
||||||
|
|
||||||
|
var result = await connection.QueryAsync<Canilla, string, string, (Canilla, string?, string?)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(can, zona, emp) => (can, zona, emp),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreZona,NombreEmpresa"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<CanillaDropdownDto>> GetAllDropdownAsync(bool? esAccionista, bool? soloActivos)
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
var sqlBuilder = new System.Text.StringBuilder(@"
|
||||||
|
SELECT c.Id_Canilla AS IdCanilla, c.Legajo, c.NomApe
|
||||||
|
FROM dbo.dist_dtCanillas c
|
||||||
WHERE 1=1 ");
|
WHERE 1=1 ");
|
||||||
|
|
||||||
var parameters = new DynamicParameters();
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
if (soloActivos.HasValue)
|
if (soloActivos.HasValue)
|
||||||
{
|
{
|
||||||
sqlBuilder.Append(soloActivos.Value ? " AND c.Baja = 0" : " AND c.Baja = 1");
|
sqlBuilder.Append(" AND c.Baja = @BajaStatus ");
|
||||||
|
parameters.Add("BajaStatus", !soloActivos.Value); // Si soloActivos es true, Baja debe ser false
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrWhiteSpace(nomApeFilter))
|
|
||||||
|
if (esAccionista.HasValue)
|
||||||
{
|
{
|
||||||
sqlBuilder.Append(" AND c.NomApe LIKE @NomApeParam");
|
sqlBuilder.Append(" AND c.Accionista = @EsAccionista ");
|
||||||
parameters.Add("NomApeParam", $"%{nomApeFilter}%");
|
parameters.Add("EsAccionista", esAccionista.Value); // true para accionistas, false para no accionistas (canillitas)
|
||||||
}
|
|
||||||
if (legajoFilter.HasValue)
|
|
||||||
{
|
|
||||||
sqlBuilder.Append(" AND c.Legajo = @LegajoParam");
|
|
||||||
parameters.Add("LegajoParam", legajoFilter.Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlBuilder.Append(" ORDER BY c.NomApe;");
|
sqlBuilder.Append(" ORDER BY c.NomApe;");
|
||||||
|
|
||||||
try
|
var result = await connection.QueryAsync<CanillaDropdownDto>(
|
||||||
{
|
|
||||||
using var connection = _connectionFactory.CreateConnection();
|
|
||||||
return await connection.QueryAsync<Canilla, string, string, (Canilla, string, string)>(
|
|
||||||
sqlBuilder.ToString(),
|
sqlBuilder.ToString(),
|
||||||
(canilla, nombreZona, nombreEmpresa) => (canilla, nombreZona, nombreEmpresa),
|
parameters
|
||||||
parameters,
|
|
||||||
splitOn: "NombreZona,NombreEmpresa"
|
|
||||||
);
|
);
|
||||||
}
|
return result;
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Error al obtener todos los Canillas. Filtros: NomApe='{NomApeFilter}', Legajo='{LegajoFilter}', SoloActivos='{SoloActivos}'", nomApeFilter, legajoFilter, soloActivos);
|
|
||||||
return Enumerable.Empty<(Canilla, string, string)>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(Canilla? Canilla, string? NombreZona, string? NombreEmpresa)> GetByIdAsync(int id)
|
public async Task<(Canilla? Canilla, string? NombreZona, string? NombreEmpresa)> GetByIdAsync(int id)
|
||||||
@@ -160,9 +197,19 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
|
|
||||||
await connection.ExecuteAsync(sqlInsertHistorico, new
|
await connection.ExecuteAsync(sqlInsertHistorico, new
|
||||||
{
|
{
|
||||||
IdCanillaParam = insertedCanilla.IdCanilla, LegajoParam = insertedCanilla.Legajo, NomApeParam = insertedCanilla.NomApe, ParadaParam = insertedCanilla.Parada, IdZonaParam = insertedCanilla.IdZona,
|
IdCanillaParam = insertedCanilla.IdCanilla,
|
||||||
AccionistaParam = insertedCanilla.Accionista, ObsParam = insertedCanilla.Obs, EmpresaParam = insertedCanilla.Empresa, BajaParam = insertedCanilla.Baja, FechaBajaParam = insertedCanilla.FechaBaja,
|
LegajoParam = insertedCanilla.Legajo,
|
||||||
Id_UsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Creado"
|
NomApeParam = insertedCanilla.NomApe,
|
||||||
|
ParadaParam = insertedCanilla.Parada,
|
||||||
|
IdZonaParam = insertedCanilla.IdZona,
|
||||||
|
AccionistaParam = insertedCanilla.Accionista,
|
||||||
|
ObsParam = insertedCanilla.Obs,
|
||||||
|
EmpresaParam = insertedCanilla.Empresa,
|
||||||
|
BajaParam = insertedCanilla.Baja,
|
||||||
|
FechaBajaParam = insertedCanilla.FechaBaja,
|
||||||
|
Id_UsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Creado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
return insertedCanilla;
|
return insertedCanilla;
|
||||||
}
|
}
|
||||||
@@ -190,10 +237,18 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
await connection.ExecuteAsync(sqlInsertHistorico, new
|
await connection.ExecuteAsync(sqlInsertHistorico, new
|
||||||
{
|
{
|
||||||
IdCanillaParam = canillaActual.IdCanilla,
|
IdCanillaParam = canillaActual.IdCanilla,
|
||||||
LegajoParam = canillaActual.Legajo, NomApeParam = canillaActual.NomApe, ParadaParam = canillaActual.Parada, IdZonaParam = canillaActual.IdZona,
|
LegajoParam = canillaActual.Legajo,
|
||||||
AccionistaParam = canillaActual.Accionista, ObsParam = canillaActual.Obs, EmpresaParam = canillaActual.Empresa,
|
NomApeParam = canillaActual.NomApe,
|
||||||
BajaParam = canillaActual.Baja, FechaBajaParam = canillaActual.FechaBaja,
|
ParadaParam = canillaActual.Parada,
|
||||||
Id_UsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Actualizado"
|
IdZonaParam = canillaActual.IdZona,
|
||||||
|
AccionistaParam = canillaActual.Accionista,
|
||||||
|
ObsParam = canillaActual.Obs,
|
||||||
|
EmpresaParam = canillaActual.Empresa,
|
||||||
|
BajaParam = canillaActual.Baja,
|
||||||
|
FechaBajaParam = canillaActual.FechaBaja,
|
||||||
|
Id_UsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Actualizado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, canillaAActualizar, transaction);
|
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, canillaAActualizar, transaction);
|
||||||
@@ -218,14 +273,65 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
|
|
||||||
await connection.ExecuteAsync(sqlInsertHistorico, new
|
await connection.ExecuteAsync(sqlInsertHistorico, new
|
||||||
{
|
{
|
||||||
IdCanillaParam = canillaActual.IdCanilla, LegajoParam = canillaActual.Legajo, NomApeParam = canillaActual.NomApe, ParadaParam = canillaActual.Parada, IdZonaParam = canillaActual.IdZona,
|
IdCanillaParam = canillaActual.IdCanilla,
|
||||||
AccionistaParam = canillaActual.Accionista, ObsParam = canillaActual.Obs, EmpresaParam = canillaActual.Empresa,
|
LegajoParam = canillaActual.Legajo,
|
||||||
BajaNuevaParam = darDeBaja, FechaBajaNuevaParam = (darDeBaja ? fechaBaja : null),
|
NomApeParam = canillaActual.NomApe,
|
||||||
Id_UsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModHistParam = (darDeBaja ? "Baja" : "Alta")
|
ParadaParam = canillaActual.Parada,
|
||||||
|
IdZonaParam = canillaActual.IdZona,
|
||||||
|
AccionistaParam = canillaActual.Accionista,
|
||||||
|
ObsParam = canillaActual.Obs,
|
||||||
|
EmpresaParam = canillaActual.Empresa,
|
||||||
|
BajaNuevaParam = darDeBaja,
|
||||||
|
FechaBajaNuevaParam = (darDeBaja ? fechaBaja : null),
|
||||||
|
Id_UsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModHistParam = (darDeBaja ? "Baja" : "Alta")
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, new { BajaParam = darDeBaja, FechaBajaParam = (darDeBaja ? fechaBaja : null), IdCanillaParam = id }, transaction);
|
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, new { BajaParam = darDeBaja, FechaBajaParam = (darDeBaja ? fechaBaja : null), IdCanillaParam = id }, transaction);
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
|
public async Task<IEnumerable<(CanillaHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idCanillaOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection(); // Asumiendo _cf es tu DbConnectionFactory
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Canilla, h.Legajo, h.NomApe, h.Parada, h.Id_Zona, h.Accionista, h.Obs,
|
||||||
|
h.Empresa, h.Baja, h.FechaBaja,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.dist_dtCanillas_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idCanillaOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Canilla = @IdCanillaOriginalParam"); parameters.Add("IdCanillaOriginalParam", idCanillaOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<CanillaHistorico, string, (CanillaHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener historial de Canillitas (Maestro).");
|
||||||
|
return Enumerable.Empty<(CanillaHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,10 +101,18 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
var inserted = await transaction.Connection!.QuerySingleAsync<ControlDevoluciones>(sqlInsert, nuevoControl, transaction);
|
var inserted = await transaction.Connection!.QuerySingleAsync<ControlDevoluciones>(sqlInsert, nuevoControl, transaction);
|
||||||
if (inserted == null || inserted.IdControl == 0) throw new DataException("Error al crear control de devoluciones o ID no generado.");
|
if (inserted == null || inserted.IdControl == 0) throw new DataException("Error al crear control de devoluciones o ID no generado.");
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdControlParam = inserted.IdControl, IdEmpresaParam = inserted.IdEmpresa, FechaParam = inserted.Fecha,
|
{
|
||||||
EntradaParam = inserted.Entrada, SobrantesParam = inserted.Sobrantes, DetalleParam = inserted.Detalle, SinCargoParam = inserted.SinCargo,
|
IdControlParam = inserted.IdControl,
|
||||||
IdUsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Creado"
|
IdEmpresaParam = inserted.IdEmpresa,
|
||||||
|
FechaParam = inserted.Fecha,
|
||||||
|
EntradaParam = inserted.Entrada,
|
||||||
|
SobrantesParam = inserted.Sobrantes,
|
||||||
|
DetalleParam = inserted.Detalle,
|
||||||
|
SinCargoParam = inserted.SinCargo,
|
||||||
|
IdUsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Creado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
return inserted;
|
return inserted;
|
||||||
}
|
}
|
||||||
@@ -126,10 +134,18 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
(Id_Control, Id_Empresa, Fecha, Entrada, Sobrantes, Detalle, SinCargo, Id_Usuario, FechaMod, TipoMod)
|
(Id_Control, Id_Empresa, Fecha, Entrada, Sobrantes, Detalle, SinCargo, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdControlParam, @IdEmpresaParam, @FechaParam, @EntradaParam, @SobrantesParam, @DetalleParam, @SinCargoParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
VALUES (@IdControlParam, @IdEmpresaParam, @FechaParam, @EntradaParam, @SobrantesParam, @DetalleParam, @SinCargoParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdControlParam = actual.IdControl, IdEmpresaParam = actual.IdEmpresa, FechaParam = actual.Fecha, // Datos originales
|
{
|
||||||
EntradaParam = actual.Entrada, SobrantesParam = actual.Sobrantes, DetalleParam = actual.Detalle, SinCargoParam = actual.SinCargo, // Valores ANTERIORES
|
IdControlParam = actual.IdControl,
|
||||||
IdUsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Actualizado"
|
IdEmpresaParam = actual.IdEmpresa,
|
||||||
|
FechaParam = actual.Fecha, // Datos originales
|
||||||
|
EntradaParam = actual.Entrada,
|
||||||
|
SobrantesParam = actual.Sobrantes,
|
||||||
|
DetalleParam = actual.Detalle,
|
||||||
|
SinCargoParam = actual.SinCargo, // Valores ANTERIORES
|
||||||
|
IdUsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Actualizado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, controlAActualizar, transaction);
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, controlAActualizar, transaction);
|
||||||
@@ -149,14 +165,66 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
(Id_Control, Id_Empresa, Fecha, Entrada, Sobrantes, Detalle, SinCargo, Id_Usuario, FechaMod, TipoMod)
|
(Id_Control, Id_Empresa, Fecha, Entrada, Sobrantes, Detalle, SinCargo, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdControlParam, @IdEmpresaParam, @FechaParam, @EntradaParam, @SobrantesParam, @DetalleParam, @SinCargoParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
VALUES (@IdControlParam, @IdEmpresaParam, @FechaParam, @EntradaParam, @SobrantesParam, @DetalleParam, @SinCargoParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
||||||
|
|
||||||
await transaction.Connection!.ExecuteAsync(sqlHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlHistorico, new
|
||||||
IdControlParam = actual.IdControl, IdEmpresaParam = actual.IdEmpresa, FechaParam = actual.Fecha,
|
{
|
||||||
EntradaParam = actual.Entrada, SobrantesParam = actual.Sobrantes, DetalleParam = actual.Detalle, SinCargoParam = actual.SinCargo,
|
IdControlParam = actual.IdControl,
|
||||||
IdUsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Eliminado"
|
IdEmpresaParam = actual.IdEmpresa,
|
||||||
|
FechaParam = actual.Fecha,
|
||||||
|
EntradaParam = actual.Entrada,
|
||||||
|
SobrantesParam = actual.Sobrantes,
|
||||||
|
DetalleParam = actual.Detalle,
|
||||||
|
SinCargoParam = actual.SinCargo,
|
||||||
|
IdUsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Eliminado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdControlParam = idControl }, transaction);
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdControlParam = idControl }, transaction);
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(ControlDevolucionesHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idControlOriginal, int? idEmpresaOriginal, DateTime? fechaOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Control, h.Id_Empresa, h.Fecha, h.Entrada, h.Sobrantes, h.Detalle, h.SinCargo,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.dist_dtCtrlDevoluciones_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idControlOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Control = @IdControlOriginalParam"); parameters.Add("IdControlOriginalParam", idControlOriginal.Value); }
|
||||||
|
if (idEmpresaOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Empresa = @IdEmpresaOriginalParam"); parameters.Add("IdEmpresaOriginalParam", idEmpresaOriginal.Value); }
|
||||||
|
if (fechaOriginal.HasValue) { sqlBuilder.Append(" AND h.Fecha = @FechaOriginalParam"); parameters.Add("FechaOriginalParam", fechaOriginal.Value.Date); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<ControlDevolucionesHistorico, string, (ControlDevolucionesHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error al obtener historial de Control de Devoluciones.");
|
||||||
|
return Enumerable.Empty<(ControlDevolucionesHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dapper;
|
using Dapper;
|
||||||
|
using GestionIntegral.Api.Dtos.Distribucion;
|
||||||
using GestionIntegral.Api.Models.Distribucion;
|
using GestionIntegral.Api.Models.Distribucion;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System; // Añadido para Exception
|
using System; // Añadido para Exception
|
||||||
@@ -21,12 +22,12 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<(Distribuidor Distribuidor, string? NombreZona)>> GetAllAsync(string? nombreFilter, string? nroDocFilter)
|
public async Task<IEnumerable<(Distribuidor Distribuidor, string? NombreZona)>> GetAllAsync(string? nombreFilter, string? nroDocFilter, bool? soloActivos = true)
|
||||||
{
|
{
|
||||||
var sqlBuilder = new StringBuilder(@"
|
var sqlBuilder = new StringBuilder(@"
|
||||||
SELECT
|
SELECT
|
||||||
d.Id_Distribuidor AS IdDistribuidor, d.Nombre, d.Contacto, d.NroDoc, d.Id_Zona AS IdZona,
|
d.Id_Distribuidor AS IdDistribuidor, d.Nombre, d.Contacto, d.NroDoc, d.Id_Zona AS IdZona,
|
||||||
d.Calle, d.Numero, d.Piso, d.Depto, d.Telefono, d.Email, d.Localidad,
|
d.Calle, d.Numero, d.Piso, d.Depto, d.Telefono, d.Email, d.Localidad, d.Baja, d.FechaBaja,
|
||||||
z.Nombre AS NombreZona
|
z.Nombre AS NombreZona
|
||||||
FROM dbo.dist_dtDistribuidores d
|
FROM dbo.dist_dtDistribuidores d
|
||||||
LEFT JOIN dbo.dist_dtZonas z ON d.Id_Zona = z.Id_Zona
|
LEFT JOIN dbo.dist_dtZonas z ON d.Id_Zona = z.Id_Zona
|
||||||
@@ -43,6 +44,11 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
sqlBuilder.Append(" AND d.NroDoc LIKE @NroDocParam");
|
sqlBuilder.Append(" AND d.NroDoc LIKE @NroDocParam");
|
||||||
parameters.Add("NroDocParam", $"%{nroDocFilter}%");
|
parameters.Add("NroDocParam", $"%{nroDocFilter}%");
|
||||||
}
|
}
|
||||||
|
if (soloActivos.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND d.Baja = @BajaStatus ");
|
||||||
|
parameters.Add("BajaStatus", !soloActivos.Value);
|
||||||
|
}
|
||||||
sqlBuilder.Append(" ORDER BY d.Nombre;");
|
sqlBuilder.Append(" ORDER BY d.Nombre;");
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -62,12 +68,43 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<DistribuidorDropdownDto?>> GetAllDropdownAsync(bool? soloActivos = true)
|
||||||
|
{
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
Id_Distribuidor AS IdDistribuidor, Nombre
|
||||||
|
FROM dbo.dist_dtDistribuidores
|
||||||
|
WHERE 1=1");
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (soloActivos.HasValue)
|
||||||
|
{
|
||||||
|
sqlBuilder.Append(" AND Baja = @BajaStatus ");
|
||||||
|
parameters.Add("BajaStatus", !soloActivos.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY Nombre;");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QueryAsync<DistribuidorDropdownDto>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
parameters
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener todos los Distribuidores.");
|
||||||
|
return Enumerable.Empty<DistribuidorDropdownDto>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<(Distribuidor? Distribuidor, string? NombreZona)> GetByIdAsync(int id)
|
public async Task<(Distribuidor? Distribuidor, string? NombreZona)> GetByIdAsync(int id)
|
||||||
{
|
{
|
||||||
const string sql = @"
|
const string sql = @"
|
||||||
SELECT
|
SELECT
|
||||||
d.Id_Distribuidor AS IdDistribuidor, d.Nombre, d.Contacto, d.NroDoc, d.Id_Zona AS IdZona,
|
d.Id_Distribuidor AS IdDistribuidor, d.Nombre, d.Contacto, d.NroDoc, d.Id_Zona AS IdZona,
|
||||||
d.Calle, d.Numero, d.Piso, d.Depto, d.Telefono, d.Email, d.Localidad,
|
d.Calle, d.Numero, d.Piso, d.Depto, d.Telefono, d.Email, d.Localidad, d.Baja, d.FechaBaja,
|
||||||
z.Nombre AS NombreZona
|
z.Nombre AS NombreZona
|
||||||
FROM dbo.dist_dtDistribuidores d
|
FROM dbo.dist_dtDistribuidores d
|
||||||
LEFT JOIN dbo.dist_dtZonas z ON d.Id_Zona = z.Id_Zona
|
LEFT JOIN dbo.dist_dtZonas z ON d.Id_Zona = z.Id_Zona
|
||||||
@@ -90,12 +127,31 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<DistribuidorLookupDto?> ObtenerLookupPorIdAsync(int id)
|
||||||
|
{
|
||||||
|
const string sql = @"
|
||||||
|
SELECT
|
||||||
|
Id_Distribuidor AS IdDistribuidor, Nombre
|
||||||
|
FROM dbo.dist_dtDistribuidores
|
||||||
|
WHERE Id_Distribuidor = @IdParam";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection();
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<DistribuidorLookupDto>(sql, new { IdParam = id });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener Distribuidor por ID: {IdDistribuidor}", id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Distribuidor?> GetByIdSimpleAsync(int id)
|
public async Task<Distribuidor?> GetByIdSimpleAsync(int id)
|
||||||
{
|
{
|
||||||
const string sql = @"
|
const string sql = @"
|
||||||
SELECT
|
SELECT
|
||||||
Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
|
Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
|
||||||
Calle, Numero, Piso, Depto, Telefono, Email, Localidad
|
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
|
||||||
FROM dbo.dist_dtDistribuidores
|
FROM dbo.dist_dtDistribuidores
|
||||||
WHERE Id_Distribuidor = @IdParam";
|
WHERE Id_Distribuidor = @IdParam";
|
||||||
try
|
try
|
||||||
@@ -179,10 +235,10 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
public async Task<Distribuidor?> CreateAsync(Distribuidor nuevoDistribuidor, int idUsuario, IDbTransaction transaction)
|
public async Task<Distribuidor?> CreateAsync(Distribuidor nuevoDistribuidor, int idUsuario, IDbTransaction transaction)
|
||||||
{
|
{
|
||||||
const string sqlInsert = @"
|
const string sqlInsert = @"
|
||||||
INSERT INTO dbo.dist_dtDistribuidores (Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad)
|
INSERT INTO dbo.dist_dtDistribuidores (Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja)
|
||||||
OUTPUT INSERTED.Id_Distribuidor AS IdDistribuidor, INSERTED.Nombre, INSERTED.Contacto, INSERTED.NroDoc, INSERTED.Id_Zona AS IdZona,
|
OUTPUT INSERTED.Id_Distribuidor AS IdDistribuidor, INSERTED.Nombre, INSERTED.Contacto, INSERTED.NroDoc, INSERTED.Id_Zona AS IdZona,
|
||||||
INSERTED.Calle, INSERTED.Numero, INSERTED.Piso, INSERTED.Depto, INSERTED.Telefono, INSERTED.Email, INSERTED.Localidad
|
INSERTED.Calle, INSERTED.Numero, INSERTED.Piso, INSERTED.Depto, INSERTED.Telefono, INSERTED.Email, INSERTED.Localidad, INSERTED.Baja, INSERTED.FechaBaja
|
||||||
VALUES (@Nombre, @Contacto, @NroDoc, @IdZona, @Calle, @Numero, @Piso, @Depto, @Telefono, @Email, @Localidad);";
|
VALUES (@Nombre, @Contacto, @NroDoc, @IdZona, @Calle, @Numero, @Piso, @Depto, @Telefono, @Email, @Localidad, 0, NULL);";
|
||||||
|
|
||||||
var connection = transaction.Connection!;
|
var connection = transaction.Connection!;
|
||||||
var inserted = await connection.QuerySingleAsync<Distribuidor>(sqlInsert, nuevoDistribuidor, transaction);
|
var inserted = await connection.QuerySingleAsync<Distribuidor>(sqlInsert, nuevoDistribuidor, transaction);
|
||||||
@@ -190,14 +246,28 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
|
|
||||||
const string sqlInsertHistorico = @"
|
const string sqlInsertHistorico = @"
|
||||||
INSERT INTO dbo.dist_dtDistribuidores_H
|
INSERT INTO dbo.dist_dtDistribuidores_H
|
||||||
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Id_Usuario, FechaMod, TipoMod)
|
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaParam, @FechaBajaParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
||||||
|
|
||||||
await connection.ExecuteAsync(sqlInsertHistorico, new
|
await connection.ExecuteAsync(sqlInsertHistorico, new
|
||||||
{
|
{
|
||||||
IdDistribuidorParam = inserted.IdDistribuidor, NombreParam = inserted.Nombre, ContactoParam = inserted.Contacto, NroDocParam = inserted.NroDoc, IdZonaParam = inserted.IdZona,
|
IdDistribuidorParam = inserted.IdDistribuidor,
|
||||||
CalleParam = inserted.Calle, NumeroParam = inserted.Numero, PisoParam = inserted.Piso, DeptoParam = inserted.Depto, TelefonoParam = inserted.Telefono, EmailParam = inserted.Email, LocalidadParam = inserted.Localidad,
|
NombreParam = inserted.Nombre,
|
||||||
IdUsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Creado"
|
ContactoParam = inserted.Contacto,
|
||||||
|
NroDocParam = inserted.NroDoc,
|
||||||
|
IdZonaParam = inserted.IdZona,
|
||||||
|
CalleParam = inserted.Calle,
|
||||||
|
NumeroParam = inserted.Numero,
|
||||||
|
PisoParam = inserted.Piso,
|
||||||
|
DeptoParam = inserted.Depto,
|
||||||
|
TelefonoParam = inserted.Telefono,
|
||||||
|
EmailParam = inserted.Email,
|
||||||
|
LocalidadParam = inserted.Localidad,
|
||||||
|
BajaParam = inserted.Baja,
|
||||||
|
FechaBajaParam = inserted.FechaBaja,
|
||||||
|
IdUsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Creado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
return inserted;
|
return inserted;
|
||||||
}
|
}
|
||||||
@@ -207,7 +277,7 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
var connection = transaction.Connection!;
|
var connection = transaction.Connection!;
|
||||||
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
|
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
|
||||||
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
|
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
|
||||||
Calle, Numero, Piso, Depto, Telefono, Email, Localidad
|
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
|
||||||
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdDistribuidorParam",
|
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdDistribuidorParam",
|
||||||
new { IdDistribuidorParam = distribuidorAActualizar.IdDistribuidor }, transaction);
|
new { IdDistribuidorParam = distribuidorAActualizar.IdDistribuidor }, transaction);
|
||||||
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado.");
|
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado.");
|
||||||
@@ -219,14 +289,28 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
WHERE Id_Distribuidor = @IdDistribuidor;";
|
WHERE Id_Distribuidor = @IdDistribuidor;";
|
||||||
const string sqlInsertHistorico = @"
|
const string sqlInsertHistorico = @"
|
||||||
INSERT INTO dbo.dist_dtDistribuidores_H
|
INSERT INTO dbo.dist_dtDistribuidores_H
|
||||||
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Id_Usuario, FechaMod, TipoMod)
|
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaParam, @FechaBajaParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
||||||
|
|
||||||
await connection.ExecuteAsync(sqlInsertHistorico, new
|
await connection.ExecuteAsync(sqlInsertHistorico, new
|
||||||
{
|
{
|
||||||
IdDistribuidorParam = actual.IdDistribuidor, NombreParam = actual.Nombre, ContactoParam = actual.Contacto, NroDocParam = actual.NroDoc, IdZonaParam = actual.IdZona,
|
IdDistribuidorParam = actual.IdDistribuidor,
|
||||||
CalleParam = actual.Calle, NumeroParam = actual.Numero, PisoParam = actual.Piso, DeptoParam = actual.Depto, TelefonoParam = actual.Telefono, EmailParam = actual.Email, LocalidadParam = actual.Localidad,
|
NombreParam = actual.Nombre,
|
||||||
IdUsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Actualizado"
|
ContactoParam = actual.Contacto,
|
||||||
|
NroDocParam = actual.NroDoc,
|
||||||
|
IdZonaParam = actual.IdZona,
|
||||||
|
CalleParam = actual.Calle,
|
||||||
|
NumeroParam = actual.Numero,
|
||||||
|
PisoParam = actual.Piso,
|
||||||
|
DeptoParam = actual.Depto,
|
||||||
|
TelefonoParam = actual.Telefono,
|
||||||
|
EmailParam = actual.Email,
|
||||||
|
LocalidadParam = actual.Localidad,
|
||||||
|
BajaParam = actual.Baja,
|
||||||
|
FechaBajaParam = actual.FechaBaja,
|
||||||
|
IdUsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Actualizado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, distribuidorAActualizar, transaction);
|
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, distribuidorAActualizar, transaction);
|
||||||
@@ -238,7 +322,7 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
var connection = transaction.Connection!;
|
var connection = transaction.Connection!;
|
||||||
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
|
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
|
||||||
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
|
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
|
||||||
Calle, Numero, Piso, Depto, Telefono, Email, Localidad
|
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
|
||||||
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdParam", new { IdParam = id }, transaction);
|
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdParam", new { IdParam = id }, transaction);
|
||||||
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado.");
|
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado.");
|
||||||
|
|
||||||
@@ -246,18 +330,116 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
const string sqlDelete = "DELETE FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdParam";
|
const string sqlDelete = "DELETE FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdParam";
|
||||||
const string sqlInsertHistorico = @"
|
const string sqlInsertHistorico = @"
|
||||||
INSERT INTO dbo.dist_dtDistribuidores_H
|
INSERT INTO dbo.dist_dtDistribuidores_H
|
||||||
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Id_Usuario, FechaMod, TipoMod)
|
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
|
||||||
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaParam, @FechaBajaParam, @IdUsuarioParam, @FechaModParam, @TipoModParam);";
|
||||||
|
|
||||||
await connection.ExecuteAsync(sqlInsertHistorico, new
|
await connection.ExecuteAsync(sqlInsertHistorico, new
|
||||||
{
|
{
|
||||||
IdDistribuidorParam = actual.IdDistribuidor, NombreParam = actual.Nombre, ContactoParam = actual.Contacto, NroDocParam = actual.NroDoc, IdZonaParam = actual.IdZona,
|
IdDistribuidorParam = actual.IdDistribuidor,
|
||||||
CalleParam = actual.Calle, NumeroParam = actual.Numero, PisoParam = actual.Piso, DeptoParam = actual.Depto, TelefonoParam = actual.Telefono, EmailParam = actual.Email, LocalidadParam = actual.Localidad,
|
NombreParam = actual.Nombre,
|
||||||
IdUsuarioParam = idUsuario, FechaModParam = DateTime.Now, TipoModParam = "Eliminado"
|
ContactoParam = actual.Contacto,
|
||||||
|
NroDocParam = actual.NroDoc,
|
||||||
|
IdZonaParam = actual.IdZona,
|
||||||
|
CalleParam = actual.Calle,
|
||||||
|
NumeroParam = actual.Numero,
|
||||||
|
PisoParam = actual.Piso,
|
||||||
|
DeptoParam = actual.Depto,
|
||||||
|
TelefonoParam = actual.Telefono,
|
||||||
|
EmailParam = actual.Email,
|
||||||
|
LocalidadParam = actual.Localidad,
|
||||||
|
BajaParam = actual.Baja,
|
||||||
|
FechaBajaParam = actual.FechaBaja,
|
||||||
|
IdUsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModParam = "Eliminado"
|
||||||
}, transaction);
|
}, transaction);
|
||||||
|
|
||||||
var rowsAffected = await connection.ExecuteAsync(sqlDelete, new { IdParam = id }, transaction);
|
var rowsAffected = await connection.ExecuteAsync(sqlDelete, new { IdParam = id }, transaction);
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> ToggleBajaAsync(int id, bool darDeBaja, DateTime? fechaBaja, int idUsuario, IDbTransaction transaction)
|
||||||
|
{
|
||||||
|
var connection = transaction.Connection!;
|
||||||
|
var actual = await connection.QuerySingleOrDefaultAsync<Distribuidor>(
|
||||||
|
@"SELECT Id_Distribuidor AS IdDistribuidor, Nombre, Contacto, NroDoc, Id_Zona AS IdZona,
|
||||||
|
Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja
|
||||||
|
FROM dbo.dist_dtDistribuidores WHERE Id_Distribuidor = @IdDistribuidorParam",
|
||||||
|
new { IdDistribuidorParam = id }, transaction);
|
||||||
|
if (actual == null) throw new KeyNotFoundException("Distribuidor no encontrado para dar de baja/alta.");
|
||||||
|
|
||||||
|
const string sqlUpdate = "UPDATE dbo.dist_dtDistribuidores SET Baja = @BajaParam, FechaBaja = @FechaBajaParam WHERE Id_Distribuidor = @IdDistribuidorParam;";
|
||||||
|
const string sqlInsertHistorico = @"
|
||||||
|
INSERT INTO dbo.dist_dtDistribuidores_H
|
||||||
|
(Id_Distribuidor, Nombre, Contacto, NroDoc, Id_Zona, Calle, Numero, Piso, Depto, Telefono, Email, Localidad, Baja, FechaBaja, Id_Usuario, FechaMod, TipoMod)
|
||||||
|
VALUES (@IdDistribuidorParam, @NombreParam, @ContactoParam, @NroDocParam, @IdZonaParam, @CalleParam, @NumeroParam, @PisoParam, @DeptoParam, @TelefonoParam, @EmailParam, @LocalidadParam, @BajaNuevaParam, @FechaBajaNuevaParam, @IdUsuarioParam, @FechaModParam, @TipoModHistParam);";
|
||||||
|
|
||||||
|
await connection.ExecuteAsync(sqlInsertHistorico, new
|
||||||
|
{
|
||||||
|
IdDistribuidorParam = actual.IdDistribuidor,
|
||||||
|
NombreParam = actual.Nombre,
|
||||||
|
ContactoParam = actual.Contacto,
|
||||||
|
NroDocParam = actual.NroDoc,
|
||||||
|
IdZonaParam = actual.IdZona,
|
||||||
|
CalleParam = actual.Calle,
|
||||||
|
NumeroParam = actual.Numero,
|
||||||
|
PisoParam = actual.Piso,
|
||||||
|
DeptoParam = actual.Depto,
|
||||||
|
TelefonoParam = actual.Telefono,
|
||||||
|
EmailParam = actual.Email,
|
||||||
|
LocalidadParam = actual.Localidad,
|
||||||
|
BajaNuevaParam = darDeBaja,
|
||||||
|
FechaBajaNuevaParam = (darDeBaja ? fechaBaja : null),
|
||||||
|
IdUsuarioParam = idUsuario,
|
||||||
|
FechaModParam = DateTime.Now,
|
||||||
|
TipoModHistParam = (darDeBaja ? "Baja" : "Alta")
|
||||||
|
}, transaction);
|
||||||
|
|
||||||
|
var rowsAffected = await connection.ExecuteAsync(sqlUpdate, new { BajaParam = darDeBaja, FechaBajaParam = (darDeBaja ? fechaBaja : null), IdDistribuidorParam = id }, transaction);
|
||||||
|
return rowsAffected == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(DistribuidorHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idDistribuidorOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection(); // Asumiendo _connectionFactory
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Distribuidor, h.Nombre, h.Contacto, h.NroDoc, h.Id_Zona, h.Calle, h.Numero,
|
||||||
|
h.Piso, h.Depto, h.Telefono, h.Email, h.Localidad,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.dist_dtDistribuidores_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idDistribuidorOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Distribuidor = @IdDistribuidorOriginalParam"); parameters.Add("IdDistribuidorOriginalParam", idDistribuidorOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<DistribuidorHistorico, string, (DistribuidorHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener historial de Distribuidores (Maestro)."); // Asumiendo _logger
|
||||||
|
return Enumerable.Empty<(DistribuidorHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Dapper;
|
using Dapper;
|
||||||
using GestionIntegral.Api.Data.Repositories;
|
using GestionIntegral.Api.Data.Repositories;
|
||||||
|
using GestionIntegral.Api.Dtos.Empresas;
|
||||||
using GestionIntegral.Api.Models.Distribucion;
|
using GestionIntegral.Api.Models.Distribucion;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
@@ -52,6 +53,25 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<EmpresaDropdownDto>> GetAllDropdownAsync()
|
||||||
|
{
|
||||||
|
var sqlBuilder = new StringBuilder("SELECT Id_Empresa AS IdEmpresa, Nombre FROM dbo.dist_dtEmpresas WHERE 1=1");
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
sqlBuilder.Append(" ORDER BY Nombre;");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var connection = _connectionFactory.CreateConnection())
|
||||||
|
{
|
||||||
|
return await connection.QueryAsync<EmpresaDropdownDto>(sqlBuilder.ToString(), parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener todas las Empresas.");
|
||||||
|
return Enumerable.Empty<EmpresaDropdownDto>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Empresa?> GetByIdAsync(int id)
|
public async Task<Empresa?> GetByIdAsync(int id)
|
||||||
{
|
{
|
||||||
var sql = "SELECT Id_Empresa AS IdEmpresa, Nombre, Detalle FROM dbo.dist_dtEmpresas WHERE Id_Empresa = @Id";
|
var sql = "SELECT Id_Empresa AS IdEmpresa, Nombre, Detalle FROM dbo.dist_dtEmpresas WHERE Id_Empresa = @Id";
|
||||||
@@ -69,6 +89,23 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Empresa?> ObtenerLookupPorIdAsync(int id)
|
||||||
|
{
|
||||||
|
var sql = "SELECT Id_Empresa AS IdEmpresa, Nombre FROM dbo.dist_dtEmpresas WHERE Id_Empresa = @Id";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var connection = _connectionFactory.CreateConnection())
|
||||||
|
{
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<Empresa>(sql, new { Id = id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener Empresa por ID: {IdEmpresa}", id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> ExistsByNameAsync(string nombre, int? excludeId = null)
|
public async Task<bool> ExistsByNameAsync(string nombre, int? excludeId = null)
|
||||||
{
|
{
|
||||||
var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.dist_dtEmpresas WHERE Nombre = @Nombre");
|
var sqlBuilder = new StringBuilder("SELECT COUNT(1) FROM dbo.dist_dtEmpresas WHERE Nombre = @Nombre");
|
||||||
@@ -144,7 +181,8 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insertar en historial
|
// Insertar en historial
|
||||||
await transaction.Connection!.ExecuteAsync(sqlInsertHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlInsertHistorico, new
|
||||||
|
{
|
||||||
IdEmpresa = insertedEmpresa.IdEmpresa,
|
IdEmpresa = insertedEmpresa.IdEmpresa,
|
||||||
insertedEmpresa.Nombre,
|
insertedEmpresa.Nombre,
|
||||||
insertedEmpresa.Detalle,
|
insertedEmpresa.Detalle,
|
||||||
@@ -172,7 +210,8 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
VALUES (@IdEmpresa, @NombreActual, @DetalleActual, @IdUsuario, @FechaMod, @TipoMod);";
|
VALUES (@IdEmpresa, @NombreActual, @DetalleActual, @IdUsuario, @FechaMod, @TipoMod);";
|
||||||
|
|
||||||
// Insertar en historial (estado anterior)
|
// Insertar en historial (estado anterior)
|
||||||
await transaction.Connection!.ExecuteAsync(sqlInsertHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlInsertHistorico, new
|
||||||
|
{
|
||||||
IdEmpresa = empresaActual.IdEmpresa,
|
IdEmpresa = empresaActual.IdEmpresa,
|
||||||
NombreActual = empresaActual.Nombre,
|
NombreActual = empresaActual.Nombre,
|
||||||
DetalleActual = empresaActual.Detalle,
|
DetalleActual = empresaActual.Detalle,
|
||||||
@@ -182,7 +221,8 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
}, transaction: transaction);
|
}, transaction: transaction);
|
||||||
|
|
||||||
// Actualizar principal
|
// Actualizar principal
|
||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, new {
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlUpdate, new
|
||||||
|
{
|
||||||
empresaAActualizar.Nombre,
|
empresaAActualizar.Nombre,
|
||||||
empresaAActualizar.Detalle,
|
empresaAActualizar.Detalle,
|
||||||
empresaAActualizar.IdEmpresa
|
empresaAActualizar.IdEmpresa
|
||||||
@@ -202,7 +242,8 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
VALUES (@IdEmpresa, @Nombre, @Detalle, @IdUsuario, @FechaMod, @TipoMod);";
|
VALUES (@IdEmpresa, @Nombre, @Detalle, @IdUsuario, @FechaMod, @TipoMod);";
|
||||||
|
|
||||||
// Insertar en historial (estado antes de borrar)
|
// Insertar en historial (estado antes de borrar)
|
||||||
await transaction.Connection!.ExecuteAsync(sqlInsertHistorico, new {
|
await transaction.Connection!.ExecuteAsync(sqlInsertHistorico, new
|
||||||
|
{
|
||||||
IdEmpresa = empresaActual.IdEmpresa,
|
IdEmpresa = empresaActual.IdEmpresa,
|
||||||
empresaActual.Nombre,
|
empresaActual.Nombre,
|
||||||
empresaActual.Detalle,
|
empresaActual.Detalle,
|
||||||
@@ -216,5 +257,47 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
|
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(EmpresaHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idEmpresaOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _connectionFactory.CreateConnection(); // Asumiendo _cf
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Empresa, h.Nombre, h.Detalle,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.dist_dtEmpresas_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idEmpresaOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Empresa = @IdEmpresaOriginalParam"); parameters.Add("IdEmpresaOriginalParam", idEmpresaOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<EmpresaHistorico, string, (EmpresaHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error al obtener historial de Empresas (Maestro)."); // Asumiendo _logger
|
||||||
|
return Enumerable.Empty<(EmpresaHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,5 +292,48 @@ namespace GestionIntegral.Api.Data.Repositories.Distribucion
|
|||||||
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdParteParam = idParte }, transaction);
|
var rowsAffected = await transaction.Connection!.ExecuteAsync(sqlDelete, new { IdParteParam = idParte }, transaction);
|
||||||
return rowsAffected == 1;
|
return rowsAffected == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<(EntradaSalidaCanillaHistorico Historial, string NombreUsuarioModifico)>> GetHistorialAsync(
|
||||||
|
DateTime? fechaDesde, DateTime? fechaHasta,
|
||||||
|
int? idUsuarioModifico, string? tipoModificacion,
|
||||||
|
int? idParteOriginal)
|
||||||
|
{
|
||||||
|
using var connection = _cf.CreateConnection();
|
||||||
|
var sqlBuilder = new StringBuilder(@"
|
||||||
|
SELECT
|
||||||
|
h.Id_Parte, h.Id_Publicacion, h.Id_Canilla, h.Fecha,
|
||||||
|
h.CantSalida, h.CantEntrada, h.Id_Precio, h.Id_Recargo, h.Id_PorcMon, h.Observacion,
|
||||||
|
h.Id_Usuario, h.FechaMod, h.TipoMod,
|
||||||
|
u.Nombre + ' ' + u.Apellido AS NombreUsuarioModifico
|
||||||
|
FROM dbo.dist_EntradasSalidasCanillas_H h
|
||||||
|
JOIN dbo.gral_Usuarios u ON h.Id_Usuario = u.Id
|
||||||
|
WHERE 1=1");
|
||||||
|
|
||||||
|
var parameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (fechaDesde.HasValue) { sqlBuilder.Append(" AND h.FechaMod >= @FechaDesdeParam"); parameters.Add("FechaDesdeParam", fechaDesde.Value.Date); }
|
||||||
|
if (fechaHasta.HasValue) { sqlBuilder.Append(" AND h.FechaMod <= @FechaHastaParam"); parameters.Add("FechaHastaParam", fechaHasta.Value.Date.AddDays(1).AddTicks(-1)); }
|
||||||
|
if (idUsuarioModifico.HasValue) { sqlBuilder.Append(" AND h.Id_Usuario = @IdUsuarioModificoParam"); parameters.Add("IdUsuarioModificoParam", idUsuarioModifico.Value); }
|
||||||
|
if (!string.IsNullOrWhiteSpace(tipoModificacion)) { sqlBuilder.Append(" AND h.TipoMod = @TipoModParam"); parameters.Add("TipoModParam", tipoModificacion); }
|
||||||
|
if (idParteOriginal.HasValue) { sqlBuilder.Append(" AND h.Id_Parte = @IdParteOriginalParam"); parameters.Add("IdParteOriginalParam", idParteOriginal.Value); }
|
||||||
|
|
||||||
|
sqlBuilder.Append(" ORDER BY h.FechaMod DESC;");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await connection.QueryAsync<EntradaSalidaCanillaHistorico, string, (EntradaSalidaCanillaHistorico, string)>(
|
||||||
|
sqlBuilder.ToString(),
|
||||||
|
(hist, userName) => (hist, userName),
|
||||||
|
parameters,
|
||||||
|
splitOn: "NombreUsuarioModifico"
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.LogError(ex, "Error al obtener historial de Entradas/Salidas Canillitas.");
|
||||||
|
return Enumerable.Empty<(EntradaSalidaCanillaHistorico, string)>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user