275 lines
8.4 KiB
PHP
275 lines
8.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Exceptions\BadRequestException;
|
|
use App\Exceptions\NotFoundException;
|
|
use App\Schedule\AssignmentForDate;
|
|
use App\Schedule\Schedule;
|
|
use App\Schedule\ScheduleAssignment;
|
|
use App\Schedule\UseCases\CreateSchedule\CreateSchedule;
|
|
use App\Schedule\UseCases\CreateSchedule\CreateScheduleRequest;
|
|
use App\Schedule\UseCases\GetSchedule\GetSchedule;
|
|
use App\Schedule\UseCases\GetSchedule\GetScheduleRequest;
|
|
use App\Schedule\UseCases\ListSchedules\ListSchedules;
|
|
use App\Schedule\UseCases\ListAssignmentsForDate\ListAssignmentsForDate;
|
|
use App\Schedule\UseCases\ListAssignmentsForDate\ListAssignmentsForDateRequest;
|
|
use App\Schedule\UseCases\SetAssignmentCompletion\SetAssignmentCompletion;
|
|
use App\Schedule\UseCases\SetAssignmentCompletion\SetAssignmentCompletionRequest;
|
|
use App\Shared\Http\RequestInput;
|
|
use App\User\User;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class ScheduleController extends Controller
|
|
{
|
|
public function __construct(
|
|
private CreateSchedule $createSchedule,
|
|
private ListSchedules $listSchedules,
|
|
private GetSchedule $getSchedule,
|
|
private ListAssignmentsForDate $listAssignmentsForDate,
|
|
private SetAssignmentCompletion $setAssignmentCompletion,
|
|
) {}
|
|
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$input = new RequestInput($request);
|
|
$user = $this->user($request);
|
|
|
|
try {
|
|
$schedule = $this->createSchedule->execute(
|
|
new CreateScheduleRequest(
|
|
user: $user,
|
|
setId: $input->integer('setId'),
|
|
levelId: $input->integer('levelId'),
|
|
startDate: $input->string('startDate'),
|
|
targetDate: $input->string('targetDate'),
|
|
),
|
|
);
|
|
} catch (BadRequestException $exception) {
|
|
return new JsonResponse(
|
|
['error' => $exception->getMessage()],
|
|
400,
|
|
);
|
|
} catch (NotFoundException $exception) {
|
|
return new JsonResponse(
|
|
['error' => $exception->getMessage()],
|
|
404,
|
|
);
|
|
}
|
|
|
|
return new JsonResponse(
|
|
['schedule' => $this->detailPayload($schedule)],
|
|
201,
|
|
);
|
|
}
|
|
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$schedules = array_map(
|
|
function (Schedule $schedule): array {
|
|
return $this->summaryPayload($schedule);
|
|
},
|
|
$this->listSchedules->execute($this->user($request)),
|
|
);
|
|
|
|
return new JsonResponse(['schedules' => $schedules]);
|
|
}
|
|
|
|
public function show(Request $request, int $scheduleId): JsonResponse
|
|
{
|
|
try {
|
|
$schedule = $this->getSchedule->execute(
|
|
new GetScheduleRequest(
|
|
scheduleId: $scheduleId,
|
|
user: $this->user($request),
|
|
),
|
|
);
|
|
} catch (NotFoundException $exception) {
|
|
return new JsonResponse(
|
|
['error' => $exception->getMessage()],
|
|
404,
|
|
);
|
|
}
|
|
|
|
return new JsonResponse([
|
|
'schedule' => $this->detailPayload($schedule),
|
|
]);
|
|
}
|
|
|
|
public function assignments(Request $request): JsonResponse
|
|
{
|
|
$input = new RequestInput($request);
|
|
$date = $input->string('date');
|
|
|
|
try {
|
|
$assignments = $this->listAssignmentsForDate->execute(
|
|
new ListAssignmentsForDateRequest(
|
|
user: $this->user($request),
|
|
date: $date,
|
|
),
|
|
);
|
|
} catch (BadRequestException $exception) {
|
|
return new JsonResponse(
|
|
['error' => $exception->getMessage()],
|
|
400,
|
|
);
|
|
}
|
|
|
|
return new JsonResponse([
|
|
'date' => $date,
|
|
'assignments' => array_map(
|
|
function (AssignmentForDate $assignment): array {
|
|
return $this->assignmentForDatePayload($assignment);
|
|
},
|
|
$assignments,
|
|
),
|
|
]);
|
|
}
|
|
|
|
public function updateAssignment(
|
|
Request $request,
|
|
int $assignmentId,
|
|
): JsonResponse {
|
|
$input = new RequestInput($request);
|
|
|
|
try {
|
|
$assignment = $this->setAssignmentCompletion->execute(
|
|
new SetAssignmentCompletionRequest(
|
|
assignmentId: $assignmentId,
|
|
user: $this->user($request),
|
|
completed: $input->boolean('completed'),
|
|
),
|
|
);
|
|
} catch (BadRequestException $exception) {
|
|
return new JsonResponse(
|
|
['error' => $exception->getMessage()],
|
|
400,
|
|
);
|
|
} catch (NotFoundException $exception) {
|
|
return new JsonResponse(
|
|
['error' => $exception->getMessage()],
|
|
404,
|
|
);
|
|
}
|
|
|
|
return new JsonResponse([
|
|
'assignment' => [
|
|
'id' => $assignment->getId(),
|
|
'completedAt' => $assignment->getCompletedAt()
|
|
?->format(DATE_ATOM),
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function summaryPayload(Schedule $schedule): array
|
|
{
|
|
return [
|
|
'id' => $schedule->getId(),
|
|
'set' => [
|
|
'name' => $schedule->getSetName(),
|
|
],
|
|
'elementKind' => $schedule->getElementKind(),
|
|
'startDate' => $schedule->getStartDate()->format('Y-m-d'),
|
|
'targetDate' => $schedule->getTargetDate()->format('Y-m-d'),
|
|
'assignmentCount' => count($schedule->getAssignments()),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function detailPayload(Schedule $schedule): array
|
|
{
|
|
$payload = $this->summaryPayload($schedule);
|
|
$payload['days'] = $this->dayPayloads($schedule);
|
|
|
|
return $payload;
|
|
}
|
|
|
|
/**
|
|
* @return list<array{date: string, assignments: list<mixed>}>
|
|
*/
|
|
private function dayPayloads(Schedule $schedule): array
|
|
{
|
|
$assignmentsByDate = [];
|
|
foreach ($schedule->getAssignments() as $assignment) {
|
|
$date = $assignment->getScheduledDate()->format('Y-m-d');
|
|
$assignmentsByDate[$date][] = $this->assignmentPayload(
|
|
$assignment,
|
|
);
|
|
}
|
|
|
|
$days = [];
|
|
$date = $schedule->getStartDate();
|
|
while ($date <= $schedule->getTargetDate()) {
|
|
$formattedDate = $date->format('Y-m-d');
|
|
$days[] = [
|
|
'date' => $formattedDate,
|
|
'assignments' => $assignmentsByDate[$formattedDate] ?? [],
|
|
];
|
|
$date = $date->modify('+1 day');
|
|
}
|
|
|
|
return $days;
|
|
}
|
|
|
|
/**
|
|
* @return array{id: int, completedAt: string|null, element: array{
|
|
* name: string,
|
|
* kind: string,
|
|
* path: list<string>
|
|
* }}
|
|
*/
|
|
private function assignmentPayload(
|
|
ScheduleAssignment $assignment,
|
|
): array {
|
|
return [
|
|
'id' => $assignment->getId(),
|
|
'completedAt' => $assignment->getCompletedAt()
|
|
?->format(DATE_ATOM),
|
|
'element' => [
|
|
'name' => $assignment->getName(),
|
|
'kind' => $assignment->getKind(),
|
|
'path' => $assignment->getPath(),
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private function assignmentForDatePayload(
|
|
AssignmentForDate $assignmentForDate,
|
|
): array {
|
|
$assignment = $assignmentForDate->getAssignment();
|
|
|
|
return [
|
|
'id' => $assignment->getId(),
|
|
'scheduledDate' => $assignment->getScheduledDate()
|
|
->format('Y-m-d'),
|
|
'schedule' => [
|
|
'id' => $assignmentForDate->getScheduleId(),
|
|
'set' => [
|
|
'name' => $assignmentForDate->getSetName(),
|
|
],
|
|
],
|
|
'element' => [
|
|
'name' => $assignment->getName(),
|
|
'kind' => $assignment->getKind(),
|
|
'path' => $assignment->getPath(),
|
|
],
|
|
];
|
|
}
|
|
|
|
private function user(Request $request): User
|
|
{
|
|
/** @var User $user */
|
|
$user = $request->attributes->get('user');
|
|
|
|
return $user;
|
|
}
|
|
}
|