fix: [payroll] 수정 모드에서 공제항목 자동 재계산 방지
- 수정 모드(editingPayrollId)에서는 /calculate API 호출 생략 - 기본급 등 변경 시 총지급액/실수령액만 로컬 재합산 - 재계산 버튼 클릭 시에만 최신 요율로 서버 계산 실행
This commit is contained in:
@@ -535,6 +535,28 @@ function recalculate() {
|
||||
}
|
||||
|
||||
function doRecalculate() {
|
||||
const baseSalary = parseMoneyValue(document.getElementById('payrollBaseSalary'));
|
||||
const overtimePay = parseMoneyValue(document.getElementById('payrollOvertimePay'));
|
||||
const bonus = parseMoneyValue(document.getElementById('payrollBonus'));
|
||||
|
||||
let allowancesTotal = 0;
|
||||
document.querySelectorAll('#allowancesContainer > div').forEach(row => {
|
||||
allowancesTotal += parseMoneyValue(row.querySelector('.allowance-amount'));
|
||||
});
|
||||
|
||||
const grossSalary = baseSalary + overtimePay + bonus + allowancesTotal;
|
||||
const taxableBase = grossSalary - bonus;
|
||||
|
||||
document.getElementById('calcGross').textContent = numberFormat(grossSalary);
|
||||
document.getElementById('calcTaxableBase').textContent = numberFormat(taxableBase);
|
||||
|
||||
// 수정 모드: 공제항목은 기존 저장값 유지, 총지급액/실수령액만 재합산
|
||||
if (editingPayrollId) {
|
||||
updateDeductionTotals();
|
||||
return;
|
||||
}
|
||||
|
||||
// 신규 등록 모드: 서버에서 요율 기반 자동 계산
|
||||
const allowances = [];
|
||||
document.querySelectorAll('#allowancesContainer > div').forEach(row => {
|
||||
const name = row.querySelector('.allowance-name').value;
|
||||
@@ -550,9 +572,9 @@ function doRecalculate() {
|
||||
});
|
||||
|
||||
const data = {
|
||||
base_salary: parseMoneyValue(document.getElementById('payrollBaseSalary')),
|
||||
overtime_pay: parseMoneyValue(document.getElementById('payrollOvertimePay')),
|
||||
bonus: parseMoneyValue(document.getElementById('payrollBonus')),
|
||||
base_salary: baseSalary,
|
||||
overtime_pay: overtimePay,
|
||||
bonus: bonus,
|
||||
allowances: allowances,
|
||||
deductions: deductions,
|
||||
user_id: parseInt(document.getElementById('payrollUserId').value) || null,
|
||||
@@ -583,8 +605,6 @@ function doRecalculate() {
|
||||
const el = document.getElementById(id);
|
||||
if (!el.dataset.manual) setMoneyValue(el, 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 + '명';
|
||||
@@ -621,7 +641,63 @@ function resetDeductionOverrides() {
|
||||
el.classList.remove('bg-yellow-50', 'border-yellow-300');
|
||||
el.classList.add('border-gray-200');
|
||||
});
|
||||
recalculate();
|
||||
// 재계산 버튼: 수정 모드에서도 서버 API 호출하여 최신 요율로 재계산
|
||||
forceRecalculate();
|
||||
}
|
||||
|
||||
function forceRecalculate() {
|
||||
const baseSalary = parseMoneyValue(document.getElementById('payrollBaseSalary'));
|
||||
const overtimePay = parseMoneyValue(document.getElementById('payrollOvertimePay'));
|
||||
const bonus = parseMoneyValue(document.getElementById('payrollBonus'));
|
||||
|
||||
const allowances = [];
|
||||
document.querySelectorAll('#allowancesContainer > div').forEach(row => {
|
||||
const name = row.querySelector('.allowance-name').value;
|
||||
const amount = parseMoneyValue(row.querySelector('.allowance-amount'));
|
||||
if (name && amount > 0) allowances.push({name, amount});
|
||||
});
|
||||
|
||||
const deductions = [];
|
||||
document.querySelectorAll('#deductionsContainer > div').forEach(row => {
|
||||
const name = row.querySelector('.deduction-name').value;
|
||||
const amount = parseMoneyValue(row.querySelector('.deduction-amount'));
|
||||
if (name && amount !== 0) deductions.push({name, amount});
|
||||
});
|
||||
|
||||
const data = {
|
||||
base_salary: baseSalary, overtime_pay: overtimePay, bonus: bonus,
|
||||
allowances: allowances, deductions: deductions,
|
||||
user_id: parseInt(document.getElementById('payrollUserId').value) || null,
|
||||
};
|
||||
|
||||
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(data),
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
const d = result.data;
|
||||
const fields = {
|
||||
'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(fields).forEach(([id, val]) => {
|
||||
const el = document.getElementById(id);
|
||||
if (!el.dataset.manual) setMoneyValue(el, 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);
|
||||
}
|
||||
|
||||
function updateDeductionTotals() {
|
||||
|
||||
Reference in New Issue
Block a user