From c24d5cc672b12c0c07c9b0fff356dfd5d8a1ad9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Tue, 10 Mar 2026 11:42:38 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[payroll]=20=EC=A0=84=ED=91=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=9D=8C=EC=88=98=20=EA=B3=B5=EC=A0=9C(?= =?UTF-8?q?=ED=99=98=EA=B8=89)=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20?= =?UTF-8?q?=EC=97=AD=EC=82=B0=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 음수 공제항목을 차변 207 예수금으로 처리 (환급 = 예수금 감소) - 역산 방식 제거, DB의 실제 net_salary 사용 - 공제항목 루프 처리로 코드 간결화 --- .../Api/Admin/HR/PayrollController.php | 171 ++++++------------ 1 file changed, 56 insertions(+), 115 deletions(-) diff --git a/app/Http/Controllers/Api/Admin/HR/PayrollController.php b/app/Http/Controllers/Api/Admin/HR/PayrollController.php index bef301dc..0f286819 100644 --- a/app/Http/Controllers/Api/Admin/HR/PayrollController.php +++ b/app/Http/Controllers/Api/Admin/HR/PayrollController.php @@ -808,11 +808,32 @@ public function generateJournalEntry(Request $request): JsonResponse $monthLabel = "{$month}월분"; // 분개 행 구성 + // 양수 공제 → 대변 207 예수금 (원천징수) + // 음수 공제 → 차변 207 예수금 (환급, 예수금 감소) + // net_salary → DB 실제 값 사용 (역산 아님) $lines = []; $lineNo = 1; - // 1. 차변: 801 급여 / 임직원 $grossAmount = (int) $sums->total_gross; + $netSalary = (int) $sums->total_net; + + // 공제항목 정의: [합산값, 거래처, 적요] + $deductionItems = [ + [(int) $sums->total_pension, '건강보험연금', '국민연금'], + [(int) $sums->total_health, '건강보험건강', '건강보험'], + [(int) $sums->total_ltc, '건강보험건강', '장기요양보험'], + [(int) $sums->total_emp, '건강보험고용', '고용보험'], + [(int) $sums->total_income_tax, '강서세무서', "{$monthLabel} 근로소득세"], + [(int) $sums->total_resident_tax, '강서구청', "{$monthLabel} 지방소득세"], + ]; + + // 기타공제 + $extraDeductions = (int) $sums->total_extra_deductions; + if ($extraDeductions != 0) { + $deductionItems[] = [$extraDeductions, '임직원', '기타공제']; + } + + // 1. 차변: 801 급여 / 임직원 — 총지급액 if ($grossAmount > 0) { $lines[] = [ 'dc_type' => 'debit', @@ -827,122 +848,42 @@ public function generateJournalEntry(Request $request): JsonResponse ]; } - // 2. 대변: 207 예수금 / 건강보험연금 — 국민연금 - $pension = (int) $sums->total_pension; - if ($pension > 0) { - $lines[] = [ - 'dc_type' => 'credit', - 'account_code' => '207', - 'account_name' => $accountCodes['207'], - 'trading_partner_id' => $partners['건강보험연금'], - 'trading_partner_name' => '건강보험연금', - 'debit_amount' => 0, - 'credit_amount' => $pension, - 'description' => '국민연금', - 'line_no' => $lineNo++, - ]; + // 2~N. 공제항목: 양수→대변, 음수→차변 (환급으로 예수금 감소) + foreach ($deductionItems as [$amount, $partnerName, $desc]) { + if ($amount == 0) { + continue; + } + + if ($amount > 0) { + // 양수: 대변 207 예수금 (원천징수) + $lines[] = [ + 'dc_type' => 'credit', + 'account_code' => '207', + 'account_name' => $accountCodes['207'], + 'trading_partner_id' => $partners[$partnerName], + 'trading_partner_name' => $partnerName, + 'debit_amount' => 0, + 'credit_amount' => $amount, + 'description' => $desc, + 'line_no' => $lineNo++, + ]; + } else { + // 음수: 차변 207 예수금 (환급) + $lines[] = [ + 'dc_type' => 'debit', + 'account_code' => '207', + 'account_name' => $accountCodes['207'], + 'trading_partner_id' => $partners[$partnerName], + 'trading_partner_name' => $partnerName, + 'debit_amount' => abs($amount), + 'credit_amount' => 0, + 'description' => "{$desc} (환급)", + 'line_no' => $lineNo++, + ]; + } } - // 3. 대변: 207 예수금 / 건강보험건강 — 건강보험 - $health = (int) $sums->total_health; - if ($health > 0) { - $lines[] = [ - 'dc_type' => 'credit', - 'account_code' => '207', - 'account_name' => $accountCodes['207'], - 'trading_partner_id' => $partners['건강보험건강'], - 'trading_partner_name' => '건강보험건강', - 'debit_amount' => 0, - 'credit_amount' => $health, - 'description' => '건강보험', - 'line_no' => $lineNo++, - ]; - } - - // 4. 대변: 207 예수금 / 건강보험건강 — 장기요양보험 - $ltc = (int) $sums->total_ltc; - if ($ltc > 0) { - $lines[] = [ - 'dc_type' => 'credit', - 'account_code' => '207', - 'account_name' => $accountCodes['207'], - 'trading_partner_id' => $partners['건강보험건강'], - 'trading_partner_name' => '건강보험건강', - 'debit_amount' => 0, - 'credit_amount' => $ltc, - 'description' => '장기요양보험', - 'line_no' => $lineNo++, - ]; - } - - // 5. 대변: 207 예수금 / 건강보험고용 — 고용보험 - $emp = (int) $sums->total_emp; - if ($emp > 0) { - $lines[] = [ - 'dc_type' => 'credit', - 'account_code' => '207', - 'account_name' => $accountCodes['207'], - 'trading_partner_id' => $partners['건강보험고용'], - 'trading_partner_name' => '건강보험고용', - 'debit_amount' => 0, - 'credit_amount' => $emp, - 'description' => '고용보험', - 'line_no' => $lineNo++, - ]; - } - - // 6. 대변: 207 예수금 / 강서세무서 — 근로소득세 - $incomeTax = (int) $sums->total_income_tax; - if ($incomeTax > 0) { - $lines[] = [ - 'dc_type' => 'credit', - 'account_code' => '207', - 'account_name' => $accountCodes['207'], - 'trading_partner_id' => $partners['강서세무서'], - 'trading_partner_name' => '강서세무서', - 'debit_amount' => 0, - 'credit_amount' => $incomeTax, - 'description' => "{$monthLabel} 근로소득세", - 'line_no' => $lineNo++, - ]; - } - - // 7. 대변: 207 예수금 / 강서구청 — 지방소득세 - $residentTax = (int) $sums->total_resident_tax; - if ($residentTax > 0) { - $lines[] = [ - 'dc_type' => 'credit', - 'account_code' => '207', - 'account_name' => $accountCodes['207'], - 'trading_partner_id' => $partners['강서구청'], - 'trading_partner_name' => '강서구청', - 'debit_amount' => 0, - 'credit_amount' => $residentTax, - 'description' => "{$monthLabel} 지방소득세", - 'line_no' => $lineNo++, - ]; - } - - // 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 미지급비용 / 임직원 — 급여 - // DB의 net_salary 대신 역산 (차변 - 기타 대변 합계)으로 차대 균형 보장 - $creditSoFar = collect($lines)->sum('credit_amount'); - $netSalary = $grossAmount - $creditSoFar; + // 최종: 대변 205 미지급비용 / 임직원 — 실수령액 (DB 값) if ($netSalary > 0) { $lines[] = [ 'dc_type' => 'credit',