fix: 당월 예상 지출 모달 데이터 불일치 수정

- dashboardDetail() 메서드에 transaction_type 파라미터 추가
- 카드별 필터링 지원 (purchase, card, bill, null=전체)
- 카드 금액과 모달 금액이 동일한 데이터 소스 사용하도록 개선

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-01-22 23:16:49 +09:00
parent f089843e1e
commit a994f27696
2 changed files with 126 additions and 0 deletions

View File

@@ -124,4 +124,18 @@ public function summary(Request $request)
return ApiResponse::success($summary, __('message.fetched'));
}
/**
* 대시보드 상세 조회 (CEO 대시보드 당월 예상 지출내역 모달용)
*
* @param Request $request transaction_type 쿼리 파라미터 (purchase, card, bill, null=전체)
*/
public function dashboardDetail(Request $request)
{
$transactionType = $request->query('transaction_type');
$data = $this->service->dashboardDetail($transactionType);
return ApiResponse::success($data, __('message.fetched'));
}
}

View File

@@ -299,4 +299,116 @@ public function summary(array $params): array
'by_month' => $byMonth,
];
}
/**
* 대시보드 상세 조회 (CEO 대시보드 당월 예상 지출내역 모달용)
*
* @param string|null $transactionType 거래유형 필터 (purchase, card, bill, null=전체)
* @return array{
* summary: array{
* total_amount: float,
* previous_month_amount: float,
* change_rate: float,
* remaining_balance: float,
* item_count: int
* },
* items: array,
* footer_summary: array
* }
*/
public function dashboardDetail(?string $transactionType = null): array
{
$tenantId = $this->tenantId();
$currentMonthStart = now()->startOfMonth()->toDateString();
$currentMonthEnd = now()->endOfMonth()->toDateString();
$previousMonthStart = now()->subMonth()->startOfMonth()->toDateString();
$previousMonthEnd = now()->subMonth()->endOfMonth()->toDateString();
// 기본 쿼리 빌더 (transaction_type 필터 적용)
$baseQuery = function () use ($tenantId, $transactionType) {
$query = ExpectedExpense::query()->where('tenant_id', $tenantId);
if ($transactionType) {
$query->where('transaction_type', $transactionType);
}
return $query;
};
// 1. 요약 정보
$currentMonthTotal = $baseQuery()
->whereBetween('expected_payment_date', [$currentMonthStart, $currentMonthEnd])
->sum('amount');
$currentMonthCount = $baseQuery()
->whereBetween('expected_payment_date', [$currentMonthStart, $currentMonthEnd])
->count();
$previousMonthTotal = $baseQuery()
->whereBetween('expected_payment_date', [$previousMonthStart, $previousMonthEnd])
->sum('amount');
$changeRate = $previousMonthTotal > 0
? round((($currentMonthTotal - $previousMonthTotal) / $previousMonthTotal) * 100, 1)
: ($currentMonthTotal > 0 ? 100 : 0);
// 미지급 잔액 (pending 상태) - remaining_balance로 반환
$pendingBalance = $baseQuery()
->where('payment_status', 'pending')
->sum('amount');
// 2. 지출예상 목록 (당월, 지급일 순)
$itemsQuery = ExpectedExpense::query()
->select([
'expected_expenses.id',
'expected_expenses.expected_payment_date',
'expected_expenses.description',
'expected_expenses.amount',
'expected_expenses.client_id',
'expected_expenses.client_name',
'expected_expenses.account_code',
'expected_expenses.payment_status',
'expected_expenses.transaction_type',
])
->leftJoin('clients', 'expected_expenses.client_id', '=', 'clients.id')
->where('expected_expenses.tenant_id', $tenantId)
->whereBetween('expected_expenses.expected_payment_date', [$currentMonthStart, $currentMonthEnd]);
if ($transactionType) {
$itemsQuery->where('expected_expenses.transaction_type', $transactionType);
}
$items = $itemsQuery
->orderBy('expected_expenses.expected_payment_date', 'asc')
->get()
->map(function ($item) {
return [
'id' => $item->id,
'payment_date' => $item->expected_payment_date?->format('Y-m-d'),
'item_name' => $item->description ?? '',
'amount' => (float) $item->amount,
'vendor_name' => $item->client_name ?? '',
'account_title' => $item->account_code ?? '',
'status' => $item->payment_status,
'transaction_type' => $item->transaction_type,
];
})
->toArray();
// 3. 푸터 합계
$footerSummary = [
'total_amount' => (float) $currentMonthTotal,
'item_count' => count($items),
];
return [
'summary' => [
'total_amount' => (float) $currentMonthTotal,
'previous_month_amount' => (float) $previousMonthTotal,
'change_rate' => $changeRate,
'remaining_balance' => (float) $pendingBalance,
],
'items' => $items,
'footer_summary' => $footerSummary,
];
}
}