import React, { useState, useEffect } from 'react'; import { Modal, Box, Typography, TextField, Button, CircularProgress, Alert, FormControl, InputLabel, Select, MenuItem } from '@mui/material'; import type { StockBobinaDto } from '../../../models/dtos/Impresion/StockBobinaDto'; import type { CambiarEstadoBobinaDto } from '../../../models/dtos/Impresion/CambiarEstadoBobinaDto'; import type { EstadoBobinaDto } from '../../../models/dtos/Impresion/EstadoBobinaDto'; import type { PublicacionDto } from '../../../models/dtos/Distribucion/PublicacionDto'; import type { PubliSeccionDto } from '../../../models/dtos/Distribucion/PubliSeccionDto'; // Asumiendo que tienes este DTO import estadoBobinaService from '../../../services/Impresion/estadoBobinaService'; // Para cargar estados import publicacionService from '../../../services/Distribucion/publicacionService'; // Para cargar publicaciones import publiSeccionService from '../../../services/Distribucion/publiSeccionService'; // Para cargar secciones const modalStyle = { /* ... (mismo estilo) ... */ position: 'absolute' as 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: { xs: '90%', sm: 500 }, bgcolor: 'background.paper', border: '2px solid #000', boxShadow: 24, p: 4, maxHeight: '90vh', overflowY: 'auto' }; // IDs de estados conocidos (ajusta según tu BD) const ID_ESTADO_EN_USO = 2; const ID_ESTADO_DANADA = 3; // const ID_ESTADO_DISPONIBLE = 1; // No se cambia a Disponible desde este modal interface StockBobinaCambioEstadoModalProps { open: boolean; onClose: () => void; onSubmit: (idBobina: number, data: CambiarEstadoBobinaDto) => Promise; bobinaActual: StockBobinaDto | null; // La bobina cuyo estado se va a cambiar errorMessage?: string | null; clearErrorMessage: () => void; } const StockBobinaCambioEstadoModal: React.FC = ({ open, onClose, onSubmit, bobinaActual, errorMessage, clearErrorMessage }) => { const [nuevoEstadoId, setNuevoEstadoId] = useState(''); const [idPublicacion, setIdPublicacion] = useState(''); const [idSeccion, setIdSeccion] = useState(''); const [obs, setObs] = useState(''); const [fechaCambioEstado, setFechaCambioEstado] = useState(''); const [estadosDisponibles, setEstadosDisponibles] = useState([]); const [publicacionesDisponibles, setPublicacionesDisponibles] = useState([]); const [seccionesDisponibles, setSeccionesDisponibles] = useState([]); const [loading, setLoading] = useState(false); const [loadingDropdowns, setLoadingDropdowns] = useState(false); const [localErrors, setLocalErrors] = useState<{ [key: string]: string | null }>({}); useEffect(() => { const fetchDropdownData = async () => { if (!bobinaActual) return; setLoadingDropdowns(true); try { const estadosData = await estadoBobinaService.getAllEstadosBobina(); // Filtrar estados: no se puede volver a "Disponible" o al mismo estado actual desde aquí. // Y si está "Dañada", no se puede cambiar. let estadosFiltrados = estadosData.filter(e => e.idEstadoBobina !== bobinaActual.idEstadoBobina && e.idEstadoBobina !== 1); if (bobinaActual.idEstadoBobina === ID_ESTADO_DANADA) { // Si ya está dañada, no hay más cambios estadosFiltrados = []; } else if (bobinaActual.idEstadoBobina === ID_ESTADO_EN_USO) { // Si está en uso, solo puede pasar a Dañada estadosFiltrados = estadosData.filter(e => e.idEstadoBobina === ID_ESTADO_DANADA); } setEstadosDisponibles(estadosFiltrados); if (estadosFiltrados.some(e => e.idEstadoBobina === ID_ESTADO_EN_USO)) { // Solo cargar publicaciones si "En Uso" es una opción const publicacionesData = await publicacionService.getAllPublicaciones(undefined, undefined, true); // Solo habilitadas setPublicacionesDisponibles(publicacionesData); } else { setPublicacionesDisponibles([]); } } catch (error) { console.error("Error al cargar datos para dropdowns (Cambio Estado Bobina)", error); setLocalErrors(prev => ({...prev, dropdowns: 'Error al cargar datos necesarios.'})); } finally { setLoadingDropdowns(false); } }; if (open && bobinaActual) { fetchDropdownData(); setNuevoEstadoId(''); setIdPublicacion(''); setIdSeccion(''); setObs(bobinaActual.obs || ''); // Pre-cargar obs existente setFechaCambioEstado(new Date().toISOString().split('T')[0]); // Default a hoy setLocalErrors({}); clearErrorMessage(); } }, [open, bobinaActual, clearErrorMessage]); // Cargar secciones cuando cambia la publicación seleccionada y el estado es "En Uso" useEffect(() => { const fetchSecciones = async () => { if (nuevoEstadoId === ID_ESTADO_EN_USO && idPublicacion) { setLoadingDropdowns(true); // Podrías tener un loader específico para secciones try { const data = await publiSeccionService.getSeccionesPorPublicacion(Number(idPublicacion), true); // Solo activas setSeccionesDisponibles(data); } catch (error) { console.error("Error al cargar secciones:", error); setLocalErrors(prev => ({ ...prev, secciones: 'Error al cargar secciones.'})); } finally { setLoadingDropdowns(false); } } else { setSeccionesDisponibles([]); // Limpiar secciones si no aplica } }; fetchSecciones(); }, [nuevoEstadoId, idPublicacion]); const validate = (): boolean => { const errors: { [key: string]: string | null } = {}; if (!nuevoEstadoId) errors.nuevoEstadoId = 'Seleccione un nuevo estado.'; if (!fechaCambioEstado.trim()) errors.fechaCambioEstado = 'La fecha de cambio es obligatoria.'; else if (!/^\d{4}-\d{2}-\d{2}$/.test(fechaCambioEstado)) errors.fechaCambioEstado = 'Formato de fecha inválido.'; if (Number(nuevoEstadoId) === ID_ESTADO_EN_USO) { if (!idPublicacion) errors.idPublicacion = 'Seleccione una publicación.'; if (!idSeccion) errors.idSeccion = 'Seleccione una sección.'; } setLocalErrors(errors); return Object.keys(errors).length === 0; }; const handleInputChange = (fieldName: string) => { if (localErrors[fieldName]) setLocalErrors(prev => ({ ...prev, [fieldName]: null })); if (errorMessage) clearErrorMessage(); if (fieldName === 'nuevoEstadoId') { // Si cambia el estado, resetear pub/secc setIdPublicacion(''); setIdSeccion(''); } if (fieldName === 'idPublicacion') { // Si cambia la publicación, resetear seccion setIdSeccion(''); } }; const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); clearErrorMessage(); if (!validate() || !bobinaActual) return; setLoading(true); try { const dataToSubmit: CambiarEstadoBobinaDto = { nuevoEstadoId: Number(nuevoEstadoId), idPublicacion: Number(nuevoEstadoId) === ID_ESTADO_EN_USO ? Number(idPublicacion) : null, idSeccion: Number(nuevoEstadoId) === ID_ESTADO_EN_USO ? Number(idSeccion) : null, obs: obs || undefined, fechaCambioEstado, }; await onSubmit(bobinaActual.idBobina, dataToSubmit); onClose(); } catch (error: any) { console.error("Error en submit de StockBobinaCambioEstadoModal:", error); } finally { setLoading(false); } }; if (!bobinaActual) return null; return ( Cambiar Estado de Bobina: {bobinaActual.nroBobina} Estado Actual: {bobinaActual.nombreEstadoBobina} Nuevo Estado {localErrors.nuevoEstadoId && {localErrors.nuevoEstadoId}} {Number(nuevoEstadoId) === ID_ESTADO_EN_USO && ( <> Publicación {localErrors.idPublicacion && {localErrors.idPublicacion}} Sección {localErrors.idSeccion && {localErrors.idSeccion}} {localErrors.secciones && {localErrors.secciones}} )} {setFechaCambioEstado(e.target.value); handleInputChange('fechaCambioEstado');}} margin="dense" fullWidth error={!!localErrors.fechaCambioEstado} helperText={localErrors.fechaCambioEstado || ''} disabled={loading} InputLabelProps={{ shrink: true }} /> setObs(e.target.value)} margin="dense" fullWidth multiline rows={3} disabled={loading} /> {errorMessage && {errorMessage}} {localErrors.dropdowns && {localErrors.dropdowns}} ); }; export default StockBobinaCambioEstadoModal;