fix:일반전표 은행거래 잔액 running balance 방식으로 수정
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 계정과목 전체 목록 (활성/비활성 포함)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user