From 54eeb33becf4d9adb5a02c7f8577a737443e45e7 Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Wed, 31 Aug 2022 08:44:44 +0000
Subject: [PATCH] also check for RESOURCES_MIN_BOOKING_TIME when handling
 course dates, closes #862

Closes #862

Merge request studip/studip!861
---
 app/controllers/course/block_appointments.php | 16 +++++
 app/controllers/course/timesrooms.php         | 66 +++++++++++++++++++
 lib/models/resources/Resource.class.php       |  2 +-
 3 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/app/controllers/course/block_appointments.php b/app/controllers/course/block_appointments.php
index a71ca7fe87f..f45ac1012ff 100644
--- a/app/controllers/course/block_appointments.php
+++ b/app/controllers/course/block_appointments.php
@@ -133,6 +133,22 @@ class Course_BlockAppointmentsController extends AuthenticatedController
             }
         }
 
+        //Calculate the duration if a minimum booking time is set:
+        if (Config::get()->RESOURCES_MIN_BOOKING_TIME) {
+            $fake_start_time = strtotime(Request::get('block_appointments_start_time'), $start_day);
+            $fake_end_time = strtotime(Request::get('block_appointments_end_time'), $start_day);
+            $duration = $fake_end_time - $fake_start_time;
+            if ($duration < Config::get()->RESOURCES_MIN_BOOKING_TIME * 60) {
+                $errors[] = sprintf(
+                    ngettext(
+                        'Die minimale Dauer eines Termins von einer Minute wurde unterschritten.',
+                        'Die minimale Dauer eines Termins von %u Minuten wurde unterschritten.',
+                        Config::get()->RESOURCES_MIN_BOOKING_TIME
+                    ),
+                    Config::get()->RESOURCES_MIN_BOOKING_TIME
+                );
+            }
+        }
 
         $termin_typ     = Request::int('block_appointments_termin_typ', 0);
         $free_room_text = Request::get('block_appointments_room_text');
diff --git a/app/controllers/course/timesrooms.php b/app/controllers/course/timesrooms.php
index 11647ac8b4c..95b797e9312 100644
--- a/app/controllers/course/timesrooms.php
+++ b/app/controllers/course/timesrooms.php
@@ -106,6 +106,13 @@ class Course_TimesroomsController extends AuthenticatedController
         }
     }
 
+
+    protected function bookingTooShort(int $start_time, int $end_time)
+    {
+        return Config::get()->RESOURCES_MIN_BOOKING_TIME &&
+            (($end_time - $start_time) < Config::get()->RESOURCES_MIN_BOOKING_TIME * 60);
+    }
+
     /**
      * Displays the times and rooms of a course
      *
@@ -378,6 +385,20 @@ class Course_TimesroomsController extends AuthenticatedController
             $end_time = $termin->end_time;
             PageLayout::postError(_('Die Zeitangaben sind nicht korrekt. Bitte überprüfen Sie diese!'));
         }
+        if ($this->bookingTooShort($date, $end_time)) {
+            PageLayout::postError(
+                sprintf(
+                    ngettext(
+                        'Die minimale Dauer eines Termins von einer Minute wurde unterschritten.',
+                        'Die minimale Dauer eines Termins von %u Minuten wurde unterschritten.',
+                        Config::get()->RESOURCES_MIN_BOOKING_TIME
+                    ),
+                    Config::get()->RESOURCES_MIN_BOOKING_TIME
+                )
+            );
+            $this->redirect('course/timesrooms/editDate/' . $termin_id, ['contentbox_open' => $termin->metadate_id]);
+            return;
+        }
 
         $time_changed = ($date != $termin->date || $end_time != $termin->end_time);
         //time changed for regular date. create normal singledate and cancel the regular date
@@ -536,6 +557,20 @@ class Course_TimesroomsController extends AuthenticatedController
 
             return;
         }
+        if ($this->bookingTooShort($start_time, $end_time)) {
+            PageLayout::postError(
+                sprintf(
+                    ngettext(
+                        'Die minimale Dauer eines Termins von einer Minute wurde unterschritten.',
+                        'Die minimale Dauer eines Termins von %u Minuten wurde unterschritten.',
+                        Config::get()->RESOURCES_MIN_BOOKING_TIME
+                    ),
+                    Config::get()->RESOURCES_MIN_BOOKING_TIME
+                )
+            );
+            $this->redirect('course/timesrooms/createSingleDate');
+            return;
+        }
 
         $termin            = new CourseDate();
         $termin->termin_id = $termin->getNewId();
@@ -1177,6 +1212,20 @@ class Course_TimesroomsController extends AuthenticatedController
 
             return;
         }
+        if ($this->bookingTooShort($start, $end)) {
+            PageLayout::postError(
+                sprintf(
+                    ngettext(
+                        'Die minimale Dauer eines Termins von einer Minute wurde unterschritten.',
+                        'Die minimale Dauer eines Termins von %u Minuten wurde unterschritten.',
+                        Config::get()->RESOURCES_MIN_BOOKING_TIME
+                    ),
+                    Config::get()->RESOURCES_MIN_BOOKING_TIME
+                )
+            );
+            $this->redirect('course/timesrooms/createCycle');
+            return;
+        }
 
         $cycle              = new SeminarCycleDate();
         $cycle->seminar_id  = $this->course->id;
@@ -1235,6 +1284,23 @@ class Course_TimesroomsController extends AuthenticatedController
             $cycle->start_time  = date('H:i:00', $start);
             $cycle->end_time    = date('H:i:00', $end);
         }
+
+        //Check the duration:
+        if ($this->bookingTooShort($start, $end)) {
+            PageLayout::postError(
+                sprintf(
+                    ngettext(
+                        'Die minimale Dauer eines Termins von einer Minute wurde unterschritten.',
+                        'Die minimale Dauer eines Termins von %u Minuten wurde unterschritten.',
+                        Config::get()->RESOURCES_MIN_BOOKING_TIME
+                    ),
+                    Config::get()->RESOURCES_MIN_BOOKING_TIME
+                )
+            );
+            $this->redirect('course/timesrooms/createCycle/' . $cycle_id);
+            return;
+        }
+
         $cycle->weekday     = Request::int('day');
         $cycle->description = Request::get('description');
         $cycle->sws         = Request::get('teacher_sws');
diff --git a/lib/models/resources/Resource.class.php b/lib/models/resources/Resource.class.php
index 9e2bf997a61..fa854a636c0 100644
--- a/lib/models/resources/Resource.class.php
+++ b/lib/models/resources/Resource.class.php
@@ -741,7 +741,7 @@ class Resource extends SimpleORMap implements StudipItem
 
             $duration     = $end->getTimestamp() - $begin->getTimestamp();
             $min_duration = Config::get()->RESOURCES_MIN_BOOKING_TIME;
-            if ($duration < ($min_duration * 60)) {
+            if ($min_duration && ($duration < ($min_duration * 60))) {
                 throw new InvalidArgumentException(
                     sprintf(
                         _('Die minimale Buchungsdauer von %1$d Minuten wurde unterschritten!'),
-- 
GitLab