From 2d7fc3a83a2a6f267e6bb61d294b40febb0cec92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Fri, 27 Feb 2026 10:06:28 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[payroll]=20=EC=9E=A5=EA=B8=B0=EC=9A=94?= =?UTF-8?q?=EC=96=91=EB=B3=B4=ED=97=98=20=EA=B3=B5=EC=A0=9C=ED=95=AD?= =?UTF-8?q?=EB=AA=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 건강보험에서 장기요양보험 분리하여 별도 항목으로 표시 - 급여등록/수정/일괄생성/상세보기/CSV 내보내기 모두 반영 - 공제순서: 국민연금-건강보험-장기요양보험-고용보험-근로소득세-지방소득세 --- .../Api/Admin/HR/PayrollController.php | 3 ++- app/Models/HR/Payroll.php | 2 ++ app/Services/HR/PayrollService.php | 20 +++++++++++++++---- resources/views/hr/payrolls/index.blade.php | 5 ++++- .../hr/payrolls/partials/table.blade.php | 1 + 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Api/Admin/HR/PayrollController.php b/app/Http/Controllers/Api/Admin/HR/PayrollController.php index 1d9dd834..b3724e2e 100644 --- a/app/Http/Controllers/Api/Admin/HR/PayrollController.php +++ b/app/Http/Controllers/Api/Admin/HR/PayrollController.php @@ -296,7 +296,7 @@ public function export(Request $request): StreamedResponse $file = fopen('php://output', 'w'); fwrite($file, "\xEF\xBB\xBF"); // UTF-8 BOM - fputcsv($file, ['사원명', '부서', '기본급', '고정연장근로수당', '상여금', '총지급액', '국민연금', '건강보험', '고용보험', '근로소득세', '지방소득세', '총공제액', '실수령액', '상태']); + fputcsv($file, ['사원명', '부서', '기본급', '고정연장근로수당', '상여금', '총지급액', '국민연금', '건강보험', '장기요양보험', '고용보험', '근로소득세', '지방소득세', '총공제액', '실수령액', '상태']); foreach ($payrolls as $payroll) { $profile = $payroll->user?->tenantProfiles?->first(); @@ -313,6 +313,7 @@ public function export(Request $request): StreamedResponse $payroll->gross_salary, $payroll->pension, $payroll->health_insurance, + $payroll->long_term_care, $payroll->employment_insurance, $payroll->income_tax, $payroll->resident_tax, diff --git a/app/Models/HR/Payroll.php b/app/Models/HR/Payroll.php index 8351587b..59f2445f 100644 --- a/app/Models/HR/Payroll.php +++ b/app/Models/HR/Payroll.php @@ -27,6 +27,7 @@ class Payroll extends Model 'income_tax', 'resident_tax', 'health_insurance', + 'long_term_care', 'pension', 'employment_insurance', 'deductions', @@ -55,6 +56,7 @@ class Payroll extends Model 'income_tax' => 'decimal:0', 'resident_tax' => 'decimal:0', 'health_insurance' => 'decimal:0', + 'long_term_care' => 'decimal:0', 'pension' => 'decimal:0', 'employment_insurance' => 'decimal:0', 'total_deductions' => 'decimal:0', diff --git a/app/Services/HR/PayrollService.php b/app/Services/HR/PayrollService.php index ef8ac6ec..c27d8476 100644 --- a/app/Services/HR/PayrollService.php +++ b/app/Services/HR/PayrollService.php @@ -170,6 +170,7 @@ public function storePayroll(array $data): Payroll 'income_tax' => $calculated['income_tax'], 'resident_tax' => $calculated['resident_tax'], 'health_insurance' => $calculated['health_insurance'], + 'long_term_care' => $calculated['long_term_care'], 'pension' => $calculated['pension'], 'employment_insurance' => $calculated['employment_insurance'], 'deductions' => $data['deductions'] ?? null, @@ -212,6 +213,7 @@ public function updatePayroll(int $id, array $data): ?Payroll 'income_tax' => $calculated['income_tax'], 'resident_tax' => $calculated['resident_tax'], 'health_insurance' => $calculated['health_insurance'], + 'long_term_care' => $calculated['long_term_care'], 'pension' => $calculated['pension'], 'employment_insurance' => $calculated['employment_insurance'], 'deductions' => array_key_exists('deductions', $data) ? $data['deductions'] : $payroll->deductions, @@ -350,6 +352,7 @@ public function bulkGenerate(int $year, int $month): array 'income_tax' => $calculated['income_tax'], 'resident_tax' => $calculated['resident_tax'], 'health_insurance' => $calculated['health_insurance'], + 'long_term_care' => $calculated['long_term_care'], 'pension' => $calculated['pension'], 'employment_insurance' => $calculated['employment_insurance'], 'deductions' => null, @@ -392,6 +395,7 @@ public function calculateAmounts(array $data, ?PayrollSetting $settings = null): // 4대보험 계산 $healthInsurance = $this->calculateHealthInsurance($grossSalary, $settings); + $longTermCare = $this->calculateLongTermCare($grossSalary, $settings); $pension = $this->calculatePension($grossSalary, $settings); $employmentInsurance = $this->calculateEmploymentInsurance($grossSalary, $settings); @@ -410,7 +414,7 @@ public function calculateAmounts(array $data, ?PayrollSetting $settings = null): } // 총 공제액 - $totalDeductions = $incomeTax + $residentTax + $healthInsurance + $pension + $employmentInsurance + $extraDeductions; + $totalDeductions = $incomeTax + $residentTax + $healthInsurance + $longTermCare + $pension + $employmentInsurance + $extraDeductions; // 실수령액 $netSalary = $grossSalary - $totalDeductions; @@ -420,6 +424,7 @@ public function calculateAmounts(array $data, ?PayrollSetting $settings = null): 'income_tax' => $incomeTax, 'resident_tax' => $residentTax, 'health_insurance' => $healthInsurance, + 'long_term_care' => $longTermCare, 'pension' => $pension, 'employment_insurance' => $employmentInsurance, 'total_deductions' => (int) $totalDeductions, @@ -457,10 +462,17 @@ public function calculateIncomeTax(float $grossSalary, int $dependents = 1): int */ private function calculateHealthInsurance(float $grossSalary, PayrollSetting $settings): int { - $healthInsurance = $grossSalary * ($settings->health_insurance_rate / 100); - $longTermCare = $healthInsurance * ($settings->long_term_care_rate / 100); + return (int) round($grossSalary * ($settings->health_insurance_rate / 100)); + } - return (int) round($healthInsurance + $longTermCare); + /** + * 장기요양보험료 계산 (건강보험료의 일정 비율) + */ + private function calculateLongTermCare(float $grossSalary, PayrollSetting $settings): int + { + $healthInsurance = $grossSalary * ($settings->health_insurance_rate / 100); + + return (int) round($healthInsurance * ($settings->long_term_care_rate / 100)); } /** diff --git a/resources/views/hr/payrolls/index.blade.php b/resources/views/hr/payrolls/index.blade.php index 6b39d5ea..e8047d6c 100644 --- a/resources/views/hr/payrolls/index.blade.php +++ b/resources/views/hr/payrolls/index.blade.php @@ -214,6 +214,7 @@ class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 f
국민연금0
건강보험0
+
장기요양보험0
고용보험0
근로소득세0
지방소득세0
@@ -495,6 +496,7 @@ function doRecalculate() { document.getElementById('calcIncomeTax').textContent = numberFormat(d.income_tax); document.getElementById('calcResidentTax').textContent = numberFormat(d.resident_tax); document.getElementById('calcHealth').textContent = numberFormat(d.health_insurance); + document.getElementById('calcLongTermCare').textContent = numberFormat(d.long_term_care); document.getElementById('calcPension').textContent = numberFormat(d.pension); document.getElementById('calcEmployment').textContent = numberFormat(d.employment_insurance); document.getElementById('calcGross').textContent = numberFormat(d.gross_salary); @@ -506,7 +508,7 @@ function doRecalculate() { } function resetCalculation() { - ['calcIncomeTax','calcResidentTax','calcHealth','calcPension','calcEmployment','calcGross','calcTotalDeductions','calcNet'].forEach(id => { + ['calcIncomeTax','calcResidentTax','calcHealth','calcLongTermCare','calcPension','calcEmployment','calcGross','calcTotalDeductions','calcNet'].forEach(id => { document.getElementById(id).textContent = '0'; }); } @@ -715,6 +717,7 @@ function openPayrollDetail(id, data) { html += '공제 항목'; html += `국민연금${numberFormat(data.pension)}`; html += `건강보험${numberFormat(data.health_insurance)}`; + html += `장기요양보험${numberFormat(data.long_term_care)}`; html += `고용보험${numberFormat(data.employment_insurance)}`; html += `근로소득세${numberFormat(data.income_tax)}`; html += `지방소득세${numberFormat(data.resident_tax)}`; diff --git a/resources/views/hr/payrolls/partials/table.blade.php b/resources/views/hr/payrolls/partials/table.blade.php index 070ab69f..53197ddc 100644 --- a/resources/views/hr/payrolls/partials/table.blade.php +++ b/resources/views/hr/payrolls/partials/table.blade.php @@ -138,6 +138,7 @@ 'income_tax' => $payroll->income_tax, 'resident_tax' => $payroll->resident_tax, 'health_insurance' => $payroll->health_insurance, + 'long_term_care' => $payroll->long_term_care, 'pension' => $payroll->pension, 'employment_insurance' => $payroll->employment_insurance, 'deductions' => $payroll->deductions,