| @@ -1,0 +1,567 @@ | ||
| 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 | +/** | |
| 14 | + * Obtain vars from arguments received in the layout file. | |
| 15 | + * This layout file should be called once at most per page. | |
| 16 | + * | |
| 17 | + * @var string $vbo_page the name of the page invoking the layout file (i.e. dashboard). | |
| 18 | + * @var array $room_ids optional array of specific room IDs to filter. | |
| 19 | + */ | |
| 20 | +extract($displayData); | |
| 21 | + | |
| 22 | +// optional vars that only some pages may define | |
| 23 | +if (!isset($room_ids)) { | |
| 24 | + $room_ids = array(); | |
| 25 | +} | |
| 26 | + | |
| 27 | +$report_name = 'occupancy_ranking'; | |
| 28 | + | |
| 29 | +$cookie = JFactory::getApplication()->input->cookie; | |
| 30 | +$cookie_step = $cookie->get("vbo_reportwidget_{$report_name}_step", 'weekend', 'string'); | |
| 31 | + | |
| 32 | +$vbo_app = VikBooking::getVboApplication(); | |
| 33 | +$vbo_app->loadDatePicker(); | |
| 34 | + | |
| 35 | +// lang vars for JS | |
| 36 | +JText::script('VBOSEVLOWOCC'); | |
| 37 | +JText::script('VBOSEVMEDOCC'); | |
| 38 | +JText::script('VBOSEVHIGHOCC'); | |
| 39 | +JText::script('VBOSEVLOWINDAYS'); | |
| 40 | +JText::script('VBOSEVMEDINDAYS'); | |
| 41 | +JText::script('VBOSEVHIGHINDAYS'); | |
| 42 | + | |
| 43 | +// get occupancy_ranking report instance | |
| 44 | +$report = VikBooking::getReportInstance($report_name)->loadChartsAssets(); | |
| 45 | + | |
| 46 | +// website date format | |
| 47 | +$df = $report->getDateFormat(); | |
| 48 | + | |
| 49 | +// get the next festivities | |
| 50 | +$fests = VikBooking::getFestivitiesInstance(); | |
| 51 | +if ($fests->shouldCheckFestivities()) { | |
| 52 | + $fests->storeNextFestivities(); | |
| 53 | +} | |
| 54 | +$next_fests = $fests->loadFestDates(); | |
| 55 | + | |
| 56 | +// calculate the next from/to date | |
| 57 | +$is_fest = null; | |
| 58 | + | |
| 59 | +// find next interval by default when page loads, unless there's a festivity | |
| 60 | +if ($cookie_step == 'month') { | |
| 61 | + // this month | |
| 62 | + $nowinfo = getdate(); | |
| 63 | + $ts_from = mktime(0, 0, 0, $nowinfo['mon'], 1, $nowinfo['year']); | |
| 64 | + $ts_to = mktime(23, 59, 59, $nowinfo['mon'], date('t', $nowinfo[0]), $nowinfo['year']); | |
| 65 | + $period_name = JText::translate('VBPVIEWRESTRICTIONSTWO'); | |
| 66 | +} elseif ($cookie_step == 'week') { | |
| 67 | + // this week | |
| 68 | + $ts_from = time(); | |
| 69 | + $ts_to = strtotime("+1 week", $ts_from); | |
| 70 | + $period_name = JText::translate('VBOWEEK'); | |
| 71 | +} else { | |
| 72 | + // next weekend by default | |
| 73 | + $ts_from = strtotime("next friday"); | |
| 74 | + $ts_to = strtotime("next saturday"); | |
| 75 | + if ($ts_to < $ts_from) { | |
| 76 | + $ts_to = strtotime("+1 week", $ts_to); | |
| 77 | + } | |
| 78 | + $period_name = JText::translate('VBONEXTWEEKND'); | |
| 79 | +} | |
| 80 | + | |
| 81 | +if (count($next_fests)) { | |
| 82 | + // we start from the next fest only if within 15 days | |
| 83 | + $festlim = strtotime("+15 days", time()); | |
| 84 | + foreach ($next_fests as $next_fest) { | |
| 85 | + if ($festlim >= $next_fest['festinfo'][0]->next_ts) { | |
| 86 | + $is_fest = $next_fest['festinfo'][0]->next_ts; | |
| 87 | + $ts_from = $next_fest['festinfo'][0]->from_ts; | |
| 88 | + $ts_to = $next_fest['festinfo'][0]->to_ts; | |
| 89 | + $period_name = $next_fest['festinfo'][0]->trans_name; | |
| 90 | + } | |
| 91 | + // we check only the very next festivity | |
| 92 | + break; | |
| 93 | + } | |
| 94 | +} | |
| 95 | + | |
| 96 | +// obtain data from the report | |
| 97 | +$rparams = array( | |
| 98 | + 'fromdate' => date($df, $ts_from), | |
| 99 | + 'todate' => date($df, $ts_to), | |
| 100 | + 'period' => 'full', | |
| 101 | + 'krsort' => 'occupancy', | |
| 102 | + 'krorder' => 'DESC', | |
| 103 | + 'idroom' => $room_ids, | |
| 104 | +); | |
| 105 | +$report->injectParams($rparams); | |
| 106 | +$report_cols = $report->getColumnsValues(); | |
| 107 | +$report_values = $report->getReportValues(1); | |
| 108 | +$report_chart = null; | |
| 109 | +$report_chart_metas = array(); | |
| 110 | +$chart_meta_data = array( | |
| 111 | + 'keys' => array( | |
| 112 | + 'occupancy', | |
| 113 | + 'tot_bookings', | |
| 114 | + 'nights_booked', | |
| 115 | + ), | |
| 116 | +); | |
| 117 | +$error = ''; | |
| 118 | +$in_days = $report->countDaysTo($ts_from); | |
| 119 | +$in_days_to = $report->countDaysTo($ts_to); | |
| 120 | +$in_days_avg = $report->countAverageDays($in_days, $in_days_to); | |
| 121 | + | |
| 122 | +if (!count($report_values)) { | |
| 123 | + $error = strlen($report->getError()) ? $report->getError() : JText::translate('VBNOTRACKINGS'); | |
| 124 | +} else { | |
| 125 | + // get doughnut chart for the occupancy | |
| 126 | + $report_chart = $report->getChart(array( | |
| 127 | + 'type' => 'doughnut', | |
| 128 | + 'depth' => 1, | |
| 129 | + 'keys' => array('occupancy'), | |
| 130 | + )); | |
| 131 | + $all_chart_metas = $report->getChartMetaData(null, $chart_meta_data); | |
| 132 | + if (count($all_chart_metas)) { | |
| 133 | + // merge all positions into one array | |
| 134 | + foreach ($all_chart_metas as $pos_metas) { | |
| 135 | + $report_chart_metas = array_merge($report_chart_metas, $pos_metas); | |
| 136 | + } | |
| 137 | + } | |
| 138 | +} | |
| 139 | + | |
| 140 | +$promo_factors = VikBooking::getPromotionFactors(); | |
| 141 | +$promo_factors = $promo_factors === false ? array() : $promo_factors; | |
| 142 | +$current_occupancy = count($report_values) ? $report_values['occupancy']['value'] : 0; | |
| 143 | +$current_in_days = $in_days > 0 ? $in_days : $in_days_avg; | |
| 144 | + | |
| 145 | +?> | |
| 146 | +<div class="vbo-reportwidget-outer vbo-reportwidget-occupancy vbo-reportwidget-<?php echo $vbo_page; ?>"> | |
| 147 | + <div class="vbo-reportwidget-commands"> | |
| 148 | + <div class="vbo-reportwidget-commands-main"> | |
| 149 | + <div class="vbo-reportwidget-command-dates"> | |
| 150 | + <div class="vbo-reportwidget-period-name"><?php echo $period_name; ?></div> | |
| 151 | + <div class="vbo-reportwidget-period-date"><?php echo count($report_values) ? $report_values['day']['display_value'] : $rparams['fromdate'] . ' - ' . $rparams['todate']; ?></div> | |
| 152 | + </div> | |
| 153 | + <div class="vbo-reportwidget-command-chevron vbo-reportwidget-command-prev"> | |
| 154 | + <span class="vbo-reportwidget-prev"><?php VikBookingIcons::e('chevron-left'); ?></span> | |
| 155 | + </div> | |
| 156 | + <div class="vbo-reportwidget-command-chevron vbo-reportwidget-command-next"> | |
| 157 | + <span class="vbo-reportwidget-next"><?php VikBookingIcons::e('chevron-right'); ?></span> | |
| 158 | + </div> | |
| 159 | + </div> | |
| 160 | + <div class="vbo-reportwidget-command-dots"> | |
| 161 | + <span class="vbo-widget-command-togglefilters vbo-reportwidget-togglefilters"><?php VikBookingIcons::e('ellipsis-v'); ?></span> | |
| 162 | + </div> | |
| 163 | + </div> | |
| 164 | + <div class="vbo-reportwidget-filters"> | |
| 165 | + <div class="vbo-reportwidget-filter"> | |
| 166 | + <span class="vbo-reportwidget-datepicker"> | |
| 167 | + <?php VikBookingIcons::e('calendar', 'vbo-widget-caltrigger'); ?> | |
| 168 | + <input type="text" id="rp_fromdate" class="vbo-report-datepicker-from" value="<?php echo $rparams['fromdate']; ?>" /> | |
| 169 | + </span> | |
| 170 | + </div> | |
| 171 | + <div class="vbo-reportwidget-filter"> | |
| 172 | + <span class="vbo-reportwidget-datepicker"> | |
| 173 | + <?php VikBookingIcons::e('calendar', 'vbo-widget-caltrigger'); ?> | |
| 174 | + <input type="text" id="rp_todate" class="vbo-report-datepicker-to" value="<?php echo $rparams['todate']; ?>" /> | |
| 175 | + </span> | |
| 176 | + <input type="hidden" id="rp_is_fest" value="<?php echo !empty($is_fest) ? $is_fest : ''; ?>" /> | |
| 177 | + </div> | |
| 178 | + <div class="vbo-reportwidget-filter"> | |
| 179 | + <select id="rp_step"> | |
| 180 | + <option value="weekend"<?php echo $cookie_step == 'weekend' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBOWEEKND'); ?></option> | |
| 181 | + <option value="week"<?php echo $cookie_step == 'week' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBOWEEK'); ?></option> | |
| 182 | + <option value="month"<?php echo $cookie_step == 'month' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPVIEWRESTRICTIONSTWO'); ?></option> | |
| 183 | + </select> | |
| 184 | + </div> | |
| 185 | + <div class="vbo-reportwidget-filter vbo-reportwidget-filter-confirm"> | |
| 186 | + <button type="button" class="btn vbo-config-btn" id="vbo-reportwidget-update"><?php echo JText::translate('VBADMINNOTESUPD'); ?></button> | |
| 187 | + </div> | |
| 188 | + </div> | |
| 189 | + <div class="vbo-reportwidget-body"> | |
| 190 | + <div class="vbo-reportwidget-chart"> | |
| 191 | + <?php | |
| 192 | + if (empty($report_chart)) { | |
| 193 | + ?> | |
| 194 | + <p class="err"><?php echo $error; ?></p> | |
| 195 | + <?php | |
| 196 | + } else { | |
| 197 | + // parse the Chart meta data (if any) | |
| 198 | + if (count($report_chart_metas)) { | |
| 199 | + ?> | |
| 200 | + <div class="vbo-reportwidget-chart-metas"> | |
| 201 | + <?php | |
| 202 | + foreach ($report_chart_metas as $chart_meta) { | |
| 203 | + ?> | |
| 204 | + <div class="vbo-reportwidget-chart-meta<?php echo isset($chart_meta['class']) ? ' ' . $chart_meta['class'] : ''; ?>"> | |
| 205 | + <div class="vbo-reportwidget-chart-meta-inner"> | |
| 206 | + <div class="vbo-reportwidget-chart-meta-lbl"><?php echo $chart_meta['label']; ?></div> | |
| 207 | + <div class="vbo-reportwidget-chart-meta-val"> | |
| 208 | + <span class="vbo-reportwidget-chart-meta-val-main"><?php echo $chart_meta['value']; ?></span> | |
| 209 | + <?php | |
| 210 | + if (!empty($chart_meta['descr'])) { | |
| 211 | + ?> | |
| 212 | + <span class="vbo-reportwidget-chart-meta-val-descr"><?php echo $chart_meta['descr']; ?></span> | |
| 213 | + <?php | |
| 214 | + } | |
| 215 | + ?> | |
| 216 | + </div> | |
| 217 | + </div> | |
| 218 | + </div> | |
| 219 | + <?php | |
| 220 | + } | |
| 221 | + ?> | |
| 222 | + </div> | |
| 223 | + <?php | |
| 224 | + } | |
| 225 | + | |
| 226 | + // display the canvas element | |
| 227 | + echo $report_chart; | |
| 228 | + } | |
| 229 | + ?> | |
| 230 | + </div> | |
| 231 | + </div> | |
| 232 | +</div> | |
| 233 | + | |
| 234 | +<a class="vbo-reportwidget-promo-baseuri" style="display: none;" href="index.php?option=com_vikbooking&task=newseason"></a> | |
| 235 | + | |
| 236 | +<script type="text/javascript"> | |
| 237 | +var vboReportWidgetPromoFactors = <?php echo json_encode($promo_factors); ?>; | |
| 238 | +var vboReportWidgetOccupancy = <?php echo $current_occupancy; ?>; | |
| 239 | +var vboReportWidgetIndays = <?php echo $current_in_days; ?>; | |
| 240 | +var vboReportWidgetDfrom = "<?php echo $rparams['fromdate']; ?>"; | |
| 241 | +var vboReportWidgetDto = "<?php echo $rparams['todate']; ?>"; | |
| 242 | +var vboReportWidgetPname = "<?php echo addslashes((count($report_values) ? $report_values['day']['display_value'] : $period_name)); ?>"; | |
| 243 | +var vboReportWidgetRoomids = <?php echo json_encode((is_array($room_ids) ? $room_ids : array())); ?>; | |
| 244 | +jQuery(function() { | |
| 245 | + // suggest promotion when the page loads for the data we have obtained via PHP | |
| 246 | + vboReportWidgetSuggestPromotion(null); | |
| 247 | + // | |
| 248 | + jQuery('.vbo-report-datepicker-from, .vbo-report-datepicker-to').datepicker({ | |
| 249 | + minDate: "-1y", | |
| 250 | + maxDate: "+2y", | |
| 251 | + yearRange: "<?php echo (date('Y') - 1); ?>:<?php echo (date('Y') + 2); ?>", | |
| 252 | + changeMonth: true, | |
| 253 | + changeYear: true, | |
| 254 | + dateFormat: "<?php echo $report->getDateFormat('jui'); ?>", | |
| 255 | + onSelect: vboReportWidgetCheckDates | |
| 256 | + }); | |
| 257 | + jQuery('i.vbo-widget-caltrigger').click(function() { | |
| 258 | + var jdp = jQuery(this).parent().find('input.hasDatepicker'); | |
| 259 | + if (jdp.length) { | |
| 260 | + jdp.focus(); | |
| 261 | + } | |
| 262 | + }); | |
| 263 | + jQuery('#rp_step').change(function() { | |
| 264 | + // update cookie for the step selected | |
| 265 | + var nd = new Date(); | |
| 266 | + nd.setTime(nd.getTime() + (365*24*60*60*1000)); | |
| 267 | + document.cookie = "vbo_reportwidget_<?php echo $report_name; ?>_step=" + jQuery(this).val() + "; expires=" + nd.toUTCString() + "; path=/; SameSite=Lax"; | |
| 268 | + }); | |
| 269 | + jQuery('.vbo-reportwidget-prev, .vbo-reportwidget-next, #vbo-reportwidget-update').click(function() { | |
| 270 | + if (typeof vboJModalShowCallback === 'function') { | |
| 271 | + // simulate STOP click for Dashboard automatic reload | |
| 272 | + vboJModalShowCallback(); | |
| 273 | + } | |
| 274 | + // make the AJAX request to obtain the necessary report data for the next/prev/selected dates | |
| 275 | + var direction = 'load'; | |
| 276 | + if (jQuery(this).hasClass('vbo-reportwidget-prev')) { | |
| 277 | + direction = 'prev'; | |
| 278 | + } else if (jQuery(this).hasClass('vbo-reportwidget-next')) { | |
| 279 | + direction = 'next'; | |
| 280 | + } | |
| 281 | + // always hide the filters when making a new request | |
| 282 | + jQuery('.vbo-reportwidget-filters').hide(); | |
| 283 | + // always hide the promotion suggestion when making a new request | |
| 284 | + vboReportWidgetDestroyPromotion(); | |
| 285 | + // | |
| 286 | + var jqxhr = jQuery.ajax({ | |
| 287 | + type: "POST", | |
| 288 | + url: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=get_report_data'); ?>", | |
| 289 | + data: { | |
| 290 | + tmpl: "component", | |
| 291 | + report_name: "<?php echo $report_name; ?>", | |
| 292 | + current_fest: jQuery('#rp_is_fest').val(), | |
| 293 | + current_fromdate: jQuery('#rp_fromdate').val(), | |
| 294 | + current_todate: jQuery('#rp_todate').val(), | |
| 295 | + step: jQuery('#rp_step').val(), | |
| 296 | + direction: direction, | |
| 297 | + chart_meta_data: JSON.stringify(<?php echo json_encode($chart_meta_data); ?>), | |
| 298 | + idroom: <?php echo json_encode($room_ids); ?>, | |
| 299 | + } | |
| 300 | + }).done(function(res) { | |
| 301 | + var obj = null; | |
| 302 | + try { | |
| 303 | + obj = JSON.parse(res); | |
| 304 | + } catch(e) { | |
| 305 | + obj = null; | |
| 306 | + console.log(res, e); | |
| 307 | + alert('Invalid response received'); | |
| 308 | + } | |
| 309 | + if (obj === null) { | |
| 310 | + return; | |
| 311 | + } | |
| 312 | + // update datepicker dates and display values for the next request | |
| 313 | + jQuery('#rp_fromdate').val(obj.fromdate).datepicker('setDate', obj.fromdate); | |
| 314 | + jQuery('#rp_todate').val(obj.todate).datepicker('setDate', obj.todate); | |
| 315 | + jQuery('.vbo-reportwidget-period-name').text(obj.period_name); | |
| 316 | + if (obj.period_date && obj.period_date.length) { | |
| 317 | + jQuery('.vbo-reportwidget-period-date').text(obj.period_date); | |
| 318 | + } else { | |
| 319 | + jQuery('.vbo-reportwidget-period-date').text(obj.fromdate + ' - ' + obj.todate); | |
| 320 | + } | |
| 321 | + if (obj.is_fest) { | |
| 322 | + jQuery('#rp_is_fest').val(obj.is_fest); | |
| 323 | + } else { | |
| 324 | + jQuery('#rp_is_fest').val(""); | |
| 325 | + } | |
| 326 | + // | |
| 327 | + if (obj.error) { | |
| 328 | + // an error occurred, remove the current Chart (if any), display error, and show filters | |
| 329 | + jQuery('.vbo-reportwidget-chart').first().html('<p class="err">' + obj.error + '</p>'); | |
| 330 | + jQuery('.vbo-reportwidget-filters').show(); | |
| 331 | + return; | |
| 332 | + } | |
| 333 | + // unset current meta data | |
| 334 | + if (jQuery('.vbo-reportwidget-chart-metas').length) { | |
| 335 | + jQuery('.vbo-reportwidget-chart-metas').remove(); | |
| 336 | + } | |
| 337 | + // | |
| 338 | + if (!jQuery('.vbo-reportwidget-chart').find('canvas').length) { | |
| 339 | + // canvas is missing, add it from zero as no update can be made | |
| 340 | + jQuery('.vbo-reportwidget-chart').first().html(obj.report_chart + "<script type=\"text/javascript\">" + obj.report_script + "<\/script>"); | |
| 341 | + vboReportWidgetBuildMetas(obj.report_chart_metas); | |
| 342 | + vboReportWidgetSuggestPromotion(obj); | |
| 343 | + return; | |
| 344 | + } | |
| 345 | + if (typeof vboReportPieData === 'undefined') { | |
| 346 | + alert('Could not update chart'); | |
| 347 | + return; | |
| 348 | + } | |
| 349 | + // update Chart report properties | |
| 350 | + vboReportPieData.labels = obj.chart_labels; | |
| 351 | + vboReportPieData.datasets[0].data = obj.chart_data; | |
| 352 | + try { | |
| 353 | + vboReportPieData.datasets[0].backgroundColor = JSON.parse(obj.chart_colors.pieBackgroundColor); | |
| 354 | + vboReportPieData.datasets[0].hoverBorderColor = JSON.parse(obj.chart_colors.pieHoverBorderColor); | |
| 355 | + } catch(e) { | |
| 356 | + // do nothing | |
| 357 | + } | |
| 358 | + // trigger Chart update | |
| 359 | + jQuery('.vbo-reportwidget-chart').find('canvas').trigger('vbo_update_report_chart'); | |
| 360 | + // re-build meta data | |
| 361 | + vboReportWidgetBuildMetas(obj.report_chart_metas); | |
| 362 | + // suggest promotion | |
| 363 | + vboReportWidgetSuggestPromotion(obj); | |
| 364 | + }).fail(function() { | |
| 365 | + alert('Request failed'); | |
| 366 | + }); | |
| 367 | + }); | |
| 368 | + jQuery('.vbo-reportwidget-togglefilters').click(function() { | |
| 369 | + jQuery('.vbo-reportwidget-filters').toggle(); | |
| 370 | + }); | |
| 371 | +}); | |
| 372 | +function vboReportWidgetCheckDates(selectedDate, inst) { | |
| 373 | + if (selectedDate === null || inst === null) { | |
| 374 | + return; | |
| 375 | + } | |
| 376 | + var cur_from_date = jQuery(this).val(); | |
| 377 | + if (jQuery(this).hasClass("vbo-report-datepicker-from") && cur_from_date.length) { | |
| 378 | + var nowstart = jQuery(this).datepicker("getDate"); | |
| 379 | + var nowstartdate = new Date(nowstart.getTime()); | |
| 380 | + jQuery(".vbo-report-datepicker-to").datepicker("option", {minDate: nowstartdate}); | |
| 381 | + } | |
| 382 | +} | |
| 383 | +function vboReportWidgetBuildMetas(chart_metas_arr) { | |
| 384 | + if (chart_metas_arr.length) { | |
| 385 | + var chart_metas = '<div class="vbo-reportwidget-chart-metas">'; | |
| 386 | + for (var i in chart_metas_arr) { | |
| 387 | + if (!chart_metas_arr.hasOwnProperty(i)) { | |
| 388 | + continue; | |
| 389 | + } | |
| 390 | + chart_metas += '<div class="vbo-reportwidget-chart-meta ' + (chart_metas_arr[i].hasOwnProperty('class') ? chart_metas_arr[i]['class'] : '') + '">'; | |
| 391 | + chart_metas += '<div class="vbo-reportwidget-chart-meta-inner">'; | |
| 392 | + chart_metas += '<div class="vbo-reportwidget-chart-meta-lbl">' + chart_metas_arr[i]['label'] + '</div>'; | |
| 393 | + chart_metas += '<div class="vbo-reportwidget-chart-meta-val">'; | |
| 394 | + chart_metas += '<span class="vbo-reportwidget-chart-meta-val-main">' + chart_metas_arr[i]['value'] + '</span>'; | |
| 395 | + if (chart_metas_arr[i].hasOwnProperty('descr') && chart_metas_arr[i]['descr'].length) { | |
| 396 | + chart_metas += '<span class="vbo-reportwidget-chart-meta-val-descr">' + chart_metas_arr[i]['descr'] + '</span>'; | |
| 397 | + } | |
| 398 | + chart_metas += '</div>'; | |
| 399 | + chart_metas += '</div>'; | |
| 400 | + chart_metas += '</div>'; | |
| 401 | + } | |
| 402 | + chart_metas += '</div>'; | |
| 403 | + // prepend composed metas | |
| 404 | + jQuery('.vbo-reportwidget-chart').prepend(chart_metas); | |
| 405 | + } | |
| 406 | +} | |
| 407 | +function vboReportWidgetSuggestPromotion(response) { | |
| 408 | + var promo_baseuri = jQuery('.vbo-reportwidget-promo-baseuri').attr('href'); | |
| 409 | + if (response !== null) { | |
| 410 | + // AJAX response | |
| 411 | + if (response.report_values.hasOwnProperty('occupancy')) { | |
| 412 | + // update global vars | |
| 413 | + vboReportWidgetOccupancy = response.report_values['occupancy']['value']; | |
| 414 | + vboReportWidgetIndays = response.in_days > 0 ? response.in_days : response.in_days_avg; | |
| 415 | + vboReportWidgetDfrom = response.fromdate; | |
| 416 | + vboReportWidgetDto = response.todate; | |
| 417 | + vboReportWidgetPname = response.period_name; | |
| 418 | + } else { | |
| 419 | + // should not occur | |
| 420 | + vboReportWidgetDestroyPromotion(); | |
| 421 | + return; | |
| 422 | + } | |
| 423 | + } | |
| 424 | + if (vboReportWidgetIndays <= 0 || vboReportWidgetOccupancy >= 100 || !vboReportWidgetPromoFactors.hasOwnProperty('compare')) { | |
| 425 | + // no promotions for dates in the past, full occupancy or no VCM | |
| 426 | + vboReportWidgetDestroyPromotion(); | |
| 427 | + return; | |
| 428 | + } | |
| 429 | + // parse factors depending on the occupancy and in_days | |
| 430 | + var occupancy_severity = null; | |
| 431 | + var in_days_severity = null; | |
| 432 | + var occupancy_compare = vboReportWidgetPromoFactors['compare']['occupancy']; | |
| 433 | + var in_days_compare = vboReportWidgetPromoFactors['compare']['in_days']; | |
| 434 | + for (var severity in vboReportWidgetPromoFactors['occupancy']) { | |
| 435 | + if (!vboReportWidgetPromoFactors['occupancy'].hasOwnProperty(severity)) { | |
| 436 | + continue; | |
| 437 | + } | |
| 438 | + if (vboReportWidgetOccupancy >= vboReportWidgetPromoFactors['occupancy'][severity] && occupancy_compare.indexOf('gt') >= 0) { | |
| 439 | + // severity found | |
| 440 | + occupancy_severity = severity; | |
| 441 | + break; | |
| 442 | + } else if (vboReportWidgetOccupancy <= vboReportWidgetPromoFactors['occupancy'][severity] && occupancy_compare.indexOf('lt') >= 0) { | |
| 443 | + // severity found | |
| 444 | + occupancy_severity = severity; | |
| 445 | + break; | |
| 446 | + } | |
| 447 | + } | |
| 448 | + for (var severity in vboReportWidgetPromoFactors['in_days']) { | |
| 449 | + if (!vboReportWidgetPromoFactors['in_days'].hasOwnProperty(severity)) { | |
| 450 | + continue; | |
| 451 | + } | |
| 452 | + if (vboReportWidgetIndays >= vboReportWidgetPromoFactors['in_days'][severity] && in_days_compare.indexOf('gt') >= 0) { | |
| 453 | + // severity found | |
| 454 | + in_days_severity = severity; | |
| 455 | + break; | |
| 456 | + } else if (vboReportWidgetIndays <= vboReportWidgetPromoFactors['in_days'][severity] && in_days_compare.indexOf('lt') >= 0) { | |
| 457 | + // severity found | |
| 458 | + in_days_severity = severity; | |
| 459 | + break; | |
| 460 | + } | |
| 461 | + } | |
| 462 | + if (occupancy_severity === null || in_days_severity === null) { | |
| 463 | + // could not find appropriate severity for occupancy or in_days | |
| 464 | + console.error('could not find appropriate severity for occupancy or in_days', occupancy_severity, in_days_severity); | |
| 465 | + vboReportWidgetDestroyPromotion(); | |
| 466 | + return; | |
| 467 | + } | |
| 468 | + var occupancy_key = 'occupancy_' + occupancy_severity; | |
| 469 | + var in_days_key = 'in_days_' + in_days_severity; | |
| 470 | + if (!vboReportWidgetPromoFactors['discount'].hasOwnProperty(in_days_key) || !vboReportWidgetPromoFactors['discount'][in_days_key].hasOwnProperty(occupancy_key)) { | |
| 471 | + // could not find appropriate discount value for the severity obtained | |
| 472 | + console.error('could not find appropriate discount value for the severity obtained', occupancy_key, in_days_key); | |
| 473 | + vboReportWidgetDestroyPromotion(); | |
| 474 | + return; | |
| 475 | + } | |
| 476 | + var suggested_disc = vboReportWidgetPromoFactors['discount'][in_days_key][occupancy_key]; | |
| 477 | + // suggest promotion | |
| 478 | + var promo_uri = promo_baseuri + '&promo=1&diffcost=' + suggested_disc + '&from=' + vboReportWidgetDfrom + '&to=' + vboReportWidgetDto + '&promoname=' + vboReportWidgetPname; | |
| 479 | + // consider type of promotion (last minute or early bird) | |
| 480 | + if (in_days_severity == 'low') { | |
| 481 | + // suggest last minute days | |
| 482 | + promo_uri += '&promolastmind=' + vboReportWidgetPromoFactors['in_days'][in_days_severity]; | |
| 483 | + } else if (in_days_severity == 'high') { | |
| 484 | + // suggest early bird days advance (28d) | |
| 485 | + promo_uri += '&promodaysadv=28'; | |
| 486 | + } | |
| 487 | + if (vboReportWidgetRoomids.length) { | |
| 488 | + for (var idr in vboReportWidgetRoomids) { | |
| 489 | + if (!vboReportWidgetRoomids.hasOwnProperty(idr)) { | |
| 490 | + continue; | |
| 491 | + } | |
| 492 | + promo_uri += '&rooms[]=' + vboReportWidgetRoomids[idr]; | |
| 493 | + } | |
| 494 | + } | |
| 495 | + // | |
| 496 | + // insight texts | |
| 497 | + var vboPromoInsightTitle = ''; | |
| 498 | + var vboPromoInsightHelp = ''; | |
| 499 | + if (occupancy_severity == 'low') { | |
| 500 | + vboPromoInsightTitle = Joomla.JText._('VBOSEVLOWOCC'); | |
| 501 | + } else if (occupancy_severity == 'med') { | |
| 502 | + vboPromoInsightTitle = Joomla.JText._('VBOSEVMEDOCC'); | |
| 503 | + } else if (occupancy_severity == 'high') { | |
| 504 | + vboPromoInsightTitle = Joomla.JText._('VBOSEVHIGHOCC'); | |
| 505 | + } | |
| 506 | + if (in_days_severity == 'low') { | |
| 507 | + vboPromoInsightHelp = Joomla.JText._('VBOSEVLOWINDAYS'); | |
| 508 | + } else if (in_days_severity == 'med') { | |
| 509 | + vboPromoInsightHelp = Joomla.JText._('VBOSEVMEDINDAYS'); | |
| 510 | + } else if (in_days_severity == 'high') { | |
| 511 | + vboPromoInsightHelp = Joomla.JText._('VBOSEVHIGHINDAYS'); | |
| 512 | + } | |
| 513 | + // cookie val | |
| 514 | + var hidepromoinsights = false; | |
| 515 | + if (response == null && jQuery('.vbo-reportwidget-ratesoverv').length) { | |
| 516 | + // hide by default the insights when the page loads and we're on the Rates Overview | |
| 517 | + hidepromoinsights = true; | |
| 518 | + } | |
| 519 | + var buiscuits = document.cookie; | |
| 520 | + if (buiscuits.length) { | |
| 521 | + var hidepromoinsightsck = "vboHidePromoInsights=1"; | |
| 522 | + if (buiscuits.indexOf(hidepromoinsightsck) >= 0) { | |
| 523 | + hidepromoinsights = true; | |
| 524 | + } | |
| 525 | + } | |
| 526 | + // build HTML content | |
| 527 | + var promo_content = ''; | |
| 528 | + promo_content += '<div class="vbo-reportwidget-promo-wrap ' + (hidepromoinsights ? 'vbo-reportwidget-promo-wrap-hidden' : 'vbo-reportwidget-promo-wrap-visible') + '" style="display: none;">'; | |
| 529 | + promo_content += '<div class="vbo-reportwidget-promo-inner">'; | |
| 530 | + promo_content += '<div class="vbo-reportwidget-promo-icon"><span onclick="vboReportWidgetShowPromotion();" title="<?php echo addslashes(JText::translate('VBOINSIGHT')); ?>"><?php VikBookingIcons::e('lightbulb'); ?></span></div>'; | |
| 531 | + promo_content += '<div class="vbo-reportwidget-promo-help" style="' + (hidepromoinsights ? 'display: none;' : '') + '">'; | |
| 532 | + promo_content += '<div class="vbo-reportwidget-promo-close"><span onclick="vboReportWidgetHidePromotion();"><?php VikBookingIcons::e('times'); ?></span></div>'; | |
| 533 | + promo_content += '<h5><?php echo addslashes(JText::translate('VBOINSIGHT')); ?></h5><p class="vbo-promo-tip-title">' + vboPromoInsightTitle + '</p><p class="vbo-promo-tip-help">' + vboPromoInsightHelp + '</p>'; | |
| 534 | + promo_content += '<div class="vbo-reportwidget-promo-link">'; | |
| 535 | + promo_content += '<a href="' + promo_uri + '" class="btn vbo-config-btn" target="_blank"><?php VikBookingIcons::e('rocket'); ?> <?php echo addslashes(JText::translate('VBOSUGGCREATEPROMOOCC')); ?></a>'; | |
| 536 | + promo_content += '</div>'; | |
| 537 | + promo_content += '</div>'; | |
| 538 | + promo_content += '</div>'; | |
| 539 | + promo_content += '</div>'; | |
| 540 | + if (!jQuery('.vbo-reportwidget-chart').find('.vbo-reportwidget-promo-wrap').length) { | |
| 541 | + jQuery('.vbo-reportwidget-chart').first().append(promo_content); | |
| 542 | + } | |
| 543 | + setTimeout(function() { | |
| 544 | + jQuery('.vbo-reportwidget-promo-wrap').fadeIn(); | |
| 545 | + }, 1000); | |
| 546 | +} | |
| 547 | +function vboReportWidgetDestroyPromotion() { | |
| 548 | + jQuery('.vbo-reportwidget-promo-wrap').remove(); | |
| 549 | +} | |
| 550 | +function vboReportWidgetHidePromotion() { | |
| 551 | + jQuery('.vbo-reportwidget-promo-help').hide(); | |
| 552 | + jQuery('.vbo-reportwidget-promo-wrap').removeClass('vbo-reportwidget-promo-wrap-visible').addClass('vbo-reportwidget-promo-wrap-hidden'); | |
| 553 | + // set cookie | |
| 554 | + var nd = new Date(); | |
| 555 | + nd.setTime(nd.getTime() + (7*24*60*60*1000)); | |
| 556 | + document.cookie = "vboHidePromoInsights=1; expires=" + nd.toUTCString() + "; path=/; SameSite=Lax"; | |
| 557 | +} | |
| 558 | +function vboReportWidgetShowPromotion() { | |
| 559 | + jQuery('.vbo-reportwidget-promo-wrap').addClass('vbo-reportwidget-promo-wrap-visible').removeClass('vbo-reportwidget-promo-wrap-hidden'); | |
| 560 | + jQuery('.vbo-reportwidget-promo-help').show(); | |
| 561 | + // unset cookie | |
| 562 | + var nd = new Date(); | |
| 563 | + nd.setTime(nd.getTime() - (7*24*60*60*1000)); | |
| 564 | + document.cookie = "vboHidePromoInsights=; expires=" + nd.toUTCString() + "; path=/; SameSite=Lax"; | |
| 565 | +} | |
| 566 | +<?php echo !empty($report_chart) && strlen($report->getScript()) ? $report->getScript() : ''; ?> | |
| 567 | +</script> | |