PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.11
VikBooking Hotel Booking Engine & PMS v1.8.11
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 / calendar / tmpl / default.php

default.php in VikBooking Hotel Booking Engine & PMS 1.8.11, at admin/views/calendar/tmpl/default.php

1,407 lines 53.2 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 $room = $this->room;
14 $allc = $this->allc;
15 $payments = $this->payments;
16 $busy = $this->busy;
17 $vmode = $this->vmode;
18
19 $dbo = JFactory::getDbo();
20 $vbo_app = VikBooking::getVboApplication();
21 $vbo_app->loadSelect2();
22 $vbo_app->loadDatePicker();
23 $vbo_app->loadDatesRangePicker();
24
25 $document = JFactory::getDocument();
26 $document->addStyleSheet(VBO_ADMIN_URI.'resources/jquery.highlighttextarea.min.css');
27 JHtml::fetch('script', VBO_ADMIN_URI.'resources/jquery.highlighttextarea.min.js');
28
29 // JS lang def
30 JText::script('VBFILLCUSTFIELDS');
31 JText::script('VBMSGTHREE');
32 JText::script('VBMSGFOUR');
33 JText::script('VBDBTEXTROOMCLOSED');
34 JText::script('ORDER_NOTES');
35 JText::script('VBSUBMCLOSEROOM');
36 JText::script('VBCUSTINFO');
37 JText::script('VBMAKERESERV');
38 JText::script('VBDAY');
39 JText::script('VBOCALCLOSEOTHERROOMS');
40 JText::script('VBERRCUSTOMEREMAILEXISTS');
41 JText::script('VBAPPLY');
42 JText::script('VBANNULLA');
43 JText::script('VBO_MARK_UNITS_CLOSED');
44
45 $vbo_df = VikBooking::getDateFormat(true);
46 if ($vbo_df == "%d/%m/%Y") {
47 $df = 'd/m/Y';
48 $juidf = 'dd/mm/yy';
49 } elseif ($vbo_df == "%m/%d/%Y") {
50 $df = 'm/d/Y';
51 $juidf = 'mm/dd/yy';
52 } else {
53 $df = 'Y/m/d';
54 $juidf = 'yy/mm/dd';
55 }
56 $datesep = VikBooking::getDateSeparator(true);
57 $prices_vat_included = (int)VikBooking::ivaInclusa();
58
59 $pcheckin = VikRequest::getString('checkin', '', 'request');
60 $pcheckin_ymd = $pcheckin;
61 if (!empty($pcheckin)) {
62 $pcheckin = date(str_replace('%', '', $vbo_df), strtotime($pcheckin));
63 }
64 $pcheckout = VikRequest::getString('checkout', '', 'request');
65 $pcheckout_ymd = $pcheckout;
66 if (!empty($pcheckout)) {
67 $pcheckout = date(str_replace('%', '', $vbo_df), strtotime($pcheckout));
68 }
69
70 $ptmpl = VikRequest::getString('tmpl', '', 'request');
71 $poverview = VikRequest::getInt('overv', '', 'request');
72 $poverview_change = VikRequest::getInt('overview_change', 0, 'request');
73 $padults = VikRequest::getInt('adults', 0, 'request');
74 $pchildren = VikRequest::getInt('children', 0, 'request');
75 $pidprice = VikRequest::getInt('idprice', 0, 'request');
76 $pbooknow = VikRequest::getInt('booknow', 0, 'request');
77
78 /**
79 * Split stay data for booking.
80 *
81 * @since 1.16.0 (J) - 1.6.0 (WP)
82 */
83 $split_stay = VikRequest::getVar('split_stay', array());
84 $rooms_data = [];
85 foreach ($allc as $room_info) {
86 $rooms_data[$room_info['id']] = $room_info['name'];
87 }
88
89 if ($this->new_res_id) {
90 ?>
91 <p class="successmade"><?php echo JText::translate('VBBOOKMADE'); ?> &nbsp;&nbsp;&nbsp; <a href="index.php?option=com_vikbooking&task=editorder&cid[]=<?php echo $this->new_res_id; ?>" target="_blank" class="btn"><i class="vboicn-eye"></i> <?php echo JText::translate('VBOVIEWBOOKINGDET'); ?></a></p>
92 <?php
93 if ($poverview > 0 && $ptmpl == 'component') {
94 $poverview_change = 1;
95 }
96 }
97
98 $timeopst = VikBooking::getTimeOpenStore();
99 if (is_array($timeopst)) {
100 $opent = VikBooking::getHoursMinutes($timeopst[0]);
101 $closet = VikBooking::getHoursMinutes($timeopst[1]);
102 $hcheckin = $opent[0];
103 $mcheckin = $opent[1];
104 $hcheckout = $closet[0];
105 $mcheckout = $closet[1];
106 } else {
107 $hcheckin = 0;
108 $mcheckin = 0;
109 $hcheckout = 0;
110 $mcheckout = 0;
111 }
112
113 /**
114 * Check if we have a listing-level check-in/check-out time to apply.
115 *
116 * @since 1.18.8 (J) - 1.8.8 (WP)
117 */
118 $customCheckin = VikBooking::getRoomParam('checkin', $room['params'] ?? '');
119 $customCheckout = VikBooking::getRoomParam('checkout', $room['params'] ?? '');
120 if ($customCheckin) {
121 // use proper check-in time at room-level
122 $parts = explode(':', $customCheckin);
123 $hcheckin = (int) $parts[0];
124 $mcheckin = (int) ($parts[1] ?? 0);
125 }
126 if ($customCheckout) {
127 // use proper check-out time at room-level
128 $parts = explode(':', $customCheckout);
129 $hcheckout = (int) $parts[0];
130 $mcheckout = (int) ($parts[1] ?? 0);
131 }
132
133 $formatparts = explode(':', VikBooking::getNumberFormatData());
134 $currencysymb = VikBooking::getCurrencySymb();
135 $globnumadults = VikBooking::getSearchNumAdults(true);
136 $adultsparts = explode('-', $globnumadults);
137 $seladults = "<select name=\"adults\" id=\"vbo-sel-adults\">\n";
138 for ($i = $adultsparts[0]; $i <= ((int)$adultsparts[1] * $room['units']); $i++) {
139 $seladults .= "<option value=\"".$i."\"".((intval($adultsparts[0]) < 1 && $i == 1 && $padults < 1) || ($padults > 0 && $i == $padults) ? " selected=\"selected\"" : "").">".$i."</option>\n";
140 }
141 $seladults .= "</select>\n";
142 $globnumchildren = VikBooking::getSearchNumChildren(true);
143 $childrenparts = explode('-', $globnumchildren);
144 $selchildren = "<select name=\"children\" id=\"vbo-sel-children\">\n";
145 for ($i = $childrenparts[0]; $i <= ((int)$childrenparts[1] * $room['units']); $i++) {
146 $selchildren .= "<option value=\"".$i."\"" . ($pchildren > 0 && $i == $pchildren ? ' selected="selected"' : '') . ">".$i."</option>\n";
147 }
148 $selchildren .= "</select>\n";
149 $selpayments = '<select name="payment"><option value="">'.JText::translate('VBPAYMUNDEFINED').'</option>';
150 if (is_array($payments) && $payments) {
151 foreach ($payments as $pay) {
152 $selpayments .= '<option value="'.$pay['id'].'">'.$pay['name'].'</option>';
153 }
154 }
155 $selpayments .= '</select>';
156 // custom fields
157 $all_countries = array();
158 $q = "SELECT * FROM `#__vikbooking_custfields` ORDER BY `#__vikbooking_custfields`.`ordering` ASC;";
159 $dbo->setQuery($q);
160 $all_cfields = $dbo->loadAssocList();
161 if ($all_cfields) {
162 $q = "SELECT * FROM `#__vikbooking_countries` ORDER BY `#__vikbooking_countries`.`country_name` ASC;";
163 $dbo->setQuery($q);
164 $all_countries = $dbo->loadAssocList();
165 }
166
167 $wiva = "";
168 $q = "SELECT * FROM `#__vikbooking_iva`;";
169 $dbo->setQuery($q);
170 $ivas = $dbo->loadAssocList();
171 if ($ivas) {
172 foreach ($ivas as $kiv => $iv) {
173 $wiva .= "<option value=\"".$iv['id']."\" data-aliqid=\"".$iv['id']."\"".($kiv < 1 ? ' selected="selected"' : '').">".(empty($iv['name']) ? $iv['aliq']."%" : $iv['name']." - ".$iv['aliq']."%")."</option>\n";
174 }
175 }
176
177 // close other rooms select
178 $closeotherrooms = '';
179 if (count($allc) > 1) {
180 $closeotherrooms = "<select id=\"vbo-calendar-closeall\" multiple=\"multiple\" name=\"closeothers[]\" onchange=\"vboCheckCloseOthers();\">\n";
181 $closeotherrooms .= "<option></option>\n";
182 $closeotherrooms .= "<option value=\"".$room['id']."\" data-currentr=\"true\" disabled=\"disabled\">".$room['name']."</option>\n";
183 $closeotherrooms .= "<option value=\"-1\">- ".JText::translate('VBOCALCLOSEALLROOMSDT')."</option>\n";
184 foreach ($allc as $cc) {
185 if ($cc['id'] == $room['id']) {
186 continue;
187 }
188 $closeotherrooms .= "<option value=\"".$cc['id']."\">".$cc['name']."</option>\n";
189 }
190 $closeotherrooms .= "</select>\n";
191 }
192
193 ?>
194
195 <div class="vbo-admin-container">
196
197 <div class="vbo-config-maintab-left">
198
199 <fieldset class="adminform">
200 <div class="vbo-params-wrap">
201 <legend class="adminlegend">
202 <div class="vbo-quickres-head">
203 <span><?php echo $room['name'] . " - " . JText::translate('VBQUICKBOOK') . (!empty($split_stay) ? ' (' . JText::translate('VBO_SPLIT_STAY') . ')' : ''); ?></span>
204 <div class="vbo-quickres-head-right">
205 <form name="vbchroom" id="vbchroom" method="post" action="index.php?option=com_vikbooking">
206 <input type="hidden" name="task" value="calendar"/>
207 <input type="hidden" name="option" value="com_vikbooking"/>
208 <select id="vbo-calendar-changeroom" name="cid[]" onchange="jQuery('#vbchroom').submit();">
209 <?php
210 foreach ($allc as $cc) {
211 echo "<option value=\"".$cc['id']."\"".($cc['id'] == $room['id'] ? " selected=\"selected\"" : "").">".$cc['name']."</option>\n";
212 }
213 ?>
214 </select>
215 <?php
216 if ($ptmpl == 'component') {
217 echo "<input type=\"hidden\" name=\"tmpl\" value=\"component\" />\n";
218 }
219 ?>
220 </form>
221 </div>
222 </div>
223 </legend>
224 <form name="newb" method="post" action="index.php?option=com_vikbooking" id="vbo-calendar-newb-form">
225 <div class="vbo-params-container">
226 <div class="vbo-param-container">
227 <div class="vbo-param-label"><?php echo JText::translate('VBDATEPICKUP'); ?></div>
228 <div class="vbo-param-setting">
229 <div class="input-append">
230 <input type="text" autocomplete="off" name="checkindate" id="checkindate" size="10" />
231 <button type="button" class="btn btn-secondary" id="checkindate-trig"><?php VikBookingIcons::e('calendar', 'icn-nomargin'); ?></button>
232 </div>
233 <span class="vbo-calendar-time-inline"><?php echo JText::translate('VBAT')." ".($hcheckin < 10 ? '0'.$hcheckin : $hcheckin).":".($mcheckin < 10 ? '0'.$mcheckin : $mcheckin); ?></span>
234 <input type="hidden" name="checkinh" value="<?php echo $hcheckin; ?>"/>
235 <input type="hidden" name="checkinm" value="<?php echo $mcheckin; ?>"/>
236 </div>
237 </div>
238 <div class="vbo-param-container">
239 <div class="vbo-param-label"><?php echo JText::translate('VBDATERELEASE'); ?></div>
240 <div class="vbo-param-setting">
241 <div class="input-append">
242 <input type="text" autocomplete="off" name="checkoutdate" id="checkoutdate" size="10" />
243 <button type="button" class="btn btn-secondary" id="checkoutdate-trig"><?php VikBookingIcons::e('calendar', 'icn-nomargin'); ?></button>
244 </div>
245 <span class="vbo-calendar-time-inline"><?php echo JText::translate('VBAT')." ".($hcheckout < 10 ? '0'.$hcheckout : $hcheckout).":".($mcheckout < 10 ? '0'.$mcheckout : $mcheckout); ?></span>
246 <span style="display: none; margin-left: 25px; vertical-align: top;" id="vbjstotnights">
247 <span style="font-weight: bold;"><?php echo JText::translate('VBDAYS'); ?></span>
248 <input type="number" min="1" step="1" value="1" id="vbo-numnights" style="margin: 0;" />
249 </span>
250 <input type="hidden" name="checkouth" value="<?php echo $hcheckout; ?>"/>
251 <input type="hidden" name="checkoutm" value="<?php echo $mcheckout; ?>"/>
252 </div>
253 </div>
254 <div class="vbo-param-container" style="<?php echo !empty($split_stay) ? 'display: none;' : ''; ?>">
255 <div class="vbo-param-label">
256 <span class="vbcloseroomsp">
257 <label for="setclosed-on"><?php echo JText::translate('VBCLOSEROOM'); ?> <i class="<?php echo VikBookingIcons::i('ban'); ?>" style="float: none;"></i></label>
258 </span>
259 </div>
260 <div class="vbo-param-setting">
261 <?php echo $vbo_app->printYesNoButtons('setclosed', JText::translate('VBYES'), JText::translate('VBNO'), 0, 1, 0, 'vbCloseRoom();'); ?>
262 <div class="vbo-close-all-rooms-sel" id="vbo-close-all-rooms-sel" style="display: none;"><?php echo $closeotherrooms; ?></div>
263 </div>
264 </div>
265 <?php
266 if ($room['units'] > 1 && empty($split_stay)) {
267 $num_rooms_vals = range(1, $room['units']);
268 $num_rooms_opts = '';
269 foreach ($num_rooms_vals as $nrv) {
270 $num_rooms_opts .= '<option value="'.$nrv.'">'.$nrv.'</option>'."\n";
271 }
272 ?>
273 <div class="vbo-param-container" id="vbo-row-numrooms">
274 <div class="vbo-param-label"><?php echo JText::translate('VBPVIEWROOMSEVEN'); ?></div>
275 <div class="vbo-param-setting">
276 <select name="num_rooms" id="vbo-sel-numrooms">
277 <?php echo $num_rooms_opts; ?>
278 </select>
279 </div>
280 </div>
281 <?php
282 } else {
283 ?>
284 <input type="hidden" name="num_rooms" value="1"/>
285 <?php
286 }
287 ?>
288 <div class="vbo-param-container" id="vbo-row-people">
289 <div class="vbo-param-label"><?php echo JText::translate('VBQUICKRESGUESTS'); ?></div>
290 <div class="vbo-param-setting">
291 <span class="vbo-quickres-aduchi-wrap">
292 <span class="vbo-quickres-aduchi-inlbl"><?php echo JText::translate('VBQUICKADULTS'); ?></span>
293 <?php echo $seladults; ?>
294 </span>
295 <span class="vbo-quickres-aduchi-wrap">
296 <span class="vbo-quickres-aduchi-inlbl"><?php echo JText::translate('VBQUICKCHILDREN'); ?></span>
297 <?php echo $selchildren; ?>
298 </span>
299 </div>
300 </div>
301 <?php
302 if (!empty($split_stay)) {
303 foreach ($split_stay as $sps_k => $sps_v) {
304 ?>
305 <div class="vbo-param-container">
306 <div class="vbo-param-label"><?php echo $sps_k < 1 ? '<i class="' . VikBookingIcons::i('random') . '"></i> ' . JText::translate('VBO_SPLIT_STAY') : ' '; ?></div>
307 <div class="vbo-param-setting">
308 <div class="vbo-cal-splitstay-details">
309 <div class="vbo-cal-splitstay-room">
310 <span class="vbo-cal-splitstay-room-name"><?php VikBookingIcons::e('bed'); ?> <?php echo $rooms_data[$sps_v['idroom']]; ?></span>
311 <span class="vbo-cal-splitstay-room-nights"><?php VikBookingIcons::e('moon'); ?> <?php echo $sps_v['nights']; ?> <?php echo $sps_v['nights'] > 1 ? JText::translate('VBDAYS') : JText::translate('VBDAY'); ?></span>
312 </div>
313 <div class="vbo-cal-splitstay-dates">
314 <span class="vbo-cal-splitstay-dates-in"><?php VikBookingIcons::e('plane-arrival'); ?> <?php echo date(str_replace("/", $datesep, $df), strtotime($sps_v['checkin'])); ?></span>
315 <span class="vbo-cal-splitstay-dates-out"><?php VikBookingIcons::e('plane-departure'); ?> <?php echo date(str_replace("/", $datesep, $df), strtotime($sps_v['checkout'])); ?></span>
316 </div>
317 </div>
318 </div>
319 </div>
320 <?php
321 }
322 }
323 ?>
324 <div class="vbo-param-container"<?php echo ($poverview > 0 ? ' style="display: none;"' : ''); ?> id="vbo-row-bstat">
325 <div class="vbo-param-label"><?php echo JText::translate('VBCALBOOKINGSTATUS'); ?></div>
326 <div class="vbo-param-setting">
327 <select name="newstatus">
328 <option value="confirmed"><?php echo JText::translate('VBCONFIRMED'); ?></option>
329 <option value="standby"><?php echo JText::translate('VBSTANDBY'); ?></option>
330 </select>
331 </div>
332 </div>
333 <div class="vbo-param-container" id="vbo-row-bpay">
334 <div class="vbo-param-label"><?php echo JText::translate('VBCALBOOKINGPAYMENT'); ?></div>
335 <div class="vbo-param-setting">
336 <?php echo $selpayments; ?>
337 </div>
338 </div>
339 <div class="vbo-param-container" id="vbo-row-fillcustfields">
340 <div class="vbo-param-label">&nbsp;</div>
341 <div class="vbo-param-setting">
342 <span class="vbo-assign-customer" id="vbfillcustfields">
343 <i class="<?php echo VikBookingIcons::i('user-circle'); ?>"></i>
344 <span><?php echo JText::translate('VBFILLCUSTFIELDS'); ?></span>
345 </span>
346 </div>
347 </div>
348 <div class="vbo-param-container" id="vbo-row-cmail">
349 <div class="vbo-param-label"><?php echo JText::translate('VBCUSTEMAIL'); ?></div>
350 <div class="vbo-param-setting">
351 <input type="text" name="custmail" id="custmailfield" value="" size="25"/>
352 </div>
353 </div>
354 <div class="vbo-param-container">
355 <div class="vbo-param-label" id="vbcustdatalbl"><?php echo JText::translate('VBCUSTINFO'); ?></div>
356 <div class="vbo-param-setting">
357 <textarea name="custdata" id="vbcustdatatxtarea" rows="5" cols="70" style="min-width: 300px;"></textarea>
358 </div>
359 </div>
360 <div class="vbo-param-container" id="vbo-website-rates-row" style="display: none;">
361 <div class="vbo-param-label"><?php echo JText::translate('VBOWEBSITERATES'); ?></div>
362 <div class="vbo-param-setting" id="vbo-website-rates-cont"></div>
363 </div>
364 <div class="vbo-param-container" id="vbo-row-custcost">
365 <div class="vbo-param-label"><?php echo JText::translate('VBOROOMCUSTRATEPLANADD'); ?></div>
366 <div class="vbo-param-setting">
367 <div class="vbo-calendar-costs-wrapper">
368 <?php echo $currencysymb; ?> <input name="cust_cost" id="cust_cost" value="" onfocus="document.getElementById('taxid').style.display = 'inline-block';" onkeyup="vbCalcDailyCost(this.value);" onchange="vbCalcDailyCost(this.value);" type="number" step="any" min="0">
369 <select class="vbo-calendar-taxid" name="taxid" id="taxid" style="display: none;">
370 <option value=""><?php echo JText::translate('VBNEWOPTFOUR'); ?></option>
371 <?php echo $wiva; ?>
372 </select>
373 <div id="avg-daycost" class="vbo-calendar-avg-daycost" style="display: none;">
374 <select name="totalpnight">
375 <option value="total"></option>
376 <option value="pnight"></option>
377 </select>
378 </div>
379 </div>
380 </div>
381 </div>
382 <div id="vbo-force-bookingdates" class="vbo-param-container" style="display: none;">
383 <div class="vbo-param-label"><?php echo $vbo_app->createPopover(array('title' => JText::translate('VBO_FORCE_BOOKDATES'), 'content' => JText::translate('VBO_FORCE_BOOKDATES_HELP'))); ?> <?php echo JText::translate('VBO_FORCE_BOOKDATES'); ?></div>
384 <div class="vbo-param-setting">
385 <?php echo $vbo_app->printYesNoButtons('forcebooking', JText::translate('VBYES'), JText::translate('VBNO'), 0, 1, 0); ?>
386 <div class="vbo-param-setting-comment"></div>
387 </div>
388 </div>
389 <div class="vbo-param-container">
390 <div class="vbo-param-label">&nbsp;</div>
391 <div class="vbo-param-setting">
392 <button type="submit" id="quickbsubmit" class="btn btn-success btn-large"><i class="icon-save"></i> <span><?php echo JText::translate('VBMAKERESERV'); ?></span></button>
393 </div>
394 </div>
395 </div>
396 <?php
397 if ($poverview > 0) {
398 ?>
399 <input type="hidden" name="overv" value="<?php echo $poverview; ?>" />
400 <?php
401 }
402 if ($ptmpl == 'component') {
403 ?>
404 <input type="hidden" name="tmpl" value="component" />
405 <?php
406 }
407 if (!empty($split_stay)) {
408 // add hidden fields for the split stay booking
409 foreach ($split_stay as $spsk => $sps_room) {
410 foreach ($sps_room as $sps_room_k => $sps_room_v) {
411 ?>
412 <input type="hidden" name="split_stay_data[<?php echo $spsk; ?>][<?php echo $sps_room_k; ?>]" value="<?php echo JHtml::fetch('esc_attr', $sps_room_v); ?>" />
413 <?php
414 }
415 }
416 }
417 ?>
418 <input type="hidden" name="customer_id" value="" id="customer_id_inpfield"/>
419 <input type="hidden" name="countrycode" value="" id="ccode_inpfield"/>
420 <input type="hidden" name="state" value="" id="state_inpfield"/>
421 <input type="hidden" name="t_first_name" value="" id="t_first_name_inpfield"/>
422 <input type="hidden" name="t_last_name" value="" id="t_last_name_inpfield"/>
423 <input type="hidden" name="phone" value="" id="phonefield"/>
424 <input type="hidden" name="idprice" value="" id="booking-idprice"/>
425 <input type="hidden" name="roomcost" value="" id="booking-roomcost"/>
426 <input type="hidden" name="task" value="calendar"/>
427 <input type="hidden" name="cid[]" value="<?php echo $room['id']; ?>"/>
428 <input type="hidden" name="option" value="com_vikbooking" />
429 </form>
430 </div>
431 </fieldset>
432
433 </div>
434
435 <div class="vbo-config-maintab-right">
436 <div class="vbo-avcalendars-wrapper">
437 <div class="vbo-avcalendars-roomphoto">
438 <?php
439 if (is_file(VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . $room['img'])) {
440 ?>
441 <img alt="Room Image" src="<?php echo VBO_SITE_URI; ?>resources/uploads/<?php echo $room['img']; ?>" />
442 <?php
443 } else {
444 VikBookingIcons::e('image', 'vbo-enormous-icn');
445 }
446 ?>
447 </div>
448 <?php
449 $check = false;
450 if (empty($busy)) {
451 ?>
452 <p class="warn"><?php echo JText::translate('VBNOFUTURERES'); ?></p>
453 <?php
454 } else {
455 $check = true;
456 // build URL for each number of calendar months
457 $base_uri_data = [
458 'option' => 'com_vikbooking',
459 'task' => 'calendar',
460 'cid' => [
461 $room['id']
462 ],
463 'split_stay' => $split_stay,
464 ];
465 if (!empty($pcheckin_ymd) && !empty($pcheckout_ymd)) {
466 $base_uri_data['checkin'] = $pcheckin_ymd;
467 $base_uri_data['checkout'] = $pcheckout_ymd;
468 }
469 if ($padults > 0) {
470 $base_uri_data['adults'] = $padults;
471 $base_uri_data['children'] = $pchildren;
472 }
473 if (!empty($pidprice)) {
474 $base_uri_data['idprice'] = $pidprice;
475 }
476 if (!empty($pbooknow)) {
477 $base_uri_data['booknow'] = $pbooknow;
478 }
479 if ($ptmpl == 'component') {
480 $base_uri_data['tmpl'] = 'component';
481 }
482 ?>
483 <div>
484 <a class="vbmodelink<?php echo $vmode == 3 ? ' vbmodelink-active' : ''; ?>" href="index.php?<?php echo http_build_query(array_merge($base_uri_data, ['vmode' => 3])); ?>"><?php VikBookingIcons::e('calendar'); ?> <span><?php echo JText::translate('VBTHREEMONTHS'); ?></span></a>
485 <a class="vbmodelink<?php echo $vmode == 6 ? ' vbmodelink-active' : ''; ?>" href="index.php?<?php echo http_build_query(array_merge($base_uri_data, ['vmode' => 6])); ?>"><?php VikBookingIcons::e('calendar'); ?> <span><?php echo JText::translate('VBSIXMONTHS'); ?></span></a>
486 <a class="vbmodelink<?php echo $vmode == 12 ? ' vbmodelink-active' : ''; ?>" href="index.php?<?php echo http_build_query(array_merge($base_uri_data, ['vmode' => 12])); ?>"><?php VikBookingIcons::e('calendar'); ?> <span><?php echo JText::translate('VBTWELVEMONTHS'); ?></span></a>
487 <a class="vbmodelink<?php echo $vmode == 24 ? ' vbmodelink-active' : ''; ?>" href="index.php?<?php echo http_build_query(array_merge($base_uri_data, ['vmode' => 24])); ?>"><?php VikBookingIcons::e('calendar'); ?> <span><?php echo JText::translate('VBTWOYEARS'); ?></span></a>
488 </div>
489 <?php
490 }
491 ?>
492 <div class="vbo-calendar-cals-container">
493 <?php
494 $arr = getdate();
495 $mon = $arr['mon'];
496 $year = $arr['year'];
497 $dayts = mktime(0, 0, 0, $mon, 1, $year);
498 $newarr = getdate($dayts);
499
500 $firstwday = (int)VikBooking::getFirstWeekDay();
501 $days_labels = array(
502 JText::translate('VBSUN'),
503 JText::translate('VBMON'),
504 JText::translate('VBTUE'),
505 JText::translate('VBWED'),
506 JText::translate('VBTHU'),
507 JText::translate('VBFRI'),
508 JText::translate('VBSAT')
509 );
510 $days_indexes = array();
511 for ($i = 0; $i < 7; $i++) {
512 $days_indexes[$i] = (6-($firstwday-$i)+1)%7;
513 }
514
515 for ($jj = 1; $jj <= $vmode; $jj++) {
516 $d_count = 0;
517 echo '<div class="vbo-calendar-cal-container">';
518 $cal = "";
519 ?>
520 <table class="vbadmincaltable">
521 <tr class="vbadmincaltrmon">
522 <td colspan="7" align="center"><?php echo VikBooking::sayMonth($newarr['mon'])." ".$newarr['year']; ?></td>
523 </tr>
524 <tr class="vbadmincaltrmdays">
525 <?php
526 for ($i = 0; $i < 7; $i++) {
527 $d_ind = ($i + $firstwday) < 7 ? ($i + $firstwday) : ($i + $firstwday - 7);
528 echo '<td>'.$days_labels[$d_ind].'</td>';
529 }
530 ?>
531 </tr>
532 <tr>
533 <?php
534 for ($i=0, $n = $days_indexes[$newarr['wday']]; $i < $n; $i++, $d_count++) {
535 $cal .= "<td align=\"center\">&nbsp;</td>";
536 }
537 while ($newarr['mon'] == $mon) {
538 if ($d_count > 6) {
539 $d_count = 0;
540 $cal .= "</tr>\n<tr>";
541 }
542 $dclass = "free";
543 $dalt = "";
544 $bid = "";
545 $totfound = 0;
546 if ($check) {
547 foreach ($busy as $b) {
548 $tmpone = getdate($b['checkin']);
549 $ritts = mktime(0, 0, 0, $tmpone['mon'], $tmpone['mday'], $tmpone['year']);
550 $tmptwo = getdate($b['checkout']);
551 $conts = mktime(0, 0, 0, $tmptwo['mon'], $tmptwo['mday'], $tmptwo['year']);
552 if ($newarr[0] >= $ritts && $newarr[0] < $conts) {
553 $dclass = "busy";
554 $bid = $b['idorder'];
555 if ((int)$b['closure']) {
556 $dclass .= " busy-closure";
557 $dalt = JText::translate('VBDBTEXTROOMCLOSED');
558 } elseif ($newarr[0] == $ritts) {
559 $dalt = JText::translate('VBPICKUPAT')." ".date('H:i', $b['checkin']);
560 } elseif ($newarr[0] == $conts) {
561 $dalt = JText::translate('VBRELEASEAT')." ".date('H:i', $b['checkout']);
562 }
563 $totfound++;
564 }
565 }
566 }
567 $useday = ($newarr['mday'] < 10 ? "0".$newarr['mday'] : $newarr['mday']);
568 if ($totfound > 0 && $totfound < $room['units']) {
569 $dclass .= " vbo-partially";
570 }
571 if ($totfound == 1) {
572 $dlnk = "<a href=\"index.php?option=com_vikbooking&task=editbusy&cid[]=".$bid."\"".($ptmpl == 'component' ? ' target="_blank"' : '').">".$useday."</a>";
573 $cal .= "<td align=\"center\" data-daydate=\"".date($df, $newarr[0])."\" class=\"".$dclass."\"".(!empty($dalt) ? " title=\"".$dalt."\"" : "").">".$dlnk."</td>\n";
574 } elseif ($totfound > 1) {
575 $dlnk = "<a href=\"index.php?option=com_vikbooking&task=choosebusy&idroom=".$room['id']."&ts=".$newarr[0]."\"".($ptmpl == 'component' ? ' target="_blank"' : '').">".$useday."</a>";
576 $cal .= "<td align=\"center\" data-daydate=\"".date($df, $newarr[0])."\" class=\"".$dclass."\">".$dlnk."</td>\n";
577 } else {
578 $dlnk = $useday;
579 $cal .= "<td align=\"center\" data-daydate=\"".date($df, $newarr[0])."\" class=\"".$dclass."\">".$dlnk."</td>\n";
580 }
581 $next = $newarr['mday'] + 1;
582 $dayts = mktime(0, 0, 0, $newarr['mon'], $next, $newarr['year']);
583 $newarr = getdate($dayts);
584 $d_count++;
585 }
586
587 for ($i = $d_count; $i <= 6; $i++) {
588 $cal .= "<td align=\"center\">&nbsp;</td>";
589 }
590
591 echo $cal;
592 ?>
593 </tr>
594 </table>
595 <?php
596 echo "</div>";
597 if ($mon == 12) {
598 $mon = 1;
599 $year += 1;
600 $dayts = mktime(0, 0, 0, $mon, 01, $year);
601 } else {
602 $mon += 1;
603 $dayts = mktime(0, 0, 0, $mon, 01, $year);
604 }
605 $newarr = getdate($dayts);
606 }
607 ?>
608 </div>
609 </div>
610 </div>
611
612 </div>
613
614 <div class="vbo-calendar-modal-helper" style="display: none;">
615 <div class="vbo-calendar-cfields-filler">
616 <div class="vbo-calendar-cfields-topcont">
617 <div class="vbo-calendar-cfields-search">
618 <div class="vbo-singleselect-inline-elems-wrap vbo-search-elems-wrap">
619 <?php
620 /**
621 * Display a search elements dropdown for searching customers.
622 *
623 * @since 1.18.0 (J) - 1.8.0 (WP)
624 */
625 echo $vbo_app->renderSearchElementsDropDown([
626 'id' => 'vbo-calendar-view-search-customer',
627 'elements' => 'customers',
628 'placeholder' => JText::translate('VBOSEARCHEXISTCUST'),
629 'allow_clear' => true,
630 'attributes' => [
631 'name' => 'calendar[id_customer]',
632 ],
633 'style_selection' => true,
634 'selection_class' => 'vbo-sel2-selected-search-elem-full',
635 'selection_event' => 'vbo-calendar-view-choose-customer',
636 'load_assets' => false,
637 'width' => '300px',
638 ]);
639 ?>
640 </div>
641 </div>
642 </div>
643 <div class="vbo-calendar-cfields-inner">
644 <?php
645 foreach ($all_cfields as $cfield) {
646 if ($cfield['type'] == 'text' && $cfield['isphone'] == 1) {
647 ?>
648 <div class="vbo-calendar-cfield-entry">
649 <label for="cfield<?php echo $cfield['id']; ?>" data-fieldid="<?php echo $cfield['id']; ?>"><?php echo JText::translate($cfield['name']); ?></label>
650 <span>
651 <?php
652 echo $vbo_app->printPhoneInputField([
653 'id' => 'cfield' . $cfield['id'],
654 'class' => 'vbo-calendar-cfield-phone',
655 'data-isemail' => '0',
656 'data-isnominative' => '0',
657 'data-isphone' => '1'
658 ], [
659 'fullNumberOnBlur' => true
660 ]);
661 ?>
662 </span>
663 </div>
664 <?php
665 } elseif ($cfield['type'] == 'text') {
666 ?>
667 <div class="vbo-calendar-cfield-entry">
668 <label for="cfield<?php echo $cfield['id']; ?>" data-fieldid="<?php echo $cfield['id']; ?>"><?php echo JText::translate($cfield['name']); ?></label>
669 <span>
670 <input type="text" id="cfield<?php echo $cfield['id']; ?>" data-isemail="<?php echo ($cfield['isemail'] == 1 ? '1' : '0'); ?>" data-isnominative="<?php echo ($cfield['isnominative'] == 1 ? '1' : '0'); ?>" data-isphone="0" value="" size="35"/>
671 </span>
672 </div>
673 <?php
674 } elseif ($cfield['type'] == 'textarea') {
675 ?>
676 <div class="vbo-calendar-cfield-entry">
677 <label for="cfield<?php echo $cfield['id']; ?>" data-fieldid="<?php echo $cfield['id']; ?>"><?php echo JText::translate($cfield['name']); ?></label>
678 <span>
679 <textarea id="cfield<?php echo $cfield['id']; ?>" rows="4" cols="35"></textarea>
680 </span>
681 </div>
682 <?php
683 } elseif ($cfield['type'] == 'country') {
684 ?>
685 <div class="vbo-calendar-cfield-entry">
686 <label for="cfield<?php echo $cfield['id']; ?>" data-fieldid="<?php echo $cfield['id']; ?>"><?php echo JText::translate($cfield['name']); ?></label>
687 <span>
688 <select id="cfield<?php echo $cfield['id']; ?>" class="vbo-calendar-cfield-country">
689 <option value=""> </option>
690 <?php
691 foreach ($all_countries as $country) {
692 ?>
693 <option value="<?php echo $country['country_name']; ?>" data-ccode="<?php echo $country['country_3_code']; ?>" data-c2code="<?php echo $country['country_2_code']; ?>"><?php echo $country['country_name']; ?></option>
694 <?php
695 }
696 ?>
697 </select>
698 </span>
699 </div>
700 <?php
701 } elseif ($cfield['type'] == 'state') {
702 ?>
703 <div class="vbo-calendar-cfield-entry">
704 <label for="cfield<?php echo $cfield['id']; ?>" data-fieldid="<?php echo $cfield['id']; ?>"><?php echo JText::translate($cfield['name']); ?></label>
705 <span>
706 <select id="cfield<?php echo $cfield['id']; ?>" class="vbo-calendar-cfield-state">
707 <option value="">-----</option>
708 </select>
709 </span>
710 </div>
711 <?php
712 }
713 }
714 ?>
715 </div>
716 </div>
717 </div>
718
719 <form action="index.php?option=com_vikbooking" method="post" name="adminForm" id="adminForm">
720 <input type="hidden" name="task" value="" />
721 <input type="hidden" name="option" value="com_vikbooking" />
722 </form>
723
724 <script type="text/javascript">
725 <?php echo ($poverview_change > 0 ? 'window.parent.hasNewBooking = true;' . "\n" : ''); ?>
726 var vbo_glob_sel_nights = 0;
727 var prev_tareat = null;
728 var booknowmade = false;
729 var vbo_quickres_has_custdetails = false;
730 var vboListingsMiniThumbnails = <?php echo json_encode(VBORoomHelper::getInstance()->loadMiniThumbnails($allc)); ?>;
731
732 function vbCloseRoom() {
733 var ckbox = jQuery('input[name="setclosed"]');
734 if (ckbox.length && ckbox.prop('checked')) {
735 jQuery('#vbo-close-all-rooms-sel').show();
736 jQuery('#vbo-row-people').hide();
737 if (jQuery('#vbo-row-numrooms').length) {
738 jQuery('#vbo-row-numrooms').hide();
739 }
740 jQuery('#vbo-row-bstat').hide();
741 jQuery('#vbo-row-custcost').hide();
742 jQuery('#vbo-row-cmail').hide();
743 jQuery('#vbo-row-fillcustfields').hide();
744 jQuery('#vbo-row-bpay').hide();
745 jQuery("#vbo-website-rates-row").hide();
746 if (prev_tareat === null) {
747 // save the previous customer information
748 prev_tareat = jQuery('#vbcustdatatxtarea').val();
749 }
750 jQuery('#vbcustdatatxtarea').val(Joomla.JText._('VBDBTEXTROOMCLOSED'));
751 jQuery('#vbcustdatalbl').text(Joomla.JText._('ORDER_NOTES'));
752 jQuery("#quickbsubmit").removeClass("btn-success").addClass("btn-danger").find("span").text(Joomla.JText._('VBSUBMCLOSEROOM'));
753 // hide force booking and untick checkbox
754 jQuery('#vbo-force-bookingdates').hide();
755 jQuery('input[name="forcebooking"]').prop('checked', false);
756 } else {
757 jQuery('#vbo-close-all-rooms-sel').hide();
758 jQuery('#vbo-row-people').show();
759 if (jQuery('#vbo-row-numrooms').length) {
760 jQuery('#vbo-row-numrooms').show();
761 }
762 jQuery('#vbo-row-bstat').show();
763 jQuery('#vbo-row-custcost').show();
764 jQuery('#vbo-row-cmail').show();
765 jQuery('#vbo-row-fillcustfields').show();
766 jQuery('#vbo-row-bpay').show();
767 jQuery('#vbcustdatatxtarea').val(prev_tareat + "");
768 jQuery('#vbcustdatalbl').text(Joomla.JText._('VBCUSTINFO'));
769 jQuery("#quickbsubmit").removeClass("btn-danger").addClass("btn-success").find("span").text(Joomla.JText._('VBMAKERESERV'));
770 }
771 }
772
773 function showCustomFields() {
774 let modal_body = VBOCore.displayModal({
775 suffix: 'calendar-cfields',
776 extra_class: 'vbo-modal-tall',
777 title: Joomla.JText._('VBFILLCUSTFIELDS'),
778 body_prepend: true,
779 footer_left: '<button type="button" class="btn" onclick="hideCustomFields();">' + Joomla.JText._('VBANNULLA') + '</button>',
780 footer_right: '<button type="button" class="btn btn-success" onclick="applyCustomFieldsContent();"><i class="icon-edit"></i> ' + Joomla.JText._('VBAPPLY') + '</button>',
781 dismiss_event: 'vbo-calendar-cfields-dismiss',
782 onDismiss: () => {
783 jQuery('.vbo-calendar-cfields-filler').appendTo('.vbo-calendar-modal-helper');
784 },
785 });
786
787 jQuery('.vbo-calendar-cfields-filler').appendTo(modal_body);
788
789 setTimeout(function() {
790 jQuery('#vbo-calendar-view-search-customer').select2('open');
791 }, 500);
792 }
793
794 function hideCustomFields() {
795 // dismiss modal
796 VBOCore.emitEvent('vbo-calendar-cfields-dismiss');
797 // trigger event to unregister the keydown event for choosing the customer
798 VBOCore.emitEvent('vbo-search-customers-navigation-dismissed');
799 }
800
801 function applyCustomFieldsContent() {
802 var cfields_cont = "";
803 var cfields_labels = new Array;
804 var nominatives = new Array;
805 var tot_rows = 1;
806 jQuery(".vbo-calendar-cfields-inner .vbo-calendar-cfield-entry").each(function() {
807 var cfield_name = jQuery(this).find("label").text();
808 var cfield_input = jQuery(this).find("span").find("input");
809 var cfield_textarea = jQuery(this).find("span").find("textarea");
810 var cfield_select = jQuery(this).find("span").find("select.vbo-calendar-cfield-country");
811 var cfield_state = jQuery(this).find("span").find("select.vbo-calendar-cfield-state");
812 var cfield_cont = "";
813 if (cfield_input.length) {
814 cfield_cont = cfield_input.val();
815 if (cfield_input.attr("data-isemail") == "1" && cfield_cont && cfield_cont.length) {
816 jQuery("#custmailfield").val(cfield_cont);
817 }
818 if (cfield_input.attr("data-isphone") == "1") {
819 jQuery("#phonefield").val(cfield_cont);
820 }
821 if (cfield_input.attr("data-isnominative") == "1") {
822 nominatives.push(cfield_cont);
823 }
824 } else if (cfield_textarea.length) {
825 cfield_cont = cfield_textarea.val();
826 } else if (cfield_select.length) {
827 cfield_cont = cfield_select.val();
828 if (cfield_cont && cfield_cont.length) {
829 var country_code = jQuery("option:selected", cfield_select).attr("data-ccode");
830 if (country_code.length) {
831 jQuery("#ccode_inpfield").val(country_code);
832 }
833 }
834 } else if (cfield_state.length) {
835 cfield_cont = cfield_state.val();
836 jQuery("#state_inpfield").val(cfield_cont);
837 }
838 if (cfield_cont && cfield_cont.length) {
839 cfields_cont += cfield_name + ": " + cfield_cont + "\r\n";
840 tot_rows++;
841 cfields_labels.push(cfield_name + ":");
842 }
843 });
844 if (cfields_cont.length) {
845 cfields_cont = cfields_cont.replace(/\r\n+$/, "");
846 }
847 if (nominatives.length > 1) {
848 jQuery("#t_first_name_inpfield").val(nominatives[0]);
849 jQuery("#t_last_name_inpfield").val(nominatives[1]);
850 }
851 jQuery("#vbcustdatatxtarea").val(cfields_cont);
852 jQuery("#vbcustdatatxtarea").attr("rows", tot_rows);
853 // highlight custom fields labels
854 if (jQuery('#vbo-highlight-cfields').length) {
855 jQuery("#vbcustdatatxtarea").highlightTextarea('destroy');
856 }
857 jQuery("#vbcustdatatxtarea").highlightTextarea({
858 words: cfields_labels,
859 color: "#ddd",
860 id: "vbo-highlight-cfields"
861 });
862 // end highlight
863 hideCustomFields();
864 // toggle var to detect some values were entered
865 vbo_quickres_has_custdetails = true;
866 }
867
868 function vbCalcNights() {
869 vbo_glob_sel_nights = 0;
870 var vbcheckin = document.getElementById("checkindate").value;
871 var vbcheckout = document.getElementById("checkoutdate").value;
872 if (vbcheckin.length > 0 && vbcheckout.length > 0) {
873 var vbcheckinp = vbcheckin.split("/");
874 var vbcheckoutp = vbcheckout.split("/");
875 var vbo_df = "<?php echo $vbo_df; ?>";
876 if (vbo_df == "%d/%m/%Y") {
877 var vbinmonth = parseInt(vbcheckinp[1]);
878 vbinmonth = vbinmonth - 1;
879 var vbinday = parseInt(vbcheckinp[0], 10);
880 var vbcheckind = new Date(vbcheckinp[2], vbinmonth, vbinday);
881 var vboutmonth = parseInt(vbcheckoutp[1]);
882 vboutmonth = vboutmonth - 1;
883 var vboutday = parseInt(vbcheckoutp[0], 10);
884 var vbcheckoutd = new Date(vbcheckoutp[2], vboutmonth, vboutday);
885 }else if (vbo_df == "%m/%d/%Y") {
886 var vbinmonth = parseInt(vbcheckinp[0]);
887 vbinmonth = vbinmonth - 1;
888 var vbinday = parseInt(vbcheckinp[1], 10);
889 var vbcheckind = new Date(vbcheckinp[2], vbinmonth, vbinday);
890 var vboutmonth = parseInt(vbcheckoutp[0]);
891 vboutmonth = vboutmonth - 1;
892 var vboutday = parseInt(vbcheckoutp[1], 10);
893 var vbcheckoutd = new Date(vbcheckoutp[2], vboutmonth, vboutday);
894 } else {
895 var vbinmonth = parseInt(vbcheckinp[1]);
896 vbinmonth = vbinmonth - 1;
897 var vbinday = parseInt(vbcheckinp[2], 10);
898 var vbcheckind = new Date(vbcheckinp[0], vbinmonth, vbinday);
899 var vboutmonth = parseInt(vbcheckoutp[1]);
900 vboutmonth = vboutmonth - 1;
901 var vboutday = parseInt(vbcheckoutp[2], 10);
902 var vbcheckoutd = new Date(vbcheckoutp[0], vboutmonth, vboutday);
903 }
904 var vbdivider = 1000 * 60 * 60 * 24;
905 var vbints = vbcheckind.getTime();
906 var vboutts = vbcheckoutd.getTime();
907 if (vboutts > vbints) {
908 //var vbnights = Math.ceil((vboutts - vbints) / (vbdivider));
909 var utc1 = Date.UTC(vbcheckind.getFullYear(), vbcheckind.getMonth(), vbcheckind.getDate());
910 var utc2 = Date.UTC(vbcheckoutd.getFullYear(), vbcheckoutd.getMonth(), vbcheckoutd.getDate());
911 var vbnights = Math.ceil((utc2 - utc1) / vbdivider);
912 if (vbnights > 0) {
913 vbo_glob_sel_nights = vbnights;
914 jQuery('#vbjstotnights').show();
915 jQuery("#vbo-numnights").val(vbnights);
916 // update average cost per night
917 vbCalcDailyCost(document.getElementById("cust_cost").value);
918 } else {
919 jQuery('#vbjstotnights').hide();
920 }
921 } else {
922 jQuery('#vbjstotnights').hide();
923 }
924 } else {
925 jQuery('#vbjstotnights').hide();
926 }
927 }
928
929 function vbCalcDailyCost(cur_val) {
930 // trigger calculation of website rates
931 vboCalcWebsiteRates();
932 //
933 if (cur_val.length && !isNaN(cur_val) && vbo_glob_sel_nights > 0) {
934 var cur_float = parseFloat(cur_val);
935 var selopts = jQuery("#avg-daycost").find("select").find("option");
936 // total cost with average cost per night
937 var avg_cost = (cur_float / vbo_glob_sel_nights).toFixed(<?php echo (int)$formatparts[0]; ?>);
938 var avg_cost_str = "<?php echo $currencysymb; ?> " + avg_cost + "/" + Joomla.JText._('VBDAY') + " = <?php echo $currencysymb; ?> " + cur_float.toFixed(<?php echo (int)$formatparts[0]; ?>);
939 selopts.first().text(avg_cost_str);
940 // cost multiplied by number of nights
941 var final_cost = (cur_float * vbo_glob_sel_nights).toFixed(<?php echo (int)$formatparts[0]; ?>);
942 var final_cost_str = "<?php echo $currencysymb; ?> " + cur_float.toFixed(<?php echo (int)$formatparts[0]; ?>) + "/" + Joomla.JText._('VBDAY') + " = <?php echo $currencysymb; ?> " + final_cost;
943 selopts.last().text(final_cost_str);
944 // show drop down
945 jQuery("#avg-daycost").show();
946 } else {
947 jQuery("#avg-daycost").hide();
948 }
949 }
950
951 function vboCalcWebsiteRates() {
952 // unset previously selected rates, if any
953 vboUnsetWebsiteRate();
954 // hide force booking and untick checkbox
955 jQuery('#vbo-force-bookingdates').hide();
956 jQuery('input[name="forcebooking"]').prop('checked', false);
957 //
958 var checkinfdate = jQuery("#checkindate").val();
959 var adults = jQuery("#vbo-sel-adults").val();
960 var children = jQuery("#vbo-sel-children").val();
961 var units = jQuery("#vbo-sel-numrooms").val();
962 if (!checkinfdate.length || vbo_glob_sel_nights < 1 || jQuery("input[name=\"setclosed\"]").is(":checked") || <?php echo !empty($split_stay) ? 'true' : 'false'; ?>) {
963 jQuery("#vbo-website-rates-row").hide();
964 return false;
965 }
966 var jqxhr = jQuery.ajax({
967 type: "POST",
968 url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=calc_rates'); ?>",
969 data: {
970 id_room: <?php echo $room['id']; ?>,
971 checkinfdate: checkinfdate,
972 num_nights: vbo_glob_sel_nights,
973 num_adults: adults,
974 num_children: children,
975 units: units,
976 only_rates: 1,
977 tmpl: "component"
978 }
979 }).done(function(resp) {
980 var obj_res = null;
981 try {
982 obj_res = typeof resp === 'string' ? JSON.parse(resp) : resp;
983 } catch(err) {
984 console.error("could not parse JSON response", resp);
985 }
986 if (obj_res === null || !Array.isArray(obj_res)) {
987 jQuery("#vbo-website-rates-row").hide();
988 console.info("invalid JSON response", resp);
989 return false;
990 }
991 if (jQuery("input[name=\"setclosed\"]").is(":checked")) {
992 jQuery("#vbo-website-rates-row").hide();
993 return false;
994 }
995 if (obj_res.hasOwnProperty(1) && obj_res[1] == -1 && !jQuery('input[name="setclosed"]').prop('checked')) {
996 // the room is not available or has no rates, display force booking toggle
997 jQuery('#vbo-force-bookingdates').show();
998 if (typeof obj_res[0] == 'string' && obj_res[0].indexOf('e4j.error') >= 0) {
999 jQuery('#vbo-force-bookingdates').find('.vbo-param-setting-comment').text(obj_res[0].replace('e4j.error.', ''));
1000 } else {
1001 jQuery('#vbo-force-bookingdates').find('.vbo-param-setting-comment').text('');
1002 }
1003 }
1004 if (!obj_res[0].hasOwnProperty("idprice")) {
1005 jQuery("#vbo-website-rates-row").hide();
1006 console.log("error in response", resp);
1007 return false;
1008 }
1009 // check whether rates are inclusive of taxes
1010 var vbo_tax_included = <?php echo $prices_vat_included; ?>;
1011 // display the rates obtained
1012 var wrhtml = "";
1013 for (var i in obj_res) {
1014 if (!obj_res.hasOwnProperty(i)) {
1015 continue;
1016 }
1017 if (!vbo_tax_included && obj_res[i].hasOwnProperty('net') && obj_res[i].hasOwnProperty('fnet')) {
1018 obj_res[i]['tot'] = obj_res[i]['net'];
1019 obj_res[i]['ftot'] = obj_res[i]['fnet'];
1020 }
1021 wrhtml += "<div class=\"vbo-cal-wbrate-wrap\" onclick=\"vboSelWebsiteRate(this);\">";
1022 wrhtml += "<div class=\"vbo-cal-wbrate-inner\">";
1023 wrhtml += "<span class=\"vbo-cal-wbrate-name\" data-idprice=\"" + obj_res[i]['idprice'] + "\">" + obj_res[i]['name'] + "</span>";
1024 wrhtml += "<span class=\"vbo-cal-wbrate-cost\" data-cost=\"" + obj_res[i]['tot'] + "\">" + obj_res[i]['ftot'] + "</span>";
1025 wrhtml += "</div>";
1026 wrhtml += "</div>";
1027 }
1028 jQuery("#vbo-website-rates-cont").html(wrhtml);
1029 jQuery("#vbo-website-rates-row").fadeIn();
1030 if (<?php echo $pidprice > 0 && $pbooknow > 0 ? 'true' : 'false'; ?> && !booknowmade) {
1031 // we get here by clicking the book-now button from the rates calculator only once
1032 booknowmade = true;
1033 // trigger the click for the requested rate plan ID
1034 jQuery('.vbo-cal-wbrate-name[data-idprice="<?php echo $pidprice; ?>"]').closest('.vbo-cal-wbrate-wrap').trigger('click');
1035 }
1036 }).fail(function() {
1037 jQuery("#vbo-website-rates-row").hide();
1038 console.error("Error calculating the rates");
1039 });
1040 }
1041
1042 function vboSelWebsiteRate(elem) {
1043 var rate = jQuery(elem);
1044 var idprice = rate.find('.vbo-cal-wbrate-name').attr('data-idprice');
1045 var cost = rate.find('.vbo-cal-wbrate-cost').attr('data-cost');
1046 var prev_idprice = jQuery('#booking-idprice').val();
1047 // reset all selected classes
1048 jQuery('.vbo-cal-wbrate-wrap').removeClass('vbo-cal-wbrate-wrap-selected');
1049 if (prev_idprice.length && prev_idprice == idprice) {
1050 // rate plan has been de-selected
1051 jQuery('#booking-idprice').val("");
1052 jQuery('#booking-roomcost').val("");
1053 jQuery('#cust_cost').attr('readonly', false);
1054 } else {
1055 // rate plan has been selected
1056 rate.addClass('vbo-cal-wbrate-wrap-selected');
1057 jQuery('#booking-idprice').val(idprice);
1058 jQuery('#booking-roomcost').val(cost);
1059 jQuery('#cust_cost').attr('readonly', true);
1060 }
1061 }
1062
1063 function vboUnsetWebsiteRate() {
1064 jQuery('#booking-idprice').val("");
1065 jQuery('#booking-roomcost').val("");
1066 jQuery('.vbo-cal-wbrate-wrap').removeClass('vbo-cal-wbrate-wrap-selected');
1067 jQuery('#cust_cost').attr('readonly', false);
1068 }
1069
1070 function vboReloadStates(country_3_code) {
1071 var states_elem = jQuery('select.vbo-calendar-cfield-state');
1072
1073 // unset the current states/provinces
1074 states_elem.html('');
1075
1076 if (!country_3_code || !country_3_code.length) {
1077 return;
1078 }
1079
1080 // make a request to load the states/provinces of the selected country
1081 VBOCore.doAjax(
1082 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=states.load_from_country'); ?>",
1083 {
1084 country_3_code: country_3_code,
1085 tmpl: "component"
1086 },
1087 (response) => {
1088 try {
1089 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
1090 if (!obj_res) {
1091 console.error('Unexpected JSON response', obj_res);
1092 return false;
1093 }
1094
1095 // append empty value
1096 states_elem.append('<option value="">-----</option>');
1097
1098 for (var i = 0; i < obj_res.length; i++) {
1099 // append state
1100 states_elem.append('<option value="' + obj_res[i]['state_2_code'] + '">' + obj_res[i]['state_name'] + '</option>');
1101 }
1102 } catch(err) {
1103 console.error('could not parse JSON response', err, response);
1104 }
1105 },
1106 (error) => {
1107 console.error(error);
1108 }
1109 );
1110 }
1111
1112 jQuery(function() {
1113
1114 jQuery('.vbo-calendar-cfield-country').on('change', function() {
1115 // trigger event for phone number
1116 jQuery('.vbo-calendar-cfield-phone').trigger('vboupdatephonenumber', jQuery(this).find('option:selected').attr('data-c2code'));
1117 // reload state/province
1118 vboReloadStates(jQuery(this).find('option:selected').attr('data-ccode'));
1119 });
1120
1121 jQuery('td.free').click(function() {
1122 var indate = jQuery('#checkindate').val();
1123 var outdate = jQuery('#checkoutdate').val();
1124 var clickdate = jQuery(this).attr('data-daydate');
1125 if (!(indate.length > 0)) {
1126 jQuery('#checkindate').vboDatesRangePicker("setCheckinDate", clickdate);
1127 } else if (!(outdate.length > 0) && clickdate != indate) {
1128 jQuery('#checkindate').vboDatesRangePicker("setDates", [indate, clickdate]);
1129 } else {
1130 jQuery('#checkindate').vboDatesRangePicker("setDates", [clickdate, '']);
1131 }
1132 jQuery(".ui-datepicker-current-day").click();
1133 });
1134
1135 jQuery("#quickbsubmit").click(function() {
1136 setTimeout(function() {
1137 jQuery(this).prop('disabled', true);
1138 }, 200);
1139 });
1140
1141 jQuery('#vbo-calendar-newb-form').on('submit', function() {
1142 if (!document.newb.checkindate.value.match(/\S/)) {
1143 alert(Joomla.JText._('VBMSGTHREE'));
1144 jQuery('#quickbsubmit').prop('disabled', false);
1145 return false;
1146 }
1147
1148 if (!document.newb.checkoutdate.value.match(/\S/)) {
1149 alert(Joomla.JText._('VBMSGFOUR'));
1150 jQuery('#quickbsubmit').prop('disabled', false);
1151 return false;
1152 }
1153
1154 jQuery('#quickbsubmit').prop('disabled', true);
1155
1156 if (!jQuery(this).find('[name="setclosed"]').prop('checked') && !jQuery(this).find('[name="custmail"]').val() && !vbo_quickres_has_custdetails && <?php echo $room['units'] > 1 ? 'true' : 'false'; ?>) {
1157 // no closure, no customer email, multiple units, ask if the units should be marked as closed
1158 if (confirm(Joomla.JText._('VBO_MARK_UNITS_CLOSED'))) {
1159 // append hidden field to form
1160 jQuery(this).append('<input type="hidden" name="setunitsclosed" value="1" />');
1161 // check if "room closed" should be added
1162 if (!jQuery('#vbcustdatatxtarea').val()) {
1163 jQuery('#vbcustdatatxtarea').val(Joomla.JText._('VBDBTEXTROOMCLOSED'));
1164 }
1165 }
1166 }
1167
1168 return true;
1169 });
1170
1171 jQuery("#vbo-calendar-changeroom").select2({
1172 templateResult: (element) => {
1173 if (typeof vboListingsMiniThumbnails !== 'undefined' && vboListingsMiniThumbnails.hasOwnProperty((element.id || 0))) {
1174 return jQuery('<span class="vbo-sel2-element-img"><img src="' + vboListingsMiniThumbnails[element.id] + '" /> <span>' + element.text + '</span></span>');
1175 } else {
1176 return element.text;
1177 }
1178 },
1179 });
1180
1181 if (jQuery("#vbo-calendar-closeall").length) {
1182 jQuery("#vbo-calendar-closeall").select2({
1183 placeholder: "- " + Joomla.JText._('VBOCALCLOSEOTHERROOMS') + " -",
1184 width: "300px",
1185 templateResult: (element) => {
1186 if (typeof vboListingsMiniThumbnails !== 'undefined' && vboListingsMiniThumbnails.hasOwnProperty((element.id || 0))) {
1187 return jQuery('<span class="vbo-sel2-element-img"><img src="' + vboListingsMiniThumbnails[element.id] + '" /> <span>' + element.text + '</span></span>');
1188 } else {
1189 return element.text;
1190 }
1191 },
1192 });
1193 }
1194
1195 jQuery("#vbo-sel-numrooms, #vbo-sel-adults").change(function() {
1196 vboCalcWebsiteRates();
1197 });
1198
1199 jQuery('.vbo-calendar-cfield-entry input[data-isemail="1"]').first().blur(function() {
1200 var curemail = jQuery(this).val();
1201 if (curemail.length) {
1202 var jqxhr = jQuery.ajax({
1203 type: "POST",
1204 url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=searchcustomer'); ?>",
1205 data: {
1206 kw: curemail,
1207 email: 1,
1208 tmpl: "component"
1209 }
1210 }).done(function(cont) {
1211 try {
1212 var obj_res = typeof cont === 'string' ? JSON.parse(cont) : cont;
1213 alert(Joomla.JText._('VBERRCUSTOMEREMAILEXISTS') + " (" + obj_res['first_name'] + " " + obj_res['last_name'] + ")");
1214 } catch(e) {
1215 console.error(e);
1216 }
1217 }).fail(function() {
1218 console.log("Error searching for existing email");
1219 });
1220 }
1221 });
1222
1223 jQuery("#vbfillcustfields").click(function() {
1224 showCustomFields();
1225 });
1226
1227 // DRP - start
1228 jQuery("#checkindate").vboDatesRangePicker({
1229 checkout: '#checkoutdate',
1230 showOn: "focus",
1231 minDate: '-2y',
1232 maxDate: '+2y',
1233 dateFormat: "<?php echo $juidf; ?>",
1234 numberOfMonths: 2,
1235 responsiveNumMonths: {
1236 threshold: 860,
1237 },
1238 onSelect: {
1239 checkin: (selectedDate) => {
1240 var nownights = parseInt(jQuery('#vbo-numnights').val());
1241 var nowcheckin = jQuery('#checkindate').vboDatesRangePicker('getCheckinDate');
1242 var nowcheckindate = new Date(nowcheckin.getTime());
1243 nowcheckindate.setDate(nowcheckindate.getDate() + nownights);
1244 jQuery('#checkindate').vboDatesRangePicker('checkout', 'minDate', nowcheckindate);
1245 vbCalcNights();
1246 },
1247 checkout: (selectedDate) => {
1248 if (!jQuery('#checkindate').vboDatesRangePicker('getCheckoutDate')) {
1249 return;
1250 }
1251 vbCalcNights();
1252 },
1253 },
1254 labels: {
1255 checkin: Joomla.JText._('VBPICKUPROOM'),
1256 checkout: Joomla.JText._('VBRETURNROOM'),
1257 },
1258 bottomCommands: {
1259 clear: Joomla.JText._('VBO_CLEAR_DATES'),
1260 close: Joomla.JText._('VBO_CLOSE'),
1261 onClear: () => {
1262 vbCalcNights();
1263 },
1264 },
1265 environment: {
1266 section: 'admin',
1267 autoHide: true,
1268 },
1269 });
1270 jQuery('#checkindate-trig, #checkoutdate-trig').click(function() {
1271 let dp = jQuery(this).prev('input');
1272 if (!dp.length) {
1273 return;
1274 }
1275 if (dp.hasClass('hasDatepicker')) {
1276 dp.focus();
1277 } else if (dp.attr('id') == 'checkoutdate') {
1278 jQuery('#checkindate').focus();
1279 }
1280 });
1281 jQuery("#vbo-numnights").on("change keyup", function() {
1282 if (!jQuery('#checkindate').vboDatesRangePicker('getCheckinDate')) {
1283 return;
1284 }
1285 var nownights = parseInt(jQuery(this).val());
1286 var nowcheckin = jQuery('#checkindate').vboDatesRangePicker('getCheckinDate');
1287 var nowcheckindate = new Date(nowcheckin.getTime());
1288 nowcheckindate.setDate(nowcheckindate.getDate() + nownights);
1289 // update checkout date
1290 jQuery('#checkindate').vboDatesRangePicker('setCheckoutDate', nowcheckindate);
1291 // update global nights of stay
1292 vbo_glob_sel_nights = nownights;
1293 // update average cost per night
1294 vbCalcDailyCost(document.getElementById("cust_cost").value);
1295 });
1296 // datepickers - end
1297 <?php echo (!empty($pcheckin) || !empty($pcheckout) ? 'jQuery("#checkindate").vboDatesRangePicker("setDates", ["'.$pcheckin.'", "'.$pcheckout.'"]);'."\n" : ''); ?>
1298 });
1299
1300 // subscribe to the event for choosing a customer to assign to a new booking
1301 document.addEventListener('vbo-calendar-view-choose-customer', vboCalendarHandleCustomerSelection);
1302
1303 /**
1304 * Handles the selection of a customer to assign to a new booking.
1305 */
1306 function vboCalendarHandleCustomerSelection(e) {
1307 if (!e?.detail?.element?.id) {
1308 return;
1309 }
1310
1311 let custid = e.detail.element.id;
1312 let custemail = e.detail.element?.email;
1313 let custphone = e.detail.element?.phone;
1314 let custcountry = e.detail.element?.country;
1315 let custfirstname = e.detail.element?.first_name;
1316 let custlastname = e.detail.element?.last_name;
1317
1318 // set customer ID
1319 jQuery("#customer_id_inpfield").val(custid);
1320
1321 // check previous custom fields
1322 if (e.detail.element?.cfields && typeof e.detail.element.cfields === 'object') {
1323 for (const [cfid, cfval] of Object.entries(e.detail.element.cfields)) {
1324 let fill_field = document.querySelector('#cfield' + cfid);
1325 if (fill_field && cfval) {
1326 // set previous value
1327 fill_field.value = cfval;
1328 }
1329 }
1330 } else {
1331 jQuery("input[data-isnominative=\"1\"]").each(function(k, v) {
1332 if (k == 0) {
1333 jQuery(this).val(custfirstname);
1334 return true;
1335 }
1336 if (k == 1) {
1337 jQuery(this).val(custlastname);
1338 return true;
1339 }
1340 return false;
1341 });
1342 jQuery("input[data-isemail=\"1\"]").val(custemail);
1343 jQuery("input[data-isphone=\"1\"]").val(custphone).trigger('vboupdatephonenumber');
1344 // populate main calendar form
1345 jQuery("#custmailfield").val(custemail);
1346 jQuery("#t_first_name_inpfield").val(custfirstname);
1347 jQuery("#t_last_name_inpfield").val(custlastname);
1348 }
1349
1350 applyCustomFieldsContent();
1351
1352 if (custcountry.length) {
1353 jQuery("#ccode_inpfield").val(custcountry);
1354 }
1355 if (custphone.length) {
1356 jQuery("#phonefield").val(custphone);
1357 }
1358 };
1359
1360 var vborefreshingsel = false;
1361 function vboCheckCloseOthers() {
1362 if (!jQuery("#vbo-calendar-closeall").length || vborefreshingsel) {
1363 // avoid recursion loop by triggering the change event for select2
1364 return;
1365 }
1366 var selall = jQuery('#vbo-calendar-closeall option[value="-1"]').is(':selected');
1367 // always select the current room unless all get de-selected
1368 var optselected = jQuery('#vbo-calendar-closeall option:selected');
1369 var none_sel = !optselected.length ? true : false;
1370 if (optselected.length === 1 && optselected.first().attr('data-currentr')) {
1371 none_sel = true;
1372 }
1373 var curropt = jQuery('#vbo-calendar-closeall option[data-currentr="true"]');
1374 if (!none_sel) {
1375 curropt.prop('selected', true);
1376 curropt.prop('disabled', true);
1377 } else {
1378 curropt.prop('selected', false);
1379 curropt.prop('disabled', true);
1380 }
1381 //
1382 jQuery('#vbo-calendar-closeall').find('option').each(function() {
1383 var curval = jQuery(this).val();
1384 var curroom = jQuery(this).attr('data-currentr');
1385 if (!curval.length || curval == '-1' || curroom) {
1386 return true;
1387 }
1388 if (selall) {
1389 jQuery(this).prop('disabled', true);
1390 jQuery(this).prop('selected', false);
1391 } else {
1392 jQuery(this).prop('disabled', false);
1393 }
1394 });
1395 vboRefreshCloseOthers();
1396 }
1397
1398 function vboRefreshCloseOthers() {
1399 // prevent recursion loop
1400 vborefreshingsel = true;
1401 jQuery("#vbo-calendar-closeall").trigger('change');
1402 setTimeout(function() {
1403 vborefreshingsel = false;
1404 }, 200);
1405 }
1406 </script>
1407