feat: 출금 오늘의 이슈를 일일 누계 방식으로 변경
- 출금 건별 개별 이슈 → 해당일 누계 1건으로 upsert - 첫 건: "거래처명 출금 금액원" - 2건+: "첫거래처명 외 N건 출금 합계 금액원" - 삭제 시 남은 건수/금액으로 자동 갱신 - FCM 푸시 미발송 (알림 설정 미구현) - 기존 개별 source_id 레거시 이슈 자동 정리 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -369,7 +369,12 @@ public function handleDepositDeleted(Deposit $deposit): void
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 출금 등록 이슈 생성
|
* 출금 등록 이슈 생성 (일일 누계 방식)
|
||||||
|
*
|
||||||
|
* - 첫 번째 출금: "거래처명 출금 금액원"
|
||||||
|
* - 두 번째 이후: "첫번째거래처명 외 N건 출금 합계 금액원"
|
||||||
|
* - source_id=null로 일일 1건만 유지 (upsert)
|
||||||
|
* - FCM 푸시 미발송 (알림 설정 미구현)
|
||||||
*/
|
*/
|
||||||
public function handleWithdrawalCreated(Withdrawal $withdrawal): void
|
public function handleWithdrawalCreated(Withdrawal $withdrawal): void
|
||||||
{
|
{
|
||||||
@@ -379,36 +384,88 @@ public function handleWithdrawalCreated(Withdrawal $withdrawal): void
|
|||||||
'amount' => $withdrawal->amount,
|
'amount' => $withdrawal->amount,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$clientName = $withdrawal->display_client_name ?: $withdrawal->merchant_name ?: __('message.today_issue.unknown_client');
|
$this->upsertWithdrawalDailyIssue($withdrawal->tenant_id);
|
||||||
$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)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 출금 삭제 시 이슈 삭제
|
* 출금 삭제 시 일일 누계 이슈 갱신
|
||||||
*/
|
*/
|
||||||
public function handleWithdrawalDeleted(Withdrawal $withdrawal): void
|
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)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -515,6 +515,7 @@
|
|||||||
'new_client' => ':name 등록',
|
'new_client' => ':name 등록',
|
||||||
'deposit_registered' => ':client 입금 :amount원',
|
'deposit_registered' => ':client 입금 :amount원',
|
||||||
'withdrawal_registered' => ':client 출금 :amount원',
|
'withdrawal_registered' => ':client 출금 :amount원',
|
||||||
|
'withdrawal_daily_summary' => ':client 외 :count건 출금 합계 :amount원',
|
||||||
|
|
||||||
// 기안 상태 변경 알림
|
// 기안 상태 변경 알림
|
||||||
'draft_approved' => ':title 결재가 승인되었습니다',
|
'draft_approved' => ':title 결재가 승인되었습니다',
|
||||||
|
|||||||
Reference in New Issue
Block a user