feat:홈택스 대시보드 카드 5개로 확장 및 테이블 합계행 추가

This commit is contained in:
김보곤
2026-02-03 17:46:22 +09:00
parent 5b1f2a45f7
commit dd9c39e048

View File

@@ -169,7 +169,8 @@ className={`px-6 py-3 text-sm font-medium rounded-lg transition-all ${
loading,
type,
onExport,
onRequestCollect
onRequestCollect,
summary // 합계 정보
}) => {
const formatCurrency = (val) => new Intl.NumberFormat('ko-KR').format(val || 0);
@@ -313,6 +314,24 @@ className="flex items-center gap-2 px-3 py-1.5 bg-blue-100 text-blue-700 rounded
);
})
)}
{/* 합계행 */}
{invoices.length > 0 && summary && (
<tr className="bg-[#e7f1ff] border-t-2 border-[#0d6efd]">
<td colSpan="6" className="px-3 py-3 text-center text-sm font-bold text-[#0d6efd] border-r border-[#dee2e6]">
합계 ({invoices.length})
</td>
<td className="px-3 py-3 text-right text-sm font-bold text-[#212529] border-r border-[#dee2e6]">
{formatCurrency(summary.supplyAmount)}
</td>
<td className="px-3 py-3 text-right text-sm font-bold text-[#212529] border-r border-[#dee2e6]">
{formatCurrency(summary.taxAmount)}
</td>
<td className="px-3 py-3 text-right text-sm font-bold text-[#0d6efd] border-r border-[#dee2e6]">
{formatCurrency(summary.totalAmount)}
</td>
<td colSpan="4" className="px-3 py-3"></td>
</tr>
)}
</tbody>
</table>
</div>
@@ -696,10 +715,41 @@ className="flex items-center gap-2 px-3 py-1.5 bg-blue-100 text-blue-700 rounded
};
const formatCurrency = (val) => new Intl.NumberFormat('ko-KR').format(val || 0) + '원';
const formatNumber = (val) => new Intl.NumberFormat('ko-KR').format(val || 0);
// 과세/면세 합계 계산
const calculateTaxTypeSummary = (invoices) => {
let taxableAmount = 0; // 과세 공급가액
let exemptAmount = 0; // 면세 공급가액
let taxableCount = 0;
let exemptCount = 0;
invoices.forEach(inv => {
const amount = inv.supplyAmount || 0;
if (inv.taxTypeName === '면세') {
exemptAmount += amount;
exemptCount++;
} else {
taxableAmount += amount;
taxableCount++;
}
});
return { taxableAmount, exemptAmount, taxableCount, exemptCount };
};
const currentData = activeTab === 'sales' ? salesData : purchaseData;
const filteredInvoices = filterByCorpName(currentData.invoices);
// 매입 과세/면세 합계
const purchaseTaxSummary = calculateTaxTypeSummary(purchaseData.invoices);
// 현재 탭 인보이스 합계 (테이블 합계용)
const currentInvoiceSummary = {
supplyAmount: filteredInvoices.reduce((sum, inv) => sum + (inv.supplyAmount || 0), 0),
taxAmount: filteredInvoices.reduce((sum, inv) => sum + (inv.taxAmount || 0), 0),
totalAmount: filteredInvoices.reduce((sum, inv) => sum + (inv.totalAmount || 0), 0),
};
return (
<div className="space-y-8">
{/* Page Header */}
@@ -911,7 +961,7 @@ className="flex items-center gap-2 text-sm font-semibold rounded-md disabled:opa
)}
{/* Dashboard */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4">
<StatCard
title="매출 공급가액"
value={formatCurrency(salesData.summary.totalAmount)}
@@ -927,12 +977,19 @@ className="flex items-center gap-2 text-sm font-semibold rounded-md disabled:opa
color="blue"
/>
<StatCard
title="매입 공급가액"
value={formatCurrency(purchaseData.summary.totalAmount)}
subtext={`${purchaseData.summary.count || 0}건`}
title="매입 과세"
value={formatCurrency(purchaseTaxSummary.taxableAmount)}
subtext={`${purchaseTaxSummary.taxableCount}건`}
icon={<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 17h8m0 0V9m0 8l-8-8-4 4-6-6"/></svg>}
color="red"
/>
<StatCard
title="매입 면세"
value={formatCurrency(purchaseTaxSummary.exemptAmount)}
subtext={`${purchaseTaxSummary.exemptCount}건`}
icon={<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>}
color="purple"
/>
<StatCard
title="매입 세액"
value={formatCurrency(purchaseData.summary.totalTax)}
@@ -1003,6 +1060,7 @@ className="flex items-center gap-2 text-sm font-semibold rounded-md disabled:opa
type={activeTab}
onExport={handleExport}
onRequestCollect={handleRequestCollect}
summary={currentInvoiceSummary}
/>
)}