initial
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
use Reservair\Logger\Logger;
|
||||
|
||||
class RsvTimetableService {
|
||||
private RsvTimetableRepository $repo;
|
||||
|
||||
public function __construct() {
|
||||
$this->repo = new RsvTimetableRepository();
|
||||
}
|
||||
|
||||
public function get_all(?int $limit = null, int $skip = 0): array {
|
||||
return $this->repo->get_all($limit, $skip);
|
||||
}
|
||||
|
||||
public function count_all(): int {
|
||||
return $this->repo->count_all();
|
||||
}
|
||||
|
||||
public function get(int $id): ?RsvTimetable {
|
||||
return $this->repo->get($id);
|
||||
}
|
||||
|
||||
public function create(RsvTimetable $timetable): int {
|
||||
return $this->repo->create($timetable);
|
||||
}
|
||||
|
||||
public function update(int $id, RsvTimetable $timetable): int {
|
||||
return $this->repo->update($id, $timetable);
|
||||
}
|
||||
|
||||
public function get_all_maintainer_emails(): array {
|
||||
return $this->repo->get_all_maintainer_emails();
|
||||
}
|
||||
|
||||
public function set_google_calendar_id(int $id, ?string $calendar_id): void {
|
||||
$this->repo->set_google_calendar_id($id, $calendar_id);
|
||||
}
|
||||
|
||||
public function delete(int $id): int {
|
||||
Logger::info('Deleting timetable: ' . $id);
|
||||
return $this->repo->delete($id);
|
||||
}
|
||||
|
||||
private function datetime_to_minutes(DateTime $dt): int {
|
||||
$d = $dt->setTimezone(wp_timezone());
|
||||
return (int) $d->format('G') * 60 + (int) $d->format('i');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int,RsvTimetableAvailability> Availability on date
|
||||
*/
|
||||
public function get_availability_on_date(int $timetable_id, int $block_length, DateTime $date) : array {
|
||||
/**
|
||||
* Get available seats for the given date
|
||||
* Keeps two stacks: capacities & reservations
|
||||
*
|
||||
* Goes from left to right in reservations and pushes to stack
|
||||
*/
|
||||
$capacities = (new RsvTimetableCapacityRepository())->get_capacities_for_date($timetable_id, $date);
|
||||
$reservations = (new RsvTimetableReservationService())->get_reservations_on_date($timetable_id, $date);
|
||||
|
||||
$capacity_stack = [];
|
||||
$reservation_stack = [];
|
||||
|
||||
$capacity_index = 0;
|
||||
$reservation_index = 0;
|
||||
|
||||
$blocks_count = 24 * 60 / $block_length;
|
||||
$blocks = array_fill(0, $blocks_count, 0);
|
||||
|
||||
$availabilities = [];
|
||||
$availability_idx = 0;
|
||||
|
||||
for($i = 0; $i < $blocks_count; $i++) {
|
||||
$reservation_stack = array_filter($reservation_stack, fn($reservation) =>
|
||||
$this->datetime_to_minutes($reservation->end_utc) > $i * $block_length
|
||||
);
|
||||
|
||||
$capacity_stack = array_filter($capacity_stack, fn($capacity) =>
|
||||
$capacity->end_time > $i * $block_length
|
||||
);
|
||||
|
||||
while($reservation_index < count($reservations) && $this->datetime_to_minutes($reservations[$reservation_index]->start_utc) <= $i * $block_length) {
|
||||
$reservation_stack[] = $reservations[$reservation_index];
|
||||
$reservation_index++;
|
||||
}
|
||||
|
||||
while($capacity_index < count($capacities) && $capacities[$capacity_index]->start_time <= $i * $block_length) {
|
||||
$capacity_stack[] = $capacities[$capacity_index];
|
||||
$capacity_index++;
|
||||
}
|
||||
|
||||
$total_capacity = array_sum(array_map(fn($x) => $x->capacity, $capacity_stack));
|
||||
|
||||
if ($total_capacity > 0) {
|
||||
if(count($availabilities) === $availability_idx) {
|
||||
$availabilities[] = new RsvTimetableAvailability($i * $block_length, ($i + 1) * $block_length, $block_length, []);
|
||||
}
|
||||
|
||||
$availabilities[$availability_idx]->push_block($total_capacity - count($reservation_stack));
|
||||
} else if($total_capacity === 0 && count($availabilities) !== $availability_idx) {
|
||||
$availability_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
return $availabilities;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user