Files
GestionIntegralWeb/Frontend/src/pages/Reportes/SeleccionaReporteCuentasDistribuidores.tsx

157 lines
6.5 KiB
TypeScript
Raw Normal View History

import React, { useState, useEffect } from 'react';
import {
Box, Typography, TextField, Button, CircularProgress, Alert,
FormControl, InputLabel, Select, MenuItem
} from '@mui/material';
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';
interface SeleccionaReporteCuentasDistribuidoresProps {
onGenerarReporte: (params: {
idDistribuidor: number;
idEmpresa: number;
fechaDesde: string;
fechaHasta: string;
}) => Promise<void>;
onCancel: () => void;
isLoading?: boolean;
apiErrorMessage?: string | null;
}
const SeleccionaReporteCuentasDistribuidores: React.FC<SeleccionaReporteCuentasDistribuidoresProps> = ({
onGenerarReporte,
isLoading,
apiErrorMessage
}) => {
const [idDistribuidor, setIdDistribuidor] = useState<number | string>('');
const [idEmpresa, setIdEmpresa] = useState<number | string>('');
const [fechaDesde, setFechaDesde] = useState<string>(new Date().toISOString().split('T')[0]);
const [fechaHasta, setFechaHasta] = useState<string>(new Date().toISOString().split('T')[0]);
const [distribuidores, setDistribuidores] = useState<DistribuidorDropdownDto[]>([]);
const [empresas, setEmpresas] = useState<EmpresaDropdownDto[]>([]);
const [loadingDropdowns, setLoadingDropdowns] = useState(false);
const [localErrors, setLocalErrors] = useState<{ [key: string]: string | null }>({});
useEffect(() => {
const fetchData = async () => {
setLoadingDropdowns(true);
try {
const [distData, empData] = await Promise.all([
distribuidorService.getAllDistribuidoresDropdown(), // Asume que este servicio existe
empresaService.getEmpresasDropdown() // Asume que este servicio existe
]);
setDistribuidores(distData.map(d => d)); // El servicio devuelve tupla
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();
}, []);
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
});
};
return (
<Box sx={{ p: 2, border: '1px solid #ccc', borderRadius: '4px', minWidth: 380 }}>
<Typography variant="h6" gutterBottom>
Parámetros: Cuenta Corriente Distribuidor
</Typography>
<FormControl fullWidth margin="normal" error={!!localErrors.idDistribuidor} disabled={isLoading || loadingDropdowns}>
<InputLabel id="distribuidor-select-label" required>Distribuidor</InputLabel>
<Select
labelId="distribuidor-select-label"
label="Distribuidor"
value={idDistribuidor}
onChange={(e) => { setIdDistribuidor(e.target.value as number); setLocalErrors(p => ({ ...p, idDistribuidor: null })); }}
>
<MenuItem value="" disabled><em>Seleccione un distribuidor</em></MenuItem>
{distribuidores.map((d) => (
<MenuItem key={d.idDistribuidor} value={d.idDistribuidor}>{d.nombre}</MenuItem>
))}
</Select>
{localErrors.idDistribuidor && <Typography color="error" variant="caption" sx={{ml:1.5}}>{localErrors.idDistribuidor}</Typography>}
</FormControl>
<FormControl fullWidth margin="normal" error={!!localErrors.idEmpresa} disabled={isLoading || loadingDropdowns}>
<InputLabel id="empresa-select-label-cta" required>Empresa</InputLabel>
<Select
labelId="empresa-select-label-cta"
label="Empresa"
value={idEmpresa}
onChange={(e) => { setIdEmpresa(e.target.value as number); setLocalErrors(p => ({ ...p, idEmpresa: null })); }}
>
<MenuItem value="" disabled><em>Seleccione una empresa</em></MenuItem>
{empresas.map((e) => (
<MenuItem key={e.idEmpresa} value={e.idEmpresa}>{e.nombre}</MenuItem>
))}
</Select>
{localErrors.idEmpresa && <Typography color="error" variant="caption" sx={{ml:1.5}}>{localErrors.idEmpresa}</Typography>}
</FormControl>
<TextField
label="Fecha Desde"
type="date"
value={fechaDesde}
onChange={(e) => { 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 }}
/>
<TextField
label="Fecha Hasta"
type="date"
value={fechaHasta}
onChange={(e) => { 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 && <Alert severity="error" sx={{ mt: 2 }}>{apiErrorMessage}</Alert>}
{localErrors.dropdowns && <Alert severity="warning" sx={{ mt: 1 }}>{localErrors.dropdowns}</Alert>}
<Box sx={{ mt: 3, display: 'flex', justifyContent: 'flex-end', gap: 1 }}>
<Button onClick={handleGenerar} variant="contained" disabled={isLoading || loadingDropdowns}>
{isLoading ? <CircularProgress size={24} /> : 'Generar Reporte'}
</Button>
</Box>
</Box>
);
};
export default SeleccionaReporteCuentasDistribuidores;