fix:일반전표 은행거래 잔액 running balance 방식으로 수정

This commit is contained in:
김보곤
2026-02-11 13:14:25 +09:00
parent 83e79cf30d
commit d2c1ce7815

View File

@@ -378,40 +378,51 @@ public function bankTransactions(Request $request): JsonResponse
$endDate = $request->input('endDate', date('Ymd'));
$accountNum = $request->input('accountNum', '');
// barobill_bank_transactions 테이블에서 직접 조회
// 같은 거래가 수동/API로 중복 저장된 경우 API(is_manual=false) 레코드 우선 사용
// API 레코드의 balance가 바로빌에서 제공한 정확한 은행 잔액
// barobill_bank_transactions 테이블에서 직접 조회 (중복 제거)
$normalizedAccNum = !empty($accountNum) ? str_replace('-', '', $accountNum) : null;
$dedupQuery = BankTransaction::where('tenant_id', $tenantId)
->whereBetween('trans_date', [$startDate, $endDate]);
if (!empty($accountNum)) {
$dedupQuery->where('bank_account_num', str_replace('-', '', $accountNum));
if ($normalizedAccNum) {
$dedupQuery->where('bank_account_num', $normalizedAccNum);
}
$latestIds = $dedupQuery
->selectRaw('MAX(CASE WHEN COALESCE(is_manual, 0) = 0 THEN id END) as api_id, MAX(id) as fallback_id')
->selectRaw('MAX(id) as id')
->groupBy('bank_account_num', 'trans_dt', 'deposit', 'withdraw')
->get()
->map(fn($row) => $row->api_id ?? $row->fallback_id)
->filter()
->values();
->pluck('id');
$transactions = BankTransaction::whereIn('id', $latestIds)
->orderByDesc('trans_date')
->orderByDesc('trans_time')
->orderBy('trans_date')
->orderBy('trans_time')
->get();
// 로그 데이터 변환
$logs = $transactions->map(function ($tx) {
return [
// 계좌별 이전 기간 잔액 조회 후 running balance 재계산
$prevBalances = $this->getPreviousBalances($tenantId, $startDate, $normalizedAccNum);
// 로그 데이터 변환 (시간순 ASC로 running balance 계산)
$logs = [];
$accountBalances = $prevBalances; // 계좌별 현재 잔액 추적
foreach ($transactions as $tx) {
$accNum = $tx->bank_account_num;
$deposit = (int) $tx->deposit;
$withdraw = (int) $tx->withdraw;
// running balance 계산
$prevBal = $accountBalances[$accNum] ?? 0;
$newBal = $prevBal + $deposit - $withdraw;
$accountBalances[$accNum] = $newBal;
$logs[] = [
'uniqueKey' => $tx->unique_key,
'transDate' => $tx->trans_date,
'transTime' => $tx->trans_time,
'bankAccountNum' => $tx->bank_account_num,
'bankAccountNum' => $accNum,
'bankName' => $tx->bank_name,
'deposit' => (int) $tx->deposit,
'withdraw' => (int) $tx->withdraw,
'balance' => (int) $tx->balance,
'deposit' => $deposit,
'withdraw' => $withdraw,
'balance' => $newBal,
'summary' => $tx->summary,
'cast' => $tx->cast,
'memo' => $tx->memo,
@@ -420,7 +431,9 @@ public function bankTransactions(Request $request): JsonResponse
'accountName' => $tx->account_name,
'isManual' => $tx->is_manual,
];
})->toArray();
}
// 최신순 정렬 (DESC)
$logs = array_reverse($logs);
// 각 거래의 uniqueKey 수집
$uniqueKeys = array_column($logs, 'uniqueKey');
@@ -650,6 +663,50 @@ public function deleteBankJournal(int $id): JsonResponse
]);
}
/**
* 조회기간 이전의 계좌별 잔액 계산
* EaccountController::findBaseBalance() 패턴을 계좌별로 확장
*/
private function getPreviousBalances(int $tenantId, string $startDate, ?string $accountNum): array
{
$query = BankTransaction::where('tenant_id', $tenantId)
->where('trans_date', '<', $startDate);
if ($accountNum) {
$query->where('bank_account_num', $accountNum);
}
// 중복 제거 (bankTransactions와 동일 기준)
$latestIds = (clone $query)
->selectRaw('MAX(id) as id')
->groupBy('bank_account_num', 'trans_dt', 'deposit', 'withdraw')
->pluck('id');
if ($latestIds->isEmpty()) {
return [];
}
$transactions = BankTransaction::whereIn('id', $latestIds)
->orderBy('trans_date')
->orderBy('trans_time')
->get();
$balances = [];
foreach ($transactions as $tx) {
$accNum = $tx->bank_account_num;
if (!$tx->is_manual && (float) $tx->balance != 0) {
// API 데이터: 바로빌이 제공한 잔액을 앵커로 사용
$balances[$accNum] = (float) $tx->balance;
} else {
// 수동입력 또는 잔액 0: 이전 잔액에서 입출금 계산
$prev = $balances[$accNum] ?? 0;
$balances[$accNum] = $prev + (float) $tx->deposit - (float) $tx->withdraw;
}
}
return $balances;
}
/**
* 계정과목 전체 목록 (활성/비활성 포함)
*/