- 점검 그리드에 holidays 테이블 기반 휴일 표시 (빨간 배경) - 휴일/주말 셀 클릭 차단 (UI + 서버 양쪽) - 자동 판정에서 휴일 제외 (기존 주말만 제외 → 주말+휴일) - 주간 1주 열 저장 누락 수정 (resolvePeriod에서 isoWeekYear 사용) - toggleDetail, setResult에 비근무일 검증 추가 - 범례에 '휴일/주말 (점검 불가)' 안내 추가
267 lines
7.3 KiB
PHP
267 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Enums;
|
|
|
|
use Carbon\Carbon;
|
|
|
|
class InspectionCycle
|
|
{
|
|
const DAILY = 'daily';
|
|
|
|
const WEEKLY = 'weekly';
|
|
|
|
const MONTHLY = 'monthly';
|
|
|
|
const BIMONTHLY = 'bimonthly';
|
|
|
|
const QUARTERLY = 'quarterly';
|
|
|
|
const SEMIANNUAL = 'semiannual';
|
|
|
|
/**
|
|
* 전체 주기 목록 (코드 → 라벨)
|
|
*/
|
|
public static function all(): array
|
|
{
|
|
return [
|
|
self::DAILY => '일일',
|
|
self::WEEKLY => '주간',
|
|
self::MONTHLY => '월간',
|
|
self::BIMONTHLY => '2개월',
|
|
self::QUARTERLY => '분기',
|
|
self::SEMIANNUAL => '반년',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 주기별 라벨 반환
|
|
*/
|
|
public static function label(string $cycle): string
|
|
{
|
|
return self::all()[$cycle] ?? $cycle;
|
|
}
|
|
|
|
/**
|
|
* 주기별 기간 필터 타입 반환
|
|
*/
|
|
public static function periodType(string $cycle): string
|
|
{
|
|
return $cycle === self::DAILY ? 'month' : 'year';
|
|
}
|
|
|
|
/**
|
|
* 주기별 그리드 열 라벨 반환
|
|
*
|
|
* @return array<int, string> [colIndex => label]
|
|
*/
|
|
public static function columnLabels(string $cycle, ?string $period = null): array
|
|
{
|
|
return match ($cycle) {
|
|
self::DAILY => self::dailyLabels($period),
|
|
self::WEEKLY => self::weeklyLabels(),
|
|
self::MONTHLY => self::monthlyLabels(),
|
|
self::BIMONTHLY => self::bimonthlyLabels(),
|
|
self::QUARTERLY => self::quarterlyLabels(),
|
|
self::SEMIANNUAL => self::semiannualLabels(),
|
|
default => self::dailyLabels($period),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 열 인덱스 → check_date 변환
|
|
*/
|
|
public static function resolveCheckDate(string $cycle, string $period, int $colIndex): string
|
|
{
|
|
return match ($cycle) {
|
|
self::DAILY => self::dailyCheckDate($period, $colIndex),
|
|
self::WEEKLY => self::weeklyCheckDate($period, $colIndex),
|
|
self::MONTHLY => self::monthlyCheckDate($period, $colIndex),
|
|
self::BIMONTHLY => self::bimonthlyCheckDate($period, $colIndex),
|
|
self::QUARTERLY => self::quarterlyCheckDate($period, $colIndex),
|
|
self::SEMIANNUAL => self::semiannualCheckDate($period, $colIndex),
|
|
default => self::dailyCheckDate($period, $colIndex),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* check_date → year_month(period) 역산
|
|
*/
|
|
public static function resolvePeriod(string $cycle, string $checkDate): string
|
|
{
|
|
$date = Carbon::parse($checkDate);
|
|
|
|
return match ($cycle) {
|
|
self::DAILY => $date->format('Y-m'),
|
|
self::WEEKLY => (string) $date->isoWeekYear,
|
|
default => $date->format('Y'),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 주기별 그리드 열 수
|
|
*/
|
|
public static function columnCount(string $cycle, ?string $period = null): int
|
|
{
|
|
return count(self::columnLabels($cycle, $period));
|
|
}
|
|
|
|
/**
|
|
* 주말 여부 (daily 전용)
|
|
*/
|
|
public static function isWeekend(string $period, int $colIndex): bool
|
|
{
|
|
$date = Carbon::createFromFormat('Y-m', $period)->startOfMonth()->addDays($colIndex - 1);
|
|
|
|
return in_array($date->dayOfWeek, [0, 6]);
|
|
}
|
|
|
|
/**
|
|
* 해당 기간의 휴일 날짜 목록 반환 (date string Set)
|
|
*/
|
|
public static function getHolidayDates(string $cycle, string $period): array
|
|
{
|
|
$tenantId = session('selected_tenant_id', 1);
|
|
|
|
if ($cycle === self::DAILY) {
|
|
$start = Carbon::createFromFormat('Y-m', $period)->startOfMonth();
|
|
$end = $start->copy()->endOfMonth();
|
|
} else {
|
|
$start = Carbon::create((int) $period, 1, 1);
|
|
$end = Carbon::create((int) $period, 12, 31);
|
|
}
|
|
|
|
$holidays = \App\Models\System\Holiday::where('tenant_id', $tenantId)
|
|
->where('start_date', '<=', $end->toDateString())
|
|
->where('end_date', '>=', $start->toDateString())
|
|
->get();
|
|
|
|
$dates = [];
|
|
foreach ($holidays as $holiday) {
|
|
$hStart = $holiday->start_date->copy()->max($start);
|
|
$hEnd = $holiday->end_date->copy()->min($end);
|
|
$current = $hStart->copy();
|
|
while ($current->lte($hEnd)) {
|
|
$dates[$current->format('Y-m-d')] = true;
|
|
$current->addDay();
|
|
}
|
|
}
|
|
|
|
return $dates;
|
|
}
|
|
|
|
/**
|
|
* 비근무일 여부 (주말 또는 휴일)
|
|
*/
|
|
public static function isNonWorkingDay(string $checkDate, array $holidayDates = []): bool
|
|
{
|
|
$date = Carbon::parse($checkDate);
|
|
|
|
return $date->isWeekend() || isset($holidayDates[$checkDate]);
|
|
}
|
|
|
|
// --- Daily ---
|
|
private static function dailyLabels(?string $period): array
|
|
{
|
|
$date = Carbon::createFromFormat('Y-m', $period ?? now()->format('Y-m'));
|
|
$days = $date->daysInMonth;
|
|
$labels = [];
|
|
for ($d = 1; $d <= $days; $d++) {
|
|
$labels[$d] = (string) $d;
|
|
}
|
|
|
|
return $labels;
|
|
}
|
|
|
|
private static function dailyCheckDate(string $period, int $colIndex): string
|
|
{
|
|
return Carbon::createFromFormat('Y-m', $period)->startOfMonth()->addDays($colIndex - 1)->format('Y-m-d');
|
|
}
|
|
|
|
// --- Weekly ---
|
|
private static function weeklyLabels(): array
|
|
{
|
|
$labels = [];
|
|
for ($w = 1; $w <= 52; $w++) {
|
|
$labels[$w] = $w.'주';
|
|
}
|
|
|
|
return $labels;
|
|
}
|
|
|
|
private static function weeklyCheckDate(string $year, int $colIndex): string
|
|
{
|
|
// ISO 주차의 월요일
|
|
return Carbon::create((int) $year)->setISODate((int) $year, $colIndex, 1)->format('Y-m-d');
|
|
}
|
|
|
|
// --- Monthly ---
|
|
private static function monthlyLabels(): array
|
|
{
|
|
$labels = [];
|
|
for ($m = 1; $m <= 12; $m++) {
|
|
$labels[$m] = $m.'월';
|
|
}
|
|
|
|
return $labels;
|
|
}
|
|
|
|
private static function monthlyCheckDate(string $year, int $colIndex): string
|
|
{
|
|
return Carbon::create((int) $year, $colIndex, 1)->format('Y-m-d');
|
|
}
|
|
|
|
// --- Bimonthly ---
|
|
private static function bimonthlyLabels(): array
|
|
{
|
|
return [
|
|
1 => '1~2월',
|
|
2 => '3~4월',
|
|
3 => '5~6월',
|
|
4 => '7~8월',
|
|
5 => '9~10월',
|
|
6 => '11~12월',
|
|
];
|
|
}
|
|
|
|
private static function bimonthlyCheckDate(string $year, int $colIndex): string
|
|
{
|
|
$month = ($colIndex - 1) * 2 + 1;
|
|
|
|
return Carbon::create((int) $year, $month, 1)->format('Y-m-d');
|
|
}
|
|
|
|
// --- Quarterly ---
|
|
private static function quarterlyLabels(): array
|
|
{
|
|
return [
|
|
1 => '1분기',
|
|
2 => '2분기',
|
|
3 => '3분기',
|
|
4 => '4분기',
|
|
];
|
|
}
|
|
|
|
private static function quarterlyCheckDate(string $year, int $colIndex): string
|
|
{
|
|
$month = ($colIndex - 1) * 3 + 1;
|
|
|
|
return Carbon::create((int) $year, $month, 1)->format('Y-m-d');
|
|
}
|
|
|
|
// --- Semiannual ---
|
|
private static function semiannualLabels(): array
|
|
{
|
|
return [
|
|
1 => '상반기',
|
|
2 => '하반기',
|
|
];
|
|
}
|
|
|
|
private static function semiannualCheckDate(string $year, int $colIndex): string
|
|
{
|
|
$month = $colIndex === 1 ? 1 : 7;
|
|
|
|
return Carbon::create((int) $year, $month, 1)->format('Y-m-d');
|
|
}
|
|
}
|