fix: [payroll] 공제항목 수정 후 이전값 표시 문제 수정
- deduction_overrides validation에서 min:0 제거 (마이너스 허용) - 수정 모달에서 calculate API 대신 DB 저장값 직접 표시
This commit is contained in:
@@ -81,12 +81,12 @@ public function store(Request $request): JsonResponse
|
|||||||
'deductions.*.name' => 'required_with:deductions|string',
|
'deductions.*.name' => 'required_with:deductions|string',
|
||||||
'deductions.*.amount' => 'required_with:deductions|numeric',
|
'deductions.*.amount' => 'required_with:deductions|numeric',
|
||||||
'deduction_overrides' => 'nullable|array',
|
'deduction_overrides' => 'nullable|array',
|
||||||
'deduction_overrides.pension' => 'nullable|numeric|min:0',
|
'deduction_overrides.pension' => 'nullable|numeric',
|
||||||
'deduction_overrides.health_insurance' => 'nullable|numeric|min:0',
|
'deduction_overrides.health_insurance' => 'nullable|numeric',
|
||||||
'deduction_overrides.long_term_care' => 'nullable|numeric|min:0',
|
'deduction_overrides.long_term_care' => 'nullable|numeric',
|
||||||
'deduction_overrides.employment_insurance' => 'nullable|numeric|min:0',
|
'deduction_overrides.employment_insurance' => 'nullable|numeric',
|
||||||
'deduction_overrides.income_tax' => 'nullable|numeric|min:0',
|
'deduction_overrides.income_tax' => 'nullable|numeric',
|
||||||
'deduction_overrides.resident_tax' => 'nullable|numeric|min:0',
|
'deduction_overrides.resident_tax' => 'nullable|numeric',
|
||||||
'note' => 'nullable|string|max:500',
|
'note' => 'nullable|string|max:500',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -135,12 +135,12 @@ public function update(Request $request, int $id): JsonResponse
|
|||||||
'deductions.*.name' => 'required_with:deductions|string',
|
'deductions.*.name' => 'required_with:deductions|string',
|
||||||
'deductions.*.amount' => 'required_with:deductions|numeric',
|
'deductions.*.amount' => 'required_with:deductions|numeric',
|
||||||
'deduction_overrides' => 'nullable|array',
|
'deduction_overrides' => 'nullable|array',
|
||||||
'deduction_overrides.pension' => 'nullable|numeric|min:0',
|
'deduction_overrides.pension' => 'nullable|numeric',
|
||||||
'deduction_overrides.health_insurance' => 'nullable|numeric|min:0',
|
'deduction_overrides.health_insurance' => 'nullable|numeric',
|
||||||
'deduction_overrides.long_term_care' => 'nullable|numeric|min:0',
|
'deduction_overrides.long_term_care' => 'nullable|numeric',
|
||||||
'deduction_overrides.employment_insurance' => 'nullable|numeric|min:0',
|
'deduction_overrides.employment_insurance' => 'nullable|numeric',
|
||||||
'deduction_overrides.income_tax' => 'nullable|numeric|min:0',
|
'deduction_overrides.income_tax' => 'nullable|numeric',
|
||||||
'deduction_overrides.resident_tax' => 'nullable|numeric|min:0',
|
'deduction_overrides.resident_tax' => 'nullable|numeric',
|
||||||
'note' => 'nullable|string|max:500',
|
'note' => 'nullable|string|max:500',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -452,41 +452,26 @@ function openEditPayrollModal(id, data) {
|
|||||||
data.deductions.forEach(d => addDeductionRow(d.name, d.amount));
|
data.deductions.forEach(d => addDeductionRow(d.name, d.amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 법정공제 항목: 자동 계산값으로 설정 (수동 수정 표시 없음)
|
// 법정공제 항목: DB에 저장된 값을 그대로 표시
|
||||||
// 사용자가 직접 필드를 수정할 때만 수동 표시됨 (oninput → markManualOverride)
|
const savedFields = {
|
||||||
const calcData = {
|
'calcPension': data.pension, 'calcHealth': data.health_insurance,
|
||||||
base_salary: parseMoneyValue(document.getElementById('payrollBaseSalary')),
|
'calcLongTermCare': data.long_term_care, 'calcEmployment': data.employment_insurance,
|
||||||
overtime_pay: parseMoneyValue(document.getElementById('payrollOvertimePay')),
|
'calcIncomeTax': data.income_tax, 'calcResidentTax': data.resident_tax,
|
||||||
bonus: parseMoneyValue(document.getElementById('payrollBonus')),
|
|
||||||
user_id: parseInt(document.getElementById('payrollUserId').value) || null,
|
|
||||||
};
|
};
|
||||||
fetch('{{ route("api.admin.hr.payrolls.calculate") }}', {
|
Object.entries(savedFields).forEach(([id, val]) => {
|
||||||
method: 'POST',
|
setMoneyValue(document.getElementById(id), val || 0);
|
||||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': '{{ csrf_token() }}', 'Accept': 'application/json' },
|
});
|
||||||
body: JSON.stringify(calcData),
|
|
||||||
})
|
// 총 지급액·과세표준 계산 표시
|
||||||
.then(r => r.json())
|
const baseSalary = data.base_salary || 0;
|
||||||
.then(result => {
|
const overtimePay = data.overtime_pay || 0;
|
||||||
if (result.success) {
|
const bonus = data.bonus || 0;
|
||||||
const d = result.data;
|
let allowancesTotal = 0;
|
||||||
const autoFields = {
|
if (data.allowances) data.allowances.forEach(a => allowancesTotal += (a.amount || 0));
|
||||||
'calcPension': d.pension, 'calcHealth': d.health_insurance,
|
const grossSalary = baseSalary + overtimePay + bonus + allowancesTotal;
|
||||||
'calcLongTermCare': d.long_term_care, 'calcEmployment': d.employment_insurance,
|
document.getElementById('calcGross').textContent = numberFormat(grossSalary);
|
||||||
'calcIncomeTax': d.income_tax, 'calcResidentTax': d.resident_tax,
|
document.getElementById('calcTaxableBase').textContent = numberFormat(grossSalary - bonus);
|
||||||
};
|
updateDeductionTotals();
|
||||||
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);
|
|
||||||
|
|
||||||
document.getElementById('payrollModal').classList.remove('hidden');
|
document.getElementById('payrollModal').classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user