import { useState, useEffect } from "react"; import { API_URL, apiFetch } from "../../utils/api"; import { PAGE_SIZE } from "../../utils/constants"; import SearchInput from "./SearchInput"; import PrimaryButton from "./PrimaryButton"; import DenseTable from "./DenseTable"; import PaginationBar from "./PaginationBar"; import type { CopyFromSource, DocumentLine } from "../../types/sapMarketing"; interface CopyFromModalProps { isOpen: boolean; onClose: () => void; source: CopyFromSource; cardCode: string; docType: "dDocument_Items" | "dDocument_Service"; copiedDocEntries: number[]; onConfirm: (lines: DocumentLine[], sourceLabel: string) => void; } export default function CopyFromModal({ isOpen, onClose, source, cardCode, docType, copiedDocEntries, onConfirm, }: CopyFromModalProps) { const [data, setData] = useState([]); const [totalCount, setTotalCount] = useState(0); const [loading, setLoading] = useState(false); const [accepting, setAccepting] = useState(false); const [error, setError] = useState(""); const [filterValue, setFilterValue] = useState(""); const [activeFilterValue, setActiveFilterValue] = useState(""); const [selectedColumn, setSelectedColumn] = useState(source.columns[0]?.key || ""); const [skip, setSkip] = useState(0); const [selectedKeys, setSelectedKeys] = useState([]); const top = PAGE_SIZE; useEffect(() => { if (isOpen) { setSelectedKeys([]); setActiveFilterValue(""); setFilterValue(""); setSkip(0); setError(""); setAccepting(false); setSelectedColumn(source.columns[0]?.key || ""); } }, [isOpen, source]); const buildFilter = () => { let filter = `CardCode eq '${cardCode}' and DocumentStatus eq 'bost_Open' and DocType eq '${docType}'`; for (const entry of copiedDocEntries) { filter += ` and DocEntry ne ${entry}`; } if (activeFilterValue.trim()) { const clause = `contains(${selectedColumn}, '${activeFilterValue.trim().toUpperCase()}')`; filter += ` and ${clause}`; } return filter; }; const fetchData = async () => { if (!isOpen) return; setLoading(true); setError(""); try { const fieldsQuery = source.fields.join(","); let url = `${API_URL}/api/${source.endpoint}?skip=${skip}&top=${top}&fields=${fieldsQuery}&filter=${encodeURIComponent(buildFilter())}`; const response = await apiFetch(url); if (!response.ok) throw new Error("Error al obtener el listado"); const json = await response.json(); setData(json.value || []); setTotalCount(json["odata.count"] ?? json["@odata.count"] ?? 0); } catch (err: any) { setError(err.message || "Error de conexión"); } finally { setLoading(false); } }; useEffect(() => { if (isOpen) { fetchData(); } }, [isOpen, skip, activeFilterValue, source.endpoint]); const handleBuscar = () => { setActiveFilterValue(filterValue); setSkip(0); }; const handleAnterior = () => setSkip(Math.max(0, skip - top)); const handleSiguiente = () => setSkip(skip + top); const handleSelectionChange = (keys: string[]) => { setSelectedKeys(keys); }; const handleConfirmar = async () => { if (selectedKeys.length === 0) return; setAccepting(true); setError(""); try { const allLines: DocumentLine[] = []; for (const docEntry of selectedKeys) { const response = await apiFetch( `${API_URL}/api/${source.endpoint}/${docEntry}`, ); if (!response.ok) throw new Error(`Error al obtener el documento #${docEntry}`); const doc = await response.json(); const lines = (doc.DocumentLines || []) .filter((l: any) => l.LineStatus === "bost_Open") .map((l: any) => ({ ...l, BaseType: source.baseType, BaseEntry: Number(docEntry), BaseLine: l.LineNum, BaseRef: doc.DocNum, LineStatus: "bost_Open" as const, LineNum: undefined, })); allLines.push(...lines); } onConfirm(allLines, source.label); onClose(); } catch (err: any) { setError(err.message || "Error al copiar las líneas"); } finally { setAccepting(false); } }; if (!isOpen) return null; return (
Copiar de — {source.label} Socio: {cardCode}
c.key === selectedColumn)?.title || selectedColumn}`} onChange={setFilterValue} onKeyDown={(e) => { if (e.key === "Enter") handleBuscar(); }} /> Buscar
{error && (
{error}
)}
{loading ? (
Cargando registros desde SAP Service Layer...
) : ( )}
); }