| @@ -1,0 +1,305 @@ | ||
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * @package VikBooking | |
| 4 | + * @subpackage com_vikbooking | |
| 5 | + * @author Alessio Gaggii - E4J srl | |
| 6 | + * @copyright Copyright (C) 2025 E4J srl. All rights reserved. | |
| 7 | + * @license GNU General Public License version 2 or later; see LICENSE | |
| 8 | + * @link https://vikwp.com | |
| 9 | + */ | |
| 10 | + | |
| 11 | +defined('ABSPATH') or die('No script kiddies please!'); | |
| 12 | + | |
| 13 | +// import Joomla view library | |
| 14 | +jimport('joomla.application.component.view'); | |
| 15 | + | |
| 16 | +class VikBookingViewOverv extends JViewVikBooking | |
| 17 | +{ | |
| 18 | + public function display($tpl = null) | |
| 19 | + { | |
| 20 | + // Set the toolbar | |
| 21 | + $this->addToolBar(); | |
| 22 | + | |
| 23 | + if (!JFactory::getUser()->authorise('core.vbo.availability', 'com_vikbooking')) { | |
| 24 | + VBOHttpDocument::getInstance()->close(403, JText::translate('JERROR_ALERTNOAUTHOR')); | |
| 25 | + } | |
| 26 | + | |
| 27 | + $dbo = JFactory::getDbo(); | |
| 28 | + $app = JFactory::getApplication(); | |
| 29 | + | |
| 30 | + if (file_exists(VCM_ADMIN_PATH.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.'css'.DIRECTORY_SEPARATOR.'vcm-channels.css')) { | |
| 31 | + $document = JFactory::getDocument(); | |
| 32 | + $document->addStyleSheet(VCM_ADMIN_URI.'assets/css/vcm-channels.css'); | |
| 33 | + } | |
| 34 | + $session = JFactory::getSession(); | |
| 35 | + $cookie = JFactory::getApplication()->input->cookie; | |
| 36 | + $pmonth = VikRequest::getInt('month', 0, 'request'); | |
| 37 | + $pmnum = VikRequest::getInt('mnum', 0, 'request'); | |
| 38 | + $cmnum = $cookie->get('vbOvwMnum', '', 'string'); | |
| 39 | + $punits_show_type = VikRequest::getString('units_show_type', '', 'request'); | |
| 40 | + | |
| 41 | + // category filter | |
| 42 | + $pcategory_id = VikRequest::getString('category_id', '', 'request'); | |
| 43 | + $scategory_id = $session->get('vbOvwCatid', 0); | |
| 44 | + $pcategory_id = !strlen($pcategory_id) && !empty($scategory_id) ? $scategory_id : $pcategory_id; | |
| 45 | + $session->set('vbOvwCatid', $pcategory_id); | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Apply task manager filters. | |
| 49 | + * | |
| 50 | + * @since 1.18.0 (J) - 1.8.0 (WP) | |
| 51 | + */ | |
| 52 | + $tmfilters = (array) $app->input->get('tmfilters', [], 'array'); | |
| 53 | + if (empty($pmonth)) { | |
| 54 | + // overwrite the first month to display | |
| 55 | + if (($tmfilters['dates'] ?? '') && preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}\s?:\s?[0-9]{4}-[0-9]{2}-[0-9]{2}$/', (string) $tmfilters['dates'])) { | |
| 56 | + // custom range of dates filter will overwrite the current month to display | |
| 57 | + $dparts = explode(':', $tmfilters['dates']); | |
| 58 | + $begin_ts = strtotime(trim($dparts[0])); | |
| 59 | + $pmonth = strtotime(date('Y-m-01', $begin_ts)); | |
| 60 | + } elseif (($tmfilters['calendar_month'] ?? '') && preg_match('/01$/', (string) $tmfilters['calendar_month'])) { | |
| 61 | + // overwrite the current month to display | |
| 62 | + $pmonth = strtotime($tmfilters['calendar_month']) ?: $pmonth; | |
| 63 | + } | |
| 64 | + } | |
| 65 | + | |
| 66 | + $pbmode = VikRequest::getString('bmode', '', 'request'); | |
| 67 | + if (!empty($pbmode) && ($pbmode == 'classic' || $pbmode == 'tags')) { | |
| 68 | + VikRequest::setCookie('vbTagsMode', $pbmode, (time() + (86400 * 365)), '/'); | |
| 69 | + $session->set('vbTagsMode', $pbmode); | |
| 70 | + } else { | |
| 71 | + $cbmode = $cookie->get('vbTagsMode', '', 'string'); | |
| 72 | + $pbmode = (!empty($cbmode) && ($cbmode == 'classic' || $cbmode == 'tags') ? $cbmode : 'classic'); | |
| 73 | + VikRequest::setCookie('vbTagsMode', $pbmode, (time() + (86400 * 365)), '/'); | |
| 74 | + $session->set('vbTagsMode', $pbmode); | |
| 75 | + } | |
| 76 | + | |
| 77 | + if (!empty($punits_show_type)) { | |
| 78 | + $session->set('vbUnitsShowType', $punits_show_type); | |
| 79 | + } | |
| 80 | + if (empty($pmonth)) { | |
| 81 | + $sess_month = $session->get('vbOverviewMonth', ''); | |
| 82 | + if (!empty($sess_month)) { | |
| 83 | + $pmonth = $sess_month; | |
| 84 | + } | |
| 85 | + } | |
| 86 | + if (intval($cmnum) > 0 && empty($pmnum)) { | |
| 87 | + $pmnum = $cmnum; | |
| 88 | + } | |
| 89 | + if ($pmnum > 0) { | |
| 90 | + VikRequest::setCookie('vbOvwMnum', $pmnum, (time() + (86400 * 365)), '/'); | |
| 91 | + $session->set('vbOvwMnum', $pmnum); | |
| 92 | + } else { | |
| 93 | + $smnum = $session->get('vbOvwMnum', '1'); | |
| 94 | + $pmnum = intval($smnum) > 0 ? $smnum : 1; | |
| 95 | + } | |
| 96 | + | |
| 97 | + // remove expired locked records | |
| 98 | + $q = "DELETE FROM `#__vikbooking_tmplock` WHERE `until`<" . time() . ";"; | |
| 99 | + $dbo->setQuery($q); | |
| 100 | + $dbo->execute(); | |
| 101 | + | |
| 102 | + $q = "SELECT `checkin` FROM `#__vikbooking_busy` ORDER BY `checkin` ASC LIMIT 1;"; | |
| 103 | + $dbo->setQuery($q); | |
| 104 | + $oldest_checkin = $dbo->loadResult(); | |
| 105 | + if (!$oldest_checkin) { | |
| 106 | + $oldest_checkin = 0; | |
| 107 | + } | |
| 108 | + | |
| 109 | + $q = "SELECT `checkout` FROM `#__vikbooking_busy` ORDER BY `checkout` DESC LIMIT 1;"; | |
| 110 | + $dbo->setQuery($q); | |
| 111 | + $furthest_checkout = $dbo->loadResult(); | |
| 112 | + if (!$furthest_checkout) { | |
| 113 | + $furthest_checkout = 0; | |
| 114 | + } | |
| 115 | + | |
| 116 | + if (!empty($pmonth)) { | |
| 117 | + $session->set('vbOverviewMonth', $pmonth); | |
| 118 | + $tsstart = $pmonth; | |
| 119 | + } else { | |
| 120 | + $oggid = getdate(); | |
| 121 | + $tsstart = mktime(0, 0, 0, $oggid['mon'], 1, $oggid['year']); | |
| 122 | + } | |
| 123 | + $oggid = getdate($tsstart); | |
| 124 | + $tsend = mktime(0, 0, 0, ($oggid['mon'] + $pmnum), 1, $oggid['year']); | |
| 125 | + $today = getdate(); | |
| 126 | + $firstmonth = mktime(0, 0, 0, $today['mon'], 1, $today['year']); | |
| 127 | + $wmonthsel = "<select name=\"month\" onchange=\"document.vboverview.submit();\">\n"; | |
| 128 | + if ($oldest_checkin) { | |
| 129 | + $oldest_date = getdate($oldest_checkin); | |
| 130 | + $oldest_month = mktime(0, 0, 0, $oldest_date['mon'], 1, $oldest_date['year']); | |
| 131 | + if ($oldest_month < $firstmonth) { | |
| 132 | + while ($oldest_month < $firstmonth) { | |
| 133 | + $wmonthsel .= "<option value=\"".$oldest_month."\"".($oldest_month == $tsstart ? " selected=\"selected\"" : "").">".VikBooking::sayMonth($oldest_date['mon'])." ".$oldest_date['year']."</option>\n"; | |
| 134 | + if ($oldest_date['mon']==12) { | |
| 135 | + $nextmon = 1; | |
| 136 | + $year = $oldest_date['year'] + 1; | |
| 137 | + } else { | |
| 138 | + $nextmon = $oldest_date['mon'] + 1; | |
| 139 | + $year = $oldest_date['year']; | |
| 140 | + } | |
| 141 | + $oldest_month = mktime(0, 0, 0, $nextmon, 1, $year); | |
| 142 | + $oldest_date = getdate($oldest_month); | |
| 143 | + } | |
| 144 | + } | |
| 145 | + } | |
| 146 | + $wmonthsel .= "<option value=\"".$firstmonth."\"".($firstmonth == $tsstart ? " selected=\"selected\"" : "").">".VikBooking::sayMonth($today['mon'])." ".$today['year']."</option>\n"; | |
| 147 | + $futuremonths = 12; | |
| 148 | + if ($furthest_checkout) { | |
| 149 | + $furthest_date = getdate($furthest_checkout); | |
| 150 | + $furthest_month = mktime(0, 0, 0, $furthest_date['mon'], 1, $furthest_date['year']); | |
| 151 | + if ($furthest_month > $firstmonth) { | |
| 152 | + $monthsdiff = floor(($furthest_month - $firstmonth) / (86400 * 30)); | |
| 153 | + $futuremonths = $monthsdiff > $futuremonths ? $monthsdiff : $futuremonths; | |
| 154 | + } | |
| 155 | + } | |
| 156 | + for ($i = 1; $i <= $futuremonths; $i++) { | |
| 157 | + $newts = getdate($firstmonth); | |
| 158 | + if ($newts['mon'] == 12) { | |
| 159 | + $nextmon = 1; | |
| 160 | + $year = $newts['year'] + 1; | |
| 161 | + } else { | |
| 162 | + $nextmon = $newts['mon'] + 1; | |
| 163 | + $year = $newts['year']; | |
| 164 | + } | |
| 165 | + $firstmonth = mktime(0, 0, 0, $nextmon, 1, $year); | |
| 166 | + $newts = getdate($firstmonth); | |
| 167 | + $wmonthsel .= "<option value=\"".$firstmonth."\"".($firstmonth==$tsstart ? " selected=\"selected\"" : "").">".VikBooking::sayMonth($newts['mon'])." ".$newts['year']."</option>\n"; | |
| 168 | + } | |
| 169 | + $wmonthsel .= "</select>\n"; | |
| 170 | + | |
| 171 | + $lim = $app->getUserStateFromRequest("com_vikbooking.limit", 'limit', $app->get('list_limit'), 'int'); | |
| 172 | + $lim0 = VikRequest::getVar('limitstart', 0, '', 'int'); | |
| 173 | + /** | |
| 174 | + * Filter by category. | |
| 175 | + * | |
| 176 | + * @since 1.13 | |
| 177 | + */ | |
| 178 | + $catfilter = !empty($pcategory_id) ? "(`r`.`idcat`='" . $pcategory_id . ";' OR `r`.`idcat` LIKE '" . $pcategory_id . ";%' OR `r`.`idcat` LIKE '%;" . $pcategory_id . ";%' OR `r`.`idcat` LIKE '%;" . $pcategory_id . ";')" : ""; | |
| 179 | + // | |
| 180 | + $q = "SELECT SQL_CALC_FOUND_ROWS `r`.* FROM `#__vikbooking_rooms` AS `r`" . (!empty($catfilter) ? " WHERE " . $catfilter : '') . " ORDER BY `r`.`name` ASC"; | |
| 181 | + $dbo->setQuery($q, $lim0, $lim); | |
| 182 | + $rows = $dbo->loadAssocList(); | |
| 183 | + if (!$rows) { | |
| 184 | + if ($session->get('vbOvwCatid', '')) { | |
| 185 | + // unset empty category with no rooms | |
| 186 | + $session->set('vbOvwCatid', 0); | |
| 187 | + } | |
| 188 | + VikError::raiseWarning('', JText::translate('VBOVERVIEWNOROOMS')); | |
| 189 | + $app->redirect("index.php?option=com_vikbooking"); | |
| 190 | + $app->close(); | |
| 191 | + } | |
| 192 | + | |
| 193 | + $dbo->setQuery('SELECT FOUND_ROWS();'); | |
| 194 | + jimport('joomla.html.pagination'); | |
| 195 | + $pageNav = new JPagination( $dbo->loadResult(), $lim0, $lim ); | |
| 196 | + $navbut = "<table align=\"center\"><tr><td>".$pageNav->getListFooter()."</td></tr></table>"; | |
| 197 | + | |
| 198 | + /** | |
| 199 | + * Filter by category. | |
| 200 | + * | |
| 201 | + * @since 1.13 (J) - 1.3 (WP) | |
| 202 | + */ | |
| 203 | + $categories = []; | |
| 204 | + $q = "SELECT `id`,`name` FROM `#__vikbooking_categories` ORDER BY `name` ASC;"; | |
| 205 | + $dbo->setQuery($q); | |
| 206 | + $allcats = $dbo->loadAssocList(); | |
| 207 | + if ($allcats) { | |
| 208 | + foreach ($allcats as $cat) { | |
| 209 | + $categories[$cat['id']] = $cat['name']; | |
| 210 | + } | |
| 211 | + } | |
| 212 | + | |
| 213 | + // load records with basic information. | |
| 214 | + $arrbusy = [ | |
| 215 | + 'tmplock' => [], | |
| 216 | + ]; | |
| 217 | + $actnow = time(); | |
| 218 | + foreach ($rows as $r) { | |
| 219 | + $q = "SELECT `b`.*,`ob`.`idorder`,`o`.`custdata`,`o`.`days`,`o`.`roomsnum`,`o`.`idorderota`,`o`.`channel`,`o`.`closure` | |
| 220 | + FROM `#__vikbooking_busy` AS `b` | |
| 221 | + LEFT JOIN `#__vikbooking_ordersbusy` AS `ob` ON `b`.`id`=`ob`.`idbusy` | |
| 222 | + LEFT JOIN `#__vikbooking_orders` AS `o` ON `ob`.`idorder`=`o`.`id` | |
| 223 | + WHERE `b`.`idroom`=" . (int)$r['id'] . " AND (`b`.`checkin`>=" . $tsstart . " OR `b`.`checkout`>=" . $tsstart . ") AND (`b`.`checkin`<=" . $tsend . " OR `b`.`checkout`<=" . $tsstart . ");"; | |
| 224 | + $dbo->setQuery($q); | |
| 225 | + $occ_rows = $dbo->loadAssocList(); | |
| 226 | + $arrbusy[$r['id']] = $occ_rows ? $occ_rows : []; | |
| 227 | + | |
| 228 | + // locked (stand-by) records | |
| 229 | + $q = "SELECT `l`.*,`or`.`idroom` FROM `#__vikbooking_tmplock` AS `l` LEFT JOIN `#__vikbooking_ordersrooms` AS `or` ON `l`.`idorder`=`or`.`idorder` WHERE `or`.`idroom`='".$r['id']."' AND (`l`.`checkin`>=".$tsstart." OR `l`.`checkout`>=".$tsstart.") AND (`l`.`checkin`<=".$tsend." OR `l`.`checkout`<=".$tsstart.") AND `l`.`until`>=".$actnow.";"; | |
| 230 | + $dbo->setQuery($q); | |
| 231 | + $lock_rows = $dbo->loadAssocList(); | |
| 232 | + if ($lock_rows) { | |
| 233 | + $arrbusy['tmplock'][$r['id']] = $lock_rows; | |
| 234 | + } | |
| 235 | + } | |
| 236 | + | |
| 237 | + // collect additional information for each booking | |
| 238 | + $extra_info_map = []; | |
| 239 | + foreach ($arrbusy as $rid => $roomres) { | |
| 240 | + foreach ($roomres as $k => $res) { | |
| 241 | + if (empty($res['idorder'])) { | |
| 242 | + continue; | |
| 243 | + } | |
| 244 | + if (isset($extra_info_map[$res['idorder']])) { | |
| 245 | + // merge existing extra information | |
| 246 | + $arrbusy[$rid][$k] = array_merge($res, $extra_info_map[$res['idorder']]); | |
| 247 | + continue; | |
| 248 | + } | |
| 249 | + // get booking extra information | |
| 250 | + $q = "SELECT `oc`.`idcustomer`,`c`.`first_name`,`c`.`last_name`,`c`.`pic` | |
| 251 | + FROM `#__vikbooking_customers_orders` AS `oc` | |
| 252 | + LEFT JOIN `#__vikbooking_customers` AS `c` ON `oc`.`idcustomer`=`c`.`id` | |
| 253 | + WHERE `oc`.`idorder`={$res['idorder']}"; | |
| 254 | + $dbo->setQuery($q, 0, 1); | |
| 255 | + $extra_info = $dbo->loadAssoc(); | |
| 256 | + $extra_info = $extra_info ? $extra_info : []; | |
| 257 | + // merge and map booking extra information | |
| 258 | + $arrbusy[$rid][$k] = array_merge($res, $extra_info); | |
| 259 | + $extra_info_map[$res['idorder']] = $extra_info; | |
| 260 | + } | |
| 261 | + } | |
| 262 | + | |
| 263 | + /** | |
| 264 | + * Check the next festivities periodically | |
| 265 | + * | |
| 266 | + * @since 1.12.0 (J) - 1.2 (WP) | |
| 267 | + */ | |
| 268 | + $fests = VikBooking::getFestivitiesInstance(); | |
| 269 | + if ($fests->shouldCheckFestivities()) { | |
| 270 | + $fests->storeNextFestivities(); | |
| 271 | + } | |
| 272 | + $festivities = $fests->loadFestDates(date('Y-m-d', $tsstart), date('Y-m-d', $tsend)); | |
| 273 | + | |
| 274 | + /** | |
| 275 | + * Load room day notes from first month | |
| 276 | + * | |
| 277 | + * @since 1.13.5 (J) - 1.3 (WP) | |
| 278 | + */ | |
| 279 | + $rdaynotes = VikBooking::getCriticalDatesInstance()->loadRoomDayNotes(date('Y-m-d', $tsstart), date('Y-m-d', $tsend)); | |
| 280 | + // | |
| 281 | + | |
| 282 | + $this->rows = $rows; | |
| 283 | + $this->arrbusy = $arrbusy; | |
| 284 | + $this->wmonthsel = $wmonthsel; | |
| 285 | + $this->tsstart = $tsstart; | |
| 286 | + $this->festivities = $festivities; | |
| 287 | + $this->rdaynotes = $rdaynotes; | |
| 288 | + $this->lim0 = $lim0; | |
| 289 | + $this->navbut = $navbut; | |
| 290 | + $this->categories = $categories; | |
| 291 | + | |
| 292 | + // Display the template | |
| 293 | + parent::display($tpl); | |
| 294 | + } | |
| 295 | + | |
| 296 | + /** | |
| 297 | + * Sets the toolbar | |
| 298 | + */ | |
| 299 | + protected function addToolBar() | |
| 300 | + { | |
| 301 | + JToolBarHelper::title(JText::translate('VBMAINOVERVIEWTITLE'), 'vikbooking'); | |
| 302 | + JToolBarHelper::cancel( 'canceledorder', JText::translate('VBBACK')); | |
| 303 | + JToolBarHelper::spacer(); | |
| 304 | + } | |
| 305 | +} | |