From a35a3a66eaeb05737167db017bd9403816d864e7 Mon Sep 17 00:00:00 2001 From: dmolinari Date: Fri, 18 Jul 2025 17:04:12 -0300 Subject: [PATCH] Fix: Filtro Fecha Tiradas --- .gitea/workflows/deploy.yml | 13 +- .../pages/Impresion/GestionarTiradasPage.tsx | 192 ++++++++++-------- 2 files changed, 114 insertions(+), 91 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 42dab63..17f2d08 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -14,7 +14,7 @@ jobs: run: | set -e - # Configura SSH + # 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 @@ -26,6 +26,12 @@ jobs: set -e echo "--- INICIO DEL DESPLIEGUE OPTIMIZADO ---" + # --- Asegurar que el Stack de la Base de Datos esté corriendo --- + echo "Asegurando que el stack de la base de datos esté activo..." + cd /opt/shared-services/database + # El comando 'up -d' es idempotente. Si ya está corriendo, no hace nada. + docker compose up -d + # 1. Preparar entorno TEMP_DIR=$(mktemp -d) REPO_OWNER="dmolinari" @@ -37,7 +43,7 @@ jobs: cd "$TEMP_DIR" git checkout "${{ gitea.sha }}" - # 2. Construcción paralela con Docker nativo (más rápido y fiable) + # 2. Construcción paralela build_image() { local dockerfile=$1 local image_name=$2 @@ -59,7 +65,7 @@ jobs: cd /opt/gestion-integral export DB_SA_PASSWORD='${{ secrets.DB_SA_PASSWORD_SECRET }}' - echo "Recreando servicios..." + echo "Recreando servicios de la aplicación..." docker compose up -d --force-recreate # 4. Limpieza @@ -68,5 +74,4 @@ jobs: docker image prune -f --filter "dangling=true" echo "--- DESPLIEGUE COMPLETADO CON ÉXITO ---" - echo "Tiempo total: $(($SECONDS / 60)) minutos y $(($SECONDS % 60)) segundos" EOSSH \ No newline at end of file diff --git a/Frontend/src/pages/Impresion/GestionarTiradasPage.tsx b/Frontend/src/pages/Impresion/GestionarTiradasPage.tsx index 98863cd..fe55fe9 100644 --- a/Frontend/src/pages/Impresion/GestionarTiradasPage.tsx +++ b/Frontend/src/pages/Impresion/GestionarTiradasPage.tsx @@ -1,11 +1,11 @@ import React, { useState, useEffect, useCallback } from 'react'; import { - Box, Typography, TextField, Button, Paper, IconButton, MenuItem, - Table, TableBody, TableCell, TableContainer, TableHead, TableRow, - CircularProgress, Alert, Accordion, AccordionSummary, AccordionDetails, Chip, - FormControl, - InputLabel, - Select + Box, Typography, TextField, Button, Paper, IconButton, MenuItem, + Table, TableBody, TableCell, TableContainer, TableHead, TableRow, + CircularProgress, Alert, Accordion, AccordionSummary, AccordionDetails, Chip, + FormControl, + InputLabel, + Select } from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; import DeleteIcon from '@mui/icons-material/Delete'; @@ -25,6 +25,13 @@ import TiradaFormModal from '../../components/Modals/Impresion/TiradaFormModal'; import { usePermissions } from '../../hooks/usePermissions'; import axios from 'axios'; +const toLocalDateString = (date: Date): string => { + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, '0'); + const day = date.getDate().toString().padStart(2, '0'); + return `${year}-${month}-${day}`; +}; + const GestionarTiradasPage: React.FC = () => { const [tiradas, setTiradas] = useState([]); const [loading, setLoading] = useState(true); @@ -32,7 +39,7 @@ const GestionarTiradasPage: React.FC = () => { const [apiErrorMessage, setApiErrorMessage] = useState(null); // Filtros - const [filtroFecha, setFiltroFecha] = useState(new Date().toISOString().split('T')[0]); + const [filtroFecha, setFiltroFecha] = useState(toLocalDateString(new Date())); const [filtroIdPublicacion, setFiltroIdPublicacion] = useState(''); const [filtroIdPlanta, setFiltroIdPlanta] = useState(''); @@ -51,17 +58,17 @@ const GestionarTiradasPage: React.FC = () => { const fetchFiltersDropdownData = useCallback(async () => { setLoadingFiltersDropdown(true); try { - const [pubsData, plantasData] = await Promise.all([ - publicacionService.getPublicacionesForDropdown(true), - plantaService.getPlantasForDropdown() - ]); - setPublicaciones(pubsData); - setPlantas(plantasData); + const [pubsData, plantasData] = await Promise.all([ + publicacionService.getPublicacionesForDropdown(true), + plantaService.getPlantasForDropdown() + ]); + setPublicaciones(pubsData); + setPlantas(plantasData); } catch (err) { - console.error("Error cargando datos para filtros:", err); - setError("Error al cargar opciones de filtro."); + console.error("Error cargando datos para filtros:", err); + setError("Error al cargar opciones de filtro."); } finally { - setLoadingFiltersDropdown(false); + setLoadingFiltersDropdown(false); } }, []); @@ -107,18 +114,21 @@ const GestionarTiradasPage: React.FC = () => { const handleDeleteTirada = async (tirada: TiradaDto) => { if (window.confirm(`¿Seguro de eliminar la tirada del ${tirada.fecha} para "${tirada.nombrePublicacion}" en planta "${tirada.nombrePlanta}"? Esta acción eliminará el total de ejemplares y todas sus secciones asociadas.`)) { - setApiErrorMessage(null); - try { + setApiErrorMessage(null); + try { await tiradaService.deleteTiradaCompleta(tirada.fecha, tirada.idPublicacion, tirada.idPlanta); cargarTiradas(); } catch (err: any) { - const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al eliminar la tirada.'; - setApiErrorMessage(message); + const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al eliminar la tirada.'; + setApiErrorMessage(message); } } }; - - const formatDate = (dateString?: string | null) => dateString ? new Date(dateString + 'T00:00:00Z').toLocaleDateString('es-AR') : '-'; + + const formatDate = (dateString?: string | null) => { + if (!dateString) return '-'; + return new Date(dateString).toLocaleDateString('es-AR', { timeZone: 'UTC' }); + }; if (!loading && !puedeVer && !loadingFiltersDropdown) return {error || "Acceso denegado."}; @@ -127,77 +137,85 @@ const GestionarTiradasPage: React.FC = () => { Gestión de Tiradas - Filtros - - setFiltroFecha(e.target.value)} InputLabelProps={{ shrink: true }} sx={{minWidth: 170}}/> - - Publicación - - - - Planta - - - {/* */} + Filtros + + setFiltroFecha(e.target.value)} + InputLabelProps={{ shrink: true }} + sx={{ minWidth: 170 }} + /> + + Publicación + + + + Planta + + + {/* */} - {puedeRegistrar && ()} + {puedeRegistrar && ()} {loading && } - {error && !loading && {error}} - {apiErrorMessage && {apiErrorMessage}} + {error && !loading && {error}} + {apiErrorMessage && {apiErrorMessage}} {!loading && !error && puedeVer && ( - - {tiradas.length === 0 ? ( - No se encontraron tiradas con los filtros aplicados. - ) : ( - tiradas.map((tirada) => ( - - }> - - {formatDate(tirada.fecha)} - {tirada.nombrePublicacion} ({tirada.nombrePlanta}) - - - - {puedeEliminar && ( - { e.stopPropagation(); handleDeleteTirada(tirada);}} sx={{ml:1}}> - - - )} - - - - - - - - Sección - Páginas - - - {tirada.seccionesImpresas.map(sec => ( - - {sec.nombreSeccion} - {sec.cantPag} - - ))} - -
-
-
-
- )) - )} -
- )} - {/* No hay paginación para la lista de Acordeones por ahora */} + + {tiradas.length === 0 ? ( + No se encontraron tiradas con los filtros aplicados. + ) : ( + tiradas.map((tirada) => ( + + }> + + {formatDate(tirada.fecha)} - {tirada.nombrePublicacion} ({tirada.nombrePlanta}) + + + + {puedeEliminar && ( + { e.stopPropagation(); handleDeleteTirada(tirada); }} sx={{ ml: 1 }}> + + + )} + + + + + + + + Sección + Páginas + + + {tirada.seccionesImpresas.map(sec => ( + + {sec.nombreSeccion} + {sec.cantPag} + + ))} + +
+
+
+
+ )) + )} +
+ )} + {/* No hay paginación para la lista de Acordeones por ahora */}