[FEAT] 優化會計報表:新增稅額、發票日期與付款方式等會計專用欄位並支援 CSV 完整匯出
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 1m0s

This commit is contained in:
2026-03-06 14:40:14 +08:00
parent 5290dd2cbe
commit 36b90370a8
3 changed files with 124 additions and 32 deletions

View File

@@ -8,7 +8,7 @@ import {
Calendar,
Filter,
TrendingDown,
Package,
Wallet,
Pocket,
RotateCcw,
FileText
@@ -29,6 +29,7 @@ import Pagination from "@/Components/shared/Pagination";
import { SearchableSelect } from "@/Components/ui/searchable-select";
import { Can } from "@/Components/Permission/Can";
import { Checkbox } from "@/Components/ui/checkbox";
import { StatusBadge } from "@/Components/shared/StatusBadge";
interface Record {
id: string;
@@ -37,8 +38,14 @@ interface Record {
category: string;
item: string;
reference: string;
invoice_number?: string;
invoice_date?: string | null;
invoice_number?: string | null;
amount: number | string;
tax_amount: number | string;
status?: string;
payment_method?: string | null;
payment_note?: string | null;
remarks?: string | null;
}
interface PageProps {
@@ -52,7 +59,7 @@ interface PageProps {
};
summary: {
total_amount: number;
purchase_total: number;
payable_total: number;
utility_total: number;
record_count: number;
};
@@ -273,10 +280,10 @@ export default function AccountingReport({ records, summary, filters }: PageProp
</div>
<div className="flex items-center gap-3 px-4 py-4 bg-white rounded-xl border-l-4 border-l-orange-500 shadow-sm border border-gray-100 transition-all hover:bg-gray-50">
<Package className="h-6 w-6 text-orange-500 shrink-0" />
<Wallet className="h-6 w-6 text-orange-500 shrink-0" />
<div className="flex flex-1 items-baseline justify-between gap-2 min-w-0">
<span className="text-sm text-gray-500 font-medium shrink-0"></span>
<span className="text-xl font-bold text-gray-900 truncate">$ {Number(summary.purchase_total).toLocaleString()}</span>
<span className="text-sm text-gray-500 font-medium shrink-0"></span>
<span className="text-xl font-bold text-gray-900 truncate">$ {Number(summary.payable_total).toLocaleString()}</span>
</div>
</div>
@@ -305,13 +312,16 @@ export default function AccountingReport({ records, summary, filters }: PageProp
<TableHead className="w-[120px] text-center"></TableHead>
<TableHead className="w-[140px] text-center"></TableHead>
<TableHead className="px-6"></TableHead>
<TableHead className="w-[180px] text-right px-6"></TableHead>
<TableHead className="w-[160px] text-center"> / </TableHead>
<TableHead className="w-[100px] text-center"></TableHead>
<TableHead className="w-[120px] text-right"></TableHead>
<TableHead className="w-[150px] text-right px-6"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{records.data.length === 0 ? (
<TableRow>
<TableCell colSpan={6}>
<TableCell colSpan={7}>
<div className="flex flex-col items-center justify-center space-y-2 py-8 text-gray-400">
<FileText className="h-10 w-10 opacity-20" />
<p></p>
@@ -333,7 +343,7 @@ export default function AccountingReport({ records, summary, filters }: PageProp
</TableCell>
<TableCell className="text-center">
<Badge variant="secondary" className={
record.source === '採購單'
record.source === '應付帳款'
? 'bg-orange-50 text-orange-700 border-orange-100'
: 'bg-blue-50 text-blue-700 border-blue-100'
}>
@@ -348,11 +358,47 @@ export default function AccountingReport({ records, summary, filters }: PageProp
<TableCell>
<div className="flex flex-col">
<span className="font-medium text-gray-900">{record.item}</span>
{record.invoice_number && (
<span className="text-xs text-gray-400">{record.invoice_number}</span>
{(record.invoice_number || record.invoice_date) && (
<span className="text-xs text-gray-400 mt-0.5">
{record.invoice_number || '-'}
{record.invoice_date && ` (${record.invoice_date})`}
</span>
)}
{record.remarks && (
<span className="text-xs text-gray-500 mt-0.5 truncate max-w-[200px]" title={record.remarks}>
{record.remarks}
</span>
)}
</div>
</TableCell>
<TableCell className="text-center">
<div className="flex flex-col items-center">
<span className="text-sm text-gray-700">{record.payment_method || '-'}</span>
{record.payment_note && (
<span className="text-xs text-gray-400 truncate max-w-[120px]" title={record.payment_note}>
{record.payment_note}
</span>
)}
</div>
</TableCell>
<TableCell className="text-center">
{record.status === 'paid' ? (
<StatusBadge variant="success"></StatusBadge>
) : record.status === 'pending' ? (
<StatusBadge variant="warning"></StatusBadge>
) : record.status === 'overdue' ? (
<StatusBadge variant="destructive"></StatusBadge>
) : record.status === 'draft' ? (
<StatusBadge variant="neutral">稿</StatusBadge>
) : record.status === 'approved' ? (
<StatusBadge variant="info"></StatusBadge>
) : (
<StatusBadge variant="neutral">{record.status || '-'}</StatusBadge>
)}
</TableCell>
<TableCell className="text-right text-gray-600">
{record.tax_amount ? `$ ${Number(record.tax_amount).toLocaleString()}` : '-'}
</TableCell>
<TableCell className="text-right font-bold text-gray-900 px-4">
$ {Number(record.amount).toLocaleString()}
</TableCell>