fix: [esign] 근로계약서 연봉계약종료연도 및 연봉 상세내역 자동반영

- 연봉계약 기간: salary_effective_date 없을 때 입사일 기념일 기준
  현재 계약기간 산출 (직전 기념일~다음 기념일-1일)
- API 응답에 기본급, 고정연장근로수당, 식대, 월급여, 통상시급 추가
- labelMap에 기본급, 고정연장근로수당, 식대, 통상시급 패턴 추가
This commit is contained in:
김보곤
2026-03-13 17:59:42 +09:00
parent 6bafafc5b1
commit bc72fadf2e
2 changed files with 63 additions and 7 deletions

View File

@@ -117,6 +117,12 @@ public function searchEmployees(Request $request): JsonResponse
// 최신 연봉 정보 결정: 현재값 우선, 없으면 이력에서 최신 탐색
$annualSalary = $salaryInfo['annual_salary'] ?? null;
$salaryEffectiveDate = $salaryInfo['effective_date'] ?? null;
$baseSalary = $salaryInfo['base_salary'] ?? null;
$fixedOvertimePay = $salaryInfo['fixed_overtime_pay'] ?? null;
$mealAllowance = $salaryInfo['meal_allowance'] ?? null;
$fixedOvertimeHours = $salaryInfo['fixed_overtime_hours'] ?? null;
$monthlySalary = $salaryInfo['monthly_salary'] ?? null;
$hourlyWage = $salaryInfo['hourly_wage'] ?? null;
if ($annualSalary === null && ! empty($salaryInfo['history'])) {
$latest = collect($salaryInfo['history'])
@@ -124,6 +130,10 @@ public function searchEmployees(Request $request): JsonResponse
->first();
$annualSalary = $latest['annual_salary'] ?? null;
$salaryEffectiveDate = $latest['effective_date'] ?? null;
$baseSalary = $latest['base_salary'] ?? null;
$fixedOvertimePay = $latest['fixed_overtime_pay'] ?? null;
$mealAllowance = $latest['meal_allowance'] ?? $mealAllowance;
$fixedOvertimeHours = $latest['fixed_overtime_hours'] ?? null;
}
return [
@@ -141,6 +151,12 @@ public function searchEmployees(Request $request): JsonResponse
'birth_day' => $birthDay,
'annual_salary' => $annualSalary,
'salary_effective_date' => $salaryEffectiveDate,
'base_salary' => $baseSalary,
'fixed_overtime_pay' => $fixedOvertimePay,
'meal_allowance' => $mealAllowance,
'fixed_overtime_hours' => $fixedOvertimeHours,
'monthly_salary' => $monthlySalary,
'hourly_wage' => $hourlyWage,
];
});

View File

@@ -953,12 +953,19 @@ className={`w-full text-left px-3 py-2.5 rounded-lg mb-1 transition-colors ${i =
// 입사일에서 년/월/일 분리
let hireYear = '', hireMonth = '', hireDay = '';
let hireEndYear = '', hireEndMonth = '', hireEndDay = '';
// 연봉계약 시작/종료일 (최신 연봉 적용일 기준, 없으면 입사일 fallback)
// 연봉계약 시작/종료일 (최신 연봉 적용일 기준, 없으면 입사일 기념일 기준)
let salaryStartYear = '', salaryStartMonth = '', salaryStartDay = '';
let salaryEndYear = '', salaryEndMonth = '', salaryEndDay = '';
// 연봉 금액 포맷
const annualSalary = emp.annual_salary ? Number(emp.annual_salary).toLocaleString() : '';
const monthlySalary = emp.annual_salary ? Math.round(emp.annual_salary / 12).toLocaleString() : '';
const monthlySalary = emp.monthly_salary ? Number(emp.monthly_salary).toLocaleString()
: (emp.annual_salary ? Math.round(emp.annual_salary / 12).toLocaleString() : '');
// 연봉 상세내역 포맷
const baseSalary = emp.base_salary ? Number(emp.base_salary).toLocaleString() : '';
const fixedOvertimePay = emp.fixed_overtime_pay ? Number(emp.fixed_overtime_pay).toLocaleString() : '';
const mealAllowance = emp.meal_allowance ? Number(emp.meal_allowance).toLocaleString() : '';
const fixedOvertimeHours = emp.fixed_overtime_hours ? String(emp.fixed_overtime_hours) : '';
const hourlyWage = emp.hourly_wage ? Number(emp.hourly_wage).toLocaleString() : '';
// 입사일 파싱
if (emp.hire_date) {
@@ -975,21 +982,42 @@ className={`w-full text-left px-3 py-2.5 rounded-lg mb-1 transition-colors ${i =
}
}
// 연봉계약 기간: 최신 연봉 적용일 기준 (없으면 입사일 fallback)
const salaryBase = emp.salary_effective_date || emp.hire_date;
if (salaryBase) {
const sd = salaryBase.replace(/-/g, '');
// 연봉계약 기간 산출
if (emp.salary_effective_date) {
// 최신 연봉 적용일이 있으면 그대로 사용
const sd = emp.salary_effective_date.replace(/-/g, '');
if (sd.length >= 8) {
salaryStartYear = sd.substring(0, 4);
salaryStartMonth = sd.substring(4, 6);
salaryStartDay = sd.substring(6, 8);
const se = new Date(parseInt(salaryStartYear), parseInt(salaryStartMonth) - 1, parseInt(salaryStartDay));
se.setFullYear(se.getFullYear() + 1);
se.setDate(se.getDate() - 1); // 1년이 되는 시점 (시작일+1년-1일)
se.setDate(se.getDate() - 1);
salaryEndYear = String(se.getFullYear());
salaryEndMonth = String(se.getMonth() + 1).padStart(2, '0');
salaryEndDay = String(se.getDate()).padStart(2, '0');
}
} else if (emp.hire_date) {
// salary_effective_date 없으면: 입사일 기준 현재 계약기간 산출
// (입사일 기념일이 매년 갱신되므로, 직전 기념일 ~ 다음 기념일-1일)
const hd = emp.hire_date.replace(/-/g, '');
if (hd.length >= 8) {
const hMonth = parseInt(hd.substring(4, 6));
const hDay = parseInt(hd.substring(6, 8));
const today = new Date();
const thisYearAnniv = new Date(today.getFullYear(), hMonth - 1, hDay);
// 올해 기념일이 아직 안 지났으면 작년 기념일이 시작일
const startDate = thisYearAnniv <= today ? thisYearAnniv : new Date(today.getFullYear() - 1, hMonth - 1, hDay);
salaryStartYear = String(startDate.getFullYear());
salaryStartMonth = String(startDate.getMonth() + 1).padStart(2, '0');
salaryStartDay = String(startDate.getDate()).padStart(2, '0');
const endDate = new Date(startDate);
endDate.setFullYear(endDate.getFullYear() + 1);
endDate.setDate(endDate.getDate() - 1);
salaryEndYear = String(endDate.getFullYear());
salaryEndMonth = String(endDate.getMonth() + 1).padStart(2, '0');
salaryEndDay = String(endDate.getDate()).padStart(2, '0');
}
}
const labelMap = {
@@ -1038,6 +1066,18 @@ className={`w-full text-left px-3 py-2.5 rounded-lg mb-1 transition-colors ${i =
'연봉$': annualSalary,
'월.*급여': monthlySalary,
'월급': monthlySalary,
// 연봉 상세내역 (기본급, 고정연장근로수당, 식대 등)
'기본급': baseSalary,
'고정연장.*수당': fixedOvertimePay,
'연장근로.*수당': fixedOvertimePay,
'OT.*수당': fixedOvertimePay,
'식대': mealAllowance,
'식비': mealAllowance,
'식대.*보조': mealAllowance,
'고정연장.*시간': fixedOvertimeHours,
'연장근로.*시간': fixedOvertimeHours,
'통상시급': hourlyWage,
'시간급': hourlyWage,
};
setMetadata(prev => {