feat: [hr] 사원 연봉 등록 시 급여 산정 테이블 추가
- 고정연장근로수당 산정 계산 로직 구현 (기본급, 통상시급, 고정OT 자동 계산) - 수정 모드에서 실시간 급여 산정 미리보기 테이블 - 조회 모드에서 요약/상세 급여 산정 내역 표시 - 식대, 월 고정연장근로시간 입력 필드 추가 - 계산 결과를 salary_info에 저장하여 급여관리에서 활용 가능
This commit is contained in:
@@ -180,12 +180,24 @@ public function setJsonExtraValue(string $key, mixed $value): void
|
||||
|
||||
public function getSalaryInfo(): array
|
||||
{
|
||||
return $this->json_extra['salary_info'] ?? [
|
||||
$defaults = [
|
||||
'annual_salary' => null,
|
||||
'effective_date' => null,
|
||||
'notes' => null,
|
||||
'fixed_overtime_hours' => null,
|
||||
'meal_allowance' => 200000,
|
||||
'monthly_salary' => null,
|
||||
'base_salary' => null,
|
||||
'fixed_overtime_pay' => null,
|
||||
'hourly_wage' => null,
|
||||
'monthly_work_hours' => 209,
|
||||
'overtime_multiplier' => 1.5,
|
||||
'history' => [],
|
||||
];
|
||||
|
||||
$data = $this->json_extra['salary_info'] ?? [];
|
||||
|
||||
return array_merge($defaults, $data);
|
||||
}
|
||||
|
||||
public function setSalaryInfo(array $data): void
|
||||
@@ -197,6 +209,10 @@ public function setSalaryInfo(array $data): void
|
||||
if ($current['annual_salary'] !== null) {
|
||||
$history[] = [
|
||||
'annual_salary' => $current['annual_salary'],
|
||||
'fixed_overtime_hours' => $current['fixed_overtime_hours'],
|
||||
'meal_allowance' => $current['meal_allowance'],
|
||||
'base_salary' => $current['base_salary'],
|
||||
'fixed_overtime_pay' => $current['fixed_overtime_pay'],
|
||||
'effective_date' => $current['effective_date'],
|
||||
'notes' => $current['notes'],
|
||||
'recorded_at' => now()->format('Y-m-d H:i:s'),
|
||||
@@ -204,12 +220,56 @@ public function setSalaryInfo(array $data): void
|
||||
];
|
||||
}
|
||||
|
||||
$this->setJsonExtraValue('salary_info', [
|
||||
'annual_salary' => $data['annual_salary'] ?? null,
|
||||
$annualSalary = $data['annual_salary'] ?? null;
|
||||
$mealAllowance = $data['meal_allowance'] ?? 200000;
|
||||
$fixedOvertimeHours = $data['fixed_overtime_hours'] ?? null;
|
||||
$breakdown = $this->calculateSalaryBreakdown($annualSalary, $mealAllowance, $fixedOvertimeHours);
|
||||
|
||||
$this->setJsonExtraValue('salary_info', array_merge([
|
||||
'annual_salary' => $annualSalary,
|
||||
'effective_date' => $data['effective_date'] ?? null,
|
||||
'notes' => $data['notes'] ?? null,
|
||||
'history' => $history,
|
||||
]);
|
||||
'fixed_overtime_hours' => $fixedOvertimeHours,
|
||||
'meal_allowance' => $mealAllowance,
|
||||
], $breakdown, ['history' => $history]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 급여 산정 계산
|
||||
*
|
||||
* 공식: (기본급 + 식대) = 월급여 × 209 / (209 + 고정연장근로시간 × 1.5)
|
||||
*/
|
||||
private function calculateSalaryBreakdown(?int $annualSalary, int $mealAllowance, ?int $fixedOvertimeHours): array
|
||||
{
|
||||
$monthlyWorkHours = 209;
|
||||
$overtimeMultiplier = 1.5;
|
||||
|
||||
if (! $annualSalary) {
|
||||
return [
|
||||
'monthly_salary' => null,
|
||||
'base_salary' => null,
|
||||
'fixed_overtime_pay' => null,
|
||||
'hourly_wage' => null,
|
||||
'monthly_work_hours' => $monthlyWorkHours,
|
||||
'overtime_multiplier' => $overtimeMultiplier,
|
||||
];
|
||||
}
|
||||
|
||||
$monthlySalary = (int) round($annualSalary / 12);
|
||||
$otFactor = ($fixedOvertimeHours ?? 0) * $overtimeMultiplier;
|
||||
$basePlusMeal = (int) round($monthlySalary * $monthlyWorkHours / ($monthlyWorkHours + $otFactor));
|
||||
$baseSalary = $basePlusMeal - $mealAllowance;
|
||||
$hourlyWage = (int) floor($basePlusMeal / $monthlyWorkHours);
|
||||
$fixedOvertimePay = $monthlySalary - $baseSalary - $mealAllowance;
|
||||
|
||||
return [
|
||||
'monthly_salary' => $monthlySalary,
|
||||
'base_salary' => $baseSalary,
|
||||
'fixed_overtime_pay' => $fixedOvertimePay,
|
||||
'hourly_wage' => $hourlyWage,
|
||||
'monthly_work_hours' => $monthlyWorkHours,
|
||||
'overtime_multiplier' => $overtimeMultiplier,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user