PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
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.8.16, at admin/helpers/report/istat_sitra.php

1,578 lines 53.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 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(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 });
343 });
344 function vboReportCheckDates(selectedDate, inst) {
345 if (selectedDate === null || inst === null) {
346 return;
347 }
348 var cur_from_date = jQuery(this).val();
349 if (jQuery(this).hasClass("vbo-report-datepicker-from") && cur_from_date.length) {
350 var nowstart = jQuery(this).datepicker("getDate");
351 var nowstartdate = new Date(nowstart.getTime());
352 jQuery(".vbo-report-datepicker-to").datepicker("option", {minDate: nowstartdate});
353 }
354 }
355 function vboReportChosenComune(comune) {
356 var c_code = comune.value;
357 var c_val = comune.options[comune.selectedIndex].text;
358 if (reportActiveCell !== null) {
359 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
360 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
361 alert("Error, cannot find element to update.");
362 } else {
363 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
364 if (!reportObj.hasOwnProperty(nowindex)) {
365 reportObj[nowindex] = {};
366 }
367 if (jQuery(reportActiveCell).hasClass("vbo-report-load-docplace")) {
368 reportObj[nowindex].docplace = c_code;
369 } else {
370 reportObj[nowindex].comres = c_code;
371 }
372 }
373 }
374 reportActiveCell = null;
375 vboHideOverlay();
376 jQuery("#choose-comune").val("").select2("data", null, false);
377 }
378 function vboReportChosenProvincia(prov) {
379 var c_code = prov.value;
380 var c_val = prov.options[prov.selectedIndex].text;
381 if (reportActiveCell !== null) {
382 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
383 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
384 alert("Error, cannot find element to update.");
385 } else {
386 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
387 if (!reportObj.hasOwnProperty(nowindex)) {
388 reportObj[nowindex] = {};
389 }
390 reportObj[nowindex].prores = c_code;
391 }
392 }
393 reportActiveCell = null;
394 vboHideOverlay();
395 jQuery("#choose-provincia").val("").select2("data", null, false);
396 }
397 function vboReportChosenNazione(naz) {
398 var c_code = naz.value;
399 var c_val = naz.options[naz.selectedIndex].text;
400 if (reportActiveCell !== null) {
401 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
402 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
403 alert("Error, cannot find element to update.");
404 } else {
405 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
406 if (!reportObj.hasOwnProperty(nowindex)) {
407 reportObj[nowindex] = {};
408 }
409 if (jQuery(reportActiveCell).hasClass("vbo-report-load-nazione")) {
410 reportObj[nowindex].stares = c_code;
411 } else if (jQuery(reportActiveCell).hasClass("vbo-report-load-docplace")) {
412 reportObj[nowindex].docplace = c_code;
413 } else {
414 reportObj[nowindex].citizen = c_code;
415 }
416 }
417 }
418 reportActiveCell = null;
419 vboHideOverlay();
420 jQuery("#choose-nazione").val("").select2("data", null, false);
421 }
422 function vboReportChosenSesso(sesso) {
423 var c_code = sesso.value;
424 var c_val = sesso.options[sesso.selectedIndex].text;
425 if (reportActiveCell !== null) {
426 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
427 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
428 alert("Error, cannot find element to update.");
429 } else {
430 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
431 if (!reportObj.hasOwnProperty(nowindex)) {
432 reportObj[nowindex] = {};
433 }
434 reportObj[nowindex].gender = c_code;
435 }
436 }
437 reportActiveCell = null;
438 vboHideOverlay();
439 jQuery("#choose-sesso").val("").select2("data", null, false);
440 }
441 function vboReportChosenTrasporto(trasporto) {
442 var c_code = trasporto.value;
443 var c_val = trasporto.options[trasporto.selectedIndex].text;
444 if (reportActiveCell !== null) {
445 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
446 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
447 alert("Error, cannot find element to update.");
448 } else {
449 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
450 if (!reportObj.hasOwnProperty(nowindex)) {
451 reportObj[nowindex] = {};
452 }
453 reportObj[nowindex].mezzo = c_code;
454 }
455 }
456 reportActiveCell = null;
457 vboHideOverlay();
458 jQuery("#choose-trasporto").val("").select2("data", null, false);
459 }
460 function vboReportChosenTurismo(turismo) {
461 var c_code = turismo.value;
462 var c_val = turismo.options[turismo.selectedIndex].text;
463 if (reportActiveCell !== null) {
464 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
465 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
466 alert("Error, cannot find element to update.");
467 } else {
468 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
469 if (!reportObj.hasOwnProperty(nowindex)) {
470 reportObj[nowindex] = {};
471 }
472 reportObj[nowindex].turismo = c_code;
473 }
474 }
475 reportActiveCell = null;
476 vboHideOverlay();
477 jQuery("#choose-turismo").val("").select2("data", null, false);
478 }
479 function vboReportChosenDbirth(val) {
480 var c_code = val, c_val = val;
481 if (reportActiveCell !== null) {
482 var nowindex = jQuery(".vbo-reports-output table tbody tr").index(jQuery(reportActiveCell).closest("tr"));
483 if (isNaN(nowindex) || parseInt(nowindex) < 0) {
484 alert("Error, cannot find element to update.");
485 } else {
486 jQuery(reportActiveCell).addClass("vbo-report-load-elem-filled").find("span").text(c_val);
487 if (!reportObj.hasOwnProperty(nowindex)) {
488 reportObj[nowindex] = {};
489 }
490 reportObj[nowindex].dbirth = c_code;
491 }
492 }
493 reportActiveCell = null;
494 vboHideOverlay();
495 jQuery("#choose-dbirth").val("");
496 }
497 //download function
498 function vboDownloadSchedaIstat() {
499 if (!confirm("Sei sicuro di aver compilato tutti i dati?")) {
500 return false;
501 }
502 document.adminForm.target = "_blank";
503 document.adminForm.action += "&tmpl=component";
504 vboSetFilters({exportreport: "1", filler: JSON.stringify(reportObj)}, true);
505 setTimeout(function() {
506 document.adminForm.target = "";
507 document.adminForm.action = document.adminForm.action.replace("&tmpl=component", "");
508 vboSetFilters({exportreport: "0", filler: ""}, false);
509 }, 1000);
510 }
511 ';
512 $this->setScript($js);
513
514 return $this->reportFilters;
515 }
516
517 /**
518 * Loads the report data from the DB.
519 * Returns true in case of success, false otherwise.
520 * Sets the columns and rows for the report to be displayed.
521 *
522 * @return boolean
523 */
524 public function getReportData()
525 {
526 if (strlen($this->getError())) {
527 //Export functions may set errors rather than exiting the process, and the View may continue the execution to attempt to render the report.
528 return false;
529 }
530 //Input fields and other vars
531 $pfromdate = VikRequest::getString('fromdate', '', 'request');
532 $ptodate = VikRequest::getString('todate', '', 'request');
533 $pkrsort = VikRequest::getString('krsort', $this->defaultKeySort, 'request');
534 $pkrsort = empty($pkrsort) ? $this->defaultKeySort : $pkrsort;
535 $pkrorder = VikRequest::getString('krorder', $this->defaultKeyOrder, 'request');
536 $pkrorder = empty($pkrorder) ? $this->defaultKeyOrder : $pkrorder;
537 $pkrorder = $pkrorder == 'DESC' ? 'DESC' : 'ASC';
538 $pcodstru = VikRequest::getString('codstru', '', 'request');
539 $papertura = VikRequest::getString('apertura', '', 'request');
540 $records = array();
541 $q = "SELECT SUM(`units`) AS `sommaunita`, SUM(`totpeople`) AS `numeropersone`, COUNT(*) AS `numerocamere` FROM `#__vikbooking_rooms` WHERE `avail`= '1';";
542 $this->dbo->setQuery($q);
543 $this->dbo->execute();
544 if ($this->dbo->getNumRows() > 0) {
545 $records = $this->dbo->loadAssocList();
546 }
547 $totalBeds = (int)($records[0]['sommaunita'] * ($records[0]['numeropersone'] / $records[0]['numerocamere']));
548 $pletti = VikRequest::getString('numletti', $totalBeds, 'request');
549 $currency_symb = VikBooking::getCurrencySymb();
550 $df = $this->getDateFormat();
551 $datesep = VikBooking::getDateSeparator();
552 if (empty($ptodate)) {
553 $ptodate = $pfromdate;
554 }
555 //Get dates timestamps
556 $from_ts = VikBooking::getDateTimestamp($pfromdate, 0, 0);
557 $to_ts = VikBooking::getDateTimestamp($ptodate, 23, 59, 59);
558 if (empty($pfromdate) || empty($from_ts) || empty($to_ts)) {
559 $this->setError(JText::translate('VBOREPORTSERRNODATES'));
560 return false;
561 }
562 if (empty($pcodstru)) {
563 $this->setError('Inserisci il codice della tua Struttura.<br/>Si tratta di un codice univoco di identificazione che ti viene assegnato dall\'Amministrazione competente.');
564 return false;
565 }
566 if (empty($papertura)) {
567 $this->setError('Devi specificare se la tua struttura è aperta o meno attraverso il menù a tendina qui sopra.');
568 return false;
569 }
570 //Query to obtain the records (all check-ins within the dates filter)
571 $records = array();
572 $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`,".
573 "`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`,".
574 "`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` ".
575 "FROM `#__vikbooking_orders` AS `o` LEFT JOIN `#__vikbooking_ordersrooms` AS `or` ON `or`.`idorder`=`o`.`id` ".
576 "LEFT JOIN `#__vikbooking_customers_orders` AS `co` ON `co`.`idorder`=`o`.`id` LEFT JOIN `#__vikbooking_customers` AS `c` ON `c`.`id`=`co`.`idcustomer` ".
577 "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.")) ".
578 "ORDER BY `o`.`checkin` ASC, `o`.`id` ASC, `or`.`id` ASC;";
579 $this->dbo->setQuery($q);
580 $records = $this->dbo->loadAssocList();
581
582 if (!$records) {
583 $this->setError(JText::translate('VBOREPORTSERRNORESERV'));
584 $this->setError('Nessun check-in nelle date selezionate.');
585 return false;
586 }
587 //nest records with multiple rooms booked inside sub-array
588 $bookings = array();
589 foreach ($records as $v) {
590 if (!isset($bookings[$v['id']])) {
591 $bookings[$v['id']] = array();
592 }
593 array_push($bookings[$v['id']], $v);
594 }
595 //define the columns of the report
596 $this->cols = array(
597 //id booking
598 array(
599 'key' => 'idbooking',
600 'attr' => array(
601 'class="center"'
602 ),
603 'label' => 'ID',
604 'sortable' => 1,
605 ),
606 //check-in
607 array(
608 'key' => 'checkin',
609 'attr' => array(
610 'class="center"'
611 ),
612 'sortable' => 1,
613 'label' => JText::translate('VBPICKUPAT')
614 ),
615 //checkout
616 array(
617 'key' => 'checkout',
618 'attr' => array(
619 'class="center"'
620 ),
621 'sortable' => 1,
622 'label' => 'Partenza'
623 ),
624 //cognome
625 array(
626 'key' => 'cognome',
627 'label' => JText::translate('VBTRAVELERLNAME'),
628 'sortable' => 1,
629 ),
630 //nome
631 array(
632 'key' => 'nome',
633 'label' => JText::translate('VBTRAVELERNAME'),
634 'sortable' => 1,
635 ),
636 //sesso
637 array(
638 'key' => 'gender',
639 'attr' => array(
640 'class="center"'
641 ),
642 'label' => JText::translate('VBCUSTOMERGENDER')
643 ),
644 //data di nascita
645 array(
646 'key' => 'dbirth',
647 'attr' => array(
648 'class="center"'
649 ),
650 'label' => JText::translate('VBCUSTOMERBDATE')
651 ),
652 //cittadinanza
653 array(
654 'key' => 'citizen',
655 'attr' => array(
656 'class="center"'
657 ),
658 'sortable' => 1,
659 'label' => 'Cittadinanza'
660 ),
661 //cittadinanza
662 array(
663 'key' => 'stares',
664 'attr' => array(
665 'class="center"'
666 ),
667 'sortable' => 1,
668 'label' => 'Stato di Residenza'
669 ),
670 //comune di residenza
671 array(
672 'key' => 'comres',
673 'attr' => array(
674 'class="center"'
675 ),
676 'sortable' => 1,
677 'label' => 'Comune Residenza',
678 'tip' => 'Inserire il comune di residenza solo se il cittadino è di nazionalità italiana.'
679 ),
680 //tipo
681 array(
682 'key' => 'tipo',
683 'attr' => array(
684 'class="vbo-report-longlbl"'
685 ),
686 'label' => 'Tipo Alloggiato'
687 ),
688 // tipo di trasporto
689 array(
690 'key' => 'mezzo',
691 'attr' => array(
692 'class="center"'
693 ),
694 'label' => 'Mezzo di Trasporto'
695 ),
696 // tipo di turismo
697 array(
698 'key' => 'turismo',
699 'attr' => array(
700 'class="center"'
701 ),
702 'label' => 'Tipo di Turismo'
703 ),
704 //quantità (numero di ospiti)
705 array(
706 'key' => 'guestsnum',
707 'attr' => array(
708 'class="center"'
709 ),
710 'sortable' => 1,
711 'label' => 'Numero Ospiti',
712 'tip' => 'Il numero di ospiti totali (adulti + bambini) per ogni prenotazione è un dato che verrà comunicato all\'ISTAT.',
713 ),
714 array(
715 'key' => 'roomsbooked',
716 'attr' => array(
717 'class="center"'
718 ),
719 'sortable' => 1,
720 'label' => 'Occupazione',
721 'tip' => 'Questo valore indica il numero di camere occupate da ogni prenotazione, ed è un dato che verrà comunicato all\'ISTAT.',
722 ),
723 );
724
725 // loop over the bookings to build the rows of the report
726 $from_info = getdate($from_ts);
727 foreach ($bookings as $gbook) {
728 $guestsnum = 0;
729 $guests_rows = array($gbook[0]);
730 $room_guests = array();
731 $tot_guests_rows = 1;
732
733 $tipo = 16;
734 // Codici Tipo Alloggiato
735 // 16 = Ospite Singolo
736 // 17 = Capofamiglia
737 // 18 = Capogruppo
738 // 19 = Familiare
739 // 20 = Membro Gruppo
740
741 foreach ($gbook as $book) {
742 $guestsnum += $book['adults'] + $book['children'];
743 $room_guests[] = ($book['adults'] + $book['children']);
744 }
745 $pax_data = null;
746 if (!empty($gbook[0]['pax_data'])) {
747 $pax_data = json_decode($gbook[0]['pax_data'], true);
748 if (is_array($pax_data) && count($pax_data)) {
749 $guests_rows[0]['pax_data'] = $pax_data;
750 $tot_guests_rows = 0;
751 foreach ($pax_data as $roomguests) {
752 $tot_guests_rows += count($roomguests);
753 }
754 for ($i = 1; $i < $tot_guests_rows; $i++) {
755 array_push($guests_rows, $guests_rows[0]);
756 }
757 $tipo = count($guests_rows) > 1 ? 17 : $tipo;
758 }
759 }
760
761 //create one row for each guest
762 $guest_ind = 1;
763 foreach ($guests_rows as $ind => $guests) {
764 // prepare row record
765 $insert_row = array();
766
767 // find the actual guest-room-index
768 $guest_room_ind = $this->calcGuestRoomIndex($room_guests, $guest_ind);
769
770 // booking ID
771 array_push($insert_row, array(
772 'key' => 'idbooking',
773 'attr' => array(
774 'class="center"'
775 ),
776 'callback' => function ($val) {
777 return '<a href="index.php?option=com_vikbooking&task=editorder&cid[]='.$val.'" target="_blank"><i class="'.VikBookingIcons::i('external-link').'"></i> '.$val.'</a>';
778 },
779 'callback_export' => function ($val) {
780 return $val;
781 },
782 'value' => $guests['id']
783 ));
784
785 // checkin date
786 array_push($insert_row, array(
787 'key' => 'checkin',
788 'attr' => array(
789 'class="center"'
790 ),
791 'callback' => function ($val) {
792 return date('d/m/Y', $val);
793 },
794 'value' => $guests['checkin']
795 ));
796
797 // checkout date
798 array_push($insert_row,array(
799 'key' => 'checkout',
800 'attr' => array(
801 'class="center"'
802 ),
803 'callback' => function ($val) {
804 return date('d/m/Y', $val);
805 },
806 'value' => $gbook[0]['checkout']
807 ));
808
809 // cognome
810 $cognome = !empty($guests['t_last_name']) ? $guests['t_last_name'] : $guests['last_name'];
811 $pax_cognome = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'last_name');
812 $cognome = !empty($pax_cognome) ? $pax_cognome : $cognome;
813 array_push($insert_row, array(
814 'key' => 'cognome',
815 'value' => $cognome
816 ));
817
818 // nome
819 $nome = !empty($guests['t_first_name']) ? $guests['t_first_name'] : $guests['first_name'];
820 $pax_nome = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'first_name');
821 $nome = !empty($pax_nome) ? $pax_nome : $nome;
822 array_push($insert_row, array(
823 'key' => 'nome',
824 'value' => $nome
825 ));
826
827 // sesso
828 $gender = !empty($guests['gender']) && $guest_ind < 2 ? strtoupper($guests['gender']) : '';
829 $gender = $gender == 'F' ? 2 : ($gender == 'M' ? 1 : $gender);
830 $pax_gender = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'gender');
831 $gender = !empty($pax_gender) ? $pax_gender : $gender;
832 if (is_numeric($gender)) {
833 $gender = (int)$gender;
834 } elseif (!strcasecmp($gender, 'F')) {
835 $gender = 2;
836 } elseif (!strcasecmp($gender, 'M')) {
837 $gender = 1;
838 }
839 array_push($insert_row, array(
840 'key' => 'gender',
841 'attr' => array(
842 'class="center'.(empty($gender) ? ' vbo-report-load-sesso' : '').'"'
843 ),
844 'callback' => function ($val) {
845 return $val == 2 ? 'F' : ($val == 1 ? 'M' : '?');
846 },
847 'callback_export' => function ($val) {
848 return $val == 2 ? 'F' : ($val == 1 ? 'M' : '?');
849 },
850 'value' => $gender
851 ));
852
853 // data di nascita
854 $dbirth = !empty($guests['bdate']) && $guest_ind < 2 ? VikBooking::getDateTimestamp($guests['bdate'], 0, 0) : '';
855 $pax_dbirth = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'date_birth');
856 $dbirth = !empty($pax_dbirth) ? $pax_dbirth : $dbirth;
857 $dbirth = (strpos($dbirth, '/') === false && strpos($dbirth, VikBooking::getDateSeparator()) === false) ? $dbirth : VikBooking::getDateTimestamp($dbirth, 0, 0);
858 array_push($insert_row, array(
859 'key' => 'dbirth',
860 'attr' => array(
861 'class="center'.(empty($dbirth) ? ' vbo-report-load-dbirth' : '').'"'
862 ),
863 'callback' => function ($val) {
864 if (!empty($val) && strpos($val, '/') === false && strpos($val, VikBooking::getDateSeparator()) === false) {
865 return date('d/m/Y', $val);
866 }
867 if (!empty($val) && strpos($val, '/') !== false) {
868 return $val;
869 }
870 return '?';
871 },
872 'no_export_callback' => 1,
873 'value' => $dbirth
874 ));
875
876 // cittadinanza (compatible with pax data field of driver "Italy")
877 $pax_country_c = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'country_c');
878 $citizen = !empty($guests['country']) && $guest_ind < 2 ? $guests['country'] : '';
879 $citizenval = '';
880 if (!empty($citizen) && $guest_ind < 2) {
881 $citizenval = $this->checkCountry($citizen);
882 }
883 // check nationality field from pre-checkin
884 $pax_citizen = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'nationality');
885 $citizen = !empty($pax_citizen) ? $pax_citizen : $citizen;
886 $citizen = !empty($pax_country_c) ? $pax_country_c : $citizen;
887 $citizenval = !empty($pax_country_c) ? $pax_country_c : $this->checkCountry($citizen);
888 array_push($insert_row, array(
889 'key' => 'citizen',
890 'attr' => array(
891 'class="center'.(empty($citizen) ? ' vbo-report-load-cittadinanza' : '').'"'
892 ),
893 'callback' => function ($val) {
894 return !empty($val) ? $this->nazioni[$val]['name'] : '?';
895 },
896 'no_export_callback' => 1,
897 'value' => !empty($citizenval) ? $citizenval : ''
898 ));
899
900 // stato di residenza
901 $provstay = '';
902 $pax_provstay = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'country_s');
903 $provstay = !empty($pax_provstay) ? $pax_provstay : $provstay;
904 array_push($insert_row, array(
905 'key' => 'stares',
906 'attr' => array(
907 'class="center'.(empty($provstay) ? ' vbo-report-load-nazione' : '').'"'
908 ),
909 'callback' => function($val) {
910 if (!empty($val) && isset($this->nazioni[$val])) {
911 return $this->nazioni[$val]['name'];
912 }
913 // information is missing and should be provided
914 return '?';
915 },
916 'no_export_callback' => 1,
917 'value' => $provstay
918 ));
919
920 // comune di residenza
921 $comstay = '';
922 $pax_comstay = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'comune_s');
923 $comstay = !empty($pax_comstay) ? $pax_comstay : $comstay;
924 array_push($insert_row, array(
925 'key' => 'comres',
926 'attr' => array(
927 'class="center'.(empty($comstay) ? ' vbo-report-load-comune' : '').'"'
928 ),
929 'callback' => function($val) {
930 if (!empty($val) && isset($this->comuniProvince['comuni'][$val])) {
931 return $this->comuniProvince['comuni'][$val]['name'];
932 }
933 // information is missing and should be provided
934 return '?';
935 },
936 'no_export_callback' => 1,
937 'value' => $comstay
938 ));
939
940 // tipo alloggiato
941 $use_tipo = $ind > 0 && $tipo == 17 ? 19 : $tipo;
942 $pax_guest_type = $this->getGuestPaxDataValue($pax_data, $room_guests, $guest_ind, 'guest_type');
943 $use_tipo = !empty($pax_guest_type) ? $pax_guest_type : $use_tipo;
944 array_push($insert_row, array(
945 'key' => 'tipo',
946 'callback' => function ($val) {
947 switch ($val) {
948 case 16:
949 return 'Ospite Singolo';
950 case 17:
951 return 'Capofamiglia';
952 case 18:
953 return 'Capogruppo';
954 case 19:
955 return 'Familiare';
956 case 20:
957 return 'Membro Gruppo';
958 }
959 return '?';
960 },
961 'no_export_callback' => 1,
962 'value' => $use_tipo
963 ));
964
965 // mezzo di trasporto
966 array_push($insert_row, array(
967 'key' => 'mezzo',
968 'attr' => array(
969 'class="center vbo-report-load-trasporto"'
970 ),
971 'value' => '?'
972 ));
973
974 // tipo di turismo
975 array_push($insert_row, array(
976 'key' => 'turismo',
977 'attr' => array(
978 'class="center vbo-report-load-turismo"'
979 ),
980 'value' => '?'
981 ));
982
983 // numero persone in prenotazione
984 array_push($insert_row, array(
985 'key' => 'guestsnum',
986 'attr' => array(
987 'class="center"'
988 ),
989 'value' => $guestsnum
990 ));
991
992 // camere prenotate
993 array_push($insert_row, array(
994 'key' => 'roomsbooked',
995 'attr' => array(
996 'class="center"'
997 ),
998 'value' => count($gbook)
999 ));
1000
1001 // push fields in the rows array as a new row
1002 array_push($this->rows, $insert_row);
1003
1004 // increment guest index
1005 $guest_ind++;
1006 }
1007 }
1008
1009 // do not sort the rows for this report because the lines of the guests of the same booking must be consecutive
1010 // $this->sortRows($pkrsort, $pkrorder);
1011
1012 // the footer row will just print the amount of records to export
1013 array_push($this->footerRow, array(
1014 array(
1015 'attr' => array(
1016 'class="vbo-report-total"'
1017 ),
1018 'value' => '<h3>'.JText::translate('VBOREPORTSTOTALROW').'</h3>'
1019 ),
1020 array(
1021 'attr' => array(
1022 'colspan="'.(count($this->cols) - 1).'"'
1023 ),
1024 'value' => count($this->rows)
1025 )
1026 ));
1027
1028 // Debug
1029 if ($this->debug) {
1030 $this->setWarning('path to report file = '.urlencode(dirname(__FILE__)).'<br/>');
1031 $this->setWarning('$total_rooms_units = '.$total_rooms_units.'<br/>');
1032 $this->setWarning('$bookings:<pre>'.print_r($bookings, true).'</pre><br/>');
1033 }
1034
1035 return true;
1036 }
1037
1038 public function formatXML(&$xml)
1039 {
1040 if (!class_exists('DOMDocument')) {
1041 // we cannot format the XML because DOMDocument is missing
1042 return $xml;
1043 }
1044
1045 $dom = new DOMDocument;
1046 $dom->preserveWhiteSpace = false;
1047 $dom->loadXML($xml);
1048 $dom->formatOutput = true;
1049 $xml = $dom->saveXML();
1050
1051 return $xml;
1052 }
1053
1054 /**
1055 * Generates the report columns and rows, then it outputs a CSV file
1056 * for download. In case of errors, the process is not terminated (exit)
1057 * to let the View display the error message.
1058 * We use customExport() rather than exportCSV() only because we need a
1059 * different download button rather than the classic "Export as CSV".
1060 *
1061 * @param string $export_type Differentiates the type of export requested.
1062 *
1063 * @return void|bool Void in case of script termination, boolean otherwise.
1064 */
1065 public function customExport($export_type = 0)
1066 {
1067 if (!$this->getReportData()) {
1068 return false;
1069 }
1070
1071 $pfromdate = VikRequest::getString('fromdate', '', 'request');
1072 $ptodate = VikRequest::getString('todate', '', 'request');
1073 $pcodstru = VikRequest::getString('codstru', '', 'request');
1074 $papertura = VikRequest::getString('apertura', '', 'request');
1075 $records = array();
1076 $q = "SELECT SUM(`units`) AS `sommaunita`, SUM(`totpeople`) AS `numeropersone`, COUNT(*) AS `numerocamere` FROM `#__vikbooking_rooms` WHERE `avail`= '1';";
1077 $this->dbo->setQuery($q);
1078 $this->dbo->execute();
1079 if ($this->dbo->getNumRows() > 0) {
1080 $records = $this->dbo->loadAssocList();
1081 }
1082 $totalBeds = (int)($records[0]['sommaunita'] * ($records[0]['numeropersone']/$records[0]['numerocamere']));
1083 // filtro numero letti
1084 $pletti = VikRequest::getString('numletti', $totalBeds, 'request');
1085
1086 // manual values in filler
1087 $pfiller = VikRequest::getString('filler', '', 'request', VIKREQUEST_ALLOWRAW);
1088 $pfiller = !empty($pfiller) ? json_decode($pfiller, true) : array();
1089 $pfiller = !is_array($pfiller) ? array() : $pfiller;
1090
1091 // Debug
1092 if ($this->debug) {
1093 $this->setError('<pre>'.print_r($pfiller, true).'</pre><br/>');
1094 return false;
1095 }
1096
1097 $q = "SELECT SUM(`units`) FROM `#__vikbooking_rooms` WHERE `avail`= '1';";
1098 $this->dbo->setQuery($q);
1099 $this->dbo->execute();
1100 $totalRooms = $this->dbo->loadResult();
1101
1102 // pool of booking IDs to update their history
1103 $booking_ids = array();
1104 // update the history for all bookings affected
1105 foreach ($booking_ids as $bid) {
1106 VikBooking::getBookingHistoryInstance()->setBid($bid)->store('RP', $this->reportName);
1107 }
1108 $date = str_replace('/', '-', $pfromdate);
1109 $dataMovim = date('Ymd', strtotime($date));
1110
1111 $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";
1112 $numOccupiedrooms = 0;
1113
1114 $from_ts = VikBooking::getDateTimestamp($pfromdate, 0, 0);
1115 $to_ts = VikBooking::getDateTimestamp($pfromdate, 23, 59, 59);
1116
1117 $clienti = array(
1118 'arrivi' => array(),
1119 'partenze' => array(),
1120 'prenotazioni' => array(),
1121 );
1122
1123 $q = "SELECT COUNT(`o`.`id`),".
1124 "(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` ".
1125 "FROM `#__vikbooking_orders` AS `o` LEFT JOIN `#__vikbooking_ordersrooms` AS `or` ON `or`.`idorder`=`o`.`id` ".
1126 "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` ".
1127 "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.")) ".
1128 "ORDER BY `o`.`checkin` ASC, `o`.`id` ASC, `or`.`id` ASC;";
1129
1130 $this->dbo->setQuery($q);
1131 $camereoccupate = $this->dbo->loadResult();
1132 $arrivi = 0;
1133 $partenze = 0;
1134 $prenotazioni = 0;
1135
1136 if ($papertura == 'SI') {
1137 $xml .= '<struttura>'."\n";
1138 $xml .= '<apertura>'.$papertura.'</apertura>'."\n";
1139 $xml .= '<camereoccupate>'.$camereoccupate.'</camereoccupate>'."\n";
1140 $xml .= '<cameredisponibili>'.$totalRooms.'</cameredisponibili>'."\n";
1141 $xml .= '<lettidisponibili>'.$pletti.'</lettidisponibili>'."\n";
1142 $xml .= '</struttura>'."\n";
1143 foreach ($this->rows as $ind => $row) {
1144 $idswh = -1;
1145 $timestamp_in = -1;
1146 $timestamp_out = -1;
1147 $control = -1; // mi serve per non ripetere ogni loop il controllo sul tipo di cliente
1148 $type = -1; // se il cliente è in arrivo il tipo è 1, se è in partenza 2, se è una nuova prenotazione 3
1149
1150 foreach ($row as $field) {
1151 if (isset($field['ignore_export'])) {
1152 continue;
1153 }
1154 // check if a value for this field was filled in manually
1155 if (is_array($pfiller) && isset($pfiller[$ind]) && isset($pfiller[$ind][$field['key']])) {
1156 if (strlen($pfiller[$ind][$field['key']])) {
1157 $field['value'] = $pfiller[$ind][$field['key']];
1158 }
1159 }
1160 // values set to -1 are usually empty and should have been filled in manually
1161 if ($field['value'] === -1) {
1162 // we raise an error in this case without stopping the process
1163 $field['value'] = 0;
1164 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.');
1165 }
1166 if (isset($field['callback_export'])) {
1167 $field['callback'] = $field['callback_export'];
1168 }
1169 $export_value = !isset($field['no_export_callback']) && isset($field['callback']) && is_callable($field['callback']) ? $field['callback']($field['value']) : $field['value'];
1170
1171 if ($field['key'] == 'idbooking') {
1172 $idswh = $export_value;
1173 }
1174 if ($field['key'] == 'checkin') {
1175 $timestamp_in = VikBooking::getDateTimestamp($export_value);
1176 }
1177 if ($field['key'] == 'checkout') {
1178 $timestamp_out = VikBooking::getDateTimestamp($export_value);
1179 }
1180 if ($control == -1 && $timestamp_in != -1 && $timestamp_out != -1) {
1181 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)) {
1182 $type = 1;
1183 } 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)) {
1184 $type = 2;
1185 } else {
1186 $type = 3;
1187 }
1188 $control = true;
1189 }
1190 if ($type == 1) {
1191 $clienti['arrivi'][$arrivi]['idswh'] = $idswh;
1192 if ($field['key'] == 'tipo') {
1193 $clienti['arrivi'][$arrivi]['tipoalloggiato'] = (string)$export_value;
1194 }
1195 if ($field['key'] == 'gender') {
1196 $clienti['arrivi'][$arrivi]['sesso'] = $export_value;
1197 }
1198 if ($field['key'] == 'turismo') {
1199 $clienti['arrivi'][$arrivi]['tipoturismo'] = $export_value;
1200 }
1201 if ($field['key'] == 'mezzo') {
1202 $clienti['arrivi'][$arrivi]['mezzotrasporto'] = $export_value;
1203 }
1204 if ($field['key'] == 'citizen') {
1205 $clienti['arrivi'][$arrivi]['cittadinanza'] = (string)$export_value;
1206 }
1207 if ($field['key'] == 'stares') {
1208 $clienti['arrivi'][$arrivi]['statoresidenza'] = (string)$export_value;
1209 }
1210 if ($field['key'] == 'dbirth') {
1211 $datanascita = date('Ymd', $export_value);
1212 $clienti['arrivi'][$arrivi]['datanascita'] = $datanascita;
1213 }
1214 if (isset($clienti['arrivi'][$arrivi]['cittadinanza']) && $clienti['arrivi'][$arrivi]['cittadinanza'] == '100000100' && $field['key'] == 'comres') {
1215 $clienti['arrivi'][$arrivi]['luogoresidenza'] = (string)$export_value;
1216 }
1217 if (isset($clienti['arrivi'][$arrivi]['tipoalloggiato']) && ($clienti['arrivi'][$arrivi]['tipoalloggiato'] == '19' || $clienti['arrivi'][$arrivi]['tipoalloggiato'] == '20') && $field['key'] == 'tipo' ) {
1218 $clienti['arrivi'][$arrivi]['idcapo'] = (string)$idswh;
1219 }
1220 } elseif ($type == 2) {
1221 $clienti['partenze'][$partenze]['idswh'] = $idswh;
1222 if ($field['key'] == 'tipo') {
1223 $clienti['partenze'][$partenze]['tipoalloggiato'] = (string)$export_value;
1224 }
1225 if ($field['key'] == 'checkin') {
1226 $arrivo = date('Ymd', VikBooking::getDateTimestamp($export_value));
1227 $clienti['partenze'][$partenze]['arrivo'] = $arrivo;
1228 }
1229 } elseif ($type == 3) {
1230 $clienti['prenotazioni'][$prenotazioni]['idswh'] = $idswh;
1231 if ($field['key'] == 'checkin') {
1232 $prenotazione = date('Ymd', VikBooking::getDateTimestamp($export_value));
1233 $clienti['prenotazioni'][$prenotazioni]['arrivo'] = $prenotazione;
1234 }
1235 if ($field['key'] == 'checkout') {
1236 $partenza = date('Ymd', VikBooking::getDateTimestamp($export_value));
1237 $clienti['prenotazioni'][$prenotazioni]['partenza'] = $partenza;
1238 }
1239 if ($field['key'] == 'guestsnum') {
1240 $clienti['prenotazioni'][$prenotazioni]['ospiti'] = (string)$export_value;
1241 }
1242 if ($field['key'] == 'roomsbooked') {
1243 $clienti['prenotazioni'][$prenotazioni]['camere'] = (string)$export_value;
1244 }
1245 }
1246 }
1247 if ($type == 1) {
1248 $arrivi++;
1249 } elseif ($type == 2) {
1250 $partenze++;
1251 } elseif ($type == 3){
1252 $prenotazioni++;
1253 }
1254 }
1255
1256 $xml .= '<arrivi>'."\n";
1257 for ($i = 0; $i < count($clienti['arrivi']); $i++) {
1258 $xml .= '<arrivo>'."\n";
1259 foreach ($clienti['arrivi'][$i] as $key => $value) {
1260 $xml .= '<'.$key.'>'.$value.'</'.$key.'>'."\n";
1261 }
1262 $xml .= '</arrivo>'."\n";
1263 }
1264 $xml .= '</arrivi>'."\n";
1265
1266 $xml .= '<partenze>'."\n";
1267 for ($i = 0; $i < count($clienti['partenze']); $i++) {
1268 $xml .= '<partenza>'."\n";
1269 foreach ($clienti['partenze'][$i] as $key => $value) {
1270 $xml .= '<'.$key.'>'.$value.'</'.$key.'>'."\n";
1271 }
1272 $xml .= '</partenza>'."\n";
1273 }
1274 $xml .= '</partenze>'."\n";
1275
1276 $xml .= '<prenotazioni>'."\n";
1277 for ($i = 0; $i < count($clienti['prenotazioni']); $i++) {
1278 $xml .= '<prenotazione>'."\n";
1279 foreach ($clienti['prenotazioni'][$i] as $key => $value) {
1280 $xml .= '<'.$key.'>'.$value.'</'.$key.'>'."\n";
1281 }
1282 $xml .= '</prenotazione>'."\n";
1283 }
1284 $xml .= '</prenotazioni>'."\n";
1285 } else {
1286 $xml .= '<struttura>'."\n";
1287 $xml .= '<apertura>'.$papertura.'</apertura>'."\n";
1288 $xml .= '<camereoccupate>0</camereoccupate>'."\n";
1289 $xml .= '<cameredisponibili>0</cameredisponibili>'."\n";
1290 $xml .= '<lettidisponibili>0</lettidisponibili>'."\n";
1291 $xml .= '</struttura>'."\n";
1292 }
1293 $xml .= '</movimento> '."\n";
1294 $xml .= '</movimenti>';
1295
1296 // format XML document
1297 $this->formatXML($xml);
1298
1299 /**
1300 * Custom export method supports a custom export handler, if previously set.
1301 *
1302 * @since 1.16.1 (J) - 1.6.1 (WP)
1303 */
1304 if ($this->hasExportHandler()) {
1305 // write data onto the custom file handler
1306 $fp = $this->getExportCSVHandler();
1307 fwrite($fp, $xml);
1308 fclose($fp);
1309
1310 return true;
1311 }
1312
1313 header('Content-Disposition: attachment; filename=' . $this->getExportCSVFileName());
1314 header('Content-type: text/xml');
1315 echo $xml;
1316
1317 exit;
1318 }
1319
1320 /**
1321 * Registers the name to give to the file being exported.
1322 *
1323 * @return void
1324 *
1325 * @since 1.16.1 (J) - 1.6.1 (WP)
1326 */
1327 private function registerExportFileName()
1328 {
1329 $pfromdate = VikRequest::getString('fromdate', '', 'request');
1330
1331 $this->setExportCSVFileName(str_replace(' ', '_', $this->reportName) . '-' . str_replace('/', '_', $pfromdate) . '.xml');
1332 }
1333
1334 /**
1335 * Parses the file Comuni.csv and returns two associative
1336 * arrays: one for the Comuni and one for the Province.
1337 * Every line of the CSV is composed of: Codice, Comune, Provincia.
1338 *
1339 * @return array
1340 */
1341 private function loadComuniProvince()
1342 {
1343 $vals = array(
1344 'comuni' => array(
1345 0 => '-- Estero --'
1346 ),
1347 'province' => array(
1348 0 => '-- Estero --'
1349 )
1350 );
1351
1352 $csv = dirname(__FILE__).DIRECTORY_SEPARATOR.'Comuni.csv';
1353 $rows = file($csv);
1354 foreach ($rows as $row) {
1355 if (empty($row)) {
1356 continue;
1357 }
1358 $v = explode(';', $row);
1359 if (count($v) != 3) {
1360 continue;
1361 }
1362 $vals['comuni'][$v[0]]['name'] = $v[1];
1363 $vals['comuni'][$v[0]]['province'] = $v[2];
1364 $vals['province'][$v[2]] = $v[2];
1365 }
1366
1367 return $vals;
1368 }
1369
1370 /**
1371 * Parses the file Nazioni.csv and returns an associative
1372 * array with the code and name of the Nazione.
1373 * Every line of the CSV is composed of: Codice, Nazione.
1374 *
1375 * @return array
1376 */
1377 private function loadNazioni()
1378 {
1379 $nazioni = array();
1380
1381 $csv = dirname(__FILE__).DIRECTORY_SEPARATOR.'Nazioni.csv';
1382 $rows = file($csv);
1383 foreach ($rows as $row) {
1384 if (empty($row)) {
1385 continue;
1386 }
1387 $v = explode(';', $row);
1388 if (count($v) != 3) {
1389 continue;
1390 }
1391
1392 $nazioni[$v[0]]['name'] = $v[1];
1393 $nazioni[$v[0]]['three_code'] = $v[2];
1394
1395 }
1396
1397 return $nazioni;
1398 }
1399
1400 /**
1401 *
1402 * Returns an array that contains both name and key of the comune selected, plus the associated province.
1403 *
1404 * @return array
1405 */
1406 private function checkComune($combirth, $checked, $province)
1407 {
1408 $result = array();
1409 $first_found = '';
1410 if (!count($this->comuniProvince)) {
1411 $this->comuniProvince = $this->loadComuniProvince();
1412 }
1413 if (empty($combirth)) {
1414 return $result;
1415 }
1416 foreach ($this->comuniProvince['comuni'] as $key => $value) {
1417 if (!isset($value['name'])) {
1418 continue;
1419 }
1420 if ($value['name'] == $combirth) {
1421 $result['found'] = true;
1422 $result['combirth'] = $value['name'];
1423 $result['province'] = $value['province'];
1424 $result['comval'] = $key;
1425 $result['similar'] = false;
1426 break;
1427 } else if (strpos($value['name'], trim($combirth)) !== false && empty($first_found)) {
1428 $result['found'] = true;
1429 $result['combirth'] = $value['name'];
1430 $first_found = $key;
1431 $result['similar'] = true;
1432 $result['province'] = $value['province'];
1433 }
1434 }
1435 if (!$result['found']) {
1436 $result['combirth'] = '';
1437 }
1438
1439 if ($checked === true && strlen($province) > 0 && $result['found']) {
1440 $result['province'] = $province;
1441 if($province == $value['province']) {
1442 $result['provinceok'] = true;
1443 $result['province'] = $province;
1444 } else {
1445 $result['provinceok'] = false;
1446 }
1447 }
1448 if ($result['similar'] && $result['found']) {
1449 $result['comval'] = $first_found;
1450 }
1451
1452 return $result;
1453 }
1454
1455 /**
1456 *
1457 * Returns the key of the state selected by the user.
1458 *
1459 * @return string
1460 *
1461 */
1462 private function checkCountry($country)
1463 {
1464 $found = false;
1465 $staval = '';
1466 if (!count($this->nazioni)) {
1467 $this->nazioni = $this->loadNazioni();
1468 }
1469 foreach ($this->nazioni as $key => $value) {
1470 if (trim($value['three_code']) == trim($country)) {
1471 $staval = $key;
1472 $found = true;
1473 break;
1474 }
1475 }
1476 if ($found !== true) {
1477 $staval = '';
1478 }
1479 return $staval;
1480 }
1481
1482 /**
1483 * Sanitizes the "Comune": if comune contains also the province, example PRATO (PO),
1484 * then I set both Comune and Province and I check both of them with the checkComune() function.
1485 *
1486 * @return array
1487 */
1488 private function sanitizeComune($combirth)
1489 {
1490 $result = array();
1491
1492 if (strlen($combirth) > 2) {
1493 if (strpos($combirth, "(") !== false) {
1494 $comnas = explode("(", $combirth);
1495 $result['combirth'] = trim($comnas[0]);
1496 $result['province'] = $comnas[1];
1497 $result['province'] = str_replace(")", "", $result['province']);
1498 $result['checked'] = true;
1499 }
1500 } else if(strlen($combirth) > 0){
1501 $result['province'] = trim($combirth);
1502 $result['similar'] = true;
1503 }
1504 return $result;
1505 }
1506
1507 /**
1508 * Helper method to quickly get a pax_data property for the guest.
1509 *
1510 * @param array $pax_data the current pax_data stored.
1511 * @param array $guests list of total guests per room.
1512 * @param int $guest_ind the guest index.
1513 * @param string $key the pax_data key to look for.
1514 *
1515 * @return mixed null on failure or value fetched.
1516 */
1517 private function getGuestPaxDataValue($pax_data, $guests, $guest_ind, $key)
1518 {
1519 if (!is_array($pax_data) || !count($pax_data) || empty($key)) {
1520 return null;
1521 }
1522
1523 // find room index for this guest number
1524 $room_num = 0;
1525 $use_guest_ind = $guest_ind;
1526 foreach ($guests as $room_index => $room_tot_guests) {
1527 // find the proper guest index for the room to which this belongs
1528 if ($use_guest_ind <= $room_tot_guests) {
1529 // proper room index found for this guest
1530 $room_num = $room_index;
1531 break;
1532 } else {
1533 // it's probably in a next room
1534 $use_guest_ind -= $room_tot_guests;
1535 }
1536 }
1537
1538 // check if a value exists for the requested key in the found room and guest indexes
1539 if (isset($pax_data[$room_num]) && isset($pax_data[$room_num][$use_guest_ind])) {
1540 if (isset($pax_data[$room_num][$use_guest_ind][$key])) {
1541 // we've got a value previously stored
1542 return $pax_data[$room_num][$use_guest_ind][$key];
1543 }
1544 }
1545
1546 // nothing was found
1547 return null;
1548 }
1549
1550 /**
1551 * Helper method to determine the exact number for this guest in the room booked.
1552 *
1553 * @param array $guests list of total guests per room.
1554 * @param int $guest_ind the guest index.
1555 *
1556 * @return int the actual guest room index starting from 1.
1557 */
1558 private function calcGuestRoomIndex($guests, $guest_ind)
1559 {
1560 // find room index for this guest number
1561 $room_num = 0;
1562 $use_guest_ind = $guest_ind;
1563 foreach ($guests as $room_index => $room_tot_guests) {
1564 // find the proper guest index for the room to which this belongs
1565 if ($use_guest_ind <= $room_tot_guests) {
1566 // proper room index found for this guest
1567 $room_num = $room_index;
1568 break;
1569 } else {
1570 // it's probably in a next room
1571 $use_guest_ind -= $room_tot_guests;
1572 }
1573 }
1574
1575 return $use_guest_ind;
1576 }
1577 }
1578