diff --git a/lbplanner/classes/helpers/slot_helper.php b/lbplanner/classes/helpers/slot_helper.php index 70a52e98..bde076f7 100644 --- a/lbplanner/classes/helpers/slot_helper.php +++ b/lbplanner/classes/helpers/slot_helper.php @@ -283,9 +283,11 @@ public static function get_reservations_for_user(int $userid): array { public static function filter_reservations_for_recency(array $reservations): array { $sentryspan = sentry_helper::span_start(__FUNCTION__, ['count_in' => count($reservations)]); + $now = new DateTimeImmutable('now', new DateTimeZone('UTC')); + $goodeggs = []; foreach ($reservations as $reservation) { - if (!$reservation->is_outdated()) { + if (!$reservation->is_endpast($now)) { array_push($goodeggs, $reservation); } } diff --git a/lbplanner/classes/model/reservation.php b/lbplanner/classes/model/reservation.php index cdd43b73..fe04f27c 100644 --- a/lbplanner/classes/model/reservation.php +++ b/lbplanner/classes/model/reservation.php @@ -164,14 +164,23 @@ public function get_datetime_end(): DateTimeImmutable { } /** - * Calculates whether the reservation is outdated + * Calculates whether the start of this reservation has passed + * @param \DateTimeInterface $now * - * @return DateTimeImmutable + * @return bool */ - public function is_outdated(): bool { - $utctz = new DateTimeZone('UTC'); - $yesterday = new DateTimeImmutable('yesterday', $utctz); - return $yesterday->diff($this->date)->invert; + public function is_startpast($now): bool { + return $this->is_endpast($now) || ($now->diff($this->get_datetime())->invert === 1); + } + + /** + * Calculates whether the end of this reservation has passed + * @param \DateTimeInterface $now + * + * @return bool + */ + public function is_endpast($now): bool { + return $now->diff($this->get_datetime_end())->invert === 1; } /** diff --git a/lbplanner/lang/de/local_lbplanner.php b/lbplanner/lang/de/local_lbplanner.php index 60e4b96e..dfe6a44d 100644 --- a/lbplanner/lang/de/local_lbplanner.php +++ b/lbplanner/lang/de/local_lbplanner.php @@ -61,6 +61,7 @@ $string['err_plan_changeaccess_ofowner'] = 'Kann Berechtigungen ders BesitzerIns nicht ändern'; $string['err_plan_changeaccess_self'] = 'Kann eigene Berechtigungen nicht ändern'; $string['err_plan_changeaccess_toowner'] = 'Kann Berechtigungen nicht auf BesitzerIn ändern'; +$string['err_reserv_current'] = 'Schon laufende Slots können nicht reserviert werden'; $string['err_reserv_past'] = 'Vergangene Termine können nicht reserviert werden'; $string['err_reserv_slotfull'] = 'Slot ist schon voll'; $string['err_reserv_studentalrin'] = 'SchülerIn hat bereits eine Reservierung für diesen Slot'; diff --git a/lbplanner/lang/en/local_lbplanner.php b/lbplanner/lang/en/local_lbplanner.php index d7173fcf..10b9baca 100644 --- a/lbplanner/lang/en/local_lbplanner.php +++ b/lbplanner/lang/en/local_lbplanner.php @@ -61,6 +61,7 @@ $string['err_plan_changeaccess_ofowner'] = 'Cannot change permissions for the plan owner'; $string['err_plan_changeaccess_self'] = 'Cannot change own permissions'; $string['err_plan_changeaccess_toowner'] = 'Cannot change permission to owner'; +$string['err_reserv_current'] = 'Can\'t reserve slot that has already started'; $string['err_reserv_past'] = 'Can\'t reserve date in the past'; $string['err_reserv_slotfull'] = 'Slot is already full'; $string['err_reserv_studentalrin'] = 'Student already has a reservation for this slot'; diff --git a/lbplanner/services/slots/book_reservation.php b/lbplanner/services/slots/book_reservation.php index 2e49839c..d4fe48f0 100644 --- a/lbplanner/services/slots/book_reservation.php +++ b/lbplanner/services/slots/book_reservation.php @@ -85,23 +85,19 @@ public static function book_reservation(int $slotid, string $date, int $userid): ); $utctz = new DateTimeZone('UTC'); - $now = new DateTimeImmutable('today', $utctz); + $now = new DateTimeImmutable('now', $utctz); + $dateobj = DateTimeImmutable::createFromFormat("Y-m-d", $date, $utctz); if ($dateobj === false) { throw new \moodle_exception(get_string('err_dateformat', 'local_lbplanner', $date)); } - $td = $now->diff($dateobj); - - if ($td->invert === 1) { - throw new \moodle_exception(get_string('err_reserv_past', 'local_lbplanner')); - } $maxdays = null; $student = null; - $curuserid = intval($USER->id); + $issupervisor = $userid === $curuserid; - if ($userid === $curuserid) { + if ($issupervisor) { // Student reserving slot for themself. $maxdays = config_helper::get_slot_futuresight(); @@ -114,12 +110,20 @@ public static function book_reservation(int $slotid, string $date, int $userid): $student = core_user::get_user($userid, '*', MUST_EXIST); } - if ($td->days > $maxdays) { + $slot = slot_helper::get_slot($slotid); + $reservation = new reservation(0, $slotid, $dateobj, $userid, $curuserid); + $reservation->set_slot($slot); + + // Check if reservation is not too old, nor too far into the future. + $td = $now->diff($dateobj); + if ($reservation->is_endpast($now)) { + throw new \moodle_exception(get_string('err_reserv_past', 'local_lbplanner')); + } else if (!$issupervisor && $reservation->is_startpast($now)) { + throw new \moodle_exception(get_string('err_reserv_current', 'local_lbplanner')); + } else if ($td->days > $maxdays) { throw new \moodle_exception(get_string('err_reserv_toofuture', 'local_lbplanner', $maxdays)); } - $slot = slot_helper::get_slot($slotid); - // Check if user has access to slot. if (count(slot_helper::filter_slots_for_user([$slot], $student)) === 0) { throw new \moodle_exception(get_string('err_reserv_studentnoaccess', 'local_lbplanner')); @@ -137,9 +141,6 @@ public static function book_reservation(int $slotid, string $date, int $userid): throw new \moodle_exception(get_string('err_reserv_slotfull', 'local_lbplanner')); } - $reservation = new reservation(0, $slotid, $dateobj, $userid, $curuserid); - $reservation->set_slot($slot); - // Check if user is already in a different slot at the same time. $overlapreservations = []; $existingreservations = slot_helper::get_reservations_for_user($userid); diff --git a/lbplanner/services/slots/unbook_reservation.php b/lbplanner/services/slots/unbook_reservation.php index d984797b..e50dd4c0 100644 --- a/lbplanner/services/slots/unbook_reservation.php +++ b/lbplanner/services/slots/unbook_reservation.php @@ -17,6 +17,7 @@ namespace local_lbplanner_services; use DateTimeImmutable; +use DateTimeZone; use core_external\{external_api, external_function_parameters, external_value}; use local_lbplanner\helpers\{slot_helper, notifications_helper}; use local_lbplanner\enums\NOTIF_TRIGGER; @@ -71,10 +72,10 @@ public static function unbook_reservation(int $reservationid, bool $nice): void $userid = intval($USER->id); $reservation = slot_helper::get_reservation($reservationid); - $now = new DateTimeImmutable(); + $now = new DateTimeImmutable('now', new DateTimeZone('UTC')); - $endpast = $now->diff($reservation->get_datetime_end())->invert === 1; - $startpast = $endpast || ($now->diff($reservation->get_datetime())->invert === 1); + $endpast = $reservation->is_endpast($now); + $startpast = $reservation->is_startpast($now); if ($userid === $reservation->userid) { if ($endpast) {