import { useEffect, useMemo, useState } from "react"; import { Link } from "react-router-dom"; import { Building2, Paperclip, Plus } from "lucide-react"; import type { Attachment, Material, Quote, Supplier } from "../../lib/types"; import { api } from "../../lib/api"; import { activeItems, materialById, materialLabel, quoteTotal } from "../../lib/quoteUtils"; import { fmtDate, faNum } from "../../lib/formatters"; import { groupCommas } from "../../lib/numutil"; import { STATUS_LABEL } from "../../lib/constants"; interface AttachSet { invoices: Attachment[]; proformas: Attachment[]; } export interface PurchaseHistoryProps { supplier: Supplier; quotes: Quote[]; materials: Material[]; } // سابقه خرید از یک تأمین‌کننده: همه‌ی پیشنهادها (با بج وضعیت، از جدیدترین) // + فاکتورها و پیش‌فاکتورها (لینک دانلود از MinIO از طریق api.files) export function PurchaseHistory({ supplier, quotes, materials }: PurchaseHistoryProps) { const purchases = useMemo(() => { return quotes .filter((q) => q.supplier_id === supplier.id) .sort((a, b) => { const ta = a.quote_date ? new Date(a.quote_date).getTime() : 0; const tb = b.quote_date ? new Date(b.quote_date).getTime() : 0; return tb - ta; }); }, [quotes, supplier.id]); // پیوست‌ها به‌صورت موازی برای همه‌ی خریدها خوانده می‌شوند (الگوی AcceptModal) const [attachments, setAttachments] = useState>({}); const [loading, setLoading] = useState(false); useEffect(() => { if (!purchases.length) return; let alive = true; setLoading(true); void Promise.all( purchases.map(async (q) => { const [invoices, proformas] = await Promise.all([ api.files.list(q.id, "invoice").catch(() => [] as Attachment[]), api.files.list(q.id, "proforma").catch(() => [] as Attachment[]), ]); return [q.id, { invoices, proformas }] as const; }), ) .then((pairs) => { if (!alive) return; const map: Record = {}; pairs.forEach(([id, set]) => (map[id] = set)); setAttachments(map); }) .finally(() => { if (alive) setLoading(false); }); return () => { alive = false; }; }, [purchases]); const wizardLink = `/wizard?topic=${encodeURIComponent(supplier.topic)}&supplier=${encodeURIComponent(supplier.id)}`; return (
سابقه خرید از این تأمین‌کننده {purchases.length > 0 && {faNum(purchases.length)} پیشنهاد}
{purchases.length === 0 && (
هنوز خریدی از این تأمین‌کننده ثبت نشده است.
اولین پیشنهاد
)} {purchases.map((q) => { const items = activeItems(q).map((li) => { const m = materialById(materials, li.material_id); return materialLabel(m); }); const total = quoteTotal(q); const attach = attachments[q.id]; const profs = attach?.proformas || []; const invs = attach?.invoices || []; const projects = q.projects && q.projects.length ? q.projects : q.project ? [q.project] : []; return (
{fmtDate(q.quote_date)} {STATUS_LABEL[q.status] || q.status} {projects.join("، ") || "بدون پروژه"}
{items.length ? `${faNum(items.length)} قلم: ${items.join("، ")}` : "بدون قلم"}
{groupCommas(total, true)} تومان
{loading && !attach ? ( در حال بارگذاری فاکتورها... ) : ( <> {profs.map((pf) => ( ))} {invs.map((inv) => ( ))} {!loading && !profs.length && !invs.length && ( فاکتوری ثبت نشده )} )}
); })}
); }