diff --git a/resources/views/hr/payrolls/index.blade.php b/resources/views/hr/payrolls/index.blade.php
index 76f52752..915ec159 100644
--- a/resources/views/hr/payrolls/index.blade.php
+++ b/resources/views/hr/payrolls/index.blade.php
@@ -187,6 +187,7 @@ class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 f
data-base-salary="{{ $si['base_salary'] ?? 0 }}"
data-overtime-pay="{{ $si['fixed_overtime_pay'] ?? 0 }}"
data-meal-allowance="{{ $si['meal_allowance'] ?? 200000 }}"
+ data-hire-date="{{ $emp->getJsonExtraValue('hire_date', '') }}"
data-dependents="{{ 1 + collect($emp->dependents)->where('is_dependent', true)->count() }}">
{{ $emp->display_name ?? $emp->user?->name }}
@@ -206,6 +207,36 @@ class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 f
+ {{-- 일할계산 안내 (입사월인 경우) --}}
+
+
+
+
+
일할계산 적용
+
+
+
+
+ | 항목 |
+ 월액 |
+ 산식 |
+ 일할금액 |
+
+
+
+
+
+ | 합계 |
+ |
+
+
+
+
+
+
+
{{-- 지급 항목 --}}
지급 항목
@@ -997,6 +1028,7 @@ function openCreatePayrollModal() {
document.getElementById('payrollPayMonth').value = document.getElementById('payrollMonth').value;
document.getElementById('allowancesContainer').innerHTML = '';
document.getElementById('deductionsContainer').innerHTML = '';
+ hideProrataNotice();
resetCalculation();
document.getElementById('payrollModal').classList.remove('hidden');
}
@@ -1055,6 +1087,58 @@ function closePayrollModal() {
document.getElementById('payrollUserId').disabled = false;
}
+ // ===== 일할계산 유틸 =====
+ function getDaysInMonth(year, month) {
+ return new Date(year, month, 0).getDate();
+ }
+
+ function checkProrata(hireDate, payYear, payMonth) {
+ if (!hireDate) return null;
+ const d = new Date(hireDate);
+ if (d.getFullYear() === payYear && (d.getMonth() + 1) === payMonth) {
+ const totalDays = getDaysInMonth(payYear, payMonth);
+ const workDays = totalDays - d.getDate() + 1;
+ return { hireDate, totalDays, workDays, hireDay: d.getDate() };
+ }
+ return null;
+ }
+
+ function applyProrata(amount, totalDays, workDays) {
+ return Math.round(amount / totalDays * workDays);
+ }
+
+ function showProrataNotice(prorata, baseSalary, overtimePay, mealAllowance) {
+ const notice = document.getElementById('prorataNotice');
+ const desc = document.getElementById('prorataDesc');
+ const tbody = document.getElementById('prorataTableBody');
+ const total = document.getElementById('prorataTotal');
+
+ desc.textContent = `입사일: ${prorata.hireDate} | 근무일수: ${prorata.workDays}일 / ${prorata.totalDays}일`;
+
+ const items = [
+ { name: '기본급', amount: baseSalary },
+ { name: '식대', amount: mealAllowance },
+ { name: '고정연장근로수당', amount: overtimePay },
+ ];
+ let sum = 0;
+ tbody.innerHTML = items.map(item => {
+ const pro = applyProrata(item.amount, prorata.totalDays, prorata.workDays);
+ sum += pro;
+ return `
+ | ${item.name} |
+ ${numberFormat(item.amount)} |
+ ${numberFormat(item.amount)}/${prorata.totalDays}*${prorata.workDays} |
+ ${numberFormat(pro)} |
+
`;
+ }).join('');
+ total.textContent = numberFormat(sum);
+ notice.classList.remove('hidden');
+ }
+
+ function hideProrataNotice() {
+ document.getElementById('prorataNotice').classList.add('hidden');
+ }
+
// ===== 사원 선택 시 급여 산정값 자동 입력 + 가족수 표시 =====
document.getElementById('payrollUserId').addEventListener('change', function() {
const selected = this.options[this.selectedIndex];
@@ -1062,17 +1146,34 @@ function closePayrollModal() {
const fcEl = document.getElementById('calcFamilyCount');
if (fcEl) fcEl.textContent = dependents + '명';
+ hideProrataNotice();
if (editingPayrollId) return;
const baseSalary = parseInt(selected.dataset.baseSalary || 0);
const overtimePay = parseInt(selected.dataset.overtimePay || 0);
const mealAllowance = parseInt(selected.dataset.mealAllowance || 0);
+ const hireDate = selected.dataset.hireDate || '';
+
+ let finalBase = baseSalary;
+ let finalOT = overtimePay;
+ let finalMeal = mealAllowance;
if (baseSalary > 0) {
- // 연봉 산정 테이블에서 계산된 값 적용
- setMoneyValue(document.getElementById('payrollBaseSalary'), baseSalary);
- setMoneyValue(document.getElementById('payrollOvertimePay'), overtimePay);
- setMoneyValue(document.getElementById('payrollBonus'), mealAllowance);
+ // 일할계산 체크
+ const payYear = parseInt(document.getElementById('payrollPayYear').value);
+ const payMonth = parseInt(document.getElementById('payrollPayMonth').value);
+ const prorata = checkProrata(hireDate, payYear, payMonth);
+
+ if (prorata && prorata.workDays < prorata.totalDays) {
+ finalBase = applyProrata(baseSalary, prorata.totalDays, prorata.workDays);
+ finalOT = applyProrata(overtimePay, prorata.totalDays, prorata.workDays);
+ finalMeal = applyProrata(mealAllowance, prorata.totalDays, prorata.workDays);
+ showProrataNotice(prorata, baseSalary, overtimePay, mealAllowance);
+ }
+
+ setMoneyValue(document.getElementById('payrollBaseSalary'), finalBase);
+ setMoneyValue(document.getElementById('payrollOvertimePay'), finalOT);
+ setMoneyValue(document.getElementById('payrollBonus'), finalMeal);
} else {
// fallback: 산정 데이터 없으면 연봉에서 단순 계산
const salary = parseInt(selected.dataset.salary || 0);