181 lines
5.1 KiB
PHP
181 lines
5.1 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Services;
|
||
|
|
|
||
|
|
use App\Models\Commons\Holiday;
|
||
|
|
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||
|
|
|
||
|
|
class CalendarScheduleService extends Service
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 연도별 일정 목록 조회
|
||
|
|
*/
|
||
|
|
public function list(int $year, ?string $type = null): array
|
||
|
|
{
|
||
|
|
$query = Holiday::forTenant($this->tenantId())
|
||
|
|
->forYear($year)
|
||
|
|
->orderBy('start_date');
|
||
|
|
|
||
|
|
if ($type) {
|
||
|
|
$query->where('type', $type);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->get()->map(function ($h) {
|
||
|
|
return [
|
||
|
|
'id' => $h->id,
|
||
|
|
'name' => $h->name,
|
||
|
|
'type' => $h->type,
|
||
|
|
'start_date' => $h->start_date->format('Y-m-d'),
|
||
|
|
'end_date' => $h->end_date->format('Y-m-d'),
|
||
|
|
'days' => $h->start_date->diffInDays($h->end_date) + 1,
|
||
|
|
'is_recurring' => $h->is_recurring,
|
||
|
|
'memo' => $h->memo,
|
||
|
|
'created_at' => $h->created_at?->toIso8601String(),
|
||
|
|
'updated_at' => $h->updated_at?->toIso8601String(),
|
||
|
|
];
|
||
|
|
})->all();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 통계 조회
|
||
|
|
*/
|
||
|
|
public function stats(int $year): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
$holidays = Holiday::forTenant($tenantId)->forYear($year)->get();
|
||
|
|
|
||
|
|
$totalDays = $holidays->sum(function ($h) {
|
||
|
|
return $h->start_date->diffInDays($h->end_date) + 1;
|
||
|
|
});
|
||
|
|
|
||
|
|
return [
|
||
|
|
'total_count' => $holidays->count(),
|
||
|
|
'total_holiday_days' => $totalDays,
|
||
|
|
'public_holiday_count' => $holidays->where('type', 'public_holiday')->count(),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 단건 조회
|
||
|
|
*/
|
||
|
|
public function show(int $id): array
|
||
|
|
{
|
||
|
|
$h = Holiday::forTenant($this->tenantId())->findOrFail($id);
|
||
|
|
|
||
|
|
return [
|
||
|
|
'id' => $h->id,
|
||
|
|
'name' => $h->name,
|
||
|
|
'type' => $h->type,
|
||
|
|
'start_date' => $h->start_date->format('Y-m-d'),
|
||
|
|
'end_date' => $h->end_date->format('Y-m-d'),
|
||
|
|
'days' => $h->start_date->diffInDays($h->end_date) + 1,
|
||
|
|
'is_recurring' => $h->is_recurring,
|
||
|
|
'memo' => $h->memo,
|
||
|
|
'created_at' => $h->created_at?->toIso8601String(),
|
||
|
|
'updated_at' => $h->updated_at?->toIso8601String(),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 등록
|
||
|
|
*/
|
||
|
|
public function store(array $data): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
|
||
|
|
$exists = Holiday::forTenant($tenantId)
|
||
|
|
->where('start_date', $data['start_date'])
|
||
|
|
->where('end_date', $data['end_date'])
|
||
|
|
->where('name', $data['name'])
|
||
|
|
->exists();
|
||
|
|
|
||
|
|
if ($exists) {
|
||
|
|
throw new HttpException(422, __('error.duplicate'));
|
||
|
|
}
|
||
|
|
|
||
|
|
$holiday = Holiday::create([
|
||
|
|
'tenant_id' => $tenantId,
|
||
|
|
'start_date' => $data['start_date'],
|
||
|
|
'end_date' => $data['end_date'],
|
||
|
|
'name' => $data['name'],
|
||
|
|
'type' => $data['type'] ?? 'public_holiday',
|
||
|
|
'is_recurring' => $data['is_recurring'] ?? false,
|
||
|
|
'memo' => $data['memo'] ?? null,
|
||
|
|
'created_by' => $this->apiUserId(),
|
||
|
|
]);
|
||
|
|
|
||
|
|
return $this->show($holiday->id);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 수정
|
||
|
|
*/
|
||
|
|
public function update(int $id, array $data): array
|
||
|
|
{
|
||
|
|
$holiday = Holiday::forTenant($this->tenantId())->findOrFail($id);
|
||
|
|
|
||
|
|
$holiday->update([
|
||
|
|
'start_date' => $data['start_date'],
|
||
|
|
'end_date' => $data['end_date'],
|
||
|
|
'name' => $data['name'],
|
||
|
|
'type' => $data['type'],
|
||
|
|
'is_recurring' => $data['is_recurring'] ?? false,
|
||
|
|
'memo' => $data['memo'] ?? null,
|
||
|
|
'updated_by' => $this->apiUserId(),
|
||
|
|
]);
|
||
|
|
|
||
|
|
return $this->show($id);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 삭제
|
||
|
|
*/
|
||
|
|
public function delete(int $id): void
|
||
|
|
{
|
||
|
|
$holiday = Holiday::forTenant($this->tenantId())->findOrFail($id);
|
||
|
|
$holiday->delete();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 대량 등록
|
||
|
|
*/
|
||
|
|
public function bulkStore(array $schedules): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
$userId = $this->apiUserId();
|
||
|
|
$count = 0;
|
||
|
|
$skipped = 0;
|
||
|
|
|
||
|
|
foreach ($schedules as $item) {
|
||
|
|
$exists = Holiday::forTenant($tenantId)
|
||
|
|
->where('start_date', $item['start_date'])
|
||
|
|
->where('end_date', $item['end_date'])
|
||
|
|
->where('name', $item['name'])
|
||
|
|
->exists();
|
||
|
|
|
||
|
|
if ($exists) {
|
||
|
|
$skipped++;
|
||
|
|
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
Holiday::create([
|
||
|
|
'tenant_id' => $tenantId,
|
||
|
|
'start_date' => $item['start_date'],
|
||
|
|
'end_date' => $item['end_date'],
|
||
|
|
'name' => $item['name'],
|
||
|
|
'type' => $item['type'] ?? 'public_holiday',
|
||
|
|
'is_recurring' => $item['is_recurring'] ?? false,
|
||
|
|
'memo' => $item['memo'] ?? null,
|
||
|
|
'created_by' => $userId,
|
||
|
|
]);
|
||
|
|
$count++;
|
||
|
|
}
|
||
|
|
|
||
|
|
return [
|
||
|
|
'created' => $count,
|
||
|
|
'skipped' => $skipped,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|