feat: [hr] Leave 모델 확장 + 결재양식 마이그레이션 추가

- Leave 타입 6개 추가: business_trip, remote, field_work, early_leave, late_reason, absent_reason
- 그룹 상수 추가: VACATION_TYPES, ATTENDANCE_REQUEST_TYPES, REASON_REPORT_TYPES
- FORM_CODE_MAP: 유형 → 결재양식코드 매핑 상수
- ATTENDANCE_STATUS_MAP: 유형 → 근태상태 매핑 상수
- 결재양식 2개 추가: attendance_request(근태신청), reason_report(사유서)
This commit is contained in:
김보곤
2026-03-03 23:50:04 +09:00
parent 2fd122feba
commit 88ef6a8490
2 changed files with 116 additions and 0 deletions

View File

@@ -82,6 +82,18 @@ class Leave extends Model
public const TYPE_PARENTAL = 'parental'; // 육아
public const TYPE_BUSINESS_TRIP = 'business_trip'; // 출장
public const TYPE_REMOTE = 'remote'; // 재택근무
public const TYPE_FIELD_WORK = 'field_work'; // 외근
public const TYPE_EARLY_LEAVE = 'early_leave'; // 조퇴
public const TYPE_LATE_REASON = 'late_reason'; // 지각사유서
public const TYPE_ABSENT_REASON = 'absent_reason'; // 결근사유서
public const STATUS_PENDING = 'pending';
public const STATUS_APPROVED = 'approved';
@@ -98,6 +110,45 @@ class Leave extends Model
self::TYPE_FAMILY,
self::TYPE_MATERNITY,
self::TYPE_PARENTAL,
self::TYPE_BUSINESS_TRIP,
self::TYPE_REMOTE,
self::TYPE_FIELD_WORK,
self::TYPE_EARLY_LEAVE,
self::TYPE_LATE_REASON,
self::TYPE_ABSENT_REASON,
];
// 그룹 상수
public const VACATION_TYPES = [
self::TYPE_ANNUAL, self::TYPE_HALF_AM, self::TYPE_HALF_PM,
self::TYPE_SICK, self::TYPE_FAMILY, self::TYPE_MATERNITY, self::TYPE_PARENTAL,
];
public const ATTENDANCE_REQUEST_TYPES = [
self::TYPE_BUSINESS_TRIP, self::TYPE_REMOTE, self::TYPE_FIELD_WORK, self::TYPE_EARLY_LEAVE,
];
public const REASON_REPORT_TYPES = [
self::TYPE_LATE_REASON, self::TYPE_ABSENT_REASON,
];
// 유형 → 결재양식코드 매핑
public const FORM_CODE_MAP = [
'annual' => 'leave', 'half_am' => 'leave', 'half_pm' => 'leave',
'sick' => 'leave', 'family' => 'leave', 'maternity' => 'leave', 'parental' => 'leave',
'business_trip' => 'attendance_request', 'remote' => 'attendance_request',
'field_work' => 'attendance_request', 'early_leave' => 'attendance_request',
'late_reason' => 'reason_report', 'absent_reason' => 'reason_report',
];
// 유형 → 근태상태 매핑 (승인 시 Attendance에 반영할 상태)
public const ATTENDANCE_STATUS_MAP = [
'annual' => 'vacation', 'half_am' => 'vacation', 'half_pm' => 'vacation',
'sick' => 'vacation', 'family' => 'vacation', 'maternity' => 'vacation', 'parental' => 'vacation',
'business_trip' => 'businessTrip', 'remote' => 'remote', 'field_work' => 'fieldWork',
'early_leave' => null,
'late_reason' => null,
'absent_reason' => null,
];
public const STATUSES = [
@@ -253,6 +304,12 @@ public function getLeaveTypeLabelAttribute(): string
self::TYPE_FAMILY => '경조사',
self::TYPE_MATERNITY => '출산휴가',
self::TYPE_PARENTAL => '육아휴직',
self::TYPE_BUSINESS_TRIP => '출장',
self::TYPE_REMOTE => '재택근무',
self::TYPE_FIELD_WORK => '외근',
self::TYPE_EARLY_LEAVE => '조퇴',
self::TYPE_LATE_REASON => '지각사유서',
self::TYPE_ABSENT_REASON => '결근사유서',
default => $this->leave_type,
};
}

View File

@@ -0,0 +1,59 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
// 근태신청 결재 양식 (출장/재택/외근/조퇴)
DB::table('approval_forms')->insertOrIgnore([
'tenant_id' => 1,
'name' => '근태신청',
'code' => 'attendance_request',
'category' => 'request',
'template' => json_encode([
'fields' => [
['name' => 'user_name', 'type' => 'text', 'label' => '신청자'],
['name' => 'request_type', 'type' => 'text', 'label' => '신청유형'],
['name' => 'period', 'type' => 'text', 'label' => '기간'],
['name' => 'days', 'type' => 'number', 'label' => '일수'],
['name' => 'reason', 'type' => 'text', 'label' => '사유'],
],
], JSON_UNESCAPED_UNICODE),
'is_active' => true,
'created_by' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
// 사유서 결재 양식 (지각사유서/결근사유서)
DB::table('approval_forms')->insertOrIgnore([
'tenant_id' => 1,
'name' => '사유서',
'code' => 'reason_report',
'category' => 'request',
'template' => json_encode([
'fields' => [
['name' => 'user_name', 'type' => 'text', 'label' => '신청자'],
['name' => 'report_type', 'type' => 'text', 'label' => '사유서유형'],
['name' => 'target_date', 'type' => 'date', 'label' => '대상일'],
['name' => 'reason', 'type' => 'text', 'label' => '사유'],
],
], JSON_UNESCAPED_UNICODE),
'is_active' => true,
'created_by' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
}
public function down(): void
{
DB::table('approval_forms')
->where('tenant_id', 1)
->whereIn('code', ['attendance_request', 'reason_report'])
->delete();
}
};