From b4f60d28c65cf6ce98ed660e1dbb9347958f6875 Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Mon, 2 Sep 2024 11:07:21 +0000
Subject: [PATCH] TIC 4387, closes #4387

Closes #4387

Merge request studip/studip!3350
---
 app/controllers/course/timesrooms.php | 73 +++++++++++++++++++++++++--
 lib/models/resources/Resource.php     |  4 +-
 2 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/app/controllers/course/timesrooms.php b/app/controllers/course/timesrooms.php
index 5eab38ab5e8..ab2acc6260e 100644
--- a/app/controllers/course/timesrooms.php
+++ b/app/controllers/course/timesrooms.php
@@ -1,5 +1,8 @@
 <?php
 
+use Studip\ResourceBookingException;
+use Studip\ResourceBookingOverlapException;
+
 /**
  * @author  David Siegfried <david.siegfried@uni-vechta.de>
  * @license GPL2 or any later version
@@ -528,11 +531,71 @@ class Course_TimesroomsController extends AuthenticatedController
                         try {
                             $failure = !$termin->bookRoom($room, $preparation_time ?: 0);
                         } catch (ResourceBookingException|ResourceBookingOverlapException $e) {
-                            PageLayout::postError(sprintf(
-                                _('Der angegebene Raum konnte für den Termin %1$s nicht gebucht werden: %2$s'),
-                                '<strong>' . htmlReady($termin->getFullName()) . '</strong>',
-                                $e->getMessage()
-                            ));
+                            $course = $e->getRange();
+                            $message_links = [];
+
+                            if ($course instanceof Course) {
+                                if ($course->isEditableByUser()) {
+                                    //Link to the times/rooms page:
+                                    $link = new LinkElement(
+                                        _('Direkt zur Veranstaltung'),
+                                        URLHelper::getURL('dispatch.php/course/timesrooms/index', ['cid' => $course->id]),
+                                        Icon::create('link-intern')
+                                    );
+                                    $message_links[] = $link->render();
+                                } elseif ($course->isAccessibleToUser()) {
+                                    //Link to the details page:
+                                    $link = new LinkElement(
+                                        _('Direkt zur Veranstaltung'),
+                                        URLHelper::getURL('course/details/index', ['cid' => $course->id]),
+                                        Icon::create('link-intern')
+                                    );
+                                    $message_links[] = $link->render();
+                                }
+                            }
+                            if ($room->userHasBookingRights(User::findCurrent())) {
+                                $room_link = new LinkElement(
+                                    _('Zum Belegungsplan'),
+                                    $room->getActionURL('booking_plan')
+                                );
+                                $message_links[] = $room_link->render();
+                            }
+                            if ($e instanceof ResourceBookingException) {
+                                PageLayout::postError(
+                                    sprintf(
+                                        _('Der angegebene Raum konnte für den Termin %1$s nicht gebucht werden: %2$s'),
+                                        '<strong>' . htmlReady($termin->getFullName()) . '</strong>',
+                                        $e->getMessage()
+                                    ),
+                                    $message_links
+                                );
+                            } else {
+                                //$e is a ResourceBookingOverlapException
+                                if ($course instanceof Course) {
+                                    PageLayout::postError(
+                                        studip_interpolate(
+                                            _('Der Raum %{room_name} wird an dem Termin %{date} bereits durch die Veranstaltung %{course_name} belegt.'),
+                                            [
+                                                'room_name'   => $room->name,
+                                                'date'        => $termin->getFullName(),
+                                                'course_name' => $course->name
+                                            ]
+                                        ),
+                                        $message_links
+                                    );
+                                } else {
+                                    PageLayout::postError(
+                                        studip_interpolate(
+                                            _('Der Raum %{room_name} wird an dem Termin %{date} bereits durch eine andere Veranstaltung belegt.'),
+                                            [
+                                                'room_name'   => $room->name,
+                                                'date'        => $termin->getFullName()
+                                            ]
+                                        ),
+                                        $message_links
+                                    );
+                                }
+                            }
                         }
                     }
                     if ($failure) {
diff --git a/lib/models/resources/Resource.php b/lib/models/resources/Resource.php
index 7c870d93262..32766e4106b 100644
--- a/lib/models/resources/Resource.php
+++ b/lib/models/resources/Resource.php
@@ -859,7 +859,7 @@ class Resource extends SimpleORMap implements StudipItem
             $booking->store($force_booking);
         } catch (ResourceBookingOverlapException $e) {
             if ($begin->format('Ymd') == $end->format('Ymd')) {
-                throw new ResourceBookingException(
+                throw new ResourceBookingOverlapException(
                     sprintf(
                         _('%1$s: Die Buchung vom %2$s bis %3$s konnte wegen Ãœberlappungen nicht gespeichert werden: %4$s'),
                         $this->getFullName(),
@@ -869,7 +869,7 @@ class Resource extends SimpleORMap implements StudipItem
                     )
                 );
             } else {
-                throw new ResourceBookingException(
+                throw new ResourceBookingOverlapException(
                     sprintf(
                         _('%1$s: Die Buchung vom %2$s bis %3$s konnte wegen Ãœberlappungen nicht gespeichert werden: %4$s'),
                         $this->getFullName(),
-- 
GitLab