import React, { useState } from "react"; import { generateId, formatCHF, formatDate, linkedClientForNote } from "../utils.js"; import { Header, Modal, FormField, StatusBadge, useConfirm , DateInput } from "../components/UI.jsx"; export default function DeliveryNotes({ data, update, saveAll, setPrintContent }) { const today = new Date().toISOString().slice(0, 10); const emptyForm = { date: today, number: "", projectId: "", clientId: "", clientManual: "", projectManual: "", deliveryAddress: "", notes: "", items: [{ id: generateId(), desc: "", qty: 1, unit: "Stk.", note: "" }], }; const [modal, setModal] = useState(null); // null | "new" | id const [form, setForm] = useState(emptyForm); const [filter, setFilter] = useState({ search: "", projectId: "", clientId: "" }); const [sort, setSort] = useState({ col: "date", dir: -1 }); const { askConfirm, ConfirmModalEl } = useConfirm(); const notes = data.deliveryNotes || []; // Nummernvergabe const nextNumber = () => { const year = new Date().getFullYear(); const existing = notes.map(n => { const m = (n.number || "").match(/LS[-–]?(\d+)/i); return m ? parseInt(m[1]) : 0; }); const max = existing.length ? Math.max(...existing) : 0; return `LS-${year}-${String(max + 1).padStart(3, "0")}`; }; const openNew = () => { setForm({ ...emptyForm, number: nextNumber() }); setModal("new"); }; const openEdit = (n) => { setForm({ ...n }); setModal(n.id); }; const closeModal = () => { setModal(null); setForm(emptyForm); }; const save = () => { const isNew = modal === "new"; const entry = { ...form, id: isNew ? generateId() : modal }; const updated = isNew ? [...notes, { ...entry, createdAt: new Date().toISOString() }] : notes.map(n => n.id === modal ? entry : n); saveAll({ ...data, deliveryNotes: updated }); closeModal(); }; const del = async (id) => { if (await askConfirm("Lieferschein löschen?")) saveAll({ ...data, deliveryNotes: notes.filter(n => n.id !== id) }); }; const addItem = () => setForm(f => ({ ...f, items: [...f.items, { id: generateId(), desc: "", qty: 1, unit: "Stk.", note: "" }] })); const updateItem = (id, changes) => setForm(f => ({ ...f, items: f.items.map(it => it.id === id ? { ...it, ...changes } : it) })); const removeItem = (id) => setForm(f => ({ ...f, items: f.items.filter(it => it.id !== id) })); // Ableitungen für Anzeige const getClient = (n) => { if (n.clientId) return ((data.persons||[]).filter(p=>p.isAuftraggeber)).find(c => c.id === n.clientId)?.name || "—"; return n.clientManual || "—"; }; const getProject = (n) => { if (n.projectId) return data.projects.find(p => p.id === n.projectId)?.name || "—"; return n.projectManual || "—"; }; // Filter const filtered = notes.filter(n => { if (filter.projectId && n.projectId !== filter.projectId) return false; if (filter.clientId && n.clientId !== filter.clientId) return false; if (filter.search) { const q = filter.search.toLowerCase(); const text = [n.number, getClient(n), getProject(n), n.notes, ...(n.items || []).map(it => it.desc)].join(" ").toLowerCase(); if (!text.includes(q)) return false; } return true; }); const toggleSort = (col) => setSort(s => ({ col, dir: s.col === col ? -s.dir : -1 })); const SortTh = ({ col, children, style }) => ( toggleSort(col)} style={{ cursor: "pointer", userSelect: "none", ...style }}> {children} {sort.col === col ? (sort.dir === 1 ? "▲" : "▼") : "⇅"} ); const sorted = [...filtered].sort((a, b) => { const va = sort.col === "date" ? (a.date || "") : sort.col === "number" ? (a.number || "") : sort.col === "client" ? getClient(a) : getProject(a); const vb = sort.col === "date" ? (b.date || "") : sort.col === "number" ? (b.number || "") : sort.col === "client" ? getClient(b) : getProject(b); return va.localeCompare(vb) * sort.dir; }); const UNITS = ["Stk.", "m", "m²", "m³", "kg", "l", "Set", "Blatt", "Rolle", "Palette", "Pkg."]; // Client-Felder im Modal: verknüpft oder manuell const linkedClient = form.clientId ? ((data.persons||[]).filter(p=>p.isAuftraggeber)).find(c => c.id === form.clientId) : null; const linkedProject = form.projectId ? data.projects.find(p => p.id === form.projectId) : null; return (
{ConfirmModalEl}
+ Neuer Lieferschein } />
setFilter({ ...filter, search: e.target.value })} style={{ minWidth: 220 }} /> {(filter.search || filter.clientId || filter.projectId) && ( )}
{filtered.length} {filtered.length === 1 ? "Lieferschein" : "Lieferscheine"}
{/* Tabelle */} {sorted.length === 0 ? (
Nr.DatumEmpfängerProjektPos.
{notes.length === 0 ? "Noch keine Lieferscheine" : "Keine Treffer"}
) : (
Nr.DatumEmpfängerProjekt {sorted.map(n => ( ))}
Pos.
{n.number || "—"} {formatDate(n.date)} {getClient(n)} {getProject(n)} {(n.items || []).length}
)} {/* Modal */} {modal && ( {/* Kopfdaten */}
ALLGEMEIN
setForm({ ...form, number: e.target.value })} placeholder="LS-2025-001" /> setForm({ ...form, date: e.target.value })} />
{/* Empfänger */}
EMPFÄNGER
{!form.clientId && ( setForm({ ...form, clientManual: e.target.value })} placeholder="Firmen- oder Personenname" /> )}
{form.clientId ? (
{linkedClient?.address || Keine Adresse beim Kunden hinterlegt}
Adresse aus Kundenstamm · unter «Kunden» bearbeitbar
) : (