"use client"; import { Suspense, useMemo, useState } from "react"; import Link from "next/link"; import { useRouter, useSearchParams } from "next/navigation"; import { useQuery } from "@tanstack/react-query"; import { Plus } from "lucide-react"; import { accountingApi } from "@/lib/accounting-api"; import { useTenantId } from "@/hooks/useTenantId"; import { formatMoney } from "@/lib/utils"; import { PageHeader, Button, DataTable, EmptyState, LoadingState, ErrorState, Badge, JalaliDateText, Pagination, Select, } from "@/components/ds"; const STATUS_FA: Record = { draft: "پیش‌نویس", validated: "اعتبارسنجی‌شده", posted: "ثبت قطعی", reversed: "برگشتی", cancelled: "لغو شده", }; const SOURCE_FA: Record = { manual: "دستی", sales: "فروش (اتومات)", purchase: "خرید (اتومات)", treasury: "خزانه (اتومات)", payroll: "حقوق (اتومات)", assets: "دارایی (اتومات)", }; function sourceLabel(raw: unknown): string { const s = String(raw ?? "").trim(); if (!s || s === "manual") return "دستی"; return SOURCE_FA[s] ?? `${s} (سیستمی)`; } function isAutoSource(raw: unknown): boolean { const s = String(raw ?? "").trim(); return !!s && s !== "manual"; } const STATUS_TITLES: Record = { draft: "اسناد پیش‌نویس", reversed: "اسناد برگشتی", posted: "اسناد ثبت‌قطع‌شده", }; function VouchersList() { const { tenantId } = useTenantId(); const sp = useSearchParams(); const router = useRouter(); const statusFilter = sp.get("status") || ""; const sourceFilter = sp.get("source") || ""; const [page, setPage] = useState(1); const pageSize = 100; const listQ = useQuery({ queryKey: ["accounting", tenantId, "vouchers", page, pageSize, statusFilter, sourceFilter], queryFn: () => accountingApi.vouchers.list(tenantId!, page, pageSize, { status: statusFilter || undefined, source: sourceFilter || undefined, }), enabled: !!tenantId, }); const rows = useMemo(() => listQ.data ?? [], [listQ.data]); const setSource = (source: string) => { const params = new URLSearchParams(); if (statusFilter) params.set("status", statusFilter); if (source) params.set("source", source); const q = params.toString(); router.push(q ? `/accounting/vouchers?${q}` : "/accounting/vouchers"); setPage(1); }; if (!tenantId || listQ.isLoading) return ; if (listQ.error) return listQ.refetch()} />; const title = sourceFilter === "auto" ? "اسناد سیستمی / اتومات" : sourceFilter === "manual" ? "اسناد دستی" : STATUS_TITLES[statusFilter] || "لیست اسناد حسابداری"; return (
} />
( {String(r.voucher_number)} ), }, { key: "voucher_date", header: "تاریخ", render: (r) => , }, { key: "source_module", header: "منبع", render: (r) => ( {sourceLabel(r.source_module)} ), }, { key: "status", header: "وضعیت", render: (r) => ( {STATUS_FA[String(r.status)] ?? String(r.status)} ), }, { key: "total_debit", header: "بدهکار", render: (r) => formatMoney(String(r.total_debit)) }, { key: "total_credit", header: "بستانکار", render: (r) => formatMoney(String(r.total_credit)) }, { key: "description", header: "شرح", render: (r) => { const ref = r.reference_number ? String(r.reference_number) : ""; const desc = r.description ? String(r.description) : ""; if (desc && ref) return `${desc} (مرجع: ${ref})`; return desc || ref || "—"; }, }, ]} rows={rows as unknown as Record[]} empty={ } /> } />
); } export default function VouchersPage() { return ( }> ); }