import { useEffect, useMemo, useState } from "react"; import { useLocation } from "react-router-dom"; import { toast } from "sonner"; import { Header, PageLayout } from "../../components/layout/Header"; import { EmptyState } from "../../components/EmptyState"; import { Badge } from "../../components/ui/badge"; import { Button } from "../../components/ui/button"; import { useAuthStore } from "../../store/auth"; import { PanelMenu } from "../../components/PanelMenu"; import { panelMenuItems, useLogout } from "./panelMenu"; import { apiV26 } from "../../lib/api"; import type { PendingArrival, Warehouse } from "../../lib/types"; import { faNum } from "../../lib/formatters"; // رسید کالاهای در راه — مدیر پروژه تأیید و بین انبارها تقسیم می‌کند (v2.6) export function ArrivalsPage() { const location = useLocation(); const logout = useLogout(); const user = useAuthStore((s) => s.user); const [items, setItems] = useState([]); const [warehouses, setWarehouses] = useState([]); const [selected, setSelected] = useState>({}); // decisionId -> warehouseIds const [qty, setQty] = useState>({}); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); useEffect(() => { if (user?.role !== "pm") return; let alive = true; void (async () => { try { const [arr, whs] = await Promise.all([ apiV26.pm.onTheWay(), apiV26.warehouses.list(user.project_id || undefined), ]); if (!alive) return; setItems(arr); setWarehouses(whs); } catch (err) { if (alive) toast.error(err instanceof Error ? err.message : "خطا در دریافت کالاهای در راه"); } finally { if (alive) setLoading(false); } })(); return () => { alive = false; }; }, [user?.role, user?.project_id]); const pending = useMemo(() => items.filter((i) => i.state !== "arrived"), [items]); const toggleWarehouse = (decisionId: string, whId: string) => { setSelected((s) => { const cur = s[decisionId] || []; return { ...s, [decisionId]: cur.includes(whId) ? cur.filter((x) => x !== whId) : [...cur, whId] }; }); }; const confirm = async (it: PendingArrival) => { const qtyStr = qty[it.item_decision_id]?.trim(); const total = parseFloat(qtyStr || ""); if (!total || total <= 0) { toast.error("تعداد رسیده را وارد کنید."); return; } const allocIds = selected[it.item_decision_id] || []; if (!allocIds.length) { toast.error("حداقل یک انبار را برای تقسیم انتخاب کنید."); return; } // تقسیم مساوی بین انبارهای انتخاب‌شده (به‌صورت پیش‌فرض؛ کاربر می‌تواند بعداً اصلاح کند) const per = Math.round((total / allocIds.length) * 10000) / 10000; const allocations = allocIds.map((whId, idx) => ({ warehouse_id: whId, quantity: idx === allocIds.length - 1 ? +(total - per * (allocIds.length - 1)).toFixed(4) : per, })); setSaving(true); try { const res = await apiV26.pm.confirmReceipt({ item_decision_id: it.item_decision_id, received_qty: total, allocations, }); toast.success(`رسید ثبت شد — ${res.posted_transactions.length} تراکنش خرید ثبت شد.`); setItems((list) => list.filter((x) => x.item_decision_id !== it.item_decision_id)); } catch (err) { toast.error(err instanceof Error ? err.message : "خطا در ثبت رسید"); } finally { setSaving(false); } }; if (loading) return
; if (user?.role !== "pm") { return (
} />
); } return (
} /> {!pending.length ? ( ) : ( pending.map((it) => (
{it.material.name} {it.state === "on_the_way" ? "در راه" : "رسید ناقص"} سفارش: {faNum(parseFloat(it.ordered_qty))} {it.unit?.name_fa || it.unit?.code || ""} — رسیده: {faNum(parseFloat(it.received_qty))}
setQty((q) => ({ ...q, [it.item_decision_id]: e.target.value }))} placeholder={it.ordered_qty} />
{warehouses.map((w) => { const on = (selected[it.item_decision_id] || []).includes(w.id); return ( ); })}
)) )}
); }