Files
sam-manage/app/Enums/InspectionCycle.php
김보곤 ba792a0fcc fix: [equipment] 점검표 휴일 표시 및 주간 1주 저장 버그 수정
- 점검 그리드에 holidays 테이블 기반 휴일 표시 (빨간 배경)
- 휴일/주말 셀 클릭 차단 (UI + 서버 양쪽)
- 자동 판정에서 휴일 제외 (기존 주말만 제외 → 주말+휴일)
- 주간 1주 열 저장 누락 수정 (resolvePeriod에서 isoWeekYear 사용)
- toggleDetail, setResult에 비근무일 검증 추가
- 범례에 '휴일/주말 (점검 불가)' 안내 추가
2026-02-28 15:30:11 +09:00

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');
}
}