From 96b2532e70ff4e72a6f49f8521e89d380d4f913b Mon Sep 17 00:00:00 2001 From: Moritz Strohm <strohm@data-quest.de> Date: Thu, 4 Nov 2021 08:58:38 +0000 Subject: [PATCH] Fix for BIESt #264 --- app/controllers/resources/room_request.php | 164 +++++++++--------- .../room_request/resolve_room_tr.php | 62 ++++--- 2 files changed, 117 insertions(+), 109 deletions(-) diff --git a/app/controllers/resources/room_request.php b/app/controllers/resources/room_request.php index 97f45b24a7a..f6c30e8c105 100644 --- a/app/controllers/resources/room_request.php +++ b/app/controllers/resources/room_request.php @@ -1177,6 +1177,65 @@ class Resources_RoomRequestController extends AuthenticatedController } + protected function calculateRoomAvailabilityData(Room $room) + { + //The time intervals are read from $this->request_time_intervals. + $this->metadate_availability_share[$room->id] = []; + $this->room_availability[$room->id] = []; + $this->room_availability_share[$room->id] = 1.0; + $this->amount_of_dates[$room->id] = 0; + $this->unavailable_dates[$room->id] = 0; + $this->unavailable_metadate_dates[$room->id] = []; + $this->amount_of_metadate_dates[$room->id] = []; + + foreach ($this->request_time_intervals as $metadate_id => $data) { + $this->unavailable_metadate_dates[$room->id][$metadate_id] = 0; + $this->amount_of_metadate_dates[$room->id][$metadate_id] = count($data['intervals']); + $this->amount_of_dates[$room->id] += $this->amount_of_metadate_dates[$room->id][$metadate_id]; + if ($data['metadate'] instanceof SeminarCycleDate && !$this->expand_metadates) { + $metadate_availability = $this->getRoomAvailability( + $room, + $data['intervals'] + ); + + $metadate_available = true; + foreach ($metadate_availability as $available) { + if (!$available) { + $this->unavailable_dates[$room->id]++; + $metadate_available = false; + $this->unavailable_metadate_dates[$room->id][$metadate_id]++; + } + } + $this->room_availability[$room->id][$metadate_id] = [$metadate_available]; + } else { + $this->visible_dates += $this->amount_of_metadate_dates[$room->id][$metadate_id]; + $metadate_availability = []; + foreach ($data['intervals'] as $interval) { + $interval_available = $this->getRoomAvailability( + $room, + [$interval] + ); + if ($interval_available[0]) { + $range_index = $interval['range'] . '_' . $interval['range_id']; + $this->selected_rooms[$range_index] = $room->id; + } else { + $this->unavailable_dates[$room->id]++; + $this->unavailable_metadate_dates[$room->id][$metadate_id]++; + } + $metadate_availability[] = $interval_available[0]; + } + $this->room_availability[$room->id][$metadate_id] = $metadate_availability; + } + + $this->metadate_availability_share[$room->id][$metadate_id] = + ($this->amount_of_metadate_dates[$room->id][$metadate_id] - $this->unavailable_metadate_dates[$room->id][$metadate_id]) + / $this->amount_of_metadate_dates[$room->id][$metadate_id]; + } + $this->room_availability_share[$room->id] = + ($this->amount_of_dates[$room->id] - $this->unavailable_dates[$room->id]) / $this->amount_of_dates[$room->id]; + } + + /** * This action displays information about a request * that are relevant before resolving it. @@ -1284,11 +1343,15 @@ class Resources_RoomRequestController extends AuthenticatedController $this->request_semester_string = $request_start_semester->name; } - $this->metadate_available = []; + $this->metadate_availability_share = []; $this->room_availability = []; $this->room_underload = []; $this->requested_room_fully_available = true; $this->room_availability_share = []; + $this->amount_of_dates = []; + $this->unavailable_dates = []; + $this->amount_of_metadate_dates = []; + $this->unavailable_metadate_dates = []; $this->selected_rooms = []; //Load all previously selected rooms where at least one date has been @@ -1298,31 +1361,26 @@ class Resources_RoomRequestController extends AuthenticatedController $this->selected_rooms = Request::getArray('selected_rooms'); } - $selected_room = $this->request_resource; $this->visible_dates = 0; + //Calculate the visible dates and check if the expand_metadates button must be shown: + foreach ($this->request_time_intervals as $data) { + if ($data['metadate'] instanceof SeminarCycleDate && !$this->expand_metadates) { + //There is at least one metadate in the grouped set + //of time intervals. The expand button must be shown. + $this->show_expand_metadates_button = true; + $this->visible_dates++; + } + } + + $selected_room = $this->request_resource; + if ($selected_room instanceof Room) { - $this->metadate_available[$selected_room->id] = []; - $this->room_availability[$selected_room->id] = []; - $this->room_availability_share[$selected_room->id] = 1.0; + $this->calculateRoomAvailabilityData($selected_room); + if ($this->room_availability_share[$selected_room->id] < 1.0) { + $this->requested_room_fully_available = false; + } foreach ($this->request_time_intervals as $metadate_id => $data) { if ($data['metadate'] instanceof SeminarCycleDate && !$this->expand_metadates) { - //There is at least one metadate in the grouped set - //of time intervals. The expand button must be shown. - $this->show_expand_metadates_button = true; - $this->visible_dates++; - $metadate_availability = $this->getRoomAvailability( - $selected_room, - $data['intervals'] - ); - - $metadate_available = true; - foreach ($metadate_availability as $available) { - if (!$available) { - $metadate_available = false; - break; - } - } - $all_dates_same_room = true; // check, if ALL dates are booked for the same room foreach ($data['intervals'] as $interval) { @@ -1331,46 +1389,15 @@ class Resources_RoomRequestController extends AuthenticatedController break; } } - - if ($all_dates_same_room && $metadate_available && !$this->selected_rooms) { + if ($all_dates_same_room && $this->room_availability[$selected_room->id][$metadate_id][0] && !$this->selected_rooms) { $this->selected_rooms['SeminarCycleDate_' . $metadate_id] = $selected_room->id; } - $this->room_availability[$selected_room->id][$metadate_id] = [$metadate_available]; - } else { - $this->visible_dates += count($data['intervals']); - $metadate_availability = []; - foreach ($data['intervals'] as $interval) { - $interval_available = $this->getRoomAvailability( - $selected_room, - [$interval] - ); - if ($interval_available[0]) { - $range_index = $interval['range'] . '_' . $interval['range_id']; - $this->selected_rooms[$range_index] = $selected_room->id; - } - $metadate_availability[] = $interval_available[0]; - } - $this->room_availability[$selected_room->id][$metadate_id] = $metadate_availability; } } if ($this->request->getProperty('seats') > 0) { $this->room_underload[$selected_room->id] = round(((int)$selected_room->seats / (int)$this->request->getProperty('seats')) * 100); } - $amount_of_dates = count(reset($this->room_availability)); - foreach ($this->room_availability[$selected_room->id] as $metadate_id => $metadate_availability) { - $this->metadate_available[$selected_room->id][$metadate_id] = true; - $unavailable_c = 0; - foreach ($metadate_availability as $available) { - if (!$available) { - $this->requested_room_fully_available = false; - $this->metadate_available[$selected_room->id][$metadate_id] = false; - $unavailable_c++; - } - } - $this->room_availability_share[$selected_room->id] = - ($amount_of_dates - $unavailable_c) / $amount_of_dates; - } } else { //If no room is selected, it cannot be declared fully available. $this->requested_room_fully_available = false; @@ -1549,34 +1576,7 @@ class Resources_RoomRequestController extends AuthenticatedController $this->alternative_rooms = $deduplicated; foreach ($this->alternative_rooms as $room) { - $this->metadate_available[$room->id] = []; - $this->room_availability[$room->id] = []; - foreach ($this->request_time_intervals as $metadate_id => $data) { - $this->metadate_available[$room->id][$metadate_id] = true; - $this->room_availability[$room->id][$metadate_id] = - $this->getRoomAvailability( - $room, - $data['intervals'] - ); - } - $this->room_availability_share[$room->id] = 1.0; - $date_c = 0; - $unavailable_c = 0; - foreach ($this->room_availability[$room->id] as $metadate_id => $metadate_availability) { - $date_c++; - foreach ($metadate_availability as $available) { - if (!$available) { - $this->room_fully_available[$room->id] = false; - $this->metadate_available[$room->id][$metadate_id] = false; - $unavailable_c++; - break; - } - } - } - if ($date_c > 0) { - $this->room_availability_share[$room->id] = - ($date_c - $unavailable_c) / $date_c; - } + $this->calculateRoomAvailabilityData($room); if ($this->request->getProperty('seats') > 0) { $this->room_underload[$room->id] = diff --git a/app/views/resources/room_request/resolve_room_tr.php b/app/views/resources/room_request/resolve_room_tr.php index ff1e53bb0fa..99509550b60 100644 --- a/app/views/resources/room_request/resolve_room_tr.php +++ b/app/views/resources/room_request/resolve_room_tr.php @@ -36,51 +36,59 @@ <?= Icon::create('decline-circle', Icon::ROLE_STATUS_RED)->asImg(['class' => 'text-bottom']) ?> <? else : ?> <?= Icon::create('exclaim-circle', Icon::ROLE_STATUS_YELLOW)->asImg(['class' => 'text-bottom']) ?> + <?= tooltipIcon(sprintf( + _('%u von %u Terminen nicht verfügbar'), + $unavailable_dates[$room->id], + $amount_of_dates[$room->id] + )) ?> <? endif ?> </td> <? endif ?> <? foreach ($time_intervals as $metadate_id => $data): ?> <? if (($data['metadate'] instanceof SeminarCycleDate)) : ?> <? - $available = $metadate_available[$room->id][$metadate_id]; + $availability = $metadate_availability_share[$room->id][$metadate_id]; $range_index = 'SeminarCycleDate' . '_' . $metadate_id; $room_radio_name = 'selected_rooms[' . $range_index . ']'; ?> <td> - <? if ($available): ?> - <input type="radio" name="<?= htmlReady($room_radio_name) ?>" - class="text-bottom radio-<?= htmlReady($room->id) ?>" - value="<?= htmlReady($room->id) ?>" - <?= $selected_dates[$range_index] == $room->id - ? 'checked="checked"' - : ''?>> + <input type="radio" name="<?= htmlReady($room_radio_name) ?>" + class="text-bottom radio-<?= htmlReady($room->id) ?>" + value="<?= htmlReady($room->id) ?>" + <?= $availability <= 0.0 ? 'disabled="disabled"' : '' ?> + <?= ($availability > 0 && $selected_dates[$range_index] == $room->id) + ? 'checked="checked"' + : ''?>> + <? if ($availability >= 1.0) : ?> <?= Icon::create('check-circle', Icon::ROLE_STATUS_GREEN)->asImg(['class' => 'text-bottom']) ?> - - <? $stats = 0; array_walk($data['intervals'], function(&$item, $key, $room_id) use (&$stats) { - if ($item['booked_room'] == $room_id) { - $stats++; - } - }, $room->id) ?> - - <? if ($stats > 0) : ?> - <?= tooltipIcon(sprintf( - _('%s von %s Terminen sind in diesem Raum'), - $stats, sizeof($data['intervals']) - )); - ?> - <? endif ?> - <? else: ?> - <input type="radio" name="<?= htmlReady($room_radio_name) ?>" - value="1" disabled="disabled" - class="text-bottom"> + <? elseif ($availability <= 0.0) : ?> <?= Icon::create('decline-circle', Icon::ROLE_STATUS_RED)->asImg(['class' => 'text-bottom']) ?> + <? else : ?> + <?= Icon::create('exclaim-circle', Icon::ROLE_STATUS_YELLOW)->asImg(['class' => 'text-bottom']) ?> + <?= tooltipIcon(sprintf( + _('%u von %u Terminen nicht verfügbar'), + $unavailable_metadate_dates[$room->id][$metadate_id], + $amount_of_metadate_dates[$room->id][$metadate_id] + )) ?> + <? endif ?> + <? $stats = 0; array_walk($data['intervals'], function(&$item, $key, $room_id) use (&$stats) { + if ($item['booked_room'] == $room_id) { + $stats++; + } + }, $room->id) ?> + <? if ($stats > 0) : ?> + <?= tooltipIcon(sprintf( + _('%s von %s Terminen sind in diesem Raum'), + $stats, sizeof($data['intervals']) + )); + ?> <? endif ?> </td> <? else : ?> <? $i = 0 ?> <? foreach($data['intervals'] as $interval) : ?> <? - $available = $availability[$metadate_id][$i]; + $available = $metadate_availability_share[$room->id][$metadate_id] >= 1.0; $range_index = $interval['range'] . '_' . $interval['range_id']; $room_radio_name = 'selected_rooms[' . $range_index . ']'; ?> -- GitLab