fix: [payroll] 전표 생성 시 기타공제 누락 수정 및 에러 모달 추가

- 기타공제(deductions JSON) 항목을 대변 207 예수금에 반영
- 차대 불균형 시 상세 분개 내역을 에러 모달로 표시
- toast 대신 복사 가능한 모달로 에러 메시지 표시
This commit is contained in:
김보곤
2026-03-10 11:30:13 +09:00
parent 5e7b434815
commit 63271ed18c
2 changed files with 110 additions and 17 deletions

View File

@@ -738,27 +738,44 @@ public function generateJournalEntry(Request $request): JsonResponse
}
// 해당월 급여 합산
$sums = Payroll::forTenant($tenantId)
$payrolls = Payroll::forTenant($tenantId)
->forPeriod($year, $month)
->selectRaw('
SUM(gross_salary) as total_gross,
SUM(pension) as total_pension,
SUM(health_insurance) as total_health,
SUM(long_term_care) as total_ltc,
SUM(employment_insurance) as total_emp,
SUM(income_tax) as total_income_tax,
SUM(resident_tax) as total_resident_tax,
SUM(net_salary) as total_net
')
->first();
->get();
if (! $sums || (int) $sums->total_gross === 0) {
if ($payrolls->isEmpty()) {
return response()->json([
'success' => false,
'message' => '해당 월 급여 데이터가 없습니다.',
], 422);
}
// 기타공제(deductions JSON) 합산 포함
$extraDeductionsTotal = 0;
foreach ($payrolls as $p) {
foreach ($p->deductions ?? [] as $d) {
$extraDeductionsTotal += (int) ($d['amount'] ?? 0);
}
}
$sums = (object) [
'total_gross' => $payrolls->sum('gross_salary'),
'total_pension' => $payrolls->sum('pension'),
'total_health' => $payrolls->sum('health_insurance'),
'total_ltc' => $payrolls->sum('long_term_care'),
'total_emp' => $payrolls->sum('employment_insurance'),
'total_income_tax' => $payrolls->sum('income_tax'),
'total_resident_tax' => $payrolls->sum('resident_tax'),
'total_net' => $payrolls->sum('net_salary'),
'total_extra_deductions' => $extraDeductionsTotal,
];
if ((int) $sums->total_gross === 0) {
return response()->json([
'success' => false,
'message' => '해당 월 급여 데이터의 총지급액이 0입니다.',
], 422);
}
// 거래처 조회
$partnerNames = ['임직원', '건강보험연금', '건강보험건강', '건강보험고용', '강서세무서', '강서구청'];
$partners = TradingPartner::forTenant($tenantId)
@@ -906,7 +923,23 @@ public function generateJournalEntry(Request $request): JsonResponse
];
}
// 8. 대변: 205 미지급비용 / 임직원 — 급여
// 8. 대변: 207 예수금 / 임직원 — 기타공제
$extraDeductions = (int) $sums->total_extra_deductions;
if ($extraDeductions > 0) {
$lines[] = [
'dc_type' => 'credit',
'account_code' => '207',
'account_name' => $accountCodes['207'],
'trading_partner_id' => $partners['임직원'],
'trading_partner_name' => '임직원',
'debit_amount' => 0,
'credit_amount' => $extraDeductions,
'description' => '기타공제',
'line_no' => $lineNo++,
];
}
// 9. 대변: 205 미지급비용 / 임직원 — 급여
$netSalary = (int) $sums->total_net;
if ($netSalary > 0) {
$lines[] = [
@@ -927,9 +960,18 @@ public function generateJournalEntry(Request $request): JsonResponse
$totalCredit = collect($lines)->sum('credit_amount');
if ($totalDebit !== $totalCredit || $totalDebit === 0) {
$detail = collect($lines)->map(fn ($l) => sprintf(
'[%s] %s %s: %s',
$l['dc_type'],
$l['account_code'],
$l['description'],
number_format($l['dc_type'] === 'debit' ? $l['debit_amount'] : $l['credit_amount'])
))->implode("\n");
return response()->json([
'success' => false,
'message' => "차변({$totalDebit})과 대변({$totalCredit})이 일치하지 않습니다.",
'message' => '차변('.number_format($totalDebit).')과 대변('.number_format($totalCredit).")이 일치하지 않습니다.\n차이: ".number_format(abs($totalDebit - $totalCredit)),
'detail' => "급여 {$payrolls->count()}건 합산\n\n{$detail}",
], 422);
}