diff --git a/app/Http/Controllers/Finance/JournalEntryController.php b/app/Http/Controllers/Finance/JournalEntryController.php index cc1417e0..313dd826 100644 --- a/app/Http/Controllers/Finance/JournalEntryController.php +++ b/app/Http/Controllers/Finance/JournalEntryController.php @@ -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; + } + /** * 계정과목 전체 목록 (활성/비활성 포함) */