PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.5
VikBooking Hotel Booking Engine & PMS v1.6.5
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 / helpers / report / istat_sitra.php

istat_sitra.php in VikBooking Hotel Booking Engine & PMS 1.6.5, at admin/helpers/report/istat_sitra.php

1,584 lines 53.4 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) 2019 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 * ISTAT Sitra è valido per diverse regioni. Sicuramente per l'Abruzzo.
15 */
16 class VikBookingReportIstatSitra extends VikBookingReport
17 {
18 /**
19 * Property 'defaultKeySort' is used by the View that renders the report.
20 */
21 public $defaultKeySort = 'idbooking';
22 /**
23 * Property 'defaultKeyOrder' is used by the View that renders the report.
24 */
25 public $defaultKeyOrder = 'ASC';
26 /**
27 * Property 'customExport' is used by the View to display custom export buttons.
28 */
29 public $customExport = '';
30 /**
31 * Debug mode is activated by passing the value 'e4j_debug' > 0
32 */
33 private $debug;
34
35 /**
36 * Other private vars of this sub-class.
37 */
38 private $comuniProvince;
39 private $nazioni;
40 private $documenti;
41 public $tipoTurismo;
42 public $mezzoDiTrasporto;
43
44 /**
45 * Class constructor should define the name of the report and
46 * other vars. Call the parent constructor to define the DB object.
47 */
48 public function __construct()
49 {
50 $this->reportFile = basename(__FILE__, '.php');
51 $this->reportName = JText::translate('ISTAT Sitra');
52 $this->reportFilters = array();
53
54 $this->cols = array();
55 $this->rows = array();
56 $this->footerRow = array();
57
58 $this->debug = (VikRequest::getInt('e4j_debug', 0, 'request') > 0);
59
60 $this->comuniProvince = array();
61 $this->nazioni = array();
62 $this->mezzoDiTrasporto = array(
63 '0' => 'Auto',
64 '1' => 'Aereo',
65 '2' => 'Aereo+Pullman',
66 '3' => 'Aereo+Navetta/Taxi/Auto',
67 '4' => 'Aereo+Treno',
68 '5' => 'Treno',
69 '6' => 'Pullman',
70 '7' => 'Caravan/Autocaravan',
71 '8' => 'Barca/Nave/Traghetto',
72 '9' => 'Moto',
73 '10' => 'Bicicletta',
74 '11' => 'A piedi',
75 '12' => 'Altro motivo',
76 '13' => 'Non specificato'
77 );
78 $this->tipoTurismo = array(
79 '0' => 'Culturale',
80 '1' => 'Balneare',
81 '2' => 'Congressuale/Affari',
82 '3' => 'Fieristico',
83 '4' => 'Sportivo/Fitness',
84 '5' => 'Scolastico',
85 '6' => 'Religioso',
86 '7' => 'Sociale',
87 '8' => 'Parchi Tematici',
88 '9' => 'Termale/Trattamenti salute',
89 '10' => 'Enogastronomico',
90 '11' => 'Cicloturismo',
91 '12' => 'Escursionistico/Naturalistico',
92 '13' => 'Altro motivo',
93 '14' => 'Non specificato'
94 );
95
96 $this->registerExportFileName();
97
98 parent::__construct();
99 }
100
101 /**
102 * Returns the name of this report.
103 *
104 * @return string
105 */
106 public function getName()
107 {
108 return $this->reportName;
109 }
110
111 /**
112 * Returns the name of this file without .php.
113 *
114 * @return string
115 */
116 public function getFileName()
117 {
118 return $this->reportFile;
119 }
120
121 /**
122 * Returns the filters of this report.
123 *
124 * @return array
125 */
126 public function getFilters()
127 {
128 if (count($this->reportFilters)) {
129 //do not run this method twice, as it could load JS and CSS files.
130 return $this->reportFilters;
131 }
132 $doc = JFactory::getDocument();
133 $css = '.vbo-report-load-trasporto span,
134 .vbo-report-load-turismo span {
135 display: inline-block;
136 border: 1px solid #dd0000;
137 cursor: pointer;
138 color: #dd0000;
139 padding: 0px 7px;
140 }';
141 $doc->addStyleDeclaration($css);
142 //get VBO Application Object
143 $vbo_app = VikBooking::getVboApplication();
144
145 //load the jQuery UI Datepicker
146 $this->loadDatePicker();
147
148 //custom export button
149 $this->customExport = '<a href="JavaScript: void(0);" onclick="vboDownloadSchedaIstat();" class="vbcsvexport"><i class="'.VikBookingIcons::i('download').'"></i> <span>Download File</span></a>';
150
151 //build the hidden values for the selection of Comuni & Province.
152 $this->comuniProvince = $this->loadComuniProvince();
153 $this->nazioni = $this->loadNazioni();
154 $hidden_vals = '<div id="vbo-report-alloggiati-hidden" style="display: none;">';
155 //Comuni
156 $hidden_vals .= ' <div id="vbo-report-alloggiati-comune" class="vbo-report-alloggiati-selcont" style="display: none;">';
157 $hidden_vals .= ' <select id="choose-comune" onchange="vboReportChosenComune(this);"><option value=""></option>';
158 if (isset($this->comuniProvince['comuni']) && count($this->comuniProvince['comuni'])) {
159 foreach ($this->comuniProvince['comuni'] as $code => $comune) {
160 $hidden_vals .= ' <option value="' . $code . '">' . (is_array($comune) ? $comune['name'] : '') . '</option>'."\n";
161 }
162 }
163 $hidden_vals .= ' </select>';
164 $hidden_vals .= ' </div>';
165 //
166 //Mezzi di Trasporto
167 $hidden_vals .= ' <div id="vbo-report-trasporto" class="vbo-report-alloggiati-selcont" style="display: none;">';
168 $hidden_vals .= ' <select id="choose-trasporto" onchange="vboReportChosenTrasporto(this);"><option value=""></option>';
169 foreach ($this->mezzoDiTrasporto as $key => $value) {
170 $hidden_vals .= ' <option value="'.$value.'">'.$value.'</option>'."\n";
171 }
172 $hidden_vals .= ' </select>';
173 $hidden_vals .= ' </div>';
174 //
175 //Tipo di turismo
176 $hidden_vals .= ' <div id="vbo-report-turismo" class="vbo-report-alloggiati-selcont" style="display: none;">';
177 $hidden_vals .= ' <select id="choose-turismo" onchange="vboReportChosenTurismo(this);"><option value=""></option>';
178 foreach ($this->tipoTurismo as $key => $value) {
179 $hidden_vals .= ' <option value="'.$value.'">'.$value.'</option>'."\n";
180 }
181 $hidden_vals .= ' </select>';
182 $hidden_vals .= ' </div>';
183 //
184 //Province
185 $hidden_vals .= ' <div id="vbo-report-alloggiati-provincia" class="vbo-report-alloggiati-selcont" style="display: none;">';
186 $hidden_vals .= ' <select id="choose-provincia" onchange="vboReportChosenProvincia(this);"><option value=""></option>';
187 if (isset($this->comuniProvince['province']) && count($this->comuniProvince['province'])) {
188 foreach ($this->comuniProvince['province'] as $code => $provincia) {
189 $hidden_vals .= ' <option value="'.$code.'">'.$provincia.'</option>'."\n";
190 }
191 }
192 $hidden_vals .= ' </select>';
193 $hidden_vals .= ' </div>';
194 //
195 //Nazioni
196 $hidden_vals .= ' <div id="vbo-report-alloggiati-nazione" class="vbo-report-alloggiati-selcont" style="display: none;">';
197 $hidden_vals .= ' <select id="choose-nazione" onchange="vboReportChosenNazione(this);"><option value=""></option>';
198 if (count($this->nazioni)) {
199 foreach ($this->nazioni as $code => $nazione) {
200 $hidden_vals .= ' <option value="'.$code.'">'.$nazione['name'].'</option>';
201 }
202 }
203 $hidden_vals .= ' </select>';
204 $hidden_vals .= ' </div>';
205 //
206 //Sesso
207 $hidden_vals .= ' <div id="vbo-report-alloggiati-sesso" class="vbo-report-alloggiati-selcont" style="display: none;">';
208 $hidden_vals .= ' <select id="choose-sesso" onchange="vboReportChosenSesso(this);"><option value=""></option>';
209 $sessos = array(
210 1 => 'M',
211 2 => 'F'
212 );
213 foreach ($sessos as $code => $ses) {
214 $hidden_vals .= ' <option value="'.$code.'">'.$ses.'</option>'."\n";
215 }
216 $hidden_vals .= ' </select>';
217 $hidden_vals .= ' </div>';
218 //
219 //Numero Documento
220 $hidden_vals .= ' <div id="vbo-report-alloggiati-docnum" class="vbo-report-alloggiati-selcont" style="display: none;">';
221 $hidden_vals .= ' <input type="text" size="40" id="choose-docnum" placeholder="Numero Documento..." value="" /><br/>';
222 $hidden_vals .= ' <button type="button" class="btn" onclick="vboReportChosenDocnum(document.getElementById(\'choose-docnum\').value);">'.JText::translate('VBAPPLY').'</button>';
223 $hidden_vals .= ' </div>';
224 //
225 //Data di Nascita
226 $hidden_vals .= ' <div id="vbo-report-alloggiati-dbirth" class="vbo-report-alloggiati-selcont" style="display: none;">';
227 $hidden_vals .= ' <input type="text" size="40" id="choose-dbirth" placeholder="Data di Nascita" value="" /><br/>';
228 $hidden_vals .= ' <button type="button" class="btn" onclick="vboReportChosenDbirth(document.getElementById(\'choose-dbirth\').value);">'.JText::translate('VBAPPLY').'</button>';
229 $hidden_vals .= ' </div>';
230 //
231 $hidden_vals .= '</div>';
232
233 //From Date Filter (with hidden values for the dropdown menus of Comuni, Province, Stati etc..)
234 $filter_opt = array(
235 'label' => '<label for="fromdate">'.JText::translate('VBOREPORTSDATEFROM').'</label>',
236 'html' => '<input type="text" id="fromdate" name="fromdate" value="" class="vbo-report-datepicker vbo-report-datepicker-from" />'.$hidden_vals,
237 'type' => 'calendar',
238 'name' => 'fromdate'
239 );
240 array_push($this->reportFilters, $filter_opt);
241
242 // apertura struttura
243 $papertura = VikRequest::getString('apertura', '', 'request');
244 $filter_opt = array(
245 'label' => '<label for="apertura">Apertura Struttura</label>',
246 'html' => '<select id="choose-apertura" name="apertura"> <option value="" '.((empty($papertura) || ($papertura != 'SI' && $papertura != 'NO')) ? 'selected="selected"' : '' ).'></option><option value="SI" ' .((!empty($papertura) && $papertura == 'SI') ? 'selected="selected"' : '') .'> La struttura è aperta in questa data. </option> <option value="NO"' .((!empty($papertura) && $papertura == 'NO') ? 'selected="selected"' : '') .'> La struttura non è aperta in questa data. </option> </select>',
247 'type' => 'text',
248 'name' => 'apertura'
249 );
250 array_push($this->reportFilters, $filter_opt);
251
252 // Filtro Numero Letti
253 $pletti = VikRequest::getInt('numletti', 0, 'request');
254 $filter_opt = array(
255 'label' => '<label for="numletti">Numero Letti Disponibili</label>',
256 'html' => '<input type="number" id="numletti" name="numletti" value="'.$pletti.'" size="10" />',
257 'type' => 'text',
258 'name' => 'numletti'
259 );
260 array_push($this->reportFilters, $filter_opt);
261 // Filtro Codice Struttura
262 $pcodstru = VikRequest::getString('codstru', '', 'request');
263 $filter_opt = array(
264 'label' => '<label for="codstru">Codice Struttura</label>',
265 'html' => '<input type="text" id="codstru" name="codstru" value="'.$pcodstru.'" size="10" />',
266 'type' => 'text',
267 'name' => 'codstru'
268 );
269 array_push($this->reportFilters, $filter_opt);
270
271 //jQuery code for the datepicker calendars, select2 and triggers for the dropdown menus
272 $pfromdate = VikRequest::getString('fromdate', '', 'request');
273 $ptodate = VikRequest::getString('todate', '', 'request');
274 $js = 'var reportActiveCell = null, reportObj = {};
275 jQuery(document).ready(function() {
276 //prepare main filters
277 jQuery(".vbo-report-datepicker:input").datepicker({
278 maxDate: "+1m",
279 dateFormat: "'.$this->getDateFormat('jui').'",
280 onSelect: vboReportCheckDates
281 });
282 '.(!empty($pfromdate) ? 'jQuery(".vbo-report-datepicker-from").datepicker("setDate", "'.$pfromdate.'");' : '').'
283 '.(!empty($ptodate) ? 'jQuery(".vbo-report-datepicker-to").datepicker("setDate", "'.$ptodate.'");' : '').'
284 //prepare filler helpers
285 jQuery("#vbo-report-alloggiati-hidden").children().detach().appendTo(".vbo-info-overlay-report");
286 jQuery("#choose-comune").select2({placeholder: "- Seleziona un Comune -", width: "200px"});
287 jQuery("#choose-provincia").select2({placeholder: "- Seleziona una Provincia -", width: "200px"});
288 jQuery("#choose-nazione").select2({placeholder: "- Seleziona una Nazione -", width: "200px"});
289 jQuery("#choose-sesso").select2({placeholder: "- Seleziona Sesso -", width: "200px"});
290 jQuery("#choose-turismo").select2({placeholder: "- Seleziona Tipo di Turismo -", width: "300px"});
291 jQuery("#choose-trasporto").select2({placeholder: "- Seleziona Mezzo di Trasporto -", width: "300px"});
292
293 jQuery("#choose-dbirth").datepicker({
294 maxDate: 0,
295 dateFormat: "dd/mm/yy",
296 changeMonth: true,
297 changeYear: true,
298 yearRange: "'.(date('Y') - 100).':'.date('Y').'"
299 });
300 //click events
301 jQuery(".vbo-report-load-comune").click(function() {
302 reportActiveCell = this;
303 jQuery(".vbo-report-alloggiati-selcont").hide();
304 jQuery("#vbo-report-alloggiati-comune").show();
305 vboShowOverlay();
306 });
307 jQuery(".vbo-report-load-provincia").click(function() {
308 reportActiveCell = this;
309 jQuery(".vbo-report-alloggiati-selcont").hide();
310 jQuery("#vbo-report-alloggiati-provincia").show();
311 vboShowOverlay();
312 });
313 jQuery(".vbo-report-load-nazione, .vbo-report-load-cittadinanza").click(function() {
314 reportActiveCell = this;
315 jQuery(".vbo-report-alloggiati-selcont").hide();
316 jQuery("#vbo-report-alloggiati-nazione").show();
317 vboShowOverlay();
318 });
319 jQuery(".vbo-report-load-sesso").click(function() {
320 reportActiveCell = this;
321 jQuery(".vbo-report-alloggiati-selcont").hide();
322 jQuery("#vbo-report-alloggiati-sesso").show();
323 vboShowOverlay();
324 });
325 jQuery(".vbo-report-load-turismo").click(function() {
326 reportActiveCell = this;
327 jQuery(".vbo-report-alloggiati-selcont").hide();
328 jQuery("#vbo-report-turismo").show();
329 vboShowOverlay();
330 });
331 jQuery(".vbo-report-load-trasporto").click(function() {
332 reportActiveCell = this;
333 jQuery(".vbo-report-alloggiati-selcont").hide();
334 jQuery("#vbo-report-trasporto").show();
335 vboShowOverlay();
336 });
337 jQuery(".vbo-report-load-dbirth").click(function() {
338 reportActiveCell = this;
339 jQuery(".vbo-report-alloggiati-selcont").hide();
340 jQuery("#vbo-report-alloggiati-dbirth").show();
341 vboShowOverlay();
342 //pretend the overlay is off, or navigating in the datepicker will close the modal.
343 setTimeout(function(){vbo_overlay_on = false;}, 800);
344 //
345 });
346 });
347 function vboReportCheckDates(selectedDate, inst) {
348 if (selectedDate === null || inst === null) {
349 return;
350 }
351 var cur_from_date = jQuery(this).val();
352 if (jQuery(this).hasClass("vbo-report-datepicker-from") && cur_from_date.length) {
353 var nowstart = jQuery(this).datepicker("getDate");
354 var nowstartdate = new Date(nowstart.getTime());
355 jQuery(".vbo-report-datepicker-to").datepicker("option", {minDate: nowstartdate});
356 }
357 }
358 function vboReportChosenComune(comune) {
359 var c_code = comune.value;
360 var c_val = comune.options[comune.selectedIndex].text;
361 if (reportActiveCell !== null) {
362 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
363 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
364 alert("Error, cannot find element to update.");
365 } else {
366 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
367 if (!reportObj.hasOwnProperty(nowindex)) {
368 reportObj[nowindex] = {};
369 }
370 if (jQuery(reportActiveCell).hasClass("vbo-report-load-docplace")) {
371 reportObj[nowindex].docplace = c_code;
372 } else {
373 reportObj[nowindex].comres = c_code;
374 }
375 }
376 }
377 reportActiveCell = null;
378 vboHideOverlay();
379 jQuery("#choose-comune").val("").select2("data", null, false);
380 }
381 function vboReportChosenProvincia(prov) {
382 var c_code = prov.value;
383 var c_val = prov.options[prov.selectedIndex].text;
384 if (reportActiveCell !== null) {
385 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
386 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
387 alert("Error, cannot find element to update.");
388 } else {
389 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
390 if (!reportObj.hasOwnProperty(nowindex)) {
391 reportObj[nowindex] = {};
392 }
393 reportObj[nowindex].prores = c_code;
394 }
395 }
396 reportActiveCell = null;
397 vboHideOverlay();
398 jQuery("#choose-provincia").val("").select2("data", null, false);
399 }
400 function vboReportChosenNazione(naz) {
401 var c_code = naz.value;
402 var c_val = naz.options[naz.selectedIndex].text;
403 if (reportActiveCell !== null) {
404 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
405 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
406 alert("Error, cannot find element to update.");
407 } else {
408 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
409 if (!reportObj.hasOwnProperty(nowindex)) {
410 reportObj[nowindex] = {};
411 }
412 if (jQuery(reportActiveCell).hasClass("vbo-report-load-nazione")) {
413 reportObj[nowindex].stares = c_code;
414 } else if (jQuery(reportActiveCell).hasClass("vbo-report-load-docplace")) {
415 reportObj[nowindex].docplace = c_code;
416 } else {
417 reportObj[nowindex].citizen = c_code;
418 }
419 }
420 }
421 reportActiveCell = null;
422 vboHideOverlay();
423 jQuery("#choose-nazione").val("").select2("data", null, false);
424 }
425 function vboReportChosenSesso(sesso) {
426 var c_code = sesso.value;
427 var c_val = sesso.options[sesso.selectedIndex].text;
428 if (reportActiveCell !== null) {
429 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
430 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
431 alert("Error, cannot find element to update.");
432 } else {
433 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
434 if (!reportObj.hasOwnProperty(nowindex)) {
435 reportObj[nowindex] = {};
436 }
437 reportObj[nowindex].gender = c_code;
438 }
439 }
440 reportActiveCell = null;
441 vboHideOverlay();
442 jQuery("#choose-sesso").val("").select2("data", null, false);
443 }
444 function vboReportChosenTrasporto(trasporto) {
445 var c_code = trasporto.value;
446 var c_val = trasporto.options[trasporto.selectedIndex].text;
447 if (reportActiveCell !== null) {
448 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
449 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
450 alert("Error, cannot find element to update.");
451 } else {
452 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
453 if (!reportObj.hasOwnProperty(nowindex)) {
454 reportObj[nowindex] = {};
455 }
456 reportObj[nowindex].mezzo = c_code;
457 }
458 }
459 reportActiveCell = null;
460 vboHideOverlay();
461 jQuery("#choose-trasporto").val("").select2("data", null, false);
462 }
463 function vboReportChosenTurismo(turismo) {
464 var c_code = turismo.value;
465 var c_val = turismo.options[turismo.selectedIndex].text;
466 if (reportActiveCell !== null) {
467 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
468 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
469 alert("Error, cannot find element to update.");
470 } else {
471 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
472 if (!reportObj.hasOwnProperty(nowindex)) {
473 reportObj[nowindex] = {};
474 }
475 reportObj[nowindex].turismo = c_code;
476 }
477 }
478 reportActiveCell = null;
479 vboHideOverlay();
480 jQuery("#choose-turismo").val("").select2("data", null, false);
481 }
482 function vboReportChosenDbirth(val) {
483 var c_code = val, c_val = val;
484 if (reportActiveCell !== null) {
485 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
486 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
487 alert("Error, cannot find element to update.");
488 } else {
489 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
490 if (!reportObj.hasOwnProperty(nowindex)) {
491 reportObj[nowindex] = {};
492 }
493 reportObj[nowindex].dbirth = c_code;
494 }
495 }
496 reportActiveCell = null;
497 vboHideOverlay();
498 jQuery("#choose-dbirth").val("");
499 }
500 //download function
501 function vboDownloadSchedaIstat() {
502 if (!confirm("Sei sicuro di aver compilato tutti i dati?")) {
503 return false;
504 }
505 document.adminForm.target = "_blank";
506 document.adminForm.action += "&tmpl=component";
507 vboSetFilters({exportreport: "1", filler: JSON.stringify(reportObj)}, true);
508 setTimeout(function() {
509 document.adminForm.target = "";
510 document.adminForm.action = document.adminForm.action.replace("&tmpl=component", "");
511 vboSetFilters({exportreport: "0", filler: ""}, false);
512 }, 1000);
513 }
514 ';
515 $this->setScript($js);
516
517 return $this->reportFilters;
518 }
519
520 /**
521 * Loads the report data from the DB.
522 * Returns true in case of success, false otherwise.
523 * Sets the columns and rows for the report to be displayed.
524 *
525 * @return boolean
526 */
527 public function getReportData()
528 {
529 if (strlen($this->getError())) {
530 //Export functions may set errors rather than exiting the process, and the View may continue the execution to attempt to render the report.
531 return false;
532 }
533 //Input fields and other vars
534 $pfromdate = VikRequest::getString('fromdate', '', 'request');
535 $ptodate = VikRequest::getString('todate', '', 'request');
536 $pkrsort = VikRequest::getString('krsort', $this->defaultKeySort, 'request');
537 $pkrsort = empty($pkrsort) ? $this->defaultKeySort : $pkrsort;
538 $pkrorder = VikRequest::getString('krorder', $this->defaultKeyOrder, 'request');
539 $pkrorder = empty($pkrorder) ? $this->defaultKeyOrder : $pkrorder;
540 $pkrorder = $pkrorder == 'DESC' ? 'DESC' : 'ASC';
541 $pcodstru = VikRequest::getString('codstru', '', 'request');
542 $papertura = VikRequest::getString('apertura', '', 'request');
543 $records = array();
544 $q = "SELECT SUM(`units`) AS `sommaunita`, SUM(`totpeople`) AS `numeropersone`, COUNT(*) AS `numerocamere` FROM `#__vikbooking_rooms` WHERE `avail`= '1';";
545 $this->dbo->setQuery($q);
546 $this->dbo->execute();
547 if ($this->dbo->getNumRows() > 0) {
548 $records = $this->dbo->loadAssocList();
549 }
550 $totalBeds = (int)($records[0]['sommaunita'] * ($records[0]['numeropersone'] / $records[0]['numerocamere']));
551 $pletti = VikRequest::getString('numletti', $totalBeds, 'request');
552 $currency_symb = VikBooking::getCurrencySymb();
553 $df = $this->getDateFormat();
554 $datesep = VikBooking::getDateSeparator();
555 if (empty($ptodate)) {
556 $ptodate = $pfromdate;
557 }
558 //Get dates timestamps
559 $from_ts = VikBooking::getDateTimestamp($pfromdate, 0, 0);
560 $to_ts = VikBooking::getDateTimestamp($ptodate, 23, 59, 59);
561 if (empty($pfromdate) || empty($from_ts) || empty($to_ts)) {
562 $this->setError(JText::translate('VBOREPORTSERRNODATES'));
563 return false;
564 }
565 if (empty($pcodstru)) {
566 $this->setError('Inserisci il codice della tua Struttura.<br/>Si tratta di un codice univoco di identificazione che ti viene assegnato dall\'Amministrazione competente.');
567 return false;
568 }
569 if (empty($papertura)) {
570 $this->setError('Devi specificare se la tua struttura è aperta o meno attraverso il menù a tendina qui sopra.');
571 return false;
572 }
573 //Query to obtain the records (all check-ins within the dates filter)
574 $records = array();
575 $q = "SELECT `o`.`id`,`o`.`custdata`,`o`.`ts`,`o`.`days`,`o`.`checkin`,`o`.`checkout`,`o`.`totpaid`,`o`.`roomsnum`,`o`.`total`,`o`.`idorderota`,`o`.`channel`,`o`.`country`,".
576 "`or`.`idorder`,`or`.`idroom`,`or`.`adults`,`or`.`children`,`or`.`t_first_name`,`or`.`t_last_name`,`or`.`cust_cost`,`or`.`cust_idiva`,`or`.`extracosts`,`or`.`room_cost`,".
577 "`co`.`idcustomer`,`co`.`pax_data`,`c`.`first_name`,`c`.`last_name`,`c`.`country` AS `customer_country`,`c`.`doctype`,`c`.`docnum`,`c`.`gender`,`c`.`bdate`,`c`.`pbirth` ".
578 "FROM `#__vikbooking_orders` AS `o` LEFT JOIN `#__vikbooking_ordersrooms` AS `or` ON `or`.`idorder`=`o`.`id` ".
579 "LEFT JOIN `#__vikbooking_customers_orders` AS `co` ON `co`.`idorder`=`o`.`id` LEFT JOIN `#__vikbooking_customers` AS `c` ON `c`.`id`=`co`.`idcustomer` ".
580 "WHERE `o`.`status`='confirmed' AND `o`.`closure`=0 AND ((`o`.`checkin`>=".$from_ts." AND `o`.`checkin`<=".$to_ts.") OR (`o`.`checkout`>=".$from_ts." AND `o`.`checkout`<=".$to_ts.")) ".
581 "ORDER BY `o`.`checkin` ASC, `o`.`id` ASC;";
582 $this->dbo->setQuery($q);
583 $this->dbo->execute();
584 if ($this->dbo->getNumRows() > 0) {
585 $records = $this->dbo->loadAssocList();
586 }
587 if (!count($records)) {
588 $this->setError(JText::translate('VBOREPORTSERRNORESERV'));
589 $this->setError('Nessun check-in nelle date selezionate.');
590 return false;
591 }
592 //nest records with multiple rooms booked inside sub-array
593 $bookings = array();
594 foreach ($records as $v) {
595 if (!isset($bookings[$v['id']])) {
596 $bookings[$v['id']] = array();
597 }
598 array_push($bookings[$v['id']], $v);
599 }
600 //define the columns of the report
601 $this->cols = array(
602 //id booking
603 array(
604 'key' => 'idbooking',
605 'attr' => array(
606 'class="center"'
607 ),
608 'label' => 'ID',
609 'sortable' => 1,
610 ),
611 //check-in
612 array(
613 'key' => 'checkin',
614 'attr' => array(
615 'class="center"'
616 ),
617 'sortable' => 1,
618 'label' => JText::translate('VBPICKUPAT')
619 ),
620 //checkout
621 array(
622 'key' => 'checkout',
623 'attr' => array(
624 'class="center"'
625 ),
626 'sortable' => 1,
627 'label' => 'Partenza'
628 ),
629 //cognome
630 array(
631 'key' => 'cognome',
632 'label' => JText::translate('VBTRAVELERLNAME'),
633 'sortable' => 1,
634 ),
635 //nome
636 array(
637 'key' => 'nome',
638 'label' => JText::translate('VBTRAVELERNAME'),
639 'sortable' => 1,
640 ),
641 //sesso
642 array(
643 'key' => 'gender',
644 'attr' => array(
645 'class="center"'
646 ),
647 'label' => JText::translate('VBCUSTOMERGENDER')
648 ),
649 //data di nascita
650 array(
651 'key' => 'dbirth',
652 'attr' => array(
653 'class="center"'
654 ),
655 'label' => JText::translate('VBCUSTOMERBDATE')
656 ),
657 //cittadinanza
658 array(
659 'key' => 'citizen',
660 'attr' => array(
661 'class="center"'
662 ),
663 'sortable' => 1,
664 'label' => 'Cittadinanza'
665 ),
666 //cittadinanza
667 array(
668 'key' => 'stares',
669 'attr' => array(
670 'class="center"'
671 ),
672 'sortable' => 1,
673 'label' => 'Stato di Residenza'
674 ),
675 //comune di residenza
676 array(
677 'key' => 'comres',
678 'attr' => array(
679 'class="center"'
680 ),
681 'sortable' => 1,
682 'label' => 'Comune Residenza',
683 'tip' => 'Inserire il comune di residenza solo se il cittadino è di nazionalità italiana.'
684 ),
685 //tipo
686 array(
687 'key' => 'tipo',
688 'attr' => array(
689 'class="vbo-report-longlbl"'
690 ),
691 'label' => 'Tipo Alloggiato'
692 ),
693 // tipo di trasporto
694 array(
695 'key' => 'mezzo',
696 'attr' => array(
697 'class="center"'
698 ),
699 'label' => 'Mezzo di Trasporto'
700 ),
701 // tipo di turismo
702 array(
703 'key' => 'turismo',
704 'attr' => array(
705 'class="center"'
706 ),
707 'label' => 'Tipo di Turismo'
708 ),
709 //quantità (numero di ospiti)
710 array(
711 'key' => 'guestsnum',
712 'attr' => array(
713 'class="center"'
714 ),
715 'sortable' => 1,
716 'label' => 'Numero Ospiti',
717 'tip' => 'Il numero di ospiti totali (adulti + bambini) per ogni prenotazione è un dato che verrà comunicato all\'ISTAT.',
718 ),
719 array(
720 'key' => 'roomsbooked',
721 'attr' => array(
722 'class="center"'
723 ),
724 'sortable' => 1,
725 'label' => 'Occupazione',
726 'tip' => 'Questo valore indica il numero di camere occupate da ogni prenotazione, ed è un dato che verrà comunicato all\'ISTAT.',
727 ),
728 );
729
730 // loop over the bookings to build the rows of the report
731 $from_info = getdate($from_ts);
732 foreach ($bookings as $gbook) {
733 $guestsnum = 0;
734 $guests_rows = array($gbook[0]);
735 $room_guests = array();
736 $tot_guests_rows = 1;
737
738 $tipo = 16;
739 // Codici Tipo Alloggiato
740 // 16 = Ospite Singolo
741 // 17 = Capofamiglia
742 // 18 = Capogruppo
743 // 19 = Familiare
744 // 20 = Membro Gruppo
745
746 foreach ($gbook as $book) {
747 $guestsnum += $book['adults'] + $book['children'];
748 $room_guests[] = ($book['adults'] + $book['children']);
749 }
750 $pax_data = null;
751 if (!empty($gbook[0]['pax_data'])) {
752 $pax_data = json_decode($gbook[0]['pax_data'], true);
753 if (is_array($pax_data) && count($pax_data)) {
754 $guests_rows[0]['pax_data'] = $pax_data;
755 $tot_guests_rows = 0;
756 foreach ($pax_data as $roomguests) {
757 $tot_guests_rows += count($roomguests);
758 }
759 for ($i = 1; $i < $tot_guests_rows; $i++) {
760 array_push($guests_rows, $guests_rows[0]);
761 }
762 $tipo = count($guests_rows) > 1 ? 17 : $tipo;
763 }
764 }
765
766 //create one row for each guest
767 $guest_ind = 1;
768 foreach ($guests_rows as $ind => $guests) {
769 // prepare row record
770 $insert_row = array();
771
772 // find the actual guest-room-index
773 $guest_room_ind = $this->calcGuestRoomIndex($room_guests, $guest_ind);
774
775 // booking ID
776 array_push($insert_row, array(
777 'key' => 'idbooking',
778 'attr' => array(
779 'class="center"'
780 ),
781 'callback' => function ($val) {
782 return '<a href="index.php?option=com_vikbooking&task=editorder&cid[]='.$val.'" target="_blank"><i class="'.VikBookingIcons::i('external-link').'"></i> '.$val.'</a>';
783 },
784 'callback_export' => function ($val) {
785 return $val;
786 },
787 'value' => $guests['id']
788 ));
789
790 // checkin date
791 array_push($insert_row, array(
792 'key' => 'checkin',
793 'attr' => array(
794 'class="center"'
795 ),
796 'callback' => function ($val) {
797 return date('d/m/Y', $val);
798 },
799 'value' => $guests['checkin']
800 ));
801
802 // checkout date
803 array_push($insert_row,array(
804 'key' => 'checkout',
805 'attr' => array(
806 'class="center"'
807 ),
808 'callback' => function ($val) {
809 return date('d/m/Y', $val);
810 },
811 'value' => $gbook[0]['checkout']
812 ));
813
814 // cognome
815 $cognome = !empty($guests['t_last_name']) ? $guests['t_last_name'] : $guests['last_name'];
816 $pax_cognome = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'last_name');
817 $cognome = !empty($pax_cognome) ? $pax_cognome : $cognome;
818 array_push($insert_row, array(
819 'key' => 'cognome',
820 'value' => $cognome
821 ));
822
823 // nome
824 $nome = !empty($guests['t_first_name']) ? $guests['t_first_name'] : $guests['first_name'];
825 $pax_nome = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'first_name');
826 $nome = !empty($pax_nome) ? $pax_nome : $nome;
827 array_push($insert_row, array(
828 'key' => 'nome',
829 'value' => $nome
830 ));
831
832 // sesso
833 $gender = !empty($guests['gender']) && $guest_ind < 2 ? strtoupper($guests['gender']) : '';
834 $gender = $gender == 'F' ? 2 : ($gender == 'M' ? 1 : $gender);
835 $pax_gender = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'gender');
836 $gender = !empty($pax_gender) ? $pax_gender : $gender;
837 if (is_numeric($gender)) {
838 $gender = (int)$gender;
839 } elseif (!strcasecmp($gender, 'F')) {
840 $gender = 2;
841 } elseif (!strcasecmp($gender, 'M')) {
842 $gender = 1;
843 }
844 array_push($insert_row, array(
845 'key' => 'gender',
846 'attr' => array(
847 'class="center'.(empty($gender) ? ' vbo-report-load-sesso' : '').'"'
848 ),
849 'callback' => function ($val) {
850 return $val == 2 ? 'F' : ($val == 1 ? 'M' : '?');
851 },
852 'callback_export' => function ($val) {
853 return $val == 2 ? 'F' : ($val == 1 ? 'M' : '?');
854 },
855 'value' => $gender
856 ));
857
858 // data di nascita
859 $dbirth = !empty($guests['bdate']) && $guest_ind < 2 ? VikBooking::getDateTimestamp($guests['bdate'], 0, 0) : '';
860 $pax_dbirth = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'date_birth');
861 $dbirth = !empty($pax_dbirth) ? $pax_dbirth : $dbirth;
862 $dbirth = (strpos($dbirth, '/') === false && strpos($dbirth, VikBooking::getDateSeparator()) === false) ? $dbirth : VikBooking::getDateTimestamp($dbirth, 0, 0);
863 array_push($insert_row, array(
864 'key' => 'dbirth',
865 'attr' => array(
866 'class="center'.(empty($dbirth) ? ' vbo-report-load-dbirth' : '').'"'
867 ),
868 'callback' => function ($val) {
869 if (!empty($val) && strpos($val, '/') === false && strpos($val, VikBooking::getDateSeparator()) === false) {
870 return date('d/m/Y', $val);
871 }
872 if (!empty($val) && strpos($val, '/') !== false) {
873 return $val;
874 }
875 return '?';
876 },
877 'no_export_callback' => 1,
878 'value' => $dbirth
879 ));
880
881 // cittadinanza (compatible with pax data field of driver "Italy")
882 $pax_country_c = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'country_c');
883 $citizen = !empty($guests['country']) && $guest_ind < 2 ? $guests['country'] : '';
884 $citizenval = '';
885 if (!empty($citizen) && $guest_ind < 2) {
886 $citizenval = $this->checkCountry($citizen);
887 }
888 // check nationality field from pre-checkin
889 $pax_citizen = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'nationality');
890 $citizen = !empty($pax_citizen) ? $pax_citizen : $citizen;
891 $citizen = !empty($pax_country_c) ? $pax_country_c : $citizen;
892 $citizenval = !empty($pax_country_c) ? $pax_country_c : $this->checkCountry($citizen);
893 array_push($insert_row, array(
894 'key' => 'citizen',
895 'attr' => array(
896 'class="center'.(empty($citizen) ? ' vbo-report-load-cittadinanza' : '').'"'
897 ),
898 'callback' => function ($val) {
899 return !empty($val) ? $this->nazioni[$val]['name'] : '?';
900 },
901 'no_export_callback' => 1,
902 'value' => !empty($citizenval) ? $citizenval : ''
903 ));
904
905 // stato di residenza
906 $provstay = '';
907 $pax_provstay = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'country_s');
908 $provstay = !empty($pax_provstay) ? $pax_provstay : $provstay;
909 array_push($insert_row, array(
910 'key' => 'stares',
911 'attr' => array(
912 'class="center'.(empty($provstay) ? ' vbo-report-load-nazione' : '').'"'
913 ),
914 'callback' => function($val) {
915 if (!empty($val) && isset($this->nazioni[$val])) {
916 return $this->nazioni[$val]['name'];
917 }
918 // information is missing and should be provided
919 return '?';
920 },
921 'no_export_callback' => 1,
922 'value' => $provstay
923 ));
924
925 // comune di residenza
926 $comstay = '';
927 $pax_comstay = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'comune_s');
928 $comstay = !empty($pax_comstay) ? $pax_comstay : $comstay;
929 array_push($insert_row, array(
930 'key' => 'comres',
931 'attr' => array(
932 'class="center'.(empty($comstay) ? ' vbo-report-load-comune' : '').'"'
933 ),
934 'callback' => function($val) {
935 if (!empty($val) && isset($this->comuniProvince['comuni'][$val])) {
936 return $this->comuniProvince['comuni'][$val]['name'];
937 }
938 // information is missing and should be provided
939 return '?';
940 },
941 'no_export_callback' => 1,
942 'value' => $comstay
943 ));
944
945 // tipo alloggiato
946 $use_tipo = $ind > 0 && $tipo == 17 ? 19 : $tipo;
947 $pax_guest_type = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'guest_type');
948 $use_tipo = !empty($pax_guest_type) ? $pax_guest_type : $use_tipo;
949 array_push($insert_row, array(
950 'key' => 'tipo',
951 'callback' => function ($val) {
952 switch ($val) {
953 case 16:
954 return 'Ospite Singolo';
955 case 17:
956 return 'Capofamiglia';
957 case 18:
958 return 'Capogruppo';
959 case 19:
960 return 'Familiare';
961 case 20:
962 return 'Membro Gruppo';
963 }
964 return '?';
965 },
966 'no_export_callback' => 1,
967 'value' => $use_tipo
968 ));
969
970 // mezzo di trasporto
971 array_push($insert_row, array(
972 'key' => 'mezzo',
973 'attr' => array(
974 'class="center vbo-report-load-trasporto"'
975 ),
976 'value' => '?'
977 ));
978
979 // tipo di turismo
980 array_push($insert_row, array(
981 'key' => 'turismo',
982 'attr' => array(
983 'class="center vbo-report-load-turismo"'
984 ),
985 'value' => '?'
986 ));
987
988 // numero persone in prenotazione
989 array_push($insert_row, array(
990 'key' => 'guestsnum',
991 'attr' => array(
992 'class="center"'
993 ),
994 'value' => $guestsnum
995 ));
996
997 // camere prenotate
998 array_push($insert_row, array(
999 'key' => 'roomsbooked',
1000 'attr' => array(
1001 'class="center"'
1002 ),
1003 'value' => count($gbook)
1004 ));
1005
1006 // push fields in the rows array as a new row
1007 array_push($this->rows, $insert_row);
1008
1009 // increment guest index
1010 $guest_ind++;
1011 }
1012 }
1013
1014 // do not sort the rows for this report because the lines of the guests of the same booking must be consecutive
1015 // $this->sortRows($pkrsort, $pkrorder);
1016
1017 // the footer row will just print the amount of records to export
1018 array_push($this->footerRow, array(
1019 array(
1020 'attr' => array(
1021 'class="vbo-report-total"'
1022 ),
1023 'value' => '<h3>'.JText::translate('VBOREPORTSTOTALROW').'</h3>'
1024 ),
1025 array(
1026 'attr' => array(
1027 'colspan="'.(count($this->cols) - 1).'"'
1028 ),
1029 'value' => count($this->rows)
1030 )
1031 ));
1032
1033 // Debug
1034 if ($this->debug) {
1035 $this->setWarning('path to report file = '.urlencode(dirname(__FILE__)).'<br/>');
1036 $this->setWarning('$total_rooms_units = '.$total_rooms_units.'<br/>');
1037 $this->setWarning('$bookings:<pre>'.print_r($bookings, true).'</pre><br/>');
1038 }
1039
1040 return true;
1041 }
1042
1043 public function formatXML(&$xml)
1044 {
1045 if (!class_exists('DOMDocument')) {
1046 // we cannot format the XML because DOMDocument is missing
1047 return $xml;
1048 }
1049
1050 $dom = new DOMDocument;
1051 $dom->preserveWhiteSpace = false;
1052 $dom->loadXML($xml);
1053 $dom->formatOutput = true;
1054 $xml = $dom->saveXML();
1055
1056 return $xml;
1057 }
1058
1059 /**
1060 * Generates the report columns and rows, then it outputs a CSV file
1061 * for download. In case of errors, the process is not terminated (exit)
1062 * to let the View display the error message.
1063 * We use customExport() rather than exportCSV() only because we need a
1064 * different download button rather than the classic "Export as CSV".
1065 *
1066 * @param int $export_type the view will pass this argument to the method to call different types of export.
1067 *
1068 * @return mixed void on success with script termination, false otherwise.
1069 */
1070 public function customExport($export_type = 0)
1071 {
1072 if (!$this->getReportData()) {
1073 return false;
1074 }
1075
1076 $pfromdate = VikRequest::getString('fromdate', '', 'request');
1077 $ptodate = VikRequest::getString('todate', '', 'request');
1078 $pcodstru = VikRequest::getString('codstru', '', 'request');
1079 $papertura = VikRequest::getString('apertura', '', 'request');
1080 $records = array();
1081 $q = "SELECT SUM(`units`) AS `sommaunita`, SUM(`totpeople`) AS `numeropersone`, COUNT(*) AS `numerocamere` FROM `#__vikbooking_rooms` WHERE `avail`= '1';";
1082 $this->dbo->setQuery($q);
1083 $this->dbo->execute();
1084 if ($this->dbo->getNumRows() > 0) {
1085 $records = $this->dbo->loadAssocList();
1086 }
1087 $totalBeds = (int)($records[0]['sommaunita'] * ($records[0]['numeropersone']/$records[0]['numerocamere']));
1088 // filtro numero letti
1089 $pletti = VikRequest::getString('numletti', $totalBeds, 'request');
1090
1091 // manual values in filler
1092 $pfiller = VikRequest::getString('filler', '', 'request', VIKREQUEST_ALLOWRAW);
1093 $pfiller = !empty($pfiller) ? json_decode($pfiller, true) : array();
1094 $pfiller = !is_array($pfiller) ? array() : $pfiller;
1095
1096 // Debug
1097 if ($this->debug) {
1098 $this->setError('<pre>'.print_r($pfiller, true).'</pre><br/>');
1099 return false;
1100 }
1101
1102 $q = "SELECT SUM(`units`) FROM `#__vikbooking_rooms` WHERE `avail`= '1';";
1103 $this->dbo->setQuery($q);
1104 $this->dbo->execute();
1105 $totalRooms = $this->dbo->loadResult();
1106
1107 // pool of booking IDs to update their history
1108 $booking_ids = array();
1109 // update the history for all bookings affected
1110 foreach ($booking_ids as $bid) {
1111 VikBooking::getBookingHistoryInstance()->setBid($bid)->store('RP', $this->reportName);
1112 }
1113 $date = str_replace('/', '-', $pfromdate);
1114 $dataMovim = date('Ymd', strtotime($date));
1115
1116 $xml = '<?xml version="1.0" encoding="UTF-8"?>'."\n".'<movimenti>'."\n".'<codice>'.$pcodstru.'</codice>'."\n".'<prodotto>VikBooking</prodotto>'."\n".'<movimento>'."\n".'<data>'.$dataMovim.'</data>'."\n";
1117 $numOccupiedrooms = 0;
1118
1119 $from_ts = VikBooking::getDateTimestamp($pfromdate, 0, 0);
1120 $to_ts = VikBooking::getDateTimestamp($pfromdate, 23, 59, 59);
1121
1122 $clienti = array(
1123 'arrivi' => array(),
1124 'partenze' => array(),
1125 'prenotazioni' => array(),
1126 );
1127
1128 $q = "SELECT COUNT(`o`.`id`),".
1129 "(SELECT `h`.`dt` FROM `#__vikbooking_orderhistory` AS `h` WHERE `h`.`idorder`=`o`.`id` AND `h`.`type`='RP' AND `h`.`descr`=".$this->dbo->quote($this->reportName)." ORDER BY `h`.`dt` DESC LIMIT 1) AS `history_last` ".
1130 "FROM `#__vikbooking_orders` AS `o` LEFT JOIN `#__vikbooking_ordersrooms` AS `or` ON `or`.`idorder`=`o`.`id` ".
1131 "LEFT JOIN `#__vikbooking_customers_orders` AS `co` ON `co`.`idorder`=`o`.`id` LEFT JOIN `#__vikbooking_customers` AS `c` ON `c`.`id`=`co`.`idcustomer` LEFT JOIN `#__vikbooking_countries` AS `cy` ON `cy`.`country_3_code`=`c`.`country` ".
1132 "WHERE `o`.`status`='confirmed' AND `o`.`closure`=0 AND ((`o`.`checkin`>=".$from_ts." AND `o`.`checkin`<=".$to_ts.") OR (`o`.`checkout`>=".$from_ts." AND `o`.`checkout`<=".$to_ts.") OR (`o`.`checkin`<=".$from_ts." AND `o`.`checkout`>=".$to_ts.")) ".
1133 "ORDER BY `o`.`checkin` ASC, `o`.`id` ASC;";
1134
1135 $this->dbo->setQuery($q);
1136 $this->dbo->execute();
1137 $camereoccupate = $this->dbo->loadResult();
1138 $arrivi = 0;
1139 $partenze = 0;
1140 $prenotazioni = 0;
1141
1142 if ($papertura == 'SI') {
1143 $xml .= '<struttura>'."\n";
1144 $xml .= '<apertura>'.$papertura.'</apertura>'."\n";
1145 $xml .= '<camereoccupate>'.$camereoccupate.'</camereoccupate>'."\n";
1146 $xml .= '<cameredisponibili>'.$totalRooms.'</cameredisponibili>'."\n";
1147 $xml .= '<lettidisponibili>'.$pletti.'</lettidisponibili>'."\n";
1148 $xml .= '</struttura>'."\n";
1149 foreach ($this->rows as $ind => $row) {
1150 $idswh = -1;
1151 $timestamp_in = -1;
1152 $timestamp_out = -1;
1153 $control = -1; // mi serve per non ripetere ogni loop il controllo sul tipo di cliente
1154 $type = -1; // se il cliente è in arrivo il tipo è 1, se è in partenza 2, se è una nuova prenotazione 3
1155
1156 foreach ($row as $field) {
1157 if (isset($field['ignore_export'])) {
1158 continue;
1159 }
1160 // check if a value for this field was filled in manually
1161 if (is_array($pfiller) && isset($pfiller[$ind]) && isset($pfiller[$ind][$field['key']])) {
1162 if (strlen($pfiller[$ind][$field['key']])) {
1163 $field['value'] = $pfiller[$ind][$field['key']];
1164 }
1165 }
1166 // values set to -1 are usually empty and should have been filled in manually
1167 if ($field['value'] === -1) {
1168 // we raise an error in this case without stopping the process
1169 $field['value'] = 0;
1170 VikError::raiseWarning('', 'La riga #'.$ind.' ha un valore vuoto che doveva essere riempito manualmente cliccando sul blocco in rosso. Il file potrebbe contenere valori invalidi per questa riga.');
1171 }
1172 if (isset($field['callback_export'])) {
1173 $field['callback'] = $field['callback_export'];
1174 }
1175 $export_value = !isset($field['no_export_callback']) && isset($field['callback']) && is_callable($field['callback']) ? $field['callback']($field['value']) : $field['value'];
1176
1177 if ($field['key'] == 'idbooking') {
1178 $idswh = $export_value;
1179 }
1180 if ($field['key'] == 'checkin') {
1181 $timestamp_in = VikBooking::getDateTimestamp($export_value);
1182 }
1183 if ($field['key'] == 'checkout') {
1184 $timestamp_out = VikBooking::getDateTimestamp($export_value);
1185 }
1186 if ($control == -1 && $timestamp_in != -1 && $timestamp_out != -1) {
1187 if (date('Y-m-d', $timestamp_in) == date('Y-m-d', $from_ts) && date('Y-m-d', $timestamp_in) <= date('Y-m-d', $to_ts)) {
1188 $type = 1;
1189 } elseif (date('Y-m-d', $timestamp_out) == date('Y-m-d', $from_ts) && date('Y-m-d', $timestamp_out) == date('Y-m-d', $to_ts)) {
1190 $type = 2;
1191 } else {
1192 $type = 3;
1193 }
1194 $control = true;
1195 }
1196 if ($type == 1) {
1197 $clienti['arrivi'][$arrivi]['idswh'] = $idswh;
1198 if ($field['key'] == 'tipo') {
1199 $clienti['arrivi'][$arrivi]['tipoalloggiato'] = (string)$export_value;
1200 }
1201 if ($field['key'] == 'gender') {
1202 $clienti['arrivi'][$arrivi]['sesso'] = $export_value;
1203 }
1204 if ($field['key'] == 'turismo') {
1205 $clienti['arrivi'][$arrivi]['tipoturismo'] = $export_value;
1206 }
1207 if ($field['key'] == 'mezzo') {
1208 $clienti['arrivi'][$arrivi]['mezzotrasporto'] = $export_value;
1209 }
1210 if ($field['key'] == 'citizen') {
1211 $clienti['arrivi'][$arrivi]['cittadinanza'] = (string)$export_value;
1212 }
1213 if ($field['key'] == 'stares') {
1214 $clienti['arrivi'][$arrivi]['statoresidenza'] = (string)$export_value;
1215 }
1216 if ($field['key'] == 'dbirth') {
1217 $datanascita = date('Ymd', $export_value);
1218 $clienti['arrivi'][$arrivi]['datanascita'] = $datanascita;
1219 }
1220 if (isset($clienti['arrivi'][$arrivi]['cittadinanza']) && $clienti['arrivi'][$arrivi]['cittadinanza'] == '100000100' && $field['key'] == 'comres') {
1221 $clienti['arrivi'][$arrivi]['luogoresidenza'] = (string)$export_value;
1222 }
1223 if (isset($clienti['arrivi'][$arrivi]['tipoalloggiato']) && ($clienti['arrivi'][$arrivi]['tipoalloggiato'] == '19' || $clienti['arrivi'][$arrivi]['tipoalloggiato'] == '20') && $field['key'] == 'tipo' ) {
1224 $clienti['arrivi'][$arrivi]['idcapo'] = (string)$idswh;
1225 }
1226 } elseif ($type == 2) {
1227 $clienti['partenze'][$partenze]['idswh'] = $idswh;
1228 if ($field['key'] == 'tipo') {
1229 $clienti['partenze'][$partenze]['tipoalloggiato'] = (string)$export_value;
1230 }
1231 if ($field['key'] == 'checkin') {
1232 $arrivo = date('Ymd', VikBooking::getDateTimestamp($export_value));
1233 $clienti['partenze'][$partenze]['arrivo'] = $arrivo;
1234 }
1235 } elseif ($type == 3) {
1236 $clienti['prenotazioni'][$prenotazioni]['idswh'] = $idswh;
1237 if ($field['key'] == 'checkin') {
1238 $prenotazione = date('Ymd', VikBooking::getDateTimestamp($export_value));
1239 $clienti['prenotazioni'][$prenotazioni]['arrivo'] = $prenotazione;
1240 }
1241 if ($field['key'] == 'checkout') {
1242 $partenza = date('Ymd', VikBooking::getDateTimestamp($export_value));
1243 $clienti['prenotazioni'][$prenotazioni]['partenza'] = $partenza;
1244 }
1245 if ($field['key'] == 'guestsnum') {
1246 $clienti['prenotazioni'][$prenotazioni]['ospiti'] = (string)$export_value;
1247 }
1248 if ($field['key'] == 'roomsbooked') {
1249 $clienti['prenotazioni'][$prenotazioni]['camere'] = (string)$export_value;
1250 }
1251 }
1252 }
1253 if ($type == 1) {
1254 $arrivi++;
1255 } elseif ($type == 2) {
1256 $partenze++;
1257 } elseif ($type == 3){
1258 $prenotazioni++;
1259 }
1260 }
1261
1262 $xml .= '<arrivi>'."\n";
1263 for ($i = 0; $i < count($clienti['arrivi']); $i++) {
1264 $xml .= '<arrivo>'."\n";
1265 foreach ($clienti['arrivi'][$i] as $key => $value) {
1266 $xml .= '<'.$key.'>'.$value.'</'.$key.'>'."\n";
1267 }
1268 $xml .= '</arrivo>'."\n";
1269 }
1270 $xml .= '</arrivi>'."\n";
1271
1272 $xml .= '<partenze>'."\n";
1273 for ($i = 0; $i < count($clienti['partenze']); $i++) {
1274 $xml .= '<partenza>'."\n";
1275 foreach ($clienti['partenze'][$i] as $key => $value) {
1276 $xml .= '<'.$key.'>'.$value.'</'.$key.'>'."\n";
1277 }
1278 $xml .= '</partenza>'."\n";
1279 }
1280 $xml .= '</partenze>'."\n";
1281
1282 $xml .= '<prenotazioni>'."\n";
1283 for ($i = 0; $i < count($clienti['prenotazioni']); $i++) {
1284 $xml .= '<prenotazione>'."\n";
1285 foreach ($clienti['prenotazioni'][$i] as $key => $value) {
1286 $xml .= '<'.$key.'>'.$value.'</'.$key.'>'."\n";
1287 }
1288 $xml .= '</prenotazione>'."\n";
1289 }
1290 $xml .= '</prenotazioni>'."\n";
1291 } else {
1292 $xml .= '<struttura>'."\n";
1293 $xml .= '<apertura>'.$papertura.'</apertura>'."\n";
1294 $xml .= '<camereoccupate>0</camereoccupate>'."\n";
1295 $xml .= '<cameredisponibili>0</cameredisponibili>'."\n";
1296 $xml .= '<lettidisponibili>0</lettidisponibili>'."\n";
1297 $xml .= '</struttura>'."\n";
1298 }
1299 $xml .= '</movimento> '."\n";
1300 $xml .= '</movimenti>';
1301
1302 // format XML document
1303 $this->formatXML($xml);
1304
1305 /**
1306 * Custom export method supports a custom export handler, if previously set.
1307 *
1308 * @since 1.16.1 (J) - 1.6.1 (WP)
1309 */
1310 if ($this->hasExportHandler()) {
1311 // write data onto the custom file handler
1312 $fp = $this->getExportCSVHandler();
1313 fwrite($fp, $xml);
1314 fclose($fp);
1315
1316 return true;
1317 }
1318
1319 header('Content-Disposition: attachment; filename=' . $this->getExportCSVFileName());
1320 header('Content-type: text/xml');
1321 echo $xml;
1322
1323 exit;
1324 }
1325
1326 /**
1327 * Registers the name to give to the file being exported.
1328 *
1329 * @return void
1330 *
1331 * @since 1.16.1 (J) - 1.6.1 (WP)
1332 */
1333 private function registerExportFileName()
1334 {
1335 $pfromdate = VikRequest::getString('fromdate', '', 'request');
1336
1337 $this->setExportCSVFileName(str_replace(' ', '_', $this->reportName) . '-' . str_replace('/', '_', $pfromdate) . '.xml');
1338 }
1339
1340 /**
1341 * Parses the file Comuni.csv and returns two associative
1342 * arrays: one for the Comuni and one for the Province.
1343 * Every line of the CSV is composed of: Codice, Comune, Provincia.
1344 *
1345 * @return array
1346 */
1347 private function loadComuniProvince()
1348 {
1349 $vals = array(
1350 'comuni' => array(
1351 0 => '-- Estero --'
1352 ),
1353 'province' => array(
1354 0 => '-- Estero --'
1355 )
1356 );
1357
1358 $csv = dirname(__FILE__).DIRECTORY_SEPARATOR.'Comuni.csv';
1359 $rows = file($csv);
1360 foreach ($rows as $row) {
1361 if (empty($row)) {
1362 continue;
1363 }
1364 $v = explode(';', $row);
1365 if (count($v) != 3) {
1366 continue;
1367 }
1368 $vals['comuni'][$v[0]]['name'] = $v[1];
1369 $vals['comuni'][$v[0]]['province'] = $v[2];
1370 $vals['province'][$v[2]] = $v[2];
1371 }
1372
1373 return $vals;
1374 }
1375
1376 /**
1377 * Parses the file Nazioni.csv and returns an associative
1378 * array with the code and name of the Nazione.
1379 * Every line of the CSV is composed of: Codice, Nazione.
1380 *
1381 * @return array
1382 */
1383 private function loadNazioni()
1384 {
1385 $nazioni = array();
1386
1387 $csv = dirname(__FILE__).DIRECTORY_SEPARATOR.'Nazioni.csv';
1388 $rows = file($csv);
1389 foreach ($rows as $row) {
1390 if (empty($row)) {
1391 continue;
1392 }
1393 $v = explode(';', $row);
1394 if (count($v) != 3) {
1395 continue;
1396 }
1397
1398 $nazioni[$v[0]]['name'] = $v[1];
1399 $nazioni[$v[0]]['three_code'] = $v[2];
1400
1401 }
1402
1403 return $nazioni;
1404 }
1405
1406 /**
1407 *
1408 * Returns an array that contains both name and key of the comune selected, plus the associated province.
1409 *
1410 * @return array
1411 */
1412 private function checkComune($combirth, $checked, $province)
1413 {
1414 $result = array();
1415 $first_found = '';
1416 if (!count($this->comuniProvince)) {
1417 $this->comuniProvince = $this->loadComuniProvince();
1418 }
1419 if (empty($combirth)) {
1420 return $result;
1421 }
1422 foreach ($this->comuniProvince['comuni'] as $key => $value) {
1423 if (!isset($value['name'])) {
1424 continue;
1425 }
1426 if ($value['name'] == $combirth) {
1427 $result['found'] = true;
1428 $result['combirth'] = $value['name'];
1429 $result['province'] = $value['province'];
1430 $result['comval'] = $key;
1431 $result['similar'] = false;
1432 break;
1433 } else if (strpos($value['name'], trim($combirth)) !== false && empty($first_found)) {
1434 $result['found'] = true;
1435 $result['combirth'] = $value['name'];
1436 $first_found = $key;
1437 $result['similar'] = true;
1438 $result['province'] = $value['province'];
1439 }
1440 }
1441 if (!$result['found']) {
1442 $result['combirth'] = '';
1443 }
1444
1445 if ($checked === true && strlen($province) > 0 && $result['found']) {
1446 $result['province'] = $province;
1447 if($province == $value['province']) {
1448 $result['provinceok'] = true;
1449 $result['province'] = $province;
1450 } else {
1451 $result['provinceok'] = false;
1452 }
1453 }
1454 if ($result['similar'] && $result['found']) {
1455 $result['comval'] = $first_found;
1456 }
1457
1458 return $result;
1459 }
1460
1461 /**
1462 *
1463 * Returns the key of the state selected by the user.
1464 *
1465 * @return string
1466 *
1467 */
1468 private function checkCountry($country)
1469 {
1470 $found = false;
1471 $staval = '';
1472 if (!count($this->nazioni)) {
1473 $this->nazioni = $this->loadNazioni();
1474 }
1475 foreach ($this->nazioni as $key => $value) {
1476 if (trim($value['three_code']) == trim($country)) {
1477 $staval = $key;
1478 $found = true;
1479 break;
1480 }
1481 }
1482 if ($found !== true) {
1483 $staval = '';
1484 }
1485 return $staval;
1486 }
1487
1488 /**
1489 * Sanitizes the "Comune": if comune contains also the province, example PRATO (PO),
1490 * then I set both Comune and Province and I check both of them with the checkComune() function.
1491 *
1492 * @return array
1493 */
1494 private function sanitizeComune($combirth)
1495 {
1496 $result = array();
1497
1498 if (strlen($combirth) > 2) {
1499 if (strpos($combirth, "(") !== false) {
1500 $comnas = explode("(", $combirth);
1501 $result['combirth'] = trim($comnas[0]);
1502 $result['province'] = $comnas[1];
1503 $result['province'] = str_replace(")", "", $result['province']);
1504 $result['checked'] = true;
1505 }
1506 } else if(strlen($combirth) > 0){
1507 $result['province'] = trim($combirth);
1508 $result['similar'] = true;
1509 }
1510 return $result;
1511 }
1512
1513 /**
1514 * Helper method to quickly get a pax_data property for the guest.
1515 *
1516 * @param array $pax_data the current pax_data stored.
1517 * @param array $guests list of total guests per room.
1518 * @param int $guest_ind the guest index.
1519 * @param string $key the pax_data key to look for.
1520 *
1521 * @return mixed null on failure or value fetched.
1522 */
1523 private function getGuestPaxDataValue($pax_data, $guests, $guest_ind, $key)
1524 {
1525 if (!is_array($pax_data) || !count($pax_data) || empty($key)) {
1526 return null;
1527 }
1528
1529 // find room index for this guest number
1530 $room_num = 0;
1531 $use_guest_ind = $guest_ind;
1532 foreach ($guests as $room_index => $room_tot_guests) {
1533 // find the proper guest index for the room to which this belongs
1534 if ($use_guest_ind <= $room_tot_guests) {
1535 // proper room index found for this guest
1536 $room_num = $room_index;
1537 break;
1538 } else {
1539 // it's probably in a next room
1540 $use_guest_ind -= $room_tot_guests;
1541 }
1542 }
1543
1544 // check if a value exists for the requested key in the found room and guest indexes
1545 if (isset($pax_data[$room_num]) && isset($pax_data[$room_num][$use_guest_ind])) {
1546 if (isset($pax_data[$room_num][$use_guest_ind][$key])) {
1547 // we've got a value previously stored
1548 return $pax_data[$room_num][$use_guest_ind][$key];
1549 }
1550 }
1551
1552 // nothing was found
1553 return null;
1554 }
1555
1556 /**
1557 * Helper method to determine the exact number for this guest in the room booked.
1558 *
1559 * @param array $guests list of total guests per room.
1560 * @param int $guest_ind the guest index.
1561 *
1562 * @return int the actual guest room index starting from 1.
1563 */
1564 private function calcGuestRoomIndex($guests, $guest_ind)
1565 {
1566 // find room index for this guest number
1567 $room_num = 0;
1568 $use_guest_ind = $guest_ind;
1569 foreach ($guests as $room_index => $room_tot_guests) {
1570 // find the proper guest index for the room to which this belongs
1571 if ($use_guest_ind <= $room_tot_guests) {
1572 // proper room index found for this guest
1573 $room_num = $room_index;
1574 break;
1575 } else {
1576 // it's probably in a next room
1577 $use_guest_ind -= $room_tot_guests;
1578 }
1579 }
1580
1581 return $use_guest_ind;
1582 }
1583 }
1584