Attainly/backend/app/Schedule/EloquentScheduleRepository.php

115 lines
3.5 KiB
PHP

<?php
namespace App\Schedule;
use App\Element\ElementRepository;
use App\Set\SetRepository;
use App\User\User;
use DateTimeImmutable;
use DateTimeZone;
use Illuminate\Support\Facades\DB;
use RuntimeException;
class EloquentScheduleRepository implements ScheduleRepository
{
public function __construct(
private SetRepository $setRepository,
private ElementRepository $elementRepository,
) {}
public function create(CreateScheduleDto $dto): Schedule
{
return DB::transaction(function () use ($dto): Schedule {
$model = ScheduleModel::create([
'user_id' => $dto->user->getId(),
'set_id' => $dto->set->getId(),
'element_kind' => $dto->elementKind,
'start_date' => $dto->startDate->format('Y-m-d'),
'target_date' => $dto->targetDate->format('Y-m-d'),
]);
foreach ($dto->assignments as $assignmentDto) {
ScheduleAssignmentModel::create([
'schedule_id' => $model->id,
'element_id' => $assignmentDto->element->getId(),
'scheduled_date' => $assignmentDto->scheduledDate
->format('Y-m-d'),
'position' => $assignmentDto->position,
]);
}
return $this->toDomain($model, $dto->user);
});
}
public function findForUser(int $id, User $user): ?Schedule
{
$model = ScheduleModel::query()
->where('id', $id)
->where('user_id', $user->getId())
->first();
return $model === null ? null : $this->toDomain($model, $user);
}
public function findAllForUser(User $user): array
{
$models = ScheduleModel::query()
->where('user_id', $user->getId())
->orderByDesc('id')
->get();
$schedules = [];
foreach ($models as $model) {
$schedules[] = $this->toDomain($model, $user);
}
return $schedules;
}
private function toDomain(ScheduleModel $model, User $user): Schedule
{
$set = $this->setRepository->find($model->set_id);
if ($set === null) {
throw new RuntimeException('schedule set not found');
}
$assignmentModels = ScheduleAssignmentModel::query()
->where('schedule_id', $model->id)
->orderBy('position')
->orderBy('id')
->get();
$assignments = [];
foreach ($assignmentModels as $assignmentModel) {
$element = $this->elementRepository->find(
$assignmentModel->element_id,
);
if ($element === null) {
throw new RuntimeException('schedule element not found');
}
$assignments[] = new ScheduleAssignment(
id: $assignmentModel->id,
element: $element,
scheduledDate: $this->date($assignmentModel->scheduled_date),
position: $assignmentModel->position,
);
}
return new Schedule(
id: $model->id,
user: $user,
set: $set,
elementKind: $model->element_kind,
startDate: $this->date($model->start_date),
targetDate: $this->date($model->target_date),
assignments: $assignments,
);
}
private function date(string $value): DateTimeImmutable
{
return new DateTimeImmutable($value, new DateTimeZone('UTC'));
}
}