Files
sam-api/app/Models/Tenants/WorkSetting.php

170 lines
4.7 KiB
PHP
Raw Normal View History

<?php
namespace App\Models\Tenants;
use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
/**
* 근무 설정 모델
*
* @property int $id
* @property int $tenant_id
* @property string $work_type
* @property int $standard_hours
* @property int $overtime_hours
* @property int $overtime_limit
* @property array|null $work_days
* @property string $start_time
* @property string $end_time
* @property int $break_minutes
* @property string|null $break_start
* @property string|null $break_end
*/
class WorkSetting extends Model
{
use BelongsToTenant;
protected $table = 'work_settings';
protected $fillable = [
'tenant_id',
'work_type',
'standard_hours',
'overtime_hours',
'overtime_limit',
'work_days',
'start_time',
'end_time',
'break_minutes',
'break_start',
'break_end',
];
protected $casts = [
// work_days는 Attribute accessor에서 처리
'standard_hours' => 'integer',
'overtime_hours' => 'integer',
'overtime_limit' => 'integer',
'break_minutes' => 'integer',
];
protected $attributes = [
'work_type' => 'fixed',
'standard_hours' => 40,
'overtime_hours' => 12,
'overtime_limit' => 52,
'start_time' => '09:00:00',
'end_time' => '18:00:00',
'break_minutes' => 60,
'break_start' => '12:00:00',
'break_end' => '13:00:00',
];
// =========================================================================
// 상수 정의
// =========================================================================
public const TYPE_FIXED = 'fixed'; // 고정 근무
public const TYPE_FLEXIBLE = 'flexible'; // 유연 근무
public const TYPE_CUSTOM = 'custom'; // 커스텀 근무
public const WORK_TYPES = [
self::TYPE_FIXED,
self::TYPE_FLEXIBLE,
self::TYPE_CUSTOM,
];
public const DEFAULT_WORK_DAYS = ['mon', 'tue', 'wed', 'thu', 'fri'];
/**
* 숫자 요일 문자열 매핑
*/
public const DAY_INDEX_MAP = [
1 => 'mon',
2 => 'tue',
3 => 'wed',
4 => 'thu',
5 => 'fri',
6 => 'sat',
7 => 'sun',
0 => 'sun', // 일요일이 0인 경우도 처리
];
// =========================================================================
// Accessors & Mutators
// =========================================================================
/**
* work_days 조회 숫자를 문자열로 변환
*/
protected function workDays(): \Illuminate\Database\Eloquent\Casts\Attribute
{
return \Illuminate\Database\Eloquent\Casts\Attribute::make(
get: function ($value) {
$days = is_string($value) ? json_decode($value, true) : $value;
if (! is_array($days)) {
return self::DEFAULT_WORK_DAYS;
}
// 숫자가 포함된 경우 문자열로 변환
return array_values(array_unique(array_map(function ($day) {
if (is_int($day) || is_numeric($day)) {
return self::DAY_INDEX_MAP[(int) $day] ?? 'mon';
}
return $day;
}, $days)));
},
set: function ($value) {
if (! is_array($value)) {
return json_encode(self::DEFAULT_WORK_DAYS);
}
// 항상 문자열 배열로 저장
$days = array_values(array_unique(array_map(function ($day) {
if (is_int($day) || is_numeric($day)) {
return self::DAY_INDEX_MAP[(int) $day] ?? 'mon';
}
return $day;
}, $value)));
return json_encode($days);
}
);
}
// =========================================================================
// 헬퍼 메서드
// =========================================================================
/**
* 근무 유형 라벨
*/
public function getWorkTypeLabelAttribute(): string
{
return match ($this->work_type) {
self::TYPE_FIXED => '고정근무',
self::TYPE_FLEXIBLE => '유연근무',
self::TYPE_CUSTOM => '커스텀',
default => $this->work_type,
};
}
/**
* 일일 근무시간 계산 ()
*/
public function getDailyWorkMinutesAttribute(): int
{
$start = strtotime($this->start_time);
$end = strtotime($this->end_time);
$totalMinutes = ($end - $start) / 60;
return (int) ($totalMinutes - $this->break_minutes);
}
}