diff --git a/app/Http/Controllers/Api/Admin/HR/PayrollController.php b/app/Http/Controllers/Api/Admin/HR/PayrollController.php index 061d207d..dfdbc267 100644 --- a/app/Http/Controllers/Api/Admin/HR/PayrollController.php +++ b/app/Http/Controllers/Api/Admin/HR/PayrollController.php @@ -81,12 +81,12 @@ public function store(Request $request): JsonResponse 'deductions.*.name' => 'required_with:deductions|string', 'deductions.*.amount' => 'required_with:deductions|numeric', 'deduction_overrides' => 'nullable|array', - 'deduction_overrides.pension' => 'nullable|numeric|min:0', - 'deduction_overrides.health_insurance' => 'nullable|numeric|min:0', - 'deduction_overrides.long_term_care' => 'nullable|numeric|min:0', - 'deduction_overrides.employment_insurance' => 'nullable|numeric|min:0', - 'deduction_overrides.income_tax' => 'nullable|numeric|min:0', - 'deduction_overrides.resident_tax' => 'nullable|numeric|min:0', + 'deduction_overrides.pension' => 'nullable|numeric', + 'deduction_overrides.health_insurance' => 'nullable|numeric', + 'deduction_overrides.long_term_care' => 'nullable|numeric', + 'deduction_overrides.employment_insurance' => 'nullable|numeric', + 'deduction_overrides.income_tax' => 'nullable|numeric', + 'deduction_overrides.resident_tax' => 'nullable|numeric', 'note' => 'nullable|string|max:500', ]); @@ -135,12 +135,12 @@ public function update(Request $request, int $id): JsonResponse 'deductions.*.name' => 'required_with:deductions|string', 'deductions.*.amount' => 'required_with:deductions|numeric', 'deduction_overrides' => 'nullable|array', - 'deduction_overrides.pension' => 'nullable|numeric|min:0', - 'deduction_overrides.health_insurance' => 'nullable|numeric|min:0', - 'deduction_overrides.long_term_care' => 'nullable|numeric|min:0', - 'deduction_overrides.employment_insurance' => 'nullable|numeric|min:0', - 'deduction_overrides.income_tax' => 'nullable|numeric|min:0', - 'deduction_overrides.resident_tax' => 'nullable|numeric|min:0', + 'deduction_overrides.pension' => 'nullable|numeric', + 'deduction_overrides.health_insurance' => 'nullable|numeric', + 'deduction_overrides.long_term_care' => 'nullable|numeric', + 'deduction_overrides.employment_insurance' => 'nullable|numeric', + 'deduction_overrides.income_tax' => 'nullable|numeric', + 'deduction_overrides.resident_tax' => 'nullable|numeric', 'note' => 'nullable|string|max:500', ]); diff --git a/resources/views/hr/payrolls/index.blade.php b/resources/views/hr/payrolls/index.blade.php index 02aea483..b5ebbd30 100644 --- a/resources/views/hr/payrolls/index.blade.php +++ b/resources/views/hr/payrolls/index.blade.php @@ -452,41 +452,26 @@ function openEditPayrollModal(id, data) { data.deductions.forEach(d => addDeductionRow(d.name, d.amount)); } - // 법정공제 항목: 자동 계산값으로 설정 (수동 수정 표시 없음) - // 사용자가 직접 필드를 수정할 때만 수동 표시됨 (oninput → markManualOverride) - const calcData = { - base_salary: parseMoneyValue(document.getElementById('payrollBaseSalary')), - overtime_pay: parseMoneyValue(document.getElementById('payrollOvertimePay')), - bonus: parseMoneyValue(document.getElementById('payrollBonus')), - user_id: parseInt(document.getElementById('payrollUserId').value) || null, + // 법정공제 항목: DB에 저장된 값을 그대로 표시 + const savedFields = { + 'calcPension': data.pension, 'calcHealth': data.health_insurance, + 'calcLongTermCare': data.long_term_care, 'calcEmployment': data.employment_insurance, + 'calcIncomeTax': data.income_tax, 'calcResidentTax': data.resident_tax, }; - fetch('{{ route("api.admin.hr.payrolls.calculate") }}', { - method: 'POST', - headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}', 'Accept': 'application/json' }, - body: JSON.stringify(calcData), - }) - .then(r => r.json()) - .then(result => { - if (result.success) { - const d = result.data; - const autoFields = { - 'calcPension': d.pension, 'calcHealth': d.health_insurance, - 'calcLongTermCare': d.long_term_care, 'calcEmployment': d.employment_insurance, - 'calcIncomeTax': d.income_tax, 'calcResidentTax': d.resident_tax, - }; - Object.entries(autoFields).forEach(([id, val]) => { - setMoneyValue(document.getElementById(id), val); - }); - document.getElementById('calcGross').textContent = numberFormat(d.gross_salary); - document.getElementById('calcTaxableBase').textContent = numberFormat(d.taxable_base); - if (d.family_count) { - const fcEl = document.getElementById('calcFamilyCount'); - if (fcEl) fcEl.textContent = d.family_count + '명'; - } - updateDeductionTotals(); - } - }) - .catch(console.error); + Object.entries(savedFields).forEach(([id, val]) => { + setMoneyValue(document.getElementById(id), val || 0); + }); + + // 총 지급액·과세표준 계산 표시 + const baseSalary = data.base_salary || 0; + const overtimePay = data.overtime_pay || 0; + const bonus = data.bonus || 0; + let allowancesTotal = 0; + if (data.allowances) data.allowances.forEach(a => allowancesTotal += (a.amount || 0)); + const grossSalary = baseSalary + overtimePay + bonus + allowancesTotal; + document.getElementById('calcGross').textContent = numberFormat(grossSalary); + document.getElementById('calcTaxableBase').textContent = numberFormat(grossSalary - bonus); + updateDeductionTotals(); document.getElementById('payrollModal').classList.remove('hidden'); }