tenantId(); $date = isset($params['date']) ? Carbon::parse($params['date']) : Carbon::today(); // 수취어음 중 보관중 상태인 것만 조회 (만기일 기준) $bills = Bill::where('tenant_id', $tenantId) ->where('bill_type', 'received') ->where('status', 'stored') ->where('maturity_date', '>=', $date->copy()->startOfDay()) ->orderBy('maturity_date', 'asc') ->get(); return $bills->map(function ($bill) { return [ 'id' => (string) $bill->id, 'content' => "(수취어음) {$bill->display_client_name} - {$bill->bill_number}", 'current_balance' => (float) $bill->amount, 'issue_date' => $bill->issue_date?->format('Y-m-d'), 'due_date' => $bill->maturity_date?->format('Y-m-d'), ]; })->values()->toArray(); } /** * 일별 계좌 현황 조회 */ public function dailyAccounts(array $params): array { $tenantId = $this->tenantId(); $date = isset($params['date']) ? Carbon::parse($params['date']) : Carbon::today(); $startOfMonth = $date->copy()->startOfMonth(); $endOfDay = $date->copy()->endOfDay(); // 활성 계좌 목록 $accounts = BankAccount::where('tenant_id', $tenantId) ->where('status', 'active') ->orderBy('is_primary', 'desc') ->orderBy('bank_name', 'asc') ->get(); $result = []; foreach ($accounts as $account) { // 전월 이월: 이번 달 1일 이전까지의 누적 잔액 $carryoverDeposits = Deposit::where('tenant_id', $tenantId) ->where('bank_account_id', $account->id) ->where('deposit_date', '<', $startOfMonth) ->sum('amount'); $carryoverWithdrawals = Withdrawal::where('tenant_id', $tenantId) ->where('bank_account_id', $account->id) ->where('withdrawal_date', '<', $startOfMonth) ->sum('amount'); $carryover = $carryoverDeposits - $carryoverWithdrawals; // 당일 수입 (입금) $income = Deposit::where('tenant_id', $tenantId) ->where('bank_account_id', $account->id) ->whereBetween('deposit_date', [$startOfMonth, $endOfDay]) ->sum('amount'); // 당일 지출 (출금) $expense = Withdrawal::where('tenant_id', $tenantId) ->where('bank_account_id', $account->id) ->whereBetween('withdrawal_date', [$startOfMonth, $endOfDay]) ->sum('amount'); // 잔액 = 전월이월 + 수입 - 지출 $balance = $carryover + $income - $expense; // 매칭 상태: Deposit과 Withdrawal 금액이 일치하면 matched $matchStatus = abs($income - $expense) < 0.01 ? 'matched' : 'unmatched'; $result[] = [ 'id' => (string) $account->id, 'category' => "{$account->bank_name} {$account->getMaskedAccountNumber()}", 'match_status' => $matchStatus, 'carryover' => (float) $carryover, 'income' => (float) $income, 'expense' => (float) $expense, 'balance' => (float) $balance, 'currency' => 'KRW', // 현재는 KRW만 지원 ]; } return $result; } /** * 일일 보고서 요약 통계 */ public function summary(array $params): array { $tenantId = $this->tenantId(); $date = isset($params['date']) ? Carbon::parse($params['date']) : Carbon::today(); // 어음 합계 $noteReceivableTotal = Bill::where('tenant_id', $tenantId) ->where('bill_type', 'received') ->where('status', 'stored') ->where('maturity_date', '>=', $date->copy()->startOfDay()) ->sum('amount'); // 계좌별 현황 $dailyAccounts = $this->dailyAccounts($params); // 통화별 합계 $krwTotal = collect($dailyAccounts) ->where('currency', 'KRW') ->reduce(function ($carry, $item) { return [ 'carryover' => $carry['carryover'] + $item['carryover'], 'income' => $carry['income'] + $item['income'], 'expense' => $carry['expense'] + $item['expense'], 'balance' => $carry['balance'] + $item['balance'], ]; }, ['carryover' => 0, 'income' => 0, 'expense' => 0, 'balance' => 0]); $usdTotal = collect($dailyAccounts) ->where('currency', 'USD') ->reduce(function ($carry, $item) { return [ 'carryover' => $carry['carryover'] + $item['carryover'], 'income' => $carry['income'] + $item['income'], 'expense' => $carry['expense'] + $item['expense'], 'balance' => $carry['balance'] + $item['balance'], ]; }, ['carryover' => 0, 'income' => 0, 'expense' => 0, 'balance' => 0]); return [ 'date' => $date->format('Y-m-d'), 'day_of_week' => $date->locale('ko')->dayName, 'note_receivable_total' => (float) $noteReceivableTotal, 'foreign_currency_total' => (float) $usdTotal['balance'], 'cash_asset_total' => (float) $krwTotal['balance'], 'krw_totals' => $krwTotal, 'usd_totals' => $usdTotal, ]; } }