fix:카드 사용내역 공제/불공제 통계를 전체 페이지 기준으로 계산
- 백엔드에서 페이지네이션 전 전체 데이터로 공제/불공제/부가세 통계 산출 - parseTransactionLogs에 deductibleAmount/Count, nonDeductibleAmount/Count, totalTax 추가 - getAllCardsTransactions summary에 공제/불공제 통계 포함 - 프론트엔드에서 logs 기반 계산 제거, summary 데이터 사용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -427,6 +427,7 @@ private function getAllCardsTransactions(string $userId, string $startDate, stri
|
||||
$totalAmount = 0;
|
||||
$approvalCount = 0;
|
||||
$cancelCount = 0;
|
||||
$totalTax = 0;
|
||||
|
||||
foreach ($cardList as $card) {
|
||||
if (!is_object($card)) continue;
|
||||
@@ -484,6 +485,7 @@ private function getAllCardsTransactions(string $userId, string $startDate, stri
|
||||
$totalAmount += $parsed['summary']['totalAmount'];
|
||||
$approvalCount += $parsed['summary']['approvalCount'];
|
||||
$cancelCount += $parsed['summary']['cancelCount'];
|
||||
$totalTax += $parsed['summary']['totalTax'] ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -493,6 +495,24 @@ private function getAllCardsTransactions(string $userId, string $startDate, stri
|
||||
return strcmp($b['useDt'] ?? '', $a['useDt'] ?? '');
|
||||
});
|
||||
|
||||
// 전체 데이터에서 공제/불공제 통계 계산
|
||||
$deductibleAmount = 0;
|
||||
$deductibleCount = 0;
|
||||
$nonDeductibleAmount = 0;
|
||||
$nonDeductibleCount = 0;
|
||||
|
||||
foreach ($allLogs as $log) {
|
||||
$type = $log['deductionType'] ?? 'non_deductible';
|
||||
$amount = abs($log['approvalAmount'] ?? 0);
|
||||
if ($type === 'deductible') {
|
||||
$deductibleAmount += $amount;
|
||||
$deductibleCount++;
|
||||
} else {
|
||||
$nonDeductibleAmount += $amount;
|
||||
$nonDeductibleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지네이션
|
||||
$totalCount = count($allLogs);
|
||||
$maxPageNum = (int)ceil($totalCount / $limit);
|
||||
@@ -513,7 +533,12 @@ private function getAllCardsTransactions(string $userId, string $startDate, stri
|
||||
'totalAmount' => $totalAmount,
|
||||
'count' => $totalCount,
|
||||
'approvalCount' => $approvalCount,
|
||||
'cancelCount' => $cancelCount
|
||||
'cancelCount' => $cancelCount,
|
||||
'totalTax' => $totalTax,
|
||||
'deductibleAmount' => $deductibleAmount,
|
||||
'deductibleCount' => $deductibleCount,
|
||||
'nonDeductibleAmount' => $nonDeductibleAmount,
|
||||
'nonDeductibleCount' => $nonDeductibleCount,
|
||||
]
|
||||
]
|
||||
]);
|
||||
@@ -528,6 +553,11 @@ private function parseTransactionLogs($resultData, $savedData = null): array
|
||||
$totalAmount = 0;
|
||||
$approvalCount = 0;
|
||||
$cancelCount = 0;
|
||||
$totalTax = 0;
|
||||
$deductibleAmount = 0;
|
||||
$deductibleCount = 0;
|
||||
$nonDeductibleAmount = 0;
|
||||
$nonDeductibleCount = 0;
|
||||
|
||||
$rawLogs = [];
|
||||
if (isset($resultData->CardLogList) && isset($resultData->CardLogList->CardApprovalLog)) {
|
||||
@@ -626,6 +656,18 @@ private function parseTransactionLogs($resultData, $savedData = null): array
|
||||
'isSaved' => $savedItem !== null,
|
||||
];
|
||||
|
||||
// 공제/불공제 통계 집계
|
||||
$deductionType = $logItem['deductionType'];
|
||||
$absAmount = abs($amount);
|
||||
$totalTax += abs(floatval($log->Tax ?? 0));
|
||||
if ($deductionType === 'deductible') {
|
||||
$deductibleAmount += $absAmount;
|
||||
$deductibleCount++;
|
||||
} else {
|
||||
$nonDeductibleAmount += $absAmount;
|
||||
$nonDeductibleCount++;
|
||||
}
|
||||
|
||||
$logs[] = $logItem;
|
||||
}
|
||||
|
||||
@@ -635,7 +677,12 @@ private function parseTransactionLogs($resultData, $savedData = null): array
|
||||
'totalAmount' => $totalAmount,
|
||||
'count' => count($logs),
|
||||
'approvalCount' => $approvalCount,
|
||||
'cancelCount' => $cancelCount
|
||||
'cancelCount' => $cancelCount,
|
||||
'totalTax' => $totalTax,
|
||||
'deductibleAmount' => $deductibleAmount,
|
||||
'deductibleCount' => $deductibleCount,
|
||||
'nonDeductibleAmount' => $nonDeductibleAmount,
|
||||
'nonDeductibleCount' => $nonDeductibleCount,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1244,20 +1244,6 @@ className="text-xs text-amber-600 hover:text-amber-700 underline"
|
||||
|
||||
const formatCurrency = (val) => new Intl.NumberFormat('ko-KR').format(val || 0) + '원';
|
||||
|
||||
// 공제/불공 통계 계산
|
||||
const deductionStats = logs.reduce((acc, log) => {
|
||||
const type = log.deductionType || (log.merchantBizNum ? 'deductible' : 'non_deductible');
|
||||
const amount = Math.abs(log.approvalAmount || 0);
|
||||
if (type === 'deductible') {
|
||||
acc.deductibleAmount += amount;
|
||||
acc.deductibleCount += 1;
|
||||
} else {
|
||||
acc.nonDeductibleAmount += amount;
|
||||
acc.nonDeductibleCount += 1;
|
||||
}
|
||||
return acc;
|
||||
}, { deductibleAmount: 0, deductibleCount: 0, nonDeductibleAmount: 0, nonDeductibleCount: 0 });
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
{/* Page Header */}
|
||||
@@ -1296,21 +1282,21 @@ className="text-xs text-amber-600 hover:text-amber-700 underline"
|
||||
/>
|
||||
<StatCard
|
||||
title="공제"
|
||||
value={formatCurrency(deductionStats.deductibleAmount)}
|
||||
subtext={`${deductionStats.deductibleCount.toLocaleString()}건`}
|
||||
value={formatCurrency(summary.deductibleAmount)}
|
||||
subtext={`${(summary.deductibleCount || 0).toLocaleString()}건`}
|
||||
icon={<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"/></svg>}
|
||||
color="green"
|
||||
/>
|
||||
<StatCard
|
||||
title="불공제"
|
||||
value={formatCurrency(deductionStats.nonDeductibleAmount)}
|
||||
subtext={`${deductionStats.nonDeductibleCount.toLocaleString()}건`}
|
||||
value={formatCurrency(summary.nonDeductibleAmount)}
|
||||
subtext={`${(summary.nonDeductibleCount || 0).toLocaleString()}건`}
|
||||
icon={<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/></svg>}
|
||||
color="red"
|
||||
/>
|
||||
<StatCard
|
||||
title="부가세 합계"
|
||||
value={formatCurrency(logs.reduce((sum, log) => sum + Math.abs(log.tax || 0), 0))}
|
||||
value={formatCurrency(summary.totalTax)}
|
||||
subtext="조회기간 합계"
|
||||
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 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>}
|
||||
color="stone"
|
||||
|
||||
Reference in New Issue
Block a user