PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.7.1
VikBooking Hotel Booking Engine & PMS v1.7.1
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / admin / views / ratesoverv / view.html.php

view.html.php in VikBooking Hotel Booking Engine & PMS 1.7.1, at admin/views/ratesoverv/view.html.php

394 lines 14.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. 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 VikBookingViewRatesoverv 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.pricing', 'com_vikbooking')) {
24 VBOHttpDocument::getInstance()->close(403, JText::translate('JERROR_ALERTNOAUTHOR'));
25 }
26
27 /**
28 * Check the next festivities periodically
29 *
30 * @since 1.12.0 (J) - 1.2.0 (WP)
31 */
32 $fests = VikBooking::getFestivitiesInstance();
33 if ($fests->shouldCheckFestivities()) {
34 $fests->storeNextFestivities();
35 }
36 $festivities = $fests->loadFestDates();
37
38 $dbo = JFactory::getDbo();
39 $app = JFactory::getApplication();
40 $session = JFactory::getSession();
41
42 // define the maximum number of days
43 $MAX_DAYS = VBOFactory::getConfig()->getInt('roverv_max_days', 60);
44
45 $cid = VikRequest::getVar('cid', array(0));
46 $sesscids = $session->get('vbRatesOviewCids', array());
47 if (empty($cid[0]) && is_array($sesscids) && count($sesscids)) {
48 // load rooms from session only if no room IDs requested
49 $cid = $sesscids;
50 }
51
52 // first room ID
53 $roomid = (int)$cid[0];
54
55 if (empty($roomid)) {
56 $q = "SELECT `id` FROM `#__vikbooking_rooms` WHERE `avail`=1 ORDER BY `#__vikbooking_rooms`.`name` ASC LIMIT 1";
57 $dbo->setQuery($q);
58 $roomid = $dbo->loadResult();
59 if (!$roomid) {
60 $q = "SELECT `id` FROM `#__vikbooking_rooms` ORDER BY `#__vikbooking_rooms`.`name` ASC LIMIT 1";
61 $dbo->setQuery($q);
62 $roomid = $dbo->loadResult();
63 }
64 }
65 if (empty($roomid)) {
66 $app->redirect("index.php?option=com_vikbooking&task=rooms");
67 exit;
68 }
69 // make sure to set at least the first index of cid[]
70 $cid[0] = $roomid;
71 //
72 $q = "SELECT `id`,`name` FROM `#__vikbooking_rooms` ORDER BY `#__vikbooking_rooms`.`name` ASC;";
73 $dbo->setQuery($q);
74 $all_rooms = $dbo->loadAssocList();
75
76 /**
77 * Load categories to be used for group filter.
78 *
79 * @since 1.13 (J) - 1.3.0 (WP)
80 */
81 $q = "SELECT `id`,`name` FROM `#__vikbooking_categories` ORDER BY `#__vikbooking_categories`.`name` ASC;";
82 $dbo->setQuery($q);
83 $categories = $dbo->loadAssocList();
84
85 // load rooms rows for all requested rooms
86 $roomrows = [];
87 $reqids = [];
88 $reqcats = [];
89 foreach ($cid as $rid) {
90 if (empty($rid)) {
91 continue;
92 }
93 $rid = (int)$rid;
94 if ($rid < 0) {
95 // category
96 array_push($reqcats, ($rid + (abs($rid) * 2)));
97 } else {
98 // room
99 array_push($reqids, $rid);
100 }
101 }
102 if (!count($reqcats) && !count($reqids)) {
103 $app->redirect("index.php?option=com_vikbooking&task=rooms");
104 exit;
105 }
106
107 if (!count($reqcats) && empty($sesscids) && count($reqids) === 1 && count($all_rooms) > 1) {
108 // push the first 5 rooms by default
109 $max_def_rooms = VBOFactory::getConfig()->getInt('roverv_def_max_rooms', 5);
110 $def_rooms_count = 0;
111 $reqids = [];
112 foreach ($all_rooms as $aroom) {
113 $reqids[] = $aroom['id'];
114 $def_rooms_count++;
115 if ($def_rooms_count >= $max_def_rooms) {
116 break;
117 }
118 }
119 }
120
121 $clauses = [];
122 if (count($reqids)) {
123 array_push($clauses, "`id` IN (" . implode(', ', $reqids) . ")");
124 }
125 foreach ($reqcats as $cat_id) {
126 array_push($clauses, "(`idcat`='" . $cat_id . ";' OR `idcat` LIKE '" . $cat_id . ";%' OR `idcat` LIKE '%;" . $cat_id . ";%' OR `idcat` LIKE '%;" . $cat_id . ";')");
127 }
128 $q = "SELECT * FROM `#__vikbooking_rooms` WHERE ".implode(' OR ', $clauses)." ORDER BY `name` ASC;";
129 $dbo->setQuery($q);
130 $rows = $dbo->loadAssocList();
131 if ($rows) {
132 foreach ($rows as $row) {
133 $roomrows[$row['id']] = $row;
134 }
135 }
136 if (!$roomrows) {
137 $app->redirect("index.php?option=com_vikbooking&task=rooms");
138 exit;
139 }
140 if (!$reqids) {
141 // in case of just a category filter we need to restore the requested room IDs for later actions
142 $reqids = array_keys($roomrows);
143 }
144 // get all requested and valid room IDs
145 $req_room_ids = array_keys($roomrows);
146 $session->set('vbRatesOviewCids', $req_room_ids);
147 // Restrictions
148 $all_restrictions = [];
149 foreach ($req_room_ids as $rid) {
150 $all_restrictions[(int)$rid] = VikBooking::loadRestrictions(true, array($rid));
151 }
152 // length of stay pricing overview (only if one single room requested)
153 $first_roomrestr = isset($all_restrictions[(int)$roomid]) ? $all_restrictions[(int)$roomid] : array();
154 $pnights_cal = VikRequest::getVar('nights_cal', array());
155 $pnights_cal = VikBooking::filterNightsSeasonsCal($pnights_cal);
156 $room_nights_cal = isset($roomrows[(int)$roomid]) ? explode(',', VikBooking::getRoomParam('seasoncal_nights', $roomrows[(int)$roomid]['params'])) : [];
157 $room_nights_cal = VikBooking::filterNightsSeasonsCal($room_nights_cal);
158 $seasons_cal = [];
159 $seasons_cal_nights = [];
160 if ($pnights_cal) {
161 $seasons_cal_nights = $pnights_cal;
162 } elseif ($room_nights_cal) {
163 $seasons_cal_nights = $room_nights_cal;
164 } else {
165 $q = "SELECT `days` FROM `#__vikbooking_dispcost` WHERE `idroom`=".intval($roomid)." ORDER BY `#__vikbooking_dispcost`.`days` ASC LIMIT 7;";
166 $dbo->setQuery($q);
167 $nights_vals = $dbo->loadAssocList();
168 if ($nights_vals) {
169 $nights_got = [];
170 foreach ($nights_vals as $night) {
171 $nights_got[] = $night['days'];
172 }
173 $seasons_cal_nights = VikBooking::filterNightsSeasonsCal($nights_got);
174 }
175 }
176 if (count($req_room_ids) > 1) {
177 // it's useless to spend server resources to calculate the seasons calendar nights (LOS Pricing Overview) since it won't be displayed when more than 1 room
178 $seasons_cal_nights = [];
179 }
180 if ($seasons_cal_nights) {
181 $q = "SELECT `p`.*,`tp`.`name`,`tp`.`attr`,`tp`.`idiva`,`tp`.`breakfast_included`,`tp`.`free_cancellation`,`tp`.`canc_deadline` FROM `#__vikbooking_dispcost` AS `p` LEFT JOIN `#__vikbooking_prices` `tp` ON `p`.`idprice`=`tp`.`id` WHERE `p`.`days` IN (".implode(',', $seasons_cal_nights).") AND `p`.`idroom`=".(int)$roomid." ORDER BY `p`.`days` ASC, `p`.`cost` ASC;";
182 $dbo->setQuery($q);
183 $tars = $dbo->loadAssocList();
184 if ($tars) {
185 $arrtar = [];
186 foreach ($tars as $tar) {
187 $arrtar[$tar['days']][] = $tar;
188 }
189 $seasons_cal['nights'] = $seasons_cal_nights;
190 $seasons_cal['offseason'] = $arrtar;
191 $q = "SELECT * FROM `#__vikbooking_seasons` WHERE `idrooms` LIKE '%-".$roomid."-%';";
192 $dbo->setQuery($q);
193 $seasons = $dbo->loadAssocList();
194 if ($seasons) {
195 //Restrictions
196 $all_seasons = [];
197 $curtime = time();
198 foreach ($seasons as $sk => $s) {
199 if (empty($s['from']) && empty($s['to'])) {
200 continue;
201 }
202 $now_year = !empty($s['year']) ? $s['year'] : date('Y');
203 list($sfrom, $sto) = VikBooking::getSeasonRangeTs($s['from'], $s['to'], $now_year);
204 if ($sto < $curtime && empty($s['year'])) {
205 $now_year += 1;
206 list($sfrom, $sto) = VikBooking::getSeasonRangeTs($s['from'], $s['to'], $now_year);
207 }
208 if ($sto >= $curtime) {
209 $s['from_ts'] = $sfrom;
210 $s['to_ts'] = $sto;
211 $all_seasons[] = $s;
212 }
213 }
214 if (count($all_seasons) > 0) {
215 $vbo_df = VikBooking::getDateFormat();
216 $vbo_df = $vbo_df == "%d/%m/%Y" ? 'd/m/Y' : ($vbo_df == "%m/%d/%Y" ? 'm/d/Y' : 'Y/m/d');
217 $hcheckin = 0;
218 $mcheckin = 0;
219 $hcheckout = 0;
220 $mcheckout = 0;
221 $timeopst = VikBooking::getTimeOpenStore();
222 if (is_array($timeopst)) {
223 $opent = VikBooking::getHoursMinutes($timeopst[0]);
224 $closet = VikBooking::getHoursMinutes($timeopst[1]);
225 $hcheckin = $opent[0];
226 $mcheckin = $opent[1];
227 $hcheckout = $closet[0];
228 $mcheckout = $closet[1];
229 }
230 $all_seasons = VikBooking::sortSeasonsRangeTs($all_seasons);
231 $seasons_cal['seasons'] = $all_seasons;
232 $seasons_cal['season_prices'] = [];
233 $seasons_cal['restrictions'] = [];
234 //calc price changes for each season and for each num-night
235 foreach ($all_seasons as $sk => $s) {
236 $checkin_base_ts = $s['from_ts'];
237 $is_dst = date('I', $checkin_base_ts);
238 foreach ($arrtar as $numnights => $tar) {
239 $checkout_base_ts = $s['to_ts'];
240 for($i = 1; $i <= $numnights; $i++) {
241 $checkout_base_ts += 86400;
242 $is_now_dst = date('I', $checkout_base_ts);
243 if ($is_dst != $is_now_dst) {
244 if ((int)$is_dst == 1) {
245 $checkout_base_ts += 3600;
246 } else {
247 $checkout_base_ts -= 3600;
248 }
249 $is_dst = $is_now_dst;
250 }
251 }
252 //calc check-in and check-out ts for the two dates
253 $first = VikBooking::getDateTimestamp(date($vbo_df, $checkin_base_ts), $hcheckin, $mcheckin);
254 $second = VikBooking::getDateTimestamp(date($vbo_df, $checkout_base_ts), $hcheckout, $mcheckout);
255 $tar = VikBooking::applySeasonsRoom($tar, $first, $second, $s);
256 $seasons_cal['season_prices'][$sk][$numnights] = $tar;
257 //Restrictions
258 if (count($first_roomrestr)) {
259 $season_restr = VikBooking::parseSeasonRestrictions($first, $second, $numnights, $first_roomrestr);
260 if (count($season_restr) > 0) {
261 $seasons_cal['restrictions'][$sk][$numnights] = $season_restr;
262 }
263 }
264 }
265 }
266 }
267 }
268 }
269 }
270 //calendar rates
271 $todayd = getdate();
272 $tsstart = mktime(0, 0, 0, $todayd['mon'], $todayd['mday'], $todayd['year']);
273 $startdate = VikRequest::getString('startdate', '', 'request');
274 if (!empty($startdate)) {
275 $startts = VikBooking::getDateTimestamp($startdate, 0, 0);
276 if (!empty($startts)) {
277 $session->set('vbRatesOviewTs', $startts);
278 $tsstart = $startts;
279 }
280 } else {
281 $prevts = $session->get('vbRatesOviewTs', '');
282 if (!empty($prevts)) {
283 $tsstart = $prevts;
284 }
285 }
286
287 // read the rates for the lowest number of nights for each room requested
288 $roomrates = [];
289 foreach ($req_room_ids as $rid) {
290 /**
291 * Some types of price may not have a cost for 1 or 2 nights,
292 * so joining by MIN(`days`) may exclude certain types of price.
293 * We need to manually get via PHP all types of price.
294 * Old query below is no longer in use, even though it was
295 * compatible with the SQL strict mode (only_full_group_by).
296 * $q = "SELECT `r`.`id`,`r`.`idroom`,`r`.`days`,`r`.`idprice`,`r`.`cost`,`p`.`name` FROM `#__vikbooking_dispcost` AS `r` INNER JOIN (SELECT MIN(`days`) AS `min_days` FROM `#__vikbooking_dispcost` WHERE `idroom`=".(int)$rid." GROUP BY `idroom`) AS `r2` ON `r`.`days`=`r2`.`min_days` LEFT JOIN `#__vikbooking_prices` `p` ON `p`.`id`=`r`.`idprice` WHERE `r`.`idroom`=".(int)$rid." GROUP BY `r`.`id`,`r`.`idroom`,`r`.`days`,`r`.`idprice`,`r`.`cost`,`p`.`name` ORDER BY `r`.`days` ASC, `r`.`cost` ASC;";
297 *
298 * @since 1.10 (J) - 1.0.14 (WP)
299 */
300 $q = "SELECT `r`.`id`,`r`.`idroom`,`r`.`days`,`r`.`idprice`,`r`.`cost`,`p`.`name`,`p`.`minlos`,`p`.`derived_id`
301 FROM `#__vikbooking_dispcost` AS `r`
302 LEFT JOIN `#__vikbooking_prices` `p` ON `p`.`id`=`r`.`idprice`
303 WHERE `r`.`idroom`=".(int)$rid."
304 ORDER BY `r`.`days` ASC, `r`.`cost` ASC";
305 $dbo->setQuery($q, 0, 50);
306 $nowroomrates = $dbo->loadAssocList();
307
308 if ($nowroomrates) {
309 $parsed_room_prices = [];
310 foreach ($nowroomrates as $rrk => $rrv) {
311 if (isset($parsed_room_prices[$rrv['idprice']])) {
312 unset($nowroomrates[$rrk]);
313 continue;
314 }
315 $nowroomrates[$rrk]['cost'] = round(($rrv['cost'] / $rrv['days']), 2);
316 $nowroomrates[$rrk]['days'] = 1;
317 $parsed_room_prices[$rrv['idprice']] = 1;
318 }
319 }
320
321 $nowroomrates = array_values($nowroomrates);
322
323 // push rates for this room
324 $roomrates[(int)$rid] = $nowroomrates;
325 }
326
327 // sort room rates by the best rate plan name
328 foreach ($roomrates as $rid => $roomrplans) {
329 $roomrates[$rid] = VikBooking::sortRatePlans($roomrplans);
330 }
331
332 // read all the bookings between these dates for all rooms
333 $booked_dates = [];
334 $info_start = getdate($tsstart);
335 $endts = mktime(23, 59, 59, $info_start['mon'], ($info_start['mday'] + $MAX_DAYS), $info_start['year']);
336 $q = "SELECT `b`.*,`ob`.`idorder` FROM `#__vikbooking_busy` AS `b`,`#__vikbooking_ordersbusy` AS `ob` WHERE `b`.`idroom` IN (".implode(', ', $reqids).") AND `b`.`id`=`ob`.`idbusy` AND (`b`.`checkin`>=".$tsstart." OR `b`.`checkout`>=".$tsstart.") AND (`b`.`checkin`<=".$endts." OR `b`.`checkout`<=".$tsstart.");";
337 $dbo->setQuery($q);
338 $rbusy = $dbo->loadAssocList();
339 $ridbusy = [];
340 foreach ($rbusy as $rb) {
341 if (!isset($ridbusy[$rb['idroom']])) {
342 $ridbusy[$rb['idroom']] = [];
343 }
344 array_push($ridbusy[$rb['idroom']], $rb);
345 }
346 foreach ($req_room_ids as $rid) {
347 $booked_dates[(int)$rid] = isset($ridbusy[(int)$rid]) ? $ridbusy[(int)$rid] : [];
348 }
349
350 /**
351 * Load room day notes for the requested dates
352 *
353 * @since 1.13.5
354 */
355 $rdaynotes = VikBooking::getCriticalDatesInstance()->loadRoomDayNotes(date('Y-m-d', $tsstart), date('Y-m-d', $endts));
356 //
357
358 $this->all_rooms = $all_rooms;
359 $this->categories = $categories;
360 $this->reqcats = $reqcats;
361 $this->all_restrictions = $all_restrictions;
362 $this->roomrows = $roomrows;
363 $this->seasons_cal_nights = $seasons_cal_nights;
364 $this->seasons_cal = $seasons_cal;
365 $this->tsstart = $tsstart;
366 $this->roomrates = $roomrates;
367 $this->booked_dates = $booked_dates;
368 $this->req_room_ids = $req_room_ids;
369 $this->firstroom = $roomid;
370 $this->festivities = $festivities;
371 $this->rdaynotes = $rdaynotes;
372 $this->max_days = $MAX_DAYS;
373
374 // Display the template
375 parent::display($tpl);
376 }
377
378 /**
379 * Sets the toolbar
380 */
381 protected function addToolBar()
382 {
383 JToolBarHelper::title(JText::translate('VBMAINRATESOVERVIEWTITLE'), 'vikbooking');
384 if (JFactory::getUser()->authorise('core.create', 'com_vikbooking')) {
385 JToolBarHelper::addNew('newseason', JText::translate('VBMAINSEASONSNEW'));
386 JToolBarHelper::spacer();
387 JToolBarHelper::addNew('newrestriction', JText::translate('VBMAINRESTRICTIONNEW'));
388 JToolBarHelper::spacer();
389 }
390 JToolBarHelper::cancel( 'cancel', JText::translate('VBBACK'));
391 JToolBarHelper::spacer();
392 }
393 }
394