feat: [payroll] 장기요양보험 공제항목 추가

- 건강보험에서 장기요양보험 분리하여 별도 항목으로 표시
- 급여등록/수정/일괄생성/상세보기/CSV 내보내기 모두 반영
- 공제순서: 국민연금-건강보험-장기요양보험-고용보험-근로소득세-지방소득세
This commit is contained in:
김보곤
2026-02-27 10:06:28 +09:00
parent c8cea0b67f
commit bd85a902ad
5 changed files with 25 additions and 6 deletions

View File

@@ -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,

View File

@@ -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',

View File

@@ -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));
}
/**

View File

@@ -217,6 +217,7 @@ class="money-input w-full px-3 py-2 border border-gray-300 rounded-lg text-sm te
<div class="bg-gray-50 rounded-lg p-3 space-y-1 text-sm">
<div class="flex justify-between"><span class="text-gray-500">국민연금</span><span id="calcPension" class="text-gray-700">0</span></div>
<div class="flex justify-between"><span class="text-gray-500">건강보험</span><span id="calcHealth" class="text-gray-700">0</span></div>
<div class="flex justify-between"><span class="text-gray-500">장기요양보험</span><span id="calcLongTermCare" class="text-gray-700">0</span></div>
<div class="flex justify-between"><span class="text-gray-500">고용보험</span><span id="calcEmployment" class="text-gray-700">0</span></div>
<div class="flex justify-between"><span class="text-gray-500">근로소득세</span><span id="calcIncomeTax" class="text-gray-700">0</span></div>
<div class="flex justify-between"><span class="text-gray-500">지방소득세</span><span id="calcResidentTax" class="text-gray-700">0</span></div>
@@ -500,6 +501,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);
@@ -511,7 +513,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';
});
}
@@ -750,6 +752,7 @@ function openPayrollDetail(id, data) {
html += '<tr class="bg-red-50"><th class="px-4 py-2 text-left text-red-800 font-medium" colspan="2">공제 항목</th></tr>';
html += `<tr class="border-t"><td class="px-4 py-2 text-gray-500">국민연금</td><td class="px-4 py-2 text-right">${numberFormat(data.pension)}</td></tr>`;
html += `<tr class="border-t"><td class="px-4 py-2 text-gray-500">건강보험</td><td class="px-4 py-2 text-right">${numberFormat(data.health_insurance)}</td></tr>`;
html += `<tr class="border-t"><td class="px-4 py-2 text-gray-500">장기요양보험</td><td class="px-4 py-2 text-right">${numberFormat(data.long_term_care)}</td></tr>`;
html += `<tr class="border-t"><td class="px-4 py-2 text-gray-500">고용보험</td><td class="px-4 py-2 text-right">${numberFormat(data.employment_insurance)}</td></tr>`;
html += `<tr class="border-t"><td class="px-4 py-2 text-gray-500">근로소득세</td><td class="px-4 py-2 text-right">${numberFormat(data.income_tax)}</td></tr>`;
html += `<tr class="border-t"><td class="px-4 py-2 text-gray-500">지방소득세</td><td class="px-4 py-2 text-right">${numberFormat(data.resident_tax)}</td></tr>`;

View File

@@ -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,