import React, { useState, useEffect } from 'react'; import { Box, Typography, TextField, Button, CircularProgress, Alert, FormControl, InputLabel, Select, MenuItem, Tooltip } from '@mui/material'; import EventAvailableIcon from '@mui/icons-material/EventAvailable'; import type { DistribuidorDropdownDto } from '../../models/dtos/Distribucion/DistribuidorDropdownDto'; import distribuidorService from '../../services/Distribucion/distribuidorService'; import type { EmpresaDropdownDto } from '../../models/dtos/Distribucion/EmpresaDropdownDto'; import empresaService from '../../services/Distribucion/empresaService'; import cierresCcService from '../../services/Contables/cierresCcService'; interface SeleccionaReporteCuentasDistribuidoresProps { onGenerarReporte: (params: { idDistribuidor: number; idEmpresa: number; fechaDesde: string; fechaHasta: string; }) => Promise; onCancel: () => void; isLoading?: boolean; apiErrorMessage?: string | null; } // Suma 1 día a una fecha en formato yyyy-MM-dd y devuelve la fecha resultante // también en yyyy-MM-dd. Usado por el atajo "Desde último cierre" para arrancar // el reporte el día siguiente al cierre. const addOneDay = (yyyyMmDd: string): string => { const d = new Date(yyyyMmDd + 'T00:00:00'); d.setDate(d.getDate() + 1); const year = d.getFullYear(); const month = String(d.getMonth() + 1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }; const SeleccionaReporteCuentasDistribuidores: React.FC = ({ onGenerarReporte, isLoading, apiErrorMessage }) => { const [idDistribuidor, setIdDistribuidor] = useState(''); const [idEmpresa, setIdEmpresa] = useState(''); const [fechaDesde, setFechaDesde] = useState(new Date().toISOString().split('T')[0]); const [fechaHasta, setFechaHasta] = useState(new Date().toISOString().split('T')[0]); const [distribuidores, setDistribuidores] = useState([]); const [empresas, setEmpresas] = useState([]); const [loadingDropdowns, setLoadingDropdowns] = useState(false); const [localErrors, setLocalErrors] = useState<{ [key: string]: string | null }>({}); const [loadingUltimoCierre, setLoadingUltimoCierre] = useState(false); const [hayCierrePrevio, setHayCierrePrevio] = useState(null); const [infoCierre, setInfoCierre] = useState(null); useEffect(() => { const fetchData = async () => { setLoadingDropdowns(true); try { const [distData, empData] = await Promise.all([ distribuidorService.getAllDistribuidoresDropdown(), empresaService.getEmpresasDropdown() ]); setDistribuidores(distData.map(d => d)); setEmpresas(empData); } catch (error) { console.error("Error al cargar datos:", error); setLocalErrors(prev => ({ ...prev, dropdowns: 'Error al cargar distribuidores o empresas.' })); } finally { setLoadingDropdowns(false); } }; fetchData(); }, []); // Reset del estado del atajo cuando cambian distribuidor/empresa: el "ultimo cierre" // depende del par (distribuidor, empresa), si alguno cambia hay que volver a chequear. useEffect(() => { setHayCierrePrevio(null); setInfoCierre(null); }, [idDistribuidor, idEmpresa]); const validate = (): boolean => { const errors: { [key: string]: string | null } = {}; if (!idDistribuidor) errors.idDistribuidor = 'Debe seleccionar un distribuidor.'; if (!idEmpresa) errors.idEmpresa = 'Debe seleccionar una empresa.'; if (!fechaDesde) errors.fechaDesde = 'Fecha Desde es obligatoria.'; if (!fechaHasta) errors.fechaHasta = 'Fecha Hasta es obligatoria.'; if (fechaDesde && fechaHasta && new Date(fechaDesde) > new Date(fechaHasta)) { errors.fechaHasta = 'Fecha Hasta no puede ser anterior a Fecha Desde.'; } setLocalErrors(errors); return Object.keys(errors).length === 0; }; const handleGenerar = () => { if (!validate()) return; onGenerarReporte({ idDistribuidor: Number(idDistribuidor), idEmpresa: Number(idEmpresa), fechaDesde, fechaHasta }); }; const handleDesdeUltimoCierre = async () => { if (!idDistribuidor || !idEmpresa) return; setLoadingUltimoCierre(true); setInfoCierre(null); try { const ultimo = await cierresCcService.getUltimoCierre(Number(idDistribuidor), Number(idEmpresa)); if (ultimo === null) { setHayCierrePrevio(false); setInfoCierre('Sin cierres previos para este distribuidor y empresa.'); } else { const nuevaFechaDesde = addOneDay(ultimo.fechaCorte); setFechaDesde(nuevaFechaDesde); setLocalErrors(p => ({ ...p, fechaDesde: null, fechaHasta: null })); setHayCierrePrevio(true); setInfoCierre(`Último cierre: ${ultimo.fechaCorte}. Fecha Desde ajustada al día siguiente.`); } } catch (err) { console.error('Error al obtener último cierre:', err); setInfoCierre('Error al consultar el último cierre.'); } finally { setLoadingUltimoCierre(false); } }; const atajoDisabled = !idDistribuidor || !idEmpresa || loadingUltimoCierre || isLoading || hayCierrePrevio === false; const atajoTooltip = !idDistribuidor || !idEmpresa ? 'Seleccioná distribuidor y empresa primero.' : hayCierrePrevio === false ? 'Sin cierres previos.' : 'Autocompleta Fecha Desde con el día siguiente al último cierre.'; return ( Parámetros: Cuenta Corriente Distribuidor Distribuidor {localErrors.idDistribuidor && {localErrors.idDistribuidor}} Empresa {localErrors.idEmpresa && {localErrors.idEmpresa}} { setFechaDesde(e.target.value); setLocalErrors(p => ({ ...p, fechaDesde: null, fechaHasta: null })); }} margin="normal" fullWidth required error={!!localErrors.fechaDesde} helperText={localErrors.fechaDesde} disabled={isLoading} InputLabelProps={{ shrink: true }} /> {infoCierre && ( {infoCierre} )} { setFechaHasta(e.target.value); setLocalErrors(p => ({ ...p, fechaHasta: null })); }} margin="normal" fullWidth required error={!!localErrors.fechaHasta} helperText={localErrors.fechaHasta} disabled={isLoading} InputLabelProps={{ shrink: true }} /> {apiErrorMessage && {apiErrorMessage}} {localErrors.dropdowns && {localErrors.dropdowns}} ); }; export default SeleccionaReporteCuentasDistribuidores;