import React, { useState, useEffect, useCallback } from 'react'; import { Box, Typography, TextField, Button, Paper, IconButton, Menu, MenuItem, Chip, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination, CircularProgress, Alert, FormControl, InputLabel, Select, Tooltip } from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import FilterListIcon from '@mui/icons-material/FilterList'; import pagoDistribuidorService from '../../services/Contables/pagoDistribuidorService'; import distribuidorService from '../../services/Distribucion/distribuidorService'; import empresaService from '../../services/Distribucion/empresaService'; import type { PagoDistribuidorDto } from '../../models/dtos/Contables/PagoDistribuidorDto'; import type { CreatePagoDistribuidorDto } from '../../models/dtos/Contables/CreatePagoDistribuidorDto'; import type { UpdatePagoDistribuidorDto } from '../../models/dtos/Contables/UpdatePagoDistribuidorDto'; import type { DistribuidorDto } from '../../models/dtos/Distribucion/DistribuidorDto'; import type { EmpresaDto } from '../../models/dtos/Distribucion/EmpresaDto'; import PagoDistribuidorFormModal from '../../components/Modals/Contables/PagoDistribuidorFormModal'; import { usePermissions } from '../../hooks/usePermissions'; import axios from 'axios'; const GestionarPagosDistribuidorPage: React.FC = () => { const [pagos, setPagos] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [pageApiErrorMessage, setPageApiErrorMessage] = useState(null); const [modalApiErrorMessage, setModalApiErrorMessage] = useState(null); const [filtroFechaDesde, setFiltroFechaDesde] = useState(new Date().toISOString().split('T')[0]); const [filtroFechaHasta, setFiltroFechaHasta] = useState(new Date().toISOString().split('T')[0]); const [filtroIdDistribuidor, setFiltroIdDistribuidor] = useState(''); const [filtroIdEmpresa, setFiltroIdEmpresa] = useState(''); const [filtroTipoMov, setFiltroTipoMov] = useState<'Recibido' | 'Realizado' | ''>(''); const [distribuidores, setDistribuidores] = useState([]); const [empresas, setEmpresas] = useState([]); const [loadingFiltersDropdown, setLoadingFiltersDropdown] = useState(false); const [modalOpen, setModalOpen] = useState(false); const [editingPago, setEditingPago] = useState(null); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(25); const [anchorEl, setAnchorEl] = useState(null); const [selectedRow, setSelectedRow] = useState(null); const { tienePermiso, isSuperAdmin } = usePermissions(); const puedeVer = isSuperAdmin || tienePermiso("CP001"); const puedeCrear = isSuperAdmin || tienePermiso("CP002"); const puedeModificar = isSuperAdmin || tienePermiso("CP003"); const puedeEliminar = isSuperAdmin || tienePermiso("CP004"); const fetchFiltersDropdownData = useCallback(async () => { setLoadingFiltersDropdown(true); try { const [distData, empData] = await Promise.all([ distribuidorService.getAllDistribuidores(), empresaService.getAllEmpresas() ]); setDistribuidores(distData); setEmpresas(empData); } catch (err) { console.error(err); setError("Error al cargar opciones de filtro."); } finally { setLoadingFiltersDropdown(false); } }, []); useEffect(() => { fetchFiltersDropdownData(); }, [fetchFiltersDropdownData]); const clearModalApiErrorMessage = useCallback(() => { setModalApiErrorMessage(null); }, []); const cargarPagos = useCallback(async () => { if (!puedeVer) { setError("No tiene permiso."); setLoading(false); return; } setLoading(true); setError(null); setPageApiErrorMessage(null); try { const params = { fechaDesde: filtroFechaDesde || null, fechaHasta: filtroFechaHasta || null, idDistribuidor: filtroIdDistribuidor ? Number(filtroIdDistribuidor) : null, idEmpresa: filtroIdEmpresa ? Number(filtroIdEmpresa) : null, tipoMovimiento: filtroTipoMov || null, }; const data = await pagoDistribuidorService.getAllPagosDistribuidor(params); setPagos(data); } catch (err) { console.error(err); setError('Error al cargar los pagos.'); } finally { setLoading(false); } }, [puedeVer, filtroFechaDesde, filtroFechaHasta, filtroIdDistribuidor, filtroIdEmpresa, filtroTipoMov]); useEffect(() => { cargarPagos(); }, [cargarPagos]); const handleOpenModal = (item?: PagoDistribuidorDto) => { setEditingPago(item || null); setModalApiErrorMessage(null); setModalOpen(true); }; const handleCloseModal = () => { setModalOpen(false); setEditingPago(null); }; const handleSubmitModal = async (data: CreatePagoDistribuidorDto | UpdatePagoDistribuidorDto, idPago?: number) => { setModalApiErrorMessage(null); try { if (idPago && editingPago) { await pagoDistribuidorService.updatePagoDistribuidor(idPago, data as UpdatePagoDistribuidorDto); } else { await pagoDistribuidorService.createPagoDistribuidor(data as CreatePagoDistribuidorDto); } cargarPagos(); } catch (err: any) { const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al guardar el pago.'; setModalApiErrorMessage(message); throw err; } }; const handleDelete = async (idPago: number) => { if (window.confirm(`¿Seguro de eliminar este pago (ID: ${idPago})? Esta acción revertirá el impacto en el saldo.`)) { setPageApiErrorMessage(null); try { await pagoDistribuidorService.deletePagoDistribuidor(idPago); cargarPagos(); } catch (err: any) { const msg = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Error al eliminar.'; setPageApiErrorMessage(msg); } } handleMenuClose(); }; const handleMenuOpen = (event: React.MouseEvent, item: PagoDistribuidorDto) => { setAnchorEl(event.currentTarget); setSelectedRow(item); }; const handleMenuClose = () => { setAnchorEl(null); setSelectedRow(null); }; const handleChangePage = (_event: unknown, newPage: number) => setPage(newPage); const handleChangeRowsPerPage = (event: React.ChangeEvent) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; const displayData = pagos.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage); const formatDate = (dateString?: string | null): string => { if (!dateString) return '-'; const datePart = dateString.split('T')[0]; const parts = datePart.split('-'); if (parts.length === 3) { return `${parts[2]}/${parts[1]}/${parts[0]}`; } return datePart; }; if (!loading && !puedeVer && !loadingFiltersDropdown) return {error || "Acceso denegado."}; return ( Pagos de Distribuidores Filtros setFiltroFechaDesde(e.target.value)} InputLabelProps={{ shrink: true }} sx={{ minWidth: 170 }} /> setFiltroFechaHasta(e.target.value)} InputLabelProps={{ shrink: true }} sx={{ minWidth: 170 }} /> Distribuidor Empresa (Saldo) Tipo Mov. {puedeCrear && ()} {loading && } {error && !loading && {error}} {pageApiErrorMessage && {pageApiErrorMessage}} {!loading && !error && puedeVer && ( FechaDistribuidorEmpresa (Saldo) Tipo Mov.Recibo N° MontoTipo Pago Detalle {(puedeModificar || puedeEliminar) && Acciones} {displayData.length === 0 ? ( No se encontraron pagos. ) : ( displayData.map((p) => ( {formatDate(p.fecha)}{p.nombreDistribuidor} {p.nombreEmpresa} {p.recibo} ${p.monto.toFixed(2)} {p.nombreTipoPago} {p.detalle || '-'} {(puedeModificar || puedeEliminar) && ( handleMenuOpen(e, p)} disabled={!puedeModificar && !puedeEliminar}> )} )))}
)} {puedeModificar && selectedRow && ( { handleOpenModal(selectedRow); handleMenuClose(); }}> Modificar)} {puedeEliminar && selectedRow && ( handleDelete(selectedRow.idPago)}> Eliminar)}
); }; export default GestionarPagosDistribuidorPage;