feat: 출금 오늘의 이슈를 일일 누계 방식으로 변경

- 출금 건별 개별 이슈 → 해당일 누계 1건으로 upsert
- 첫 건: "거래처명 출금 금액원"
- 2건+: "첫거래처명 외 N건 출금 합계 금액원"
- 삭제 시 남은 건수/금액으로 자동 갱신
- FCM 푸시 미발송 (알림 설정 미구현)
- 기존 개별 source_id 레거시 이슈 자동 정리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-29 11:03:19 +09:00
parent aa7678c358
commit 7acaac8340
2 changed files with 83 additions and 25 deletions

View File

@@ -369,7 +369,12 @@ public function handleDepositDeleted(Deposit $deposit): void
}
/**
* 출금 등록 이슈 생성
* 출금 등록 이슈 생성 (일일 누계 방식)
*
* - 첫 번째 출금: "거래처명 출금 금액원"
* - 두 번째 이후: "첫번째거래처명 외 N건 출금 합계 금액원"
* - source_id=null로 일일 1건만 유지 (upsert)
* - FCM 푸시 미발송 (알림 설정 미구현)
*/
public function handleWithdrawalCreated(Withdrawal $withdrawal): void
{
@@ -379,36 +384,88 @@ public function handleWithdrawalCreated(Withdrawal $withdrawal): void
'amount' => $withdrawal->amount,
]);
$clientName = $withdrawal->display_client_name ?: $withdrawal->merchant_name ?: __('message.today_issue.unknown_client');
$amount = number_format($withdrawal->amount ?? 0);
Log::info('TodayIssue: Creating withdrawal issue', [
'withdrawal_id' => $withdrawal->id,
'client' => $clientName,
'amount' => $amount,
]);
$this->createIssueWithFcm(
tenantId: $withdrawal->tenant_id,
sourceType: TodayIssue::SOURCE_WITHDRAWAL,
sourceId: $withdrawal->id,
badge: TodayIssue::BADGE_WITHDRAWAL,
content: __('message.today_issue.withdrawal_registered', [
'client' => $clientName,
'amount' => $amount,
]),
path: "/accounting/withdrawals/{$withdrawal->id}",
needsApproval: false,
expiresAt: Carbon::now()->addDays(7)
);
$this->upsertWithdrawalDailyIssue($withdrawal->tenant_id);
}
/**
* 출금 삭제 시 이슈 삭제
* 출금 삭제 시 일일 누계 이슈 갱신
*/
public function handleWithdrawalDeleted(Withdrawal $withdrawal): void
{
TodayIssue::removeBySource($withdrawal->tenant_id, TodayIssue::SOURCE_WITHDRAWAL, $withdrawal->id);
$this->upsertWithdrawalDailyIssue($withdrawal->tenant_id);
}
/**
* 출금 일일 누계 이슈 upsert
*
* 오늘 날짜의 출금 건수/합계를 집계하여 이슈 1건으로 관리
*/
private function upsertWithdrawalDailyIssue(int $tenantId): void
{
// 기존 개별 출금 이슈 정리 (source_id가 있는 레거시 데이터)
TodayIssue::where('tenant_id', $tenantId)
->where('source_type', TodayIssue::SOURCE_WITHDRAWAL)
->whereNotNull('source_id')
->delete();
// 오늘 날짜 출금 조회 (출금일 기준, soft delete 제외)
$todayWithdrawals = Withdrawal::withoutGlobalScopes()
->where('tenant_id', $tenantId)
->whereDate('withdrawal_date', Carbon::today())
->whereNull('deleted_at')
->orderBy('created_at', 'asc')
->get();
$count = $todayWithdrawals->count();
$totalAmount = $todayWithdrawals->sum('amount');
Log::info('TodayIssue: Withdrawal daily summary', [
'tenant_id' => $tenantId,
'count' => $count,
'total_amount' => $totalAmount,
]);
// 출금이 없으면 이슈 삭제
if ($count === 0) {
TodayIssue::where('tenant_id', $tenantId)
->where('source_type', TodayIssue::SOURCE_WITHDRAWAL)
->whereNull('source_id')
->delete();
return;
}
// 첫 번째 출금의 거래처명
$first = $todayWithdrawals->first();
$firstClientName = $first->display_client_name
?: $first->merchant_name
?: __('message.today_issue.unknown_client');
// 1건이면 단건 메시지, 2건 이상이면 누계 메시지
if ($count === 1) {
$content = __('message.today_issue.withdrawal_registered', [
'client' => $firstClientName,
'amount' => number_format($totalAmount),
]);
} else {
$content = __('message.today_issue.withdrawal_daily_summary', [
'client' => $firstClientName,
'count' => $count - 1,
'amount' => number_format($totalAmount),
]);
}
// source_id=null 로 일일 1건 upsert (FCM 미발송)
TodayIssue::createIssue(
tenantId: $tenantId,
sourceType: TodayIssue::SOURCE_WITHDRAWAL,
sourceId: null,
badge: TodayIssue::BADGE_WITHDRAWAL,
content: $content,
path: '/accounting/withdrawals',
needsApproval: false,
expiresAt: Carbon::now()->addDays(7)
);
}
/**

View File

@@ -515,6 +515,7 @@
'new_client' => ':name 등록',
'deposit_registered' => ':client 입금 :amount원',
'withdrawal_registered' => ':client 출금 :amount원',
'withdrawal_daily_summary' => ':client 외 :count건 출금 합계 :amount원',
// 기안 상태 변경 알림
'draft_approved' => ':title 결재가 승인되었습니다',