Si è verificato un errore nell'elaborarazione del modello.
For "." left-hand operand: Expected a hash, but this has evaluated to a sequence (wrapper: f.t.SimpleSequence): ==> programs [in template "383767#383802#1838824" at line 1825, column 37] ---- FTL stack trace ("~" means nesting-related): - Failed at: ${programs.getJSONObject("data").getJ... [in template "383767#383802#1838824" at line 1825, column 35] ----
1<#import "${templatesPath}/1724005" as d40>
2
3 <#assign
4 JALS = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")
5 JSONFactoryUtil = staticUtil["com.liferay.portal.kernel.json.JSONFactoryUtil"]
6
7 articleId = "1221309"
8 article = JALS.fetchArticle(groupId, articleId)
9 document = saxReaderUtil.read(article.getContent())
10 rootElement = document.getRootElement()
11 allegati = []
12 tipoProgramma=""
13 requestType="programma"
14 soggiorniStudioAdulti="Soggiorni studio 18+"
15 workExperience="Work Experience - Stage"
16 corsiOnline="Corsi Online"
17 giftCard="Gift Card"
18
19 stringSelector = "dynamic-element[@name='allegato']"
20 xPathSelector = saxReaderUtil.createXPath(stringSelector)
21 />
22
23 <#if xPathSelector.selectNodes(rootElement)??>
24 <#assign allegati = xPathSelector.selectNodes(rootElement)>
25 </#if>
26
27 <style>
28 .card.border-aqua{
29 border: 2px solid #43A08E !important;
30 }
31 .bg-aqua{
32 background-color: #43A08E !important;
33 }
34 </style>
35
36 <#macro printContent>
37 <div id="pay" class="p-3" v-cloak>
38 <div v-show="loading">
39 <div class="d-flex align-items-center justify-content-center h-full">
40 <div class="loading-animation"></div>
41 </div>
42 </div>
43
44 <div class="container" v-show="!loading">
45 <div class="text-center" v-if="name == 'Placeholder'">
46 <p class="text-dark">Errore interno.</p>
47 <p class="text-dark">Ricarica la pagina per continuare.</p>
48 </div>
49 <div class="row" v-else>
50 <div class="col-12">
51 <ol class="d-none d-lg-flex nav multi-step-nav multi-step-nav-collapse-sm flex-row" role="tablist">
52 <li v-for="(num, index) in totalSteps" class="multi-step-item" :class="{'complete': currentStep >= num, 'multi-step-item-expand': index != totalSteps-1}">
53 <div class="multi-step-divider"></div>
54 <div class="multi-step-indicator">
55 <button v-if="isDev" @click="currentStep = num" class="multi-step-icon bg-image-none" data-toggle="tab">
56 <span class="text-white font-weight-bold">{{ num }}</span>
57 </button>
58 <div v-else class="multi-step-icon bg-image-none" data-toggle="tab">
59 <span class="text-white font-weight-bold">{{ num }}</span>
60 </div>
61 </div>
62 </li>
63 </ol>
64
65 <div class="tbar subnav-tbar subnav-tbar-light d-lg-none">
66 <div class="container-fluid container-fluid-max-xl">
67 <div class="tbar-nav">
68 <div class="tbar-item tbar-item-expand">
69 <div class="tbar-section">
70 <span class="component-text text-truncate-inline">
71 <span class="text-truncate">Acquisto</span>
72 </span>
73 </div>
74 </div>
75 <div class="tbar-item">
76 <span class="component-text">Pagina {{ currentStep }} di {{ totalSteps }}</span>
77 </div>
78 </div>
79 </div>
80 </div>
81
82 <div class="tab-content mt-lg-5">
83
84 <#-- SELEZIONE PROGRAMMA -->
85 <div class="tab-pane fade" :class="{'show active': currentStep == 1}" role="tabpanel">
86 <div class="row justify-content-between">
87 <div class="d-none d-lg-block col-12 mb-4">
88 <p class="text-dark display-5 font-weight-light">Vai avanti per confermare il programma ${tipoProgramma} <span class="text-gray small" style="font-size:1rem;">(oppure modifica la tua scelta)</span></p>
89 </div>
90
91 <div class="col-12 col-lg-5">
92
93 <div class="mb-4 mt-5 mt-lg-0">
94 <p class="h4 text-dark mb-0">Scegli il periodo</p>
95 </div>
96
97 <div id="results">
98 <template v-for="(program, index) in programs">
99 <div v-if="program.sd != ''" :key="program._id.$oid" class="card void">
100 <div class="card-row">
101 <div class="autofit-col autofit-col-expand">
102 <section class="autofit-section">
103 <#--
104 <p class="text-muted mb-0">dal {{ program.sd | moment("DD/MM/YYYY").format("DD MMMM YYYY") }} al {{ program.ed | moment("DD/MM/YYYY").format("DD MMMM YYYY") }}</p>
105 -->
106 <p class="text-muted mb-0">{{ program.nomeTariffa }}</p>
107 <p class="mb-0">
108 <span class="badge badge-pill badge-primary bg-gradient-h" v-if="program.forGroup">
109 <span class="badge-item badge-item-expand">Per gruppi</span>
110 </span>
111 <template v-if="program.marketingGroups">
112 <span v-for="(item, index) in program.marketingGroups" :key="'mg-' + index" class="badge badge-pill badge-primary bg-gradient-h">
113 <span class="badge-item badge-item-expand">{{ labels[item] }}</span>
114 </span>
115 </template>
116 </p>
117 <p class="text-dark mb-0" v-if="program.basePrice!='' && program.basePrice!='0'">A partire da {{ program.basePrice | money }}</p>
118
119 <template v-for="(sconto, index) in program.purchaseBeforeDiscount">
120 <p v-if="isDiscountValid(sconto) && sconto.discount != 0" :key="'discount-' + index + '-' + program._id.$oid" class="text-muted small mb-0">
121 Acquista prima del {{ sconto.dateEnd | moment().format("DD MMMM YYYY") }}:
122 <span class="label label-success">
123 <span class="label-item label-item-expand">Sconto di {{ sconto.discount | money }}</span>
124 </span>
125 </p>
126 </template>
127 </section>
128 </div>
129 <div class="autofit-col">
130 <section class="autofit-section">
131 <button v-if="selectedProgram?._id?.$oid == program._id.$oid" class="btn bg-aqua py-2 px-3 px-lg-4 text-white">
132 Scelto
133 <i class="fas fa-check ml-2"></i>
134 </button>
135
136 <button v-else @click="selectProgram(program)" class="btn btn-outline-dark py-2 px-3 px-lg-4">
137 Scegli
138 </button>
139 </section>
140 </div>
141 </div>
142
143 <div v-if="index < programs.length - 1" class="dropdown-divider w-75 mx-auto my-3"></div>
144 </div>
145 </template>
146 </div>
147 </div>
148
149 <div class="col-12 col-lg-7">
150 <div v-if="selectedProgram != null" class="mb-4 mt-5 mt-lg-0">
151 <div class="card no-shadow border-aqua rounded">
152 <div class="card-body p-3">
153 <div class="card-row flex-column flex-lg-row">
154 <div class="autofit-col autofit-col-gutters">
155 <div class="flex-column text-lg-center">
156 <template v-for="(block, bIndex) in selectedProgram?.nomeTariffa.split(' ')">
157 <p v-if="block.trim() != ''" :key="'block-' + bIndex" class="text-aqua font-weight-bold text-uppercase mb-0 mb-lg-3">
158 {{ block }}
159 </p>
160 </template>
161 </div>
162 </div>
163 <div class="autofit-col autofit-col-expand autofit-col-gutters border-lg-left">
164 <div class="autofit-section">
165 <template v-if="selectedProgram.marketingGroups">
166 <button v-for="(item, index) in selectedProgram.marketingGroups" :key="'smg-' + index" class="btn btn-secondary active no-events mr-2">
167 {{ labels[item] }}
168 </button>
169 </template>
170 <p class="text-aqua font-weight-bold mt-3" v-if="hasScontiDisponibili(selectedProgram)">
171 <span class="component-text"> {{getScontiDisponibili(selectedProgram)}}</span>
172 </p>
173 <p v-if="!isAirportAndPricesEmpty()" class="text-dark mb-0 mt-3">
174 <i class="fas fa-plane fa-lg mr-2"></i>
175 <span class="font-weight-bold">
176 Partenza:
177
178 <template v-for="(part, pIndex) in selectedProgram.airportsAndPrices">
179 <span :key="'part-' + pIndex">
180 {{ getAirportLabel(part.airport,pIndex, selectedProgram.airportsAndPrices) }}
181 </span>
182 </template>
183 </span>
184 </p>
185
186 <p v-if="selectedProgram.marketingText != ''" class="text-aqua font-weight-bold mt-3">
187 {{ selectedProgram.marketingText }}
188 </p>
189 </div>
190 </div>
191 <div class="autofit-col">
192 <div class="autofit-section">
193 <p v-if="selectedProgram.basePrice!='' && selectedProgram.basePrice!='0'" class="text-dark text-right">A partire da</p>
194 <p v-if="selectedProgram.basePrice!='' && selectedProgram.basePrice!='0'" class="text-aqua font-weight-bold text-right">{{ selectedProgram.basePrice | money }}</p>
195 </div>
196 </div>
197 </div>
198 </div>
199 </div>
200 </div>
201 </div>
202
203 <div class="col-12">
204 <div class="card void mt-3 mt-lg-5 mb-0">
205 <div class="card-row">
206 <div class="autofit-col autofit-col-expand">
207 <section class="autofit-section text-right">
208 <template v-if="isSceltaNonDisponibile()">
209 <button @click="selectedProgram != null ? gotoStep(3) : ''" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="selectedProgram == null">
210 Avanti
211 </button>
212 </template>
213 <template v-else>
214 <button @click="selectedProgram != null ? gotoStep('next') : ''" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="selectedProgram == null">
215 Avanti
216 </button>
217 </template>
218
219 </section>
220 </div>
221 </div>
222 </div>
223 </div>
224 </div>
225 </div>
226
227 <#-- STEP 2: AREA E SCUOLA -->
228 <div class="tab-pane fade" :class="{'show active': currentStep == 2}" role="tabpanel">
229 <div class="row justify-content-between">
230 <div class="d-none d-lg-block col-12 mb-4">
231 <p class="text-dark display-5 font-weight-light">Procedi alla tua scelta</p>
232 </div>
233 <div style="display:none" class="XXX">{{isSceltaNonDisponibile()}}</div>
234 <div class="col-12 col-lg-6" v-if="selectedProgram != null && ! isSceltaNonDisponibile()">
235 <div class="dropdown">
236 <button class="btn btn-secondary dropdown-toggle" data-toggle="dropdown">
237 Scegli
238 <i class="fas fa-chevron-down ml-2 fa-lg"></i>
239 </button>
240 <div class="dropdown-menu">
241 <div class="dropdown-section">
242 <div class="input-group input-group-sm">
243 <div class="input-group-item">
244 <input type="text" v-model="searchTerm" class="form-control input-group-inset input-group-inset-after" placeholder="Cerca...">
245 <span class="input-group-inset-item input-group-inset-item-after">
246 <button class="btn btn-unstyled" type="button">
247 <i class="fal fa-search fa-lg"></i>
248 </button>
249 </span>
250 </div>
251 </div>
252 </div>
253 <ul class="list-unstyled">
254 <li v-for="(item, index) in computedResults" :key="'computedItem-'+ index">
255 <a href="javascript:void(0);" @click="selectedArea = item; selectedSchool = null;" class="dropdown-item" :class="{'active': selectedArea?.id == item?.id}">
256 {{ item?.name }}{{getAreaPriceIfSet(item)}}
257 </a>
258 </li>
259 </ul>
260 </div>
261 </div>
262
263 <div v-if="selectedArea != null" class="mt-4">
264 <p class="text-dark">
265 La tua scelta:
266 <strong>{{ selectedArea.name }}</strong>
267 </p>
268 </div>
269 </div>
270 <div class="col-12 col-lg-6" v-if="selectedProgram != null && isSceltaNonDisponibile()">
271 <div v-if="selectedArea != null" class="mt-4">
272 <p class="text-dark">
273 Per questo programma non sono previste scelte
274 </p>
275 </div>
276 </div>
277 <div class="col-12 col-lg-6" v-if="selectedArea != null && hasSchools(selectedArea)">
278 <div class="dropdown">
279 <button class="btn btn-secondary dropdown-toggle" data-toggle="dropdown">
280 Scegli
281 <i class="fas fa-chevron-down ml-2 fa-lg"></i>
282 </button>
283 <div class="dropdown-menu">
284 <ul class="list-unstyled">
285 <li v-for="(school, index) in selectedArea.children" :key="'school-' + index" v-if="school!== null">
286 <a href="javascript:void(0);" @click="selectedSchool = school" class="dropdown-item" :class="{'active': selectedSchool?.id == school?.id}">
287 {{ school?.name }} - {{ school?.price | money }}
288 </a>
289 </li>
290 </ul>
291 </div>
292 </div>
293
294 <div v-if="selectedSchool != null" class="mt-4">
295 <p class="text-dark">
296 La tua scelta:
297 <strong>{{ selectedSchool.name }}</strong>
298 </p>
299 </div>
300 </div>
301
302 <div class="col-12">
303 <div class="card void mt-3 mt-lg-5 mb-0">
304 <div class="card-row">
305 <div class="autofit-col autofit-col-expand">
306 <section class="autofit-section text-left">
307 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
308 Indietro
309 </button>
310 </section>
311 </div>
312 <div class="autofit-col autofit-col-expand">
313 <section class="autofit-section text-right">
314 <button @click="gotoStep('next')" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="selectedSchool == null && ( selectedArea==null || hasSchools(selectedArea))">
315 Avanti
316 </button>
317 </section>
318 </div>
319 </div>
320 </div>
321 </div>
322 </div>
323 </div>
324
325 <#-- SERVIZI -->
326 <div class="tab-pane fade" :class="{'show active': currentStep == 3}" role="tabpanel">
327 <div class="row">
328 <div class="d-none d-lg-block col-12 mb-4">
329 <p class="text-dark display-5 font-weight-light">Scegli altri servizi</p>
330 </div>
331
332 <div class="col-12 col-lg-7" v-if="selectedProgram != null">
333 <ul class="list-group mb-lg-0">
334 <li v-for="(service, index) in selectedProgram?.servicesAndPrices" :key="'service-' + index" class="list-group-item">
335 <div class="card-row flex-column flex-lg-row">
336 <div class="autofit-col autofit-col-expand">
337 <section class="autofit-section my-auto">
338 <span class="label label-danger" v-if="service.mandatory">
339 <span class="label-item label-item-expand">Obbligatorio</span>
340 </span>
341
342 <div class="custom-control custom-checkbox">
343 <label class="{'no-events': service.mandatory}">
344 <input class="custom-control-input" :class="{'no-events': service.mandatory}" type="checkbox" v-model="selectedServices" :value="service" :checked="service.mandatory" :disabled="service.mandatory" />
345 <span class="custom-control-label">
346 <span class="custom-control-label-text">{{ labels[service.service] }}</span>
347 </span>
348 </label>
349 </div>
350 </section>
351 </div>
352 <div class="autofit-col autofit-col-expand" style="min-width: 20%;">
353 <section class="autofit-section my-auto">
354 <p class="text-dark text-right h3 mb-0 mr-3">{{ service.price | money }}</p>
355 </section>
356 </div>
357 </div>
358 </li>
359 </ul>
360 </div>
361 <div class="col-12" v-else>
362 <p class="text-dark display-5 font-weight-light">Per continuare, seleziona un periodo dalla prima pagina.</p>
363 </div>
364
365 <div class="col-12">
366 <div class="card void mt-3 mt-lg-5 mb-0">
367 <div class="card-row">
368 <div class="autofit-col autofit-col-expand">
369 <section class="autofit-section text-left">
370 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
371 Indietro
372 </button>
373 </section>
374 </div>
375 <div class="autofit-col autofit-col-expand">
376 <section class="autofit-section text-right">
377 <button @click="gotoStep('next')" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="selectedServices.length == 0 && areServicesMandatory()">
378 Avanti
379 </button>
380 </section>
381 </div>
382 </div>
383 </div>
384 </div>
385 </div>
386 </div>
387 <#-- STEP 4: TRASPORTO -->
388 <div class="tab-pane fade" :class="{'show active': currentStep == 4}" role="tabpanel">
389 <div class="row justify-content-between">
390 <div class="d-none d-lg-block col-12 mb-4">
391 <p class="text-dark display-5 font-weight-light">Scegli il tuo trasferimento</p>
392 </div>
393
394 <div class="col-12 col-lg-6" v-if="selectedProgram != null">
395 <ul class="list-group mb-lg-0">
396 <li v-for="(partenza, index) in selectedProgram?.airportsAndPrices" :key="'airport-' + index" class="list-group-item">
397 <div class="card-row flex-column flex-lg-row">
398 <div class="autofit-col autofit-col-expand">
399 <section class="autofit-section my-auto">
400 <div class="custom-control custom-radio">
401 <label>
402 <input class="custom-control-input" type="radio" name="airportsAndPrices" v-model="selectedAirport" :value="partenza" />
403 <span class="custom-control-label">
404 <div class="d-none">{{ getCategoryName(partenza.airport) }}</div>
405 <span class="custom-control-label-text">{{ labels[partenza.airport] }}</span>
406 </span>
407 </label>
408 </div>
409 </section>
410 </div>
411 <div class="autofit-col autofit-col-expand">
412 <section class="autofit-section my-auto">
413 <p class="text-dark text-right h3 mb-0 mr-3">{{ partenza.price | money }}</p>
414 </section>
415 </div>
416 </div>
417 </li>
418 </ul>
419 </div>
420 <div class="col-12 col-lg-6" v-else>
421 <p class="text-dark display-5 font-weight-light">Per continuare, seleziona un periodo dalla prima pagina.</p>
422 </div>
423
424 <div class="col-12">
425 <div class="card void mt-3 mt-lg-5 mb-0">
426 <div class="card-row">
427 <div class="autofit-col autofit-col-expand">
428 <section class="autofit-section text-left">
429 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
430 Indietro
431 </button>
432 </section>
433 </div>
434 <div class="autofit-col autofit-col-expand">
435 <section class="autofit-section text-right">
436 <template v-if="selectedProgram?.otherDiscounts.length">
437 <button @click="selectedAirport != null ? gotoStep('next') : ''" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="_.isEmpty(selectedAirport)">
438 Avanti
439 </button>
440 </template>
441 <template v-else>
442 <button @click="selectedAirport != null ? gotoStep(6) : ''" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="_.isEmpty(selectedAirport)">
443 Avanti
444 </button>
445 </template>
446 </section>
447 </div>
448 </div>
449 </div>
450 </div>
451 </div>
452 </div>
453 <#-- STEP 5: SCONTI -->
454 <div class="tab-pane fade" :class="{'show active': currentStep == 5}" role="tabpanel">
455 <div class="row justify-content-between">
456 <div class="d-none d-lg-block col-12 mb-4">
457 <p class="text-dark display-5 font-weight-light">Inserisci gli sconti ai quali hai diritto</p>
458 </div>
459
460 <div class="col-12 col-lg-6" v-if="selectedProgram != null">
461 <ul class="list-group mb-lg-0">
462 <li v-for="(discount, index) in selectedProgram?.otherDiscounts" :key="'discount-' + index" class="list-group-item">
463 <div class="card-row flex-column flex-lg-row">
464 <div class="autofit-col autofit-col-expand">
465 <section class="autofit-section my-auto">
466 <div class="custom-control custom-checkbox">
467 <label>
468 <input class="custom-control-input" type="checkbox" v-model="selectedDiscounts" :value="discount" />
469 <span class="custom-control-label">
470 <span class="custom-control-label-text">{{ labels[discount.description] }}</span>
471 </span>
472 </label>
473 </div>
474 </section>
475 </div>
476 <div class="autofit-col autofit-col-expand" style="min-width: 20%;">
477 <section class="autofit-section my-auto">
478 <p class="text-dark text-right h3 mb-0 mr-3">{{ discount.discount | money }}</p>
479 </section>
480 </div>
481 </div>
482 </li>
483 </ul>
484 <div class="form-text mt-3">
485 <p class="text-muted small" style="color:red !important;">
486 Gli sconti selezionati saranno confermati dopo il controllo da parte dello staff
487 <i style="color:red;">(per Borsisti Itaca valido solo "Bonus porta un amico")</i>
488 </p>
489 </div>
490 </div>
491 <div class="col-12 col-lg-6" v-else>
492 <p class="text-dark display-5 font-weight-light">Per continuare, seleziona un periodo dalla prima pagina.</p>
493 </div>
494
495 <div class="col-12">
496 <div class="card void mt-3 mt-lg-5 mb-0">
497 <div class="card-row">
498 <div class="autofit-col autofit-col-expand">
499 <section class="autofit-section text-left">
500 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
501 Indietro
502 </button>
503 </section>
504 </div>
505 <div class="autofit-col autofit-col-expand">
506 <section class="autofit-section text-right">
507 <button @click="gotoStep('next')" class="btn btn-gradient py-2 px-3 px-lg-4">
508 Avanti
509 </button>
510 </section>
511 </div>
512 </div>
513 </div>
514 </div>
515 </div>
516 </div>
517
518 <#-- FORM DATI MINIMAL -->
519 <div class="tab-pane fade" :class="{'show active': currentStep == 6}" role="tabpanel">
520 <div class="row justify-content-center">
521 <div class="d-none d-lg-block col-12 mb-4">
522 <p class="text-dark display-5 font-weight-light">Inserisci i tuoi dati</p>
523 </div>
524
525 <div class="col-12 col-lg-9" v-if="selectedProgram != null">
526 <div class="sheet sheet-lg">
527 <div class="sheet-header">
528 <div class="sheet-text">
529 Inserisci i tuoi dati per poter calcolare, senza impegno, il preventivo e riceverlo automaticamente per email.
530 </div>
531 </div>
532 <div class="sheet-section">
533 <div class="form-group-autofit">
534 <div class="form-group-item">
535 <label for="userName">Nome *</label>
536 <input class="form-control" id="userName" v-model="userData.firstName" type="text"/>
537 </div>
538 <div class="form-group-item">
539 <label for="userSurname">Cognome *</label>
540 <input class="form-control" id="userSurname" v-model="userData.lastName" type="text"/>
541 </div>
542 </div>
543 <div class="form-group-autofit">
544 <div class="form-group-item">
545 <label for="billingEmail">Email *</label>
546 <input class="form-control" id="billingEmail" v-model="userMail" type="email"/>
547 </div>
548 <div class="form-group-item">
549 <label for="phone">Telefono *</label>
550 <input class="form-control" id="phone" v-model="userData.phone" type="text"/>
551 </div>
552 </div>
553
554 <div class="form-group-autofit">
555 <div class="form-group-item">
556 <div class="form-text">I campi contrassegnati con * sono obbligatori.</div>
557 </div>
558 </div>
559 <div class="form-group-autofit" v-if='sendingMessageError != ""'>
560 <div class="form-group-item">
561 <div class="form-text">
562 <p class="text-muted " style="color:red !important;">
563 Errore durante l'invio del preventivo. Correggi i dati inseriti e riprova
564 </p>
565 </div>
566 </div>
567 </div>
568 </div>
569 </div>
570 </div>
571 <div class="col-12" v-else>
572 <p class="text-dark display-5 font-weight-light">Per continuare, seleziona un periodo dalla prima pagina.</p>
573 </div>
574
575 <div class="col-12">
576 <div class="card void mt-3 mt-lg-5 mb-0">
577 <div class="card-row">
578 <div class="autofit-col autofit-col-expand">
579 <section class="autofit-section text-left">
580 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
581 Indietro
582 </button>
583 </section>
584 </div>
585 <div class="autofit-col autofit-col-expand">
586 <section class="autofit-section text-right">
587 <button @click="sendRequestMessage()" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="!isValid">
588 Scarica preventivo
589 </button>
590 </section>
591 </div>
592 </div>
593 </div>
594 </div>
595 </div>
596 </div>
597
598 <#-- RIEPILOGO -->
599 <div class="tab-pane fade" :class="{'show active': currentStep == 7}" role="tabpanel">
600
601 <div class="sheet border-0 p-0 p-lg-4">
602 <div class="row">
603 <div class="d-none d-lg-block col-12 mb-4">
604 <p class="text-dark display-5 font-weight-light">Il tuo preventivo è stato inviato</p>
605 </div>
606
607 <div class="col-12">
608 <div class="card void">
609 <div class="card-row flex-column flex-lg-row mb-4 mb-lg-0">
610 <div class="autofit-col autofit-col-expand">
611 <section class="autofit-section mb-auto">
612 <p class="h1 display-5 title-large">{{ name }}</p>
613 <p class="text-dark">
614 <#-- Dal {{ selectedProgram?.sd | moment("DD/MM/YYYY").format("DD MMMM YYYY") }} al {{ selectedProgram?.ed | moment("DD/MM/YYYY").format("DD MMMM YYYY") }} -->
615 {{ selectedProgram?.nomeTariffa}}
616 </p>
617 </section>
618 </div>
619 </div>
620 </div>
621 </div>
622 </div>
623
624 <div class="row">
625 <div class="col-12 col-lg-6 order-2 order-lg-1">
626 <div class="panel panel-secondary" v-if="programPrice != 0">
627 <div class="panel-header">
628 <div class="panel-title">
629 Informazioni di base:
630 </div>
631 </div>
632 <div class="panel-body">
633 <p class="mb-0">
634 Prezzo del viaggio: <span class="font-weight-bold">{{ programPrice | money }}</span>
635 </p>
636 <p class="mb-0" v-if="programDiscount != 0">
637 Sconto applicato: <span class="font-weight-bold">{{ programDiscount | money }}</span>
638 </p>
639 </div>
640 </div>
641
642 <div class="panel panel-secondary" v-if="getSelectedAreaAndSchoolPrice() != ''">
643 <div class="panel-header">
644 <div class="panel-title">
645 La tua scelta:
646 </div>
647 </div>
648 <div class="panel-body">
649 <p class="mb-0">
650 {{getSelectedAreaAndSchoolLabel()}} <span class="font-weight-bold">({{getSelectedAreaAndSchoolPrice() }})</span>
651 <#-- {{ selectedArea?.name }}, {{ selectedSchool?.name }} <span class="font-weight-bold">({{ selectedSchool?.price | money }})</span> -->
652 </p>
653 </div>
654 </div>
655
656 <div class="panel panel-secondary">
657 <div class="panel-header">
658 <div class="panel-title">
659 Servizi scelti:
660 </div>
661 </div>
662 <div class="panel-body">
663 <template v-if="selectedServices.length > 0">
664 <p v-for="(service, index) in selectedServices" :key="'selectedService-' + index" class="mb-0">
665 {{ labels[service.service] }} <span class="font-weight-bold" v-if="service.price > 0">({{ service.price | money }})</span>
666 </p>
667 </template>
668 <template v-else>
669 <p class="mb-0">Nessun servizio scelto</p>
670 </template>
671 </div>
672 </div>
673
674 <div class="panel panel-secondary">
675 <div class="panel-header">
676 <div class="panel-title">
677 Trasporto scelto:
678 </div>
679 </div>
680 <div class="panel-body">
681 <p class="mb-0">
682 {{ labels[selectedAirport?.airport] }} <span class="font-weight-bold" v-if="selectedAirport?.price > 0">({{ selectedAirport?.price | money }})</span>
683 </p>
684 </div>
685 </div>
686
687 <div class="panel panel-secondary">
688 <div class="panel-header">
689 <div class="panel-title">
690 Sconti scelti:
691 </div>
692 </div>
693 <div class="panel-body">
694 <template v-if="selectedDiscounts.length > 0">
695 <p v-for="(discount, index) in selectedDiscounts" :key="'selectedDiscount-' + index" class="mb-0">
696 {{ labels[discount.description] }} <span class="font-weight-bold">(-{{ discount.discount | money }})</span>
697 </p>
698 </template>
699 <template v-else>
700 <p class="mb-0">Nessuno sconto scelto</p>
701 </template>
702 </div>
703 </div>
704
705 <div class="panel panel-secondary" v-if="isDev">
706 <div class="panel-header">
707 <div class="panel-title">
708 Tipo di pagamento scelto (Acconto):
709 </div>
710 </div>
711 <div class="panel-body">
712 <div class="card void m-0 p-0">
713 <div class="card-row">
714 <div class="autofit-col autofit-col-expand my-auto">
715 <section class="autofit-section">
716 <p class="mb-0">
717 {{ getPaymentLabel(selectedPayment)}} <span class="font-weight-bold" v-if="selectedPayment=='cartaCreditoAcconto' && selectedProgram.depositAmount != 0">( Acconto: {{ selectedProgram.depositAmount | money }})</span>
718 </p>
719 </section>
720 </div>
721 </div>
722 </div>
723 </div>
724 </div>
725
726 <div class="panel panel-secondary" v-if="isDev">
727 <div class="panel-header">
728 <div class="panel-title">
729 Tipo di pagamento scelto (Saldo):
730 </div>
731 </div>
732 <div class="panel-body">
733 <div class="card void m-0 p-0">
734 <div class="card-row">
735 <div class="autofit-col autofit-col-expand my-auto">
736 <section class="autofit-section">
737 <p class="mb-0">
738 {{selectedBalance}}
739 </p>
740 </section>
741 </div>
742 </div>
743 </div>
744 </div>
745 </div>
746
747 <div class="panel panel-secondary">
748 <div class="panel-header">
749 <div class="panel-title">
750 Voucher:
751 </div>
752 </div>
753 <div class="panel-body">
754 <p v-if="voucherDiscount > 0">
755 Sconto applicato: <span class="font-weight-bold">{{ voucherDiscount | money }}</span>
756 </p>
757
758 <div class="card void m-0 p-0">
759 <div class="card-row">
760 <div class="autofit-col autofit-col-expand my-auto">
761 <section class="autofit-section">
762 <div class="form-group">
763 <div class="input-group">
764 <div class="input-group-item input-group-prepend">
765 <input type="text" v-model="voucher" class="form-control" placeholder="Inserisci il codice" :disabled="voucherValid" />
766 </div>
767 <span class="input-group-append input-group-item input-group-item-shrink">
768 <button @click="checkVoucher()" class="btn btn-secondary" :disabled="voucher == '' || voucherValid">
769 <span v-if="voucherValid">
770 Valido
771 <i class="fas fa-check ml-2"></i>
772 </span>
773 <span v-else>
774 Verifica
775 </span>
776 </button>
777 </span>
778 </div>
779 </div>
780 </section>
781 </div>
782 </div>
783 </div>
784 </div>
785 </div>
786 </div>
787 <div class="col-12 col-lg-6 order-1 order-lg-2">
788 <div class="panel panel-secondary">
789 <div class="panel-body">
790 <div class="card void my-3">
791 <div class="d-flex justify-content-center">
792 <div class="d-flex flex-column text-center mx-auto">
793 <span class="sticker sticker-xl sticker-person rounded-circle mb-4">
794 <span class="sticker-overlay">
795 <img :src="image" class="img-fluid" :alt="name">
796 </span>
797 </span>
798
799 <#--
800 <button class="btn btn-outline-dark px-3" @click="favourite ? removeFavourite() : setFavourite()" v-if="signedIn">
801 {{ favourite ? 'Salvato' : 'Salva' }}
802
803 <i class="fa-heart fa-lg ml-3" :class="favourite ? 'fas' : 'far'"></i>
804 </button>
805 -->
806 </div>
807 </div>
808 </div>
809
810 <div class="card void my-3">
811 <div class="card-row flex-column">
812 <div class="autofit-col autofit-col-expand">
813 <section v-if="voucherDiscount > 0" class="autofit-section">
814 <div class="d-flex flex-row text-dark text-center my-4 justify-content-center">
815 <p class="my-auto">Totale importo: </p>
816 <span class="text-left d-flex flex-column">
817 <span class="ml-3" style="text-decoration: line-through;">{{ totalPrice | money }}</span>
818 <span class="display-5 ml-3">{{ totalPriceWithVoucher | money }}</span>
819 </span>
820 </div>
821 <p v-if="selectedPayment == 'cartaCreditoAcconto'" class="text-dark text-center my-4">
822 Acconto da pagare:
823 <span class="display-5 ml-3">{{ selectedProgram.depositAmount | money }}</span>
824 </p>
825 </section>
826
827 <section v-else class="autofit-section">
828 <p class="text-dark text-center my-4">
829 Totale importo:
830 <span class="display-5 ml-3">{{ totalPrice | money }}</span>
831 </p>
832 <p class="text-dark text-center my-4" v-if="selectedPayment == 'cartaCreditoAcconto'">
833 Acconto da pagare:
834 <span class="display-5 ml-3">{{ selectedProgram.depositAmount | money }}</span>
835 </p>
836 </section>
837 </div>
838 <div class="autofit-col autofit-col-expand">
839 <div class="autofit-section">
840 <p style="font-size: 0.9rem; line-height: 1.5 !important; font-weight:600;">Grazie! Ti abbiamo inviato il preventivo per email, per qualsiasi informazione contattaci.</p>
841 <p style="font-size: 0.9rem; line-height: 1.5 !important;font-weight:600;">Se vuoi procedere all'acquisto, clicca sul pulsante.</p>
842 <p style="font-size: 0.9rem; line-height: 1.5 !important;">
843 Modalità di pagamento: acconto alla conferma, quattro ulteriori rate a distanza di un mese l'una dall'altra, saldo prima della data prevista per la partenza. Se sei interessato ad un eventuale finanziamento, richiedi informazioni a
844 <a href="mailto:info@zainettoverde.it" class="text-aqua"><u>info@zainettoverde.it</u></a>.
845 </p>
846 </div>
847 </div>
848 <div class="autofit-col autofit-col-expand">
849 <section class="autofit-section">
850 <button v-if="signedIn" @click="gotoStep('next')" class="btn btn-gradient btn-block py-2">
851 Iscrizione e pagamento acconto
852 </button>
853 <button v-else @click="setProgressData();redirectParent('/login')" class="btn btn-gradient btn-block py-2">
854 Accedi per procedere al pagamento acconto
855 </button>
856 </section>
857 </div>
858 </div>
859 </div>
860 </div>
861 </div>
862 </div>
863 </div>
864
865 <div class="row">
866 <div class="col-12">
867 <div class="card void mt-3 mt-lg-5 mb-0">
868 <div class="card-row">
869 <div class="autofit-col autofit-col-expand">
870 <section class="autofit-section text-left">
871 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
872 Indietro
873 </button>
874 </section>
875 </div>
876 </div>
877 </div>
878 </div>
879 </div>
880 </div>
881 </div>
882
883 <#-- FORM DATI ESTESO -->
884 <div class="tab-pane fade" id="payment_step" :class="{'show active': currentStep == 8}" role="tabpanel">
885 <div class="row justify-content-center">
886 <div class="d-none d-lg-block col-12 mb-4">
887 <p class="text-dark display-5 font-weight-light">Compila il modulo di iscrizione</p>
888 </div>
889
890 <div class="col-12 col-lg-9" v-if="selectedProgram != null && userData != null && signedIn">
891 <div class="sheet sheet-lg">
892 <div class="sheet-header">
893 <div class="sheet-text" style="color:red;">
894 <span class="text-red font-weight-bold">IMPORTANTE:</span> per poter impostare correttamente la pratica, è indispensabile compilare <u>tutti i campi</u> del presente modulo
895 </div>
896
897 </div>
898 <div class="sheet-section">
899 <#if tipoProgramma==soggiorniStudioAdulti || tipoProgramma==workExperience || tipoProgramma==corsiOnline || tipoProgramma==giftCard>
900 <p class="sheet-title">Dati di fatturazione</p>
901 <#else>
902 <p class="sheet-title">Dati del genitore o del tutore</p>
903 </#if>
904
905 <div class="form-group-autofit">
906 <div class="form-group-item">
907 <label for="tutoreFirstName">Nome</label>
908 <input @blur="checkEmpty($event)" class="form-control" id="tutoreFirstName" v-model="userData.tutore.firstName" type="text"/>
909 </div>
910 <div class="form-group-item">
911 <label for="tutoreLastName">Cognome</label>
912 <input @blur="checkEmpty($event)" class="form-control" id="tutoreLastName" v-model="userData.tutore.lastName" type="text"/>
913 </div>
914 </div>
915 <div class="form-group-autofit">
916 <div class="form-group-item">
917 <label for="tutoreAddress">Indirizzo</label>
918 <input @blur="checkEmpty($event)" class="form-control" id="tutoreAddress" v-model="userData.tutore.address" type="text"/>
919 </div>
920 </div>
921 <div class="form-group-autofit">
922 <div class="form-group-item">
923 <label for="tutoreCitta">Città</label>
924 <input @blur="checkEmpty($event)" class="form-control" id="tutoreCitta" v-model="userData.tutore.citta" type="text"/>
925 </div>
926 <div class="form-group-item">
927 <label for="tutoreCap">CAP</label>
928 <input @blur="checkEmpty($event)" class="form-control" id="tutoreCap" v-model="userData.tutore.cap" type="text"/>
929 </div>
930 <div class="form-group-item">
931 <label for="tutoreProvincia">Provincia</label>
932 <select @blur="checkSelect($event)" class="form-control" id="tutoreProvincia" v-model="userData.tutore.provincia">
933 <option v-for="province in italianProvinces" :key="province.code" :value="province.code">{{ province.name }}</option>
934 </select>
935 </div>
936 </div>
937 <div class="form-group-autofit">
938 <div class="form-group-item">
939 <label for="tutoreCellulare">Cellulare (solo numeri)</label>
940 <input @blur="checkTelefono($event)" class="form-control" id="tutoreCellulare" @keydown="restrictDigitInput" v-model="userData.tutore.cellulare" type="text"/>
941 </div>
942 <div class="form-group-item">
943 <label for="tutoreEmail">Email</label>
944 <input @blur="checkEmail($event)" class="form-control" id="tutoreEmail" v-model="userData.tutore.email" type="email"/>
945 </div>
946 </div>
947 <div class="form-group-autofit">
948 <div class="form-group-item">
949 <label for="tutoreTelefono">Telefono casa/ufficio (solo numeri)</label>
950 <input @blur="checkTelefono($event)" @keydown="restrictDigitInput" class="form-control" id="tutoreTelefono" v-model="userData.tutore.telefono" type="text"/>
951 </div>
952 <div class="form-group-item">
953 <label for="tutoreCodiceFiscale">Codice fiscale</label>
954 <input @blur="checkCodiceFiscale($event)" class="form-control" id="tutoreCodiceFiscale" v-model="userData.tutore.codiceFiscale" type="text"/>
955 </div>
956 </div>
957 <#if tipoProgramma!=soggiorniStudioAdulti && tipoProgramma!=workExperience && tipoProgramma!=corsiOnline && tipoProgramma!=giftCard>
958 <div class="form-group-autofit">
959 <div class="form-group-item">
960 <label for="tutore2Cellulare">Cellulare secondo genitore (inserisci solo numeri)</label>
961 <input @blur="checkTelefono($event)" class="form-control" id="tutore2Cellulare" @keydown="restrictDigitInput" v-model="userData.tutore2.cellulare" type="text"/>
962 </div>
963 <div class="form-group-item">
964 <label for="tutore2Email">Email secondo genitore</label>
965 <input @blur="checkEmail($event)" class="form-control" id="tutore2Email" v-model="userData.tutore2.email" type="email"/>
966 </div>
967 </div>
968 <div class="form-group-autofit">
969 <div class="form-group-item">
970 <label for="tutore2Telefono">Telefono casa/ufficio secondo genitore (inserisci solo numeri)</label>
971 <input @blur="checkTelefono($event)" class="form-control" id="tutore2Telefono" @keydown="restrictDigitInput" v-model="userData.tutore2.telefono" type="text"/>
972 </div>
973 </div>
974 </#if>
975 </div>
976 <div class="sheet-section">
977 <#if tipoProgramma!=soggiorniStudioAdulti && tipoProgramma!=workExperience && tipoProgramma!=corsiOnline && tipoProgramma!=giftCard>
978 <p class="sheet-title">Dati dello studente</p>
979 <#else>
980 <#if tipoProgramma!=giftCard>
981 <p class="sheet-title">Dati del partecipante</p>
982 <#else>
983 <p class="sheet-title">A chi vuoi regalare la gift card</p>
984 </#if>
985 </#if>
986
987 <div class="form-group-autofit">
988 <div class="form-group-item">
989 <label for="firstName">Nome</label>
990 <input @blur="checkEmpty($event)" @change="checkOrderAlreadyPresent()" class="form-control" id="firstName" v-model="userData.firstName" type="text"/>
991 </div>
992 <div class="form-group-item">
993 <label for="lastName">Cognome</label>
994 <input @blur="checkEmpty($event)" @change="checkOrderAlreadyPresent()" class="form-control" id="lastName" v-model="userData.lastName" type="text"/>
995 </div>
996 </div>
997 <#if tipoProgramma!=giftCard>
998 <div class="form-group-autofit">
999 <div class="form-group-item">
1000 <label for="birthPlace">Nato a</label>
1001 <input @blur="checkEmpty($event)" class="form-control" id="birthPlace" v-model="userData.birthPlace" type="text"/>
1002 </div>
1003 <div class="form-group-item">
1004 <label for="provincia">Provincia</label>
1005 <select @blur="checkSelect($event)" class="form-control" id="provinciaStudente" v-model="userData.provincia">
1006 <option v-for="province in italianProvinces" :key="province.code" :value="province.code">{{ province.name }}</option>
1007 </select>
1008 </div>
1009 <div class="form-group-item">
1010 <label for="birthday">Il (gg/mm/aaaa)</label>
1011 <input @blur="checkDateLength($event)" class="form-control" id="birthday" @keydown="restrictDateInput" v-model="userData.birthday" type="text"/>
1012 </div>
1013 <div class="form-group-item">
1014 <label>Sesso</label>
1015 <div>
1016 <div class="custom-control custom-radio custom-control-inline">
1017 <label>
1018 <input @change="checkRadio('gender')" class="custom-control-input" name="gender" type="radio" value="male" v-model="userData.gender"/>
1019 <span class="custom-control-label">
1020 <span class="custom-control-label-text">M</span>
1021 </span>
1022 </label>
1023 </div>
1024 <div class="custom-control custom-radio custom-control-inline">
1025 <label>
1026 <input @change="checkRadio('gender')" class="custom-control-input" name="gender" type="radio" value="female" v-model="userData.gender"/>
1027 <span class="custom-control-label">
1028 <span class="custom-control-label-text">F</span>
1029 </span>
1030 </label>
1031 </div>
1032 </div>
1033 </div>
1034 </div>
1035 <div class="form-group-autofit">
1036 <div class="form-group-item">
1037 <label for="address">Indirizzo</label>
1038 <input @blur="checkEmpty($event)" class="form-control" id="address" v-model="userData.billingStreetAddress" type="text"/>
1039 </div>
1040 </div>
1041 <div class="form-group-autofit">
1042 <div class="form-group-item">
1043 <label for="citta">Città</label>
1044 <input @blur="checkEmpty($event)" class="form-control" id="citta" v-model="userData.billingCity" type="text"/>
1045 </div>
1046 <div class="form-group-item">
1047 <label for="cap">CAP</label>
1048 <input @blur="checkEmpty($event)" class="form-control" id="cap" v-model="userData.billingPostalCode" type="text"/>
1049 </div>
1050 <div class="form-group-item">
1051 <label for="provincia">Provincia</label>
1052 <select @blur="checkSelect($event)" class="form-control" id="provincia" v-model="userData.billingRegionCode">
1053 <option v-for="province in italianProvinces" :key="province.code" :value="province.code">{{ province.name }}</option>
1054 </select>
1055 </div>
1056 </div>
1057 </#if>
1058 <div class="form-group-autofit">
1059 <div class="form-group-item">
1060 <label for="cellulare">Cellulare (inserisci solo numeri)</label>
1061 <input @blur="checkTelefono($event)" class="form-control" id="cellulare" @keydown="restrictDigitInput" v-model="userData.phone" type="text"/>
1062 </div>
1063 <div class="form-group-item">
1064 <label for="email">Email</label>
1065 <input @blur="checkEmail($event)" class="form-control" id="email" v-model="userData.studenteMail" type="email"/>
1066 </div>
1067 </div>
1068 <#if tipoProgramma==giftCard>
1069 <div class="form-group-autofit">
1070 <div class="form-group-item">
1071 <label for="giftCardMessage">Messaggio da inserire nella email di consegna della gift card</label>
1072 <input @blur="checkEmpty($event)" class="form-control" id="giftCardMessage" v-model="userData.giftCardMessage" type="text"/>
1073 </div>
1074 </div>
1075 </#if>
1076 <#if tipoProgramma!=corsiOnline && tipoProgramma!=giftCard>
1077 <div class="form-group-autofit">
1078 <div class="form-group-item">
1079 <label for="nazionalita">Nazionalità</label>
1080 <input @blur="checkEmpty($event)" class="form-control" id="nazionalita" v-model="userData.nazionalita" type="text"/>
1081 </div>
1082 <div class="form-group-item">
1083 <label for="codiceFiscale">Codice fiscale</label>
1084 <input @blur="checkCodiceFiscale($event)" class="form-control" id="codiceFiscale" v-model="userData.fiscalCode" type="text"/>
1085 </div>
1086 </div>
1087 <div class="form-group-autofit">
1088 <div class="form-group-item">
1089 <label for="tipoDocumento">Tipo documento valido per l'espatrio</label>
1090 <input @blur="checkEmpty($event)" class="form-control" id="tipoDocumento" v-model="userData.tipoDocumento" type="text"/>
1091 </div>
1092 <div class="form-group-item">
1093 <label for="numeroDocumento">Numero</label>
1094 <input @blur="checkEmpty($event)" class="form-control" id="numeroDocumento" v-model="userData.numeroDocumento" type="text"/>
1095 </div>
1096 </div>
1097 <div class="form-group-autofit">
1098 <div class="form-group-item">
1099 <label for="enteRilascioDocumento">Rilasciato da</label>
1100 <input @blur="checkEmpty($event)" class="form-control" id="enteRilascioDocumento" v-model="userData.enteRilascioDocumento" type="text"/>
1101 </div>
1102 <div class="form-group-item">
1103 <label for="paeseEmissioneDocumento">Paese di emissione</label>
1104 <input @blur="checkEmpty($event)" class="form-control" id="paeseEmissioneDocumento" v-model="userData.paeseEmissioneDocumento" type="text"/>
1105 </div>
1106 </div>
1107 <div class="form-group-autofit">
1108 <div class="form-group-item">
1109 <label for="dataRilascioDocumento">Data rilascio (gg/mm/aaaa)</label>
1110 <input @blur="checkDateLength($event)" class="form-control" id="dataRilascioDocumento" @keydown="restrictDateInput" v-model="userData.dataRilascioDocumento" type="text"/>
1111 </div>
1112 <div class="form-group-item">
1113 <label for="dataScadenzaDocumento">Data di scadenza (gg/mm/aaaa)</label>
1114 <input @blur="checkDateLength($event)" class="form-control" id="dataScadenzaDocumento" @keydown="restrictDateInput" v-model="userData.dataScadenzaDocumento" type="text"/>
1115 </div>
1116 </div>
1117 <div class="form-group-autofit">
1118 <div class="form-group-item">
1119 <label for="documentoViaggio">Documento necessario per poter effettuare il viaggio</label>
1120 <input @blur="checkEmpty($event)" class="form-control" id="documentoViaggio" v-model="userData.documentoViaggio" type="text"/>
1121 </div>
1122 </div>
1123 </#if>
1124 <#if tipoProgramma!=soggiorniStudioAdulti && tipoProgramma!=workExperience && tipoProgramma!=corsiOnline && tipoProgramma!=giftCard>
1125 <div class="form-group-autofit">
1126 <div class="form-group-item">
1127 <label>Fumatore</label>
1128 <div>
1129 <div class="custom-control custom-radio custom-control-inline">
1130 <label>
1131 <input @change="checkRadio('fumatore')" class="custom-control-input" name="fumatore" type="radio" value="true" v-model="userData.fumatore"/>
1132 <span class="custom-control-label">
1133 <span class="custom-control-label-text">Si</span>
1134 </span>
1135 </label>
1136 </div>
1137 <div class="custom-control custom-radio custom-control-inline">
1138 <label>
1139 <input @change="checkRadio('fumatore')" class="custom-control-input" name="fumatore" type="radio" value="false" v-model="userData.fumatore"/>
1140 <span class="custom-control-label">
1141 <span class="custom-control-label-text">No</span>
1142 </span>
1143 </label>
1144 </div>
1145 </div>
1146 </div>
1147 </div>
1148 <div class="form-group-autofit">
1149 <div class="form-group-item">
1150 <label>Problemi di salute dello studente da segnalare (allergie/intolleranze alimentari o disturbi di altro genere)</label>
1151 <div class="custom-control custom-radio">
1152 <label>
1153 <input @change="checkRadio('problemiSalute')" class="custom-control-input" name="problemiSalute" type="radio" value="true" v-model="userData.problemiSalute"/>
1154 <span class="custom-control-label">
1155 <span class="custom-control-label-text">Si, come da certificato medico che sarà inviato</span>
1156 </span>
1157 </label>
1158 </div>
1159 <div class="custom-control custom-radio">
1160 <label>
1161 <input @change="checkRadio('problemiSalute')" class="custom-control-input" name="problemiSalute" type="radio" value="false" v-model="userData.problemiSalute"/>
1162 <span class="custom-control-label">
1163 <span class="custom-control-label-text">No</span>
1164 </span>
1165 </label>
1166 </div>
1167 </div>
1168 </div>
1169 <div class="form-group-autofit">
1170 <div class="form-group-item">
1171 <label>Autorizzo la pubblicazione di foto e video di mio/a figlio/a, realizzati durante il programma, sulle pagine social di Zainetto Verde e sul gruppo creato per le famiglie</label>
1172 <div>
1173 <div class="custom-control custom-radio custom-control-inline">
1174 <label>
1175 <input @change="checkRadio('usofoto')" class="custom-control-input" name="usofoto" type="radio" value="true" v-model="userData.usofoto"/>
1176 <span class="custom-control-label">
1177 <span class="custom-control-label-text">Si</span>
1178 </span>
1179 </label>
1180 </div>
1181 <div class="custom-control custom-radio custom-control-inline">
1182 <label>
1183 <input @change="checkRadio('usofoto')" class="custom-control-input" name="usofoto" type="radio" value="false" v-model="userData.usofoto"/>
1184 <span class="custom-control-label">
1185 <span class="custom-control-label-text">No</span>
1186 </span>
1187 </label>
1188 </div>
1189 </div>
1190 </div>
1191 </div>
1192 </#if>
1193
1194
1195 </div>
1196 <#if tipoProgramma!=soggiorniStudioAdulti && tipoProgramma!=workExperience && tipoProgramma!=corsiOnline && tipoProgramma!=giftCard>
1197 <div class="sheet-section">
1198 <p class="sheet-title">Dati della scuola frequentata dal/dalla proprio/a figlio/a</p>
1199
1200 <div class="form-group-autofit">
1201 <div class="form-group-item">
1202 <label for="nomeScuola">Nome scuola</label>
1203 <input @blur="checkEmpty($event)" class="form-control" id="nomeScuola" v-model="userData.nomeScuola" type="text"/>
1204 </div>
1205 <div class="form-group-item">
1206 <label for="codiceMeccanografico">Codice meccanografico</label>
1207 <input @blur="checkEmpty($event)" class="form-control" id="codiceMeccanografico" v-model="userData.codiceMeccanografico" type="text"/>
1208 </div>
1209 </div>
1210 <div class="form-group-autofit">
1211 <div class="form-group-item">
1212 <label for="indirizzoScuola">Indirizzo</label>
1213 <input @blur="checkEmpty($event)" class="form-control" id="indirizzoScuola" v-model="userData.indirizzoScuola" type="text"/>
1214 </div>
1215 </div>
1216 <div class="form-group-autofit">
1217 <div class="form-group-item">
1218 <label for="cittaScuola">Città</label>
1219 <input @blur="checkEmpty($event)" class="form-control" id="cittaScuola" v-model="userData.cittaScuola" type="text"/>
1220 </div>
1221 <div class="form-group-item">
1222 <label for="provinciaScuola">Provincia</label>
1223 <select @blur="checkSelect($event)" class="form-control" id="provinciaScuola" v-model="userData.provinciaScuola">
1224 <option v-for="province in italianProvinces" :key="province.code" :value="province.code">{{ province.name }}</option>
1225 </select>
1226 </div>
1227 </div>
1228 <div class="form-group-autofit">
1229 <div class="form-group-item">
1230 <label for="telefonoScuola">Telefono (inserisci solo numeri)</label>
1231 <input @blur="checkTelefono($event)" class="form-control" id="telefonoScuola" @keydown="restrictDigitInput" v-model="userData.telefonoScuola" type="text"/>
1232 </div>
1233 <div class="form-group-item">
1234 <label for="emailScuola">Email</label>
1235 <input @blur="checkEmail($event)" class="form-control" id="emailScuola" v-model="userData.emailScuola" type="email"/>
1236 </div>
1237 </div>
1238 <div class="form-group-autofit">
1239 <div class="form-group-item">
1240 <label for="nomeCognomeDirigenteScolastico">Nome e cognome del dirigente scolastico</label>
1241 <input @blur="checkEmpty($event)" class="form-control" id="nomeCognomeDirigenteScolastico" v-model="userData.nomeCognomeDirigenteScolastico" type="text"/>
1242 </div>
1243 </div>
1244 <div class="form-group-autofit">
1245 <div class="form-group-item">
1246 <label for="nomeCognomeTutorMobilta">Nome e cognome del tutor mobilità studentesca</label>
1247 <input @blur="checkEmpty($event)" class="form-control" id="nomeCognomeTutorMobilita" v-model="userData.nomeCognomeTutorMobilita" type="text"/>
1248 </div>
1249 <div class="form-group-item">
1250 <label for="emailTutorMobilita">Email</label>
1251 <input @blur="checkEmail($event)" class="form-control" id="emailTutorMobilita" v-model="userData.emailTutorMobilita" type="email"/>
1252 </div>
1253 </div>
1254 <div class="form-group-autofit">
1255 <div class="form-group-item">
1256 <label for="nomeCognomeDocenteLinguaStraniera">Nome e cognome del docente di lingua straniera</label>
1257 <input @blur="checkEmpty($event)" class="form-control" id="nomeCognomeDocenteLinguaStraniera" v-model="userData.nomeCognomeDocenteLinguaStraniera" type="text"/>
1258 </div>
1259 <div class="form-group-item">
1260 <label for="emailDocenteLinguaStraniera">Email</label>
1261 <input @blur="checkEmail($event)" class="form-control" id="emailDocenteLinguaStraniera" v-model="userData.emailDocenteLinguaStraniera" type="email"/>
1262 </div>
1263 </div>
1264 </div>
1265 </#if>
1266 </div>
1267 </div>
1268 <div class="col-12" v-else>
1269 <p class="text-dark display-5 font-weight-light">Per continuare, seleziona un periodo dalla prima pagina.</p>
1270 </div>
1271
1272 <div class="col-12 mt-4 text-center" v-if="!moduloValid">
1273 <span style="color:red;">Non sono compilati tutti i campi richiesti, vedi campi evidenziati</span>
1274 </div>
1275 <div class="col-12 mt-4 text-center" v-if="orderAlreadyPresent">
1276 <span style="color:red;">Attenzione: questo programma risulta già ordinato dal tuo account per lo stesso partecipante.</span>
1277 </div>
1278
1279
1280
1281 <div class="col-12">
1282 <div class="card void mt-3 mt-lg-5 mb-0">
1283 <div class="card-row">
1284 <div class="autofit-col autofit-col-expand">
1285 <section class="autofit-section text-left">
1286 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
1287 Indietro
1288 </button>
1289 </section>
1290 </div>
1291 <div class="autofit-col autofit-col-expand">
1292 <section class="autofit-section text-right">
1293 <button @click="gotoStep('next')" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="!moduloValid || orderAlreadyPresent">
1294 Avanti
1295 </button>
1296 </section>
1297 </div>
1298 </div>
1299 </div>
1300 </div>
1301 </div>
1302 </div>
1303
1304 <#-- PAGAMENTO -->
1305 <div class="tab-pane fade" id="chose_payment" :class="{'show active': currentStep == 9}" v-if="signedIn" role="tabpanel">
1306 <div class="row">
1307 <div class="d-none d-lg-block col-12 mb-4">
1308 <p class="text-dark display-5 font-weight-light" style="line-height: 3rem !important;">Conferma l'acquisto scegliendo il metodo di pagamento</p>
1309 </div>
1310
1311 <#-- SET ACCONTO -->
1312 <template v-for="(type, index) in selectedProgram.paymentType">
1313 <template v-if="type == 'cartaCreditoAcconto' && selectedProgram.depositAmount != 0">
1314 <p :set="acconto=1"></p>
1315 </template>
1316 </template>
1317
1318 <template v-if="!_.isEmpty(selectedProgram) && acconto != 0">
1319 <div class="col-12 col-xl-6 br-light pr-xl-5" v-if="selectedProgram != null">
1320 <template v-for="(type, index) in selectedProgram.paymentType">
1321 <template v-if="type == 'cartaCreditoAcconto' && selectedProgram.depositAmount != 0">
1322 <p class="text-dark h4">Scegli modalità pagamento acconto</p>
1323 <p class="custom-control-label-text pl-0">Importo acconto: {{ selectedProgram.depositAmount | money }}</p>
1324 </template>
1325 </template>
1326
1327 <#-- ACCONTO -->
1328 <ul class="list-group mb-lg-0">
1329 <li v-for="(type, index) in selectedProgram.paymentType" :key="'type-' + index" class="list-group-item" v-if="type=='cartaCredito' || type == 'bonifico' || type =='cartaCreditoAcconto'">
1330 <div class="card-row flex-column flex-lg-row">
1331 <div class="autofit-col autofit-col-expand">
1332 <section class="autofit-section my-auto">
1333 <div class="custom-control custom-radio">
1334 <label>
1335 <input @change="checkRadio('paymentMethod')" class="custom-control-input" type="radio" name="paymentMethod" v-model="selectedPayment" :value="type" />
1336 <span class="custom-control-label">
1337 <span class="custom-control-label-text">
1338 {{ getPaymentLabel(type) }}
1339 </span>
1340 </span>
1341 </label>
1342 </div>
1343 </section>
1344 </div>
1345 <div class="autofit-col autofit-col-expand">
1346 <section class="autofit-section text-right my-auto">
1347 <img src="${images_folder}/bonifico.png" height="60" alt="bonifico" v-if="type == 'bonifico'">
1348 <img src="${images_folder}/visa-mastercard.png" height="60" alt="visa-mastercard" v-if="type == 'cartaCredito'">
1349 <img src="${images_folder}/visa-mastercard.png" height="60" alt="visa-mastercard" v-if="type == 'cartaCreditoAcconto'">
1350 </section>
1351 </div>
1352 </div>
1353
1354 <p v-if="type == 'bonifico'" class="card-subtitle px-1" style="display: block; margin-left: 1.5rem;">
1355 Intestato a Zainetto Verde srl - IBAN IT42L0100513700000000002639
1356 </p>
1357 </li>
1358 </ul>
1359 </div>
1360
1361 <#-- SALDO -->
1362 <div class="col-12 col-xl-6 pl-xl-5" v-if="selectedProgram != null">
1363 <p class="text-dark h4">Scegli come vorrai pagare il saldo</p>
1364 <p class="custom-control-label-text pl-0">Importo saldo: come da preventivo</p>
1365
1366 <ul class="list-group mb-lg-0">
1367 <li class="list-group-item">
1368 <div class="card-row flex-column flex-lg-row">
1369 <div class="autofit-col autofit-col-expand">
1370 <section class="autofit-section my-auto">
1371 <div class="custom-control custom-radio">
1372 <label>
1373 <input @change="checkRadio('paymentBalanceMethod')" class="custom-control-input" type="radio" name="paymentBalanceMethod" v-model="selectedBalance" value="rateale-zv" />
1374 <span class="custom-control-label">
1375 <span class="custom-control-label-text" style="display: block; margin-left: 1rem;">
1376 bonifico come da accordi con ZV, con saldo prima della partenza
1377 </span>
1378 </span>
1379 </label>
1380 </div>
1381 </section>
1382 </div>
1383 </div>
1384 </li>
1385 <li class="list-group-item">
1386 <div class="card-row flex-column flex-lg-row">
1387 <div class="autofit-col autofit-col-expand">
1388 <section class="autofit-section my-auto">
1389 <div class="custom-control custom-radio">
1390 <label>
1391 <input @change="checkRadio('paymentBalanceMethod')" class="custom-control-input" type="radio" name="paymentBalanceMethod" v-model="selectedBalance" value="rateale" />
1392 <span class="custom-control-label">
1393 <span class="custom-control-label-text" style="display: block; margin-left: 1rem;">
1394 Richiesta di finanziamento con possibilità di scegliere il numero delle rate<br/> (soggetta ad approvazione della finanziaria)
1395 </span>
1396 </span>
1397 </label>
1398 </div>
1399 </section>
1400 </div>
1401 <div class="autofit-col autofit-col-expand">
1402 <section class="autofit-section text-right my-auto">
1403 <#--
1404 <img src="${images_folder}/rateale.png" height="80" alt="rateale">
1405
1406 <img src="/documents/383793/2101965/PagoLight+Pro.svg/a66a8c4e-2422-7684-074c-3478d7862d22?t=1709719439418" height="80" width="120" alt="rateale">-->
1407
1408 <img src="/documents/383793/2101965/Findomestic.jpg/6f581557-094b-14d4-917a-65244cd94560?t=1738307202362" height="51" width="120" alt="rateale">
1409
1410 </section>
1411 </div>
1412 </div>
1413 </li>
1414
1415 </ul>
1416 </div>
1417
1418 </template>
1419
1420
1421 <#-- SALDO COMPLETO SENZA ACCONTO -->
1422 <template v-if="!_.isEmpty(selectedProgram) && acconto == 0">
1423 <div class="col-12" v-if="!_.isEmpty(selectedProgram)">
1424 <p class="text-dark h4">Scegli come vorrai pagare il saldo</p>
1425 <p class="custom-control-label-text pl-0">Importo saldo: come da preventivo</p>
1426 <ul class="list-group mb-lg-0">
1427 <template v-if="!_.isEmpty(selectedProgram) && acconto == 0">
1428 <template v-for="(type, index) in selectedProgram.paymentType">
1429 <li v-if="type == 'cartaCredito'" :key="'type-' + index" class="list-group-item">
1430 <div class="card-row flex-column flex-lg-row">
1431 <div class="autofit-col autofit-col-expand">
1432 <section class="autofit-section my-auto">
1433 <div class="custom-control custom-radio">
1434 <label>
1435 <input @change="checkRadio('paymentMethod')" class="custom-control-input" type="radio" name="paymentMethod" v-model="selectedPayment" :value="type" />
1436 <span class="custom-control-label">
1437 <span class="custom-control-label-text">
1438 {{ getPaymentLabel(type) }}
1439 </span>
1440 </span>
1441 </label>
1442 </div>
1443 </section>
1444 </div>
1445 <div class="autofit-col autofit-col-expand">
1446 <section class="autofit-section text-right my-auto">
1447 <img src="${images_folder}/visa-mastercard.png" height="60" alt="visa-mastercard" v-if="type == 'cartaCredito'">
1448 </section>
1449 </div>
1450 </div>
1451 </li>
1452 </template>
1453 </template>
1454
1455 <li class="list-group-item">
1456 <div class="card-row flex-column flex-lg-row">
1457 <div class="autofit-col autofit-col-expand">
1458 <section class="autofit-section my-auto">
1459 <div class="custom-control custom-radio">
1460 <label>
1461 <input @change="checkRadio('paymentMethod')" class="custom-control-input" type="radio" name="paymentMethod" v-model="selectedPayment" value="rateale-zv" />
1462 <span class="custom-control-label">
1463 <span class="custom-control-label-text" style="display: block; margin-left: 1rem;">
1464 bonifico come da accordi con ZV, con saldo prima della partenza
1465 </span>
1466 </span>
1467 </label>
1468 </div>
1469 </section>
1470 </div>
1471 </div>
1472 </li>
1473 <li class="list-group-item">
1474 <div class="card-row flex-column flex-lg-row">
1475 <div class="autofit-col autofit-col-expand">
1476 <section class="autofit-section my-auto">
1477 <div class="custom-control custom-radio">
1478 <label>
1479 <input @change="checkRadio('paymentMethod')" class="custom-control-input" type="radio" name="paymentMethod" v-model="selectedPayment" value="rateale" />
1480 <span class="custom-control-label">
1481 <span class="custom-control-label-text" style="display: block; margin-left: 1rem;">
1482 Richiesta di finanziamento con possibilità di scegliere il numero delle rate<br/> (soggetta ad approvazione della finanziaria)
1483 </span>
1484 </span>
1485 </label>
1486 </div>
1487 </section>
1488 </div>
1489 <div class="autofit-col autofit-col-expand">
1490 <section class="autofit-section text-right my-auto">
1491 <#--
1492 <img src="${images_folder}/rateale.png" height="80" alt="rateale">
1493
1494 <img src="/documents/383793/2101965/PagoLight+Pro.svg/a66a8c4e-2422-7684-074c-3478d7862d22?t=1709719439418" height="80" width="120" alt="rateale">-->
1495
1496 <img src="/documents/383793/2101965/Findomestic.jpg/6f581557-094b-14d4-917a-65244cd94560?t=1738307202362" height="51" width="120" alt="rateale">
1497 </section>
1498 </div>
1499 </div>
1500 </li>
1501
1502 </ul>
1503 </div>
1504 </template>
1505
1506
1507 <hr class="col-12">
1508
1509 <div class="col-12 col-lg-7">
1510
1511 <p v-if="!attachments.every(att => att.downloaded)" class="mb-3" id="info_accept" style="color:#FF0000;">È necessario scaricare gli allegati per procedere all'accettazione delle condizioni sottostanti</p>
1512
1513 <div class="autofit-section" id="field_att">
1514 <div v-for="(attachment, index) in attachments" :key="'attachment-' + index">
1515 <div class="card-row mb-4 mb-lg-2">
1516 <div class="autofit-col autofit-col-expand">
1517 <section class="autofit-section">
1518 <div class="custom-control custom-checkbox">
1519 <label>
1520 <input v-model="policyContent['condition' + sum(index, 1)]" :id="'condition_' + sum(index, 1)" @change="checkPolicy($event)" class="custom-control-input" type="checkbox" :disabled="!attachments.every(att => att.downloaded)">
1521 <span class="custom-control-label">
1522 <span class="custom-control-label-text">
1523 {{ attachment.title }}
1524 <template v-if="attachment.mandatory">*</template>
1525 </span>
1526 </span>
1527 </label>
1528 </div>
1529 </section>
1530 </div>
1531 <div class="autofit-col">
1532 <section class="autofit-section">
1533 <button v-if="attachment.downloaded" @click="downloadAttachment(attachment)" class="btn btn-link text-aqua p-0 mb-0">
1534 documento scaricato
1535 <i class="fas fa-check ml-1"></i>
1536 </button>
1537 <button v-else @click="downloadAttachment(attachment)" class="btn btn-link p-0 mb-0" style="color:red;">
1538 Scarica il documento
1539 <i class="fas fa-download ml-1"></i>
1540 </button>
1541 </section>
1542 </div>
1543 </div>
1544 <div class="card-row mb-4 mb-lg-2" v-if="index==0">
1545 <div class="autofit-col autofit-col-expand">
1546 <section class="autofit-section">
1547 <div class="custom-control custom-checkbox">
1548 <label>
1549 <input v-model="doppiocheck" class="custom-control-input" id="condition_x" @change="checkPolicy($event)" type="checkbox" :disabled="(!attachments.every(att => att.downloaded)) ">
1550 <span class="custom-control-label">
1551 <span class="custom-control-label-text">
1552 Per espressa accettazione, ex art. 1341 e 1342 c.c., delle condizioni generali richiamate
1553 <template v-if="attachment.mandatory">*</template>
1554 </span>
1555 </span>
1556 </label>
1557 </div>
1558 </section>
1559 </div>
1560 </div>
1561 </div>
1562 </div>
1563
1564 <p v-if="selectedProgram != null && orderResult != ''" class="h4">{{ orderResult }}</p>
1565 </div>
1566
1567 <template v-if="!_.isEmpty(selectedProgram) && acconto == 0">
1568 <div v-if="selectedPayment == null || !validPolicyContent" style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;" class="col-12 text-center py-3 mt-3 mt-lg-5">
1569 <p style="color:red;" class="m-0">non sono flaggati tutti i campi richiesti, vedi campi evidenziati in rosso</p>
1570 </div>
1571 </template>
1572 <template v-else>
1573 <div v-if="selectedPayment == null || selectedBalance == null || !validPolicyContent" style="border-top: 1px solid #ccc;border-bottom: 1px solid #ccc;" class="col-12 text-center py-3 mt-3 mt-lg-5">
1574 <p style="color:red;" class="m-0">non sono flaggati tutti i campi richiesti, vedi campi evidenziati in rosso</p>
1575 </div>
1576 </template>
1577
1578 <div class="col-12">
1579 <div class="card void mt-3 mt-lg-5 mb-0">
1580 <div class="card-row">
1581 <div class="autofit-col autofit-col-expand">
1582 <section class="autofit-section text-left">
1583 <button @click="gotoStep('prev')" class="btn btn-outline-dark py-2 px-3 px-lg-4">
1584 Indietro
1585 </button>
1586 </section>
1587 </div>
1588
1589
1590 <div v-if="!_.isEmpty(selectedProgram) && acconto == 0" class="autofit-col autofit-col-expand">
1591 <section class="autofit-section text-right">
1592 <#-- <button v-if="orderAlreadyPresent" class="btn btn-gradient py-2 px-3 px-lg-4" disabled>
1593 Già ordinato
1594 </button> -->
1595 <button @click="createOrderAndPaymentUrl()" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="selectedPayment == null || !validPolicyContent">
1596 Conferma l'ordine
1597 </button>
1598 </section>
1599 </div>
1600
1601 <div v-if="!_.isEmpty(selectedProgram) && acconto != 0" class="autofit-col autofit-col-expand">
1602 <section class="autofit-section text-right">
1603 <#-- <button v-if="orderAlreadyPresent" class="btn btn-gradient py-2 px-3 px-lg-4" disabled>
1604 Già ordinato
1605 </button> -->
1606 <button @click="createOrderAndPaymentUrl()" class="btn btn-gradient py-2 px-3 px-lg-4" :disabled="selectedPayment == null || selectedBalance == null || !validPolicyContent">
1607 Conferma l'ordine
1608 </button>
1609 </section>
1610 </div>
1611
1612 </div>
1613 </div>
1614 </div>
1615 </div>
1616 </div>
1617
1618 <#-- RINGRAZIAMENTO -->
1619 <div class="tab-pane fade" :class="{'show active': currentStep == 10}" v-if="signedIn" role="tabpanel">
1620 <div class="row">
1621 <div class="d-none d-lg-block col-12 mb-4">
1622 <p class="text-dark display-5 font-weight-light">Grazie per la tua prenotazione</p>
1623 </div>
1624
1625 <div class="col-12 col-lg-7">
1626 <p class="h4 text-dark font-weight-regular mt-5">
1627 Grazie per aver prenotato un programma Zainetto Verde!<br>
1628 Ti è stata inviata una mail di riepilogo e potrai trovare il riepilogo del tuo acquisto anche nella sezione dei tuoi viaggi.
1629 </p>
1630 </div>
1631
1632 <div class="col-12 col-lg-5">
1633 <div class="d-flex h-100 align-items-end justify-content-center">
1634 <button @click="redirectParent('/i-miei-viaggi')" class="btn btn-gradient btn-lg mt-4 mt-lg-0">Vai ai tuoi viaggi</button>
1635 </div>
1636 </div>
1637 </div>
1638 </div>
1639 </div>
1640 </div>
1641 </div>
1642 </div>
1643 </div>
1644 </#macro>
1645
1646 <#assign
1647 RILS = serviceLocator.findService("eu.suggesto.d40.builder.d40.service.RateItemLocalService")
1648 DLAppLocalService = serviceLocator.findService("com.liferay.document.library.kernel.service.DLAppLocalService")
1649 JALS = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")
1650 suggestoMkspAPI = serviceLocator.findService("eu.suggesto.suggestogui.service.SuggestoGuiLocalService")
1651 productServiceAPI = serviceLocator.findService("eu.suggesto.d40.builder.d40.service.ProductLocalService")
1652 saxReaderUtil = staticUtil["com.liferay.portal.kernel.xml.SAXReaderUtil"]
1653
1654 images_folder = themeDisplay.getPathThemeImages()
1655 icons_folder = images_folder + "/icons"
1656 contentId = result.getRequestStringParameter("contentId")
1657 programId = result.getRequestStringParameter("progId")
1658 defLocale = localeUtil.fromLanguageId("it_IT")
1659 image = "https://via.placeholder.com/300"
1660 dateSoggiorno = []
1661 programs = []
1662 name = "Placeholder"
1663 prezzo_base = 0
1664 sCatSistemazione = ""
1665 gruppiDiMarketing=JSONFactoryUtil.createJSONArray()
1666 />
1667
1668 <#if contentId?has_content>
1669 <#assign
1670 programs = RILS.getAvailRatesByItemId(groupId, "", groupId, contentId, '{"validDates.start":1}', 0, 100)
1671 article = JALS.getArticle(themeDisplay.getSiteGroupId(), contentId)
1672 docTitle=article.getTitle(defLocale)
1673 document = saxReaderUtil.read(article.getContent())
1674 rootElement = document.getRootElement()
1675 groupedCategories = suggestoMkspAPI.getGroupedArticleCategories(groupId, contentId, locale, defLocale)
1676
1677 xPathDate = saxReaderUtil.createXPath("dynamic-element[@name='data_inizio']")
1678 xPathImage = saxReaderUtil.createXPath("dynamic-element[@name='anteprima']")
1679 xPathName = saxReaderUtil.createXPath("dynamic-element[@name='nome_scuola']/dynamic-content[@language-id='" + themeDisplay.getLocale() + "']")
1680 xPathPrezzo = saxReaderUtil.createXPath("dynamic-element[@name='prezzo_base']/dynamic-content[@language-id='" + themeDisplay.getLocale() + "']")
1681 allegatiContent = []
1682 stringSelectorContent = "dynamic-element[@name='documentoContrattuale']"
1683 xPathSelectorContent = saxReaderUtil.createXPath(stringSelectorContent)
1684 />
1685 <#if xPathSelector.selectNodes(rootElement)??>
1686 <#assign allegatiContent = xPathSelectorContent.selectNodes(rootElement)>
1687 </#if>
1688
1689
1690 <#if (groupedCategories.length() > 0) >
1691 <#list 0..groupedCategories.length()-1 as i>
1692 <#assign
1693 gc = groupedCategories.getJSONObject(i)
1694 gcCat = gc.getJSONArray("categories")
1695 vacabularyName = gc.getString("vocabularyName")
1696 />
1697
1698 <#if vacabularyName == "Tipo di sistemazione">
1699 <#list 0..gcCat.length()-1 as y>
1700 <#assign
1701 sCat = gcCat.getJSONObject(y)
1702 sCatId = sCat.getString("categoryId")
1703 sCatSistemazione = sCat.getString("name")
1704 sCatIcon = sCat.getString("icon")
1705 />
1706 </#list>
1707 </#if>
1708 <#if vacabularyName == "Gruppi di Marketing">
1709 <#list 0..gcCat.length()-1 as y>
1710 <#assign
1711 z = gcCat.getJSONObject(y)
1712 a =gruppiDiMarketing.put(z.getString("name"))
1713 />
1714 </#list>
1715 </#if>
1716 <#if vacabularyName == "Tipo di Programma">
1717 <#list 0..gcCat.length()-1 as y>
1718 <#assign
1719 z = gcCat.getJSONObject(y)
1720 tipoProgramma=z.getString("name")
1721 requestType=tipoProgramma
1722 />
1723 </#list>
1724 </#if>
1725
1726 </#list>
1727 </#if>
1728
1729 <#if xPathDate.selectNodes(rootElement)??>
1730 <#list xPathDate.selectNodes(rootElement) as node>
1731 <#assign
1732 dataInizio = node.selectSingleNode("dynamic-content[@language-id='" + themeDisplay.getLocale() + "']").getStringValue()?replace("-", "/")
1733 dataFine = node.selectSingleNode("dynamic-element[@name='data_fine']/dynamic-content[@language-id='" + themeDisplay.getLocale() + "']").getStringValue()?replace("-", "/")
1734 dateSoggiorno += [
1735 {
1736 "dataInizio": "${dataInizio}",
1737 "dataFine": "${dataFine}"
1738 }
1739 ]
1740 />
1741 </#list>
1742 </#if>
1743
1744 <#if xPathImage.selectSingleNode(rootElement)??>
1745 <#compress>
1746 <#assign tmpImage = xPathImage.selectSingleNode(rootElement).getStringValue()?trim>
1747 </#compress>
1748
1749 <#if tmpImage?has_content>
1750 <#assign
1751 image = tmpImage
1752 jsonField = jsonFactoryUtil.createJSONObject(image)
1753 fileEntry = DLAppLocalService.getFileEntryByUuidAndGroupId(jsonField.uuid, groupId)
1754 image = "/documents/" + jsonField.groupId + "/" + fileEntry.folderId + "/" + jsonField.title + "/" + jsonField.uuid
1755 />
1756 </#if>
1757 </#if>
1758
1759 <#if xPathName.selectSingleNode(rootElement)??>
1760 <#assign name = xPathName.selectSingleNode(rootElement).getStringValue()?trim>
1761 </#if>
1762
1763 <#if xPathPrezzo.selectSingleNode(rootElement)??>
1764 <#assign prezzo_base = xPathPrezzo.selectSingleNode(rootElement).getStringValue()?trim>
1765 </#if>
1766 </#if>
1767
1768 <@printContent />
1769
1770 <script src="https://s3-eu-west-1.amazonaws.com/mkspresstage.suggesto.eu/components/securityV2.js"></script>
1771
1772 <script>
1773 document.addEventListener("DOMContentLoaded", function (){
1774 Vue.filter("money", function(value){
1775 var formatter = new Intl.NumberFormat('it-IT', {
1776 style: 'currency',
1777 currency: 'EUR',
1778 });
1779 if(typeof value!="undefined" && value!="" && value!="0") {
1780 return formatter.format(parseFloat(value));
1781 return parseFloat(value).toFixed(2).toString().replace(".", ",") + "€";
1782 }
1783 else
1784 return "";
1785 });
1786
1787 var pay = new Vue({
1788 el: "#pay",
1789 data: {
1790 /*
1791 isDev: Liferay.ThemeDisplay.getUserEmailAddress().includes("@suggesto") && !Liferay.ThemeDisplay.getUserEmailAddress().includes("studente"),
1792 */
1793 isValid:false,
1794 isDev: false,
1795 loading: true,
1796 favourite: false,
1797 contentId: "${contentId}",
1798 image: "${htmlUtil.escape(image)}",
1799 currentStep: 1,
1800 totalSteps: 0,
1801 name: "${name}",
1802 signedIn: Liferay.ThemeDisplay.isSignedIn(),
1803 groupId: Liferay.ThemeDisplay.getScopeGroupId(),
1804 userMail: Liferay.ThemeDisplay.getUserEmailAddress(),
1805 defaultLanguage: "it",
1806 defaultCountryId: "8",
1807 programPrice: 0,
1808 programDiscount: 0,
1809 acconto: 0,
1810 selectedProgram: null,
1811 selectedAirport: null,
1812 selectedAccomodation: null,
1813 selectedServices: [],
1814 selectedDiscounts: [],
1815 selectedPayment: null,
1816 selectedBalance:null,
1817 selectedArea: null,
1818 selectedSchool: null,
1819 paymentLink: "#",
1820 oid: "",
1821 voucher: "",
1822 voucherDiscount: 0,
1823 voucherValid: false,
1824 searchTerm: "",
1825 programs: ${programs.getJSONObject('data').getJSONArray('items')},
1826 attachments: [],
1827 doppiocheck:false,
1828 labels: {},
1829 policy: {
1830 <#list allegati as allegato>
1831 condition${allegato?counter}: false,
1832 </#list>
1833 },
1834 policyContent: {
1835 <#list allegatiContent as allegato>
1836 conditionContent${allegato?counter}: false,
1837 </#list>
1838 },
1839 countryList: [],
1840 regionList: [],
1841 userData: {"firstName":"","lastName":"",phone:""},
1842 orderResult: "",
1843 sameUserOrders:[],
1844 orderAlreadyPresent: false,
1845 msgCodiceFiscale:"",
1846 italianProvinces: [
1847 { code: 'AG', name: 'Agrigento' },
1848 { code: 'AL', name: 'Alessandria' },
1849 { code: 'AN', name: 'Ancona' },
1850 { code: 'AO', name: 'Aosta' },
1851 { code: 'AR', name: 'Arezzo' },
1852 { code: 'AP', name: 'Ascoli Piceno' },
1853 { code: 'AT', name: 'Asti' },
1854 { code: 'AV', name: 'Avellino' },
1855 { code: 'BA', name: 'Bari' },
1856 { code: 'BT', name: 'Barletta-Andria-Trani' },
1857 { code: 'BL', name: 'Belluno' },
1858 { code: 'BN', name: 'Benevento' },
1859 { code: 'BG', name: 'Bergamo' },
1860 { code: 'BI', name: 'Biella' },
1861 { code: 'BO', name: 'Bologna' },
1862 { code: 'BZ', name: 'Bolzano' },
1863 { code: 'BS', name: 'Brescia' },
1864 { code: 'BR', name: 'Brindisi' },
1865 { code: 'CA', name: 'Cagliari' },
1866 { code: 'CL', name: 'Caltanissetta' },
1867 { code: 'CB', name: 'Campobasso' },
1868 { code: 'CI', name: 'Carbonia-Iglesias' },
1869 { code: 'CE', name: 'Caserta' },
1870 { code: 'CT', name: 'Catania' },
1871 { code: 'CZ', name: 'Catanzaro' },
1872 { code: 'CH', name: 'Chieti' },
1873 { code: 'CO', name: 'Como' },
1874 { code: 'CS', name: 'Cosenza' },
1875 { code: 'CR', name: 'Cremona' },
1876 { code: 'KR', name: 'Crotone' },
1877 { code: 'CN', name: 'Cuneo' },
1878 { code: 'EN', name: 'Enna' },
1879 { code: 'FM', name: 'Fermo' },
1880 { code: 'FE', name: 'Ferrara' },
1881 { code: 'FI', name: 'Firenze' },
1882 { code: 'FG', name: 'Foggia' },
1883 { code: 'FC', name: 'Forlì-Cesena' },
1884 { code: 'FR', name: 'Frosinone' },
1885 { code: 'GE', name: 'Genova' },
1886 { code: 'GO', name: 'Gorizia' },
1887 { code: 'GR', name: 'Grosseto' },
1888 { code: 'IM', name: 'Imperia' },
1889 { code: 'IS', name: 'Isernia' },
1890 { code: 'SP', name: 'La Spezia' },
1891 { code: 'AQ', name: "L'Aquila" },
1892 { code: 'LT', name: 'Latina' },
1893 { code: 'LE', name: 'Lecce' },
1894 { code: 'LC', name: 'Lecco' },
1895 { code: 'LI', name: 'Livorno' },
1896 { code: 'LO', name: 'Lodi' },
1897 { code: 'LU', name: 'Lucca' },
1898 { code: 'MC', name: 'Macerata' },
1899 { code: 'MN', name: 'Mantova' },
1900 { code: 'MS', name: 'Massa-Carrara' },
1901 { code: 'MT', name: 'Matera' },
1902 { code: 'VS', name: 'Medio Campidano' },
1903 { code: 'ME', name: 'Messina' },
1904 { code: 'MI', name: 'Milano' },
1905 { code: 'MO', name: 'Modena' },
1906 { code: 'MB', name: 'Monza e della Brianza' },
1907 { code: 'NA', name: 'Napoli' },
1908 { code: 'NO', name: 'Novara' },
1909 { code: 'NU', name: 'Nuoro' },
1910 { code: 'OG', name: 'Ogliastra' },
1911 { code: 'OT', name: 'Olbia-Tempio' },
1912 { code: 'OR', name: 'Oristano' },
1913 { code: 'PD', name: 'Padova' },
1914 { code: 'PA', name: 'Palermo' },
1915 { code: 'PR', name: 'Parma' },
1916 { code: 'PV', name: 'Pavia' },
1917 { code: 'PG', name: 'Perugia' },
1918 { code: 'PU', name: 'Pesaro e Urbino' },
1919 { code: 'PE', name: 'Pescara' },
1920 { code: 'PC', name: 'Piacenza' },
1921 { code: 'PI', name: 'Pisa' },
1922 { code: 'PT', name: 'Pistoia' },
1923 { code: 'PN', name: 'Pordenone' },
1924 { code: 'PZ', name: 'Potenza' },
1925 { code: 'PO', name: 'Prato' },
1926 { code: 'RG', name: 'Ragusa' },
1927 { code: 'RA', name: 'Ravenna' },
1928 { code: 'RC', name: 'Reggio Calabria' },
1929 { code: 'RE', name: 'Reggio Emilia' },
1930 { code: 'RI', name: 'Rieti' },
1931 { code: 'RN', name: 'Rimini' },
1932 { code: 'RM', name: 'Roma' },
1933 { code: 'RO', name: 'Rovigo' },
1934 { code: 'SA', name: 'Salerno' },
1935 { code: 'SS', name: 'Sassari' },
1936 { code: 'SV', name: 'Savona' },
1937 { code: 'SI', name: 'Siena' },
1938 { code: 'SR', name: 'Siracusa' },
1939 { code: 'SO', name: 'Sondrio' },
1940 { code: 'TA', name: 'Taranto' },
1941 { code: 'TE', name: 'Teramo' },
1942 { code: 'TR', name: 'Terni' },
1943 { code: 'TO', name: 'Torino' },
1944 { code: 'TP', name: 'Trapani' },
1945 { code: 'TN', name: 'Trento' },
1946 { code: 'TV', name: 'Treviso' },
1947 { code: 'TS', name: 'Trieste' },
1948 { code: 'UD', name: 'Udine' },
1949 { code: 'VA', name: 'Varese' },
1950 { code: 'VE', name: 'Venezia' },
1951 { code: 'VB', name: 'Verbano-Cusio-Ossola' },
1952 { code: 'VC', name: 'Vercelli' },
1953 { code: 'VR', name: 'Verona' },
1954 { code: 'VV', name: 'Vibo Valentia' },
1955 { code: 'VI', name: 'Vicenza' },
1956 { code: 'VT', name: 'Viterbo' },
1957 { code: 'STE', name: 'Stato Estero' }
1958 ],
1959 sendingMessageError:"",
1960 workExperience:"${workExperience}",
1961 corsiOnline:"${corsiOnline}",
1962 soggiorniStudioAdulti:"${soggiorniStudioAdulti}",
1963 giftCard:"${giftCard}",
1964 requestType:"${requestType}",
1965 <#if tipoProgramma==soggiorniStudioAdulti || tipoProgramma==workExperience || tipoProgramma==corsiOnline || tipoProgramma==giftCard>
1966 tipoProgramma:"${tipoProgramma}"
1967 <#else>
1968 tipoProgramma:"programma"
1969 </#if>
1970 },
1971 created(){
1972 var that = this;
1973
1974 moment.locale(navigator.language.split("-")[0]);
1975
1976 window.addEventListener("keyup", function(e){
1977 if(e.which == 27){
1978 that.closeParentModal("#pay-modal");
1979 }
1980 });
1981
1982 /* this.setAttachments(); */
1983 this.setAttachmentsContent();
1984
1985 },
1986 watch: {
1987 userData: {
1988 handler: 'validateForm',
1989 deep: true,
1990 immediate: true
1991 },
1992 userMail: {
1993 handler: 'validateForm',
1994 immediate: true
1995 }
1996 },
1997 mounted(){
1998 //window.addEventListener("message", this.getExternalData.bind(this));
1999
2000 if(this.signedIn){
2001 this.userId = Liferay.ThemeDisplay.getUserId();
2002 this.checkFavourite();
2003 this.getUserData();
2004
2005 this.totalSteps = 9;
2006 }else{
2007 this.userData.firstName = "";
2008 this.userData.lastName = "";
2009 this.userData.phone = "";
2010 this.totalSteps = 8;
2011 }
2012
2013 console.log("total steps: " + this.totalSteps);
2014
2015 this.getVocabularyLabels();
2016 this.getProgressData();
2017 this.getOrderStatus();
2018
2019 if(this.currentStep == 1){
2020 console.log("${programId}");
2021
2022 if("${programId}" != "")
2023 {
2024 this.selectProgramId();
2025 }
2026 }
2027
2028 this.loading = false;
2029 },
2030 computed: {
2031 computedResults: function(){
2032 var that = this,
2033 zones = [];
2034
2035 this.selectedProgram.statoZonaScuolaTree.forEach(function(zone){
2036 // if(that.selectedProgram.title.toLowerCase().includes("classic") || that.selectedProgram.title.toLowerCase().includes("combo")){
2037 if(that.isClassic()){
2038 if(zone.name?.toLowerCase().includes(that.searchTerm)){
2039 zones.push(zone);
2040 }
2041 }else{
2042 if(_.has(zone, "children") && zone.name?.toLowerCase().includes(that.searchTerm)){
2043 zones.push(zone);
2044 }
2045 }
2046 });
2047
2048 return zones.sort((a, b) => a.name.localeCompare(b.name));
2049 },
2050 totalPrice: function(){
2051 return this.selectedServices.reduce(function(total, item){
2052 return Number(total) + Number(item.price);
2053 }, Number(this.programPrice) - Number(this.programDiscount) + Number(this.selectedArea?.price || 0) + Number(this.selectedSchool?.price || 0) + Number(this.selectedAirport?.price || 0) + Number(this.selectedAccomodation?.price || 0) - Number(this.totalDiscounts || 0));
2054 },
2055 totalPriceWithVoucher: function(){
2056 return this.selectedServices.reduce(function(total, item){
2057 return Number(total) + Number(item.price);
2058 }, Number(this.programPrice) - Number(this.programDiscount) + Number(this.selectedArea?.price || 0) + Number(this.selectedSchool?.price || 0) + Number(this.selectedAirport?.price || 0) + Number(this.selectedAccomodation?.price || 0) - Number(this.totalDiscounts || 0) - Number(this.voucherDiscount || 0));
2059 },
2060 totalDiscounts: function(){
2061 return this.selectedDiscounts.reduce(function(total, item){
2062 return Number(total) + Number(item.discount);
2063 }, 0)
2064 },
2065 validPolicy: function(){
2066 var valid = false;
2067
2068 <#if ! allegati?has_content>
2069 valid=true;
2070 </#if>
2071
2072 if(
2073 <#list allegati as allegato>
2074 <#assign stringSelector = "dynamic-element[@name='mandatory']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
2075 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
2076 <#if xPathSelector.selectSingleNode(allegato)??>
2077 <#assign mandatory = xPathSelector.selectSingleNode(allegato).getData()>
2078 </#if>
2079
2080 <#if mandatory == "true">
2081 <#if !allegato?is_first> && </#if>
2082 this.policy.condition${allegato?counter}
2083 </#if>
2084 </#list>
2085 ){
2086 valid = true;
2087 }
2088
2089 return valid;
2090 },
2091 validPolicyContent: function(){
2092 var valid = false;
2093
2094 if(
2095 <#assign listEmpty = "true">
2096 <#list allegatiContent as allegato>
2097 <#assign stringSelector = "dynamic-element[@name='mandatory']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
2098 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
2099 <#assign mandatoryContent="false">
2100 <#if xPathSelector.selectSingleNode(allegato)??>
2101 <#assign mandatoryContent = xPathSelector.selectSingleNode(allegato).getData()>
2102 </#if>
2103 <#if mandatoryContent == "true">
2104 <#if !allegato?is_first> && </#if>
2105 <#assign listEmpty="false">
2106 this.policyContent.condition${allegato?counter}
2107 </#if>
2108 </#list>
2109 <#if listEmpty == "true">
2110 false
2111 </#if>
2112 ){
2113 valid = true;
2114 }
2115 console.log("doppiocheck:"+ this.doppiocheck);
2116 if(this.doppiocheck==false)
2117 return false;
2118 return valid;
2119 },
2120 minimumValid: function(){
2121 var valid = true;
2122 console.log("minimumValid");
2123 if(this.userData != null){
2124 /*
2125 if(!this.userData.hasOwnProperty("firstName") || typeof this.userData["firstName"] !== "string" || this.userData["firstName"].length == 0){
2126 valid = false;
2127 }
2128 if(!this.userData.hasOwnProperty("lastName") || typeof this.userData["lastName"] !== "string" || this.userData["lastName"].length == 0){
2129 valid = false;
2130 }
2131 if(!this.userData.hasOwnProperty("phone") || ((/^[0-9]+$/.test(this.userData["phone"]))==false ) || this.userData["phone"].length == 0){
2132 valid = false;
2133 }
2134 */
2135 if(this.userData.firstName==""){
2136 valid = false;
2137 }
2138 if(this.userData.lastName==""){
2139 valid = false;
2140 }
2141 if(!this.userData.hasOwnProperty("phone") || ((/^[0-9]+$/.test(this.userData["phone"]))==false ) || this.userData["phone"].length == 0){
2142 valid = false;
2143 }
2144
2145 if(this.userMail == ""){
2146 valid = false;
2147 }
2148 }else{
2149 valid = false;
2150 }
2151
2152 return valid;
2153 },
2154 moduloValid: function(){
2155 var valid = true;
2156 console.log("moduloValid");
2157 if(this.userData != null){
2158 // Tutore/i
2159 if(_.has(this.userData, "tutore.firstName")){
2160 if(typeof this.userData.tutore.firstName !== "string" || this.userData.tutore.firstName.length == 0){
2161 valid = false
2162 }
2163 }else{
2164 valid = false;
2165 }
2166
2167 if(_.has(this.userData, "tutore.lastName")){
2168 if(typeof this.userData.tutore.lastName !== "string" || this.userData.tutore.lastName.length == 0){
2169 valid = false
2170 }
2171 }else{
2172 valid = false;
2173 }
2174
2175 if(_.has(this.userData, "tutore.address")){
2176 if(typeof this.userData.tutore.address !== "string" || this.userData.tutore.address.length == 0){
2177 valid = false
2178 }
2179 }else{
2180 valid = false;
2181 }
2182
2183 if(_.has(this.userData, "tutore.citta")){
2184 if(typeof this.userData.tutore.citta !== "string" || this.userData.tutore.citta.length == 0){
2185 valid = false
2186 }
2187 }else{
2188 valid = false;
2189 }
2190
2191 if(_.has(this.userData, "tutore.cap")){
2192 if(typeof this.userData.tutore.cap !== "string" || this.userData.tutore.cap.length == 0){
2193 valid = false
2194 }
2195 }else{
2196 valid = false;
2197 }
2198
2199 if(_.has(this.userData, "tutore.provincia")){
2200 if(typeof this.userData.tutore.provincia !== "string" || this.userData.tutore.provincia.length == 0){
2201 valid = false
2202 }
2203 }else{
2204 valid = false;
2205 }
2206
2207 if(_.has(this.userData, "tutore.cellulare")){
2208 if((typeof this.userData.tutore.cellulare !== "string" || this.userData.tutore.cellulare.length == 0) ||
2209 ((/^[0-9]+$/.test(this.userData.tutore.cellulare))==false )
2210 ){
2211 console.log("tutiore.celluare false");
2212 valid = false
2213 }
2214 }else{
2215 valid = false;
2216 }
2217
2218 if(_.has(this.userData, "tutore.email")){
2219 if(typeof this.userData.tutore.email !== "string" || this.userData.tutore.email.length == 0){
2220 valid = false;
2221 }else{
2222 if(this.userData.tutore.email.indexOf("@")>0) {
2223 // if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(this.userData.tutore.email)) {
2224 } else {
2225 valid = false;
2226 }
2227 }
2228 }else{
2229 valid = false;
2230 }
2231
2232 if(_.has(this.userData, "tutore.telefono")){
2233 if( (typeof this.userData.tutore.telefono !== "string" || this.userData.tutore.telefono.length == 0) ||
2234 ((/^[0-9]+$/.test(this.userData.tutore.telefono))==false )
2235 ){
2236 console.log("tutore.telefono false");
2237 valid = false
2238 }
2239 }else{
2240 valid = false;
2241 }
2242
2243 if(_.has(this.userData, "tutore.codiceFiscale")){
2244 if(typeof this.userData.tutore.codiceFiscale !== "string" || this.userData.tutore.codiceFiscale.length == 0 ||
2245 this.controllaCF(this.userData.tutore.codiceFiscale).length!=0){
2246 valid = false
2247 }
2248 else
2249 this.userData.tutore.codiceFiscale=this.userData.tutore.codiceFiscale.toUpperCase();
2250 }else{
2251 valid = false;
2252 }
2253
2254 if(this.tipoProgramma!=this.soggiorniStudioAdulti && this.tipoProgramma!=this.workExperience && this.tipoProgramma!=this.corsiOnline && this.tipoProgramma!=this.giftCard) {
2255 //Tutore2
2256 if(_.has(this.userData, "tutore2.cellulare")){
2257 if((typeof this.userData.tutore2.cellulare !== "string" || this.userData.tutore2.cellulare.length == 0) || ((/^[0-9]+$/.test(this.userData.tutore2.cellulare))==false )){
2258 console.log("tutore2.cellulare false");
2259 valid = false
2260 }
2261 }else{
2262 valid = false;
2263 }
2264 if(_.has(this.userData, "tutore2.email")){
2265 if(typeof this.userData.tutore2.email !== "string" || this.userData.tutore2.email.length == 0){
2266 valid = false
2267 }else{
2268 if(this.userData.tutore2.email.indexOf("@")>0) {
2269 } else {
2270 valid = false;
2271 }
2272 }
2273 }else{
2274 valid = false;
2275 }
2276
2277 if(_.has(this.userData, "tutore2.telefono")){
2278 if((typeof this.userData.tutore2.telefono !== "string" || this.userData.tutore2.telefono.length == 0) ||
2279 ((/^[0-9]+$/.test(this.userData.tutore2.telefono))==false )
2280 ){
2281 console.log("userData.tutore2.telefono false");
2282 valid = false
2283 }
2284 }else{
2285 valid = false;
2286 }
2287 }
2288 //Studente
2289 if(_.has(this.userData, "firstName")){
2290 if(typeof this.userData.firstName !== "string" || this.userData.firstName.length == 0){
2291 valid = false
2292 }
2293 }else{
2294 valid = false;
2295 }
2296
2297 if(_.has(this.userData, "lastName")){
2298 if(typeof this.userData.lastName !== "string" || this.userData.lastName.length == 0){
2299 valid = false
2300 }
2301 }else{
2302 valid = false;
2303 }
2304 if(_.has(this.userData, "phone")){
2305 if(typeof this.userData.phone !== "string" || this.userData.phone.length == 0 ||
2306 ((/^[0-9]+$/.test(this.userData.phone))==false )
2307 ){
2308 valid = false
2309 }
2310 }else{
2311 valid = false;
2312 }
2313 if(this.tipoProgramma==this.giftCard) {
2314
2315 if(_.has(this.userData, "studenteMail")){
2316 if(typeof this.userData.studenteMail !== "string" || this.userData.studenteMail.length == 0){
2317 valid = false
2318 }
2319 }else{
2320 valid = false;
2321 }
2322 }
2323 if(this.tipoProgramma!=this.giftCard) {
2324 if(_.has(this.userData, "birthPlace")){
2325 if(typeof this.userData.birthPlace !== "string" || this.userData.birthPlace.length == 0){
2326 valid = false
2327 }
2328 }else{
2329 valid = false;
2330 }
2331
2332 if(_.has(this.userData, "provincia")){
2333 if(typeof this.userData.provincia !== "string" || this.userData.provincia.length == 0){
2334 valid = false
2335 }
2336 }else{
2337 valid = false;
2338 }
2339
2340 if(_.has(this.userData, "birthday")){
2341 if(typeof this.userData.birthday !== "string" || this.userData.birthday.length != 10 || ! this.dateFormat(this.userData.birthday) ){
2342 valid = false
2343 }
2344 }else{
2345 valid = false;
2346 }
2347
2348 if(_.has(this.userData, "gender")){
2349 if(typeof this.userData.gender !== "string" || this.userData.gender.length == 0){
2350 valid = false
2351 }
2352 }else{
2353 valid = false;
2354 }
2355 if(_.has(this.userData, "billingStreetAddress")){
2356 if(typeof this.userData.billingStreetAddress !== "string" || this.userData.billingStreetAddress.length == 0){
2357 valid = false
2358 }
2359 }else{
2360 valid = false;
2361 }
2362 if(_.has(this.userData, "billingCity")){
2363 if(typeof this.userData.billingCity !== "string" || this.userData.billingCity.length == 0){
2364 valid = false
2365 }
2366 }else{
2367 valid = false;
2368 }
2369 if(_.has(this.userData, "billingPostalCode")){
2370 if(typeof this.userData.billingPostalCode !== "string" || this.userData.billingPostalCode.length == 0){
2371 valid = false
2372 }
2373 }else{
2374 valid = false;
2375 }
2376
2377 if(_.has(this.userData, "billingRegionCode")){
2378 if(typeof this.userData.billingRegionCode !== "string" || this.userData.billingRegionCode.length == 0){
2379 valid = false
2380 }
2381 }else{
2382 valid = false;
2383 }
2384 if(typeof this.userMail !== "string" || this.userMail.length == 0){
2385 valid = false
2386 }
2387 }
2388 if( this.tipoProgramma!=this.corsiOnline && this.tipoProgramma!=this.giftCard) {
2389 if(_.has(this.userData, "nazionalita")){
2390 if(typeof this.userData.nazionalita !== "string" || this.userData.nazionalita.length == 0){
2391 valid = false
2392 }
2393 }else{
2394 valid = false;
2395 }
2396 if(_.has(this.userData, "fiscalCode")){
2397 if(typeof this.userData.fiscalCode !== "string" || this.userData.fiscalCode.length == 0 || this.controllaCF(this.userData.fiscalCode).length!=0 ){
2398 valid = false
2399 }
2400 else
2401 this.userData.fiscalCode=this.userData.fiscalCode.toUpperCase();
2402
2403 }else{
2404 valid = false;
2405 }
2406
2407 if(_.has(this.userData, "tipoDocumento")){
2408 if(typeof this.userData.tipoDocumento !== "string" || this.userData.tipoDocumento.length == 0){
2409 valid = false
2410 }
2411 }else{
2412 valid = false;
2413 }
2414 if(_.has(this.userData, "numeroDocumento")){
2415 if(typeof this.userData.numeroDocumento !== "string" || this.userData.numeroDocumento.length == 0){
2416 valid = false
2417 }
2418 }else{
2419 valid = false;
2420 }
2421
2422 if(_.has(this.userData, "enteRilascioDocumento")){
2423 if(typeof this.userData.enteRilascioDocumento !== "string" || this.userData.enteRilascioDocumento.length == 0){
2424 valid = false
2425 }
2426 }else{
2427 valid = false;
2428 }
2429 if(_.has(this.userData, "dataRilascioDocumento")){
2430 if(typeof this.userData.dataRilascioDocumento !== "string" || this.userData.dataRilascioDocumento.length != 10 || ! this.dateFormat(this.userData.dataRilascioDocumento)){
2431 valid = false
2432 }
2433 }else{
2434 valid = false;
2435 }
2436
2437 if(_.has(this.userData, "dataScadenzaDocumento")){
2438 if(typeof this.userData.dataScadenzaDocumento !== "string" || this.userData.dataScadenzaDocumento.length != 10 || ! this.dateFormat(this.userData.dataScadenzaDocumento)) {
2439 valid = false
2440 }
2441 }else{
2442 valid = false;
2443 }
2444
2445 if(_.has(this.userData, "documentoViaggio")){
2446 if(typeof this.userData.documentoViaggio !== "string" || this.userData.documentoViaggio.length == 0){
2447 valid = false
2448 }
2449 }else{
2450 valid = false;
2451 }
2452 }
2453 if(this.tipoProgramma!=this.soggiorniStudioAdulti && this.tipoProgramma!=this.workExperience && this.tipoProgramma!=this.corsiOnline && this.tipoProgramma!=this.giftCard) {
2454 if(_.has(this.userData, "fumatore")){
2455 if(typeof this.userData.fumatore !== "string" || this.userData.fumatore.length == 0){
2456 valid = false
2457 }
2458 }else{
2459 valid = false;
2460 }
2461
2462 if(_.has(this.userData, "problemiSalute")){
2463 if(typeof this.userData.problemiSalute !== "string" || this.userData.problemiSalute.length == 0){
2464 valid = false
2465 }
2466 }else{
2467 valid = false;
2468 }
2469 if(_.has(this.userData, "usofoto")){
2470 if(typeof this.userData.usofoto !== "string" || this.userData.usofoto.length == 0){
2471 valid = false
2472 }
2473 }else{
2474 valid = false;
2475 }
2476
2477
2478 //Scuola
2479 if(_.has(this.userData, "nomeScuola")){
2480 if(typeof this.userData.nomeScuola !== "string" || this.userData.nomeScuola.length == 0){
2481 valid = false
2482 }
2483 }else{
2484 valid = false;
2485 }
2486
2487 if(_.has(this.userData, "codiceMeccanografico")){
2488 if(typeof this.userData.codiceMeccanografico !== "string" || this.userData.codiceMeccanografico.length == 0){
2489 valid = false
2490 }
2491 }else{
2492 valid = false;
2493 }
2494
2495 if(_.has(this.userData, "indirizzoScuola")){
2496 if(typeof this.userData.indirizzoScuola !== "string" || this.userData.indirizzoScuola.length == 0){
2497 valid = false
2498 }
2499 }else{
2500 valid = false;
2501 }
2502
2503 if(_.has(this.userData, "cittaScuola")){
2504 if(typeof this.userData.cittaScuola !== "string" || this.userData.cittaScuola.length == 0){
2505 valid = false
2506 }
2507 }else{
2508 valid = false;
2509 }
2510
2511 if(_.has(this.userData, "provinciaScuola")){
2512 if(typeof this.userData.provinciaScuola !== "string" || this.userData.provinciaScuola.length == 0){
2513 valid = false
2514 }
2515 }else{
2516 valid = false;
2517 }
2518
2519 if(_.has(this.userData, "telefonoScuola")){
2520 if((typeof this.userData.telefonoScuola !== "string" || this.userData.telefonoScuola.length == 0) ||
2521 ((/^[0-9]+$/.test(this.userData.telefonoScuola))==false)
2522 ){
2523 console.log("userData.telefonoScuola false");
2524 valid = false
2525 }
2526 }else{
2527 valid = false;
2528 }
2529
2530 if(_.has(this.userData, "emailScuola")){
2531 if(typeof this.userData.emailScuola !== "string" || this.userData.emailScuola.length == 0){
2532 valid = false
2533 }else{
2534 if(this.userData.emailScuola.indexOf("@")>0) {
2535 } else {
2536 valid = false;
2537 }
2538 }
2539 }else{
2540 valid = false;
2541 }
2542
2543 if(_.has(this.userData, "nomeCognomeDirigenteScolastico")){
2544 if(typeof this.userData.nomeCognomeDirigenteScolastico !== "string" || this.userData.nomeCognomeDirigenteScolastico.length == 0){
2545 valid = false
2546 }
2547 }else{
2548 valid = false;
2549 }
2550
2551 if(_.has(this.userData, "nomeCognomeTutorMobilita")){
2552 if(typeof this.userData.nomeCognomeTutorMobilita !== "string" || this.userData.nomeCognomeTutorMobilita.length == 0){
2553 valid = false
2554 }
2555 }else{
2556 valid = false;
2557 }
2558
2559 if(_.has(this.userData, "emailTutorMobilita")){
2560 if(typeof this.userData.emailTutorMobilita !== "string" || this.userData.emailTutorMobilita.length == 0){
2561 valid = false
2562 }else{
2563 if(this.userData.emailTutorMobilita.indexOf("@")>0) {
2564 } else {
2565 valid = false;
2566 }
2567 }
2568 }else{
2569 valid = false;
2570 }
2571
2572 if(_.has(this.userData, "nomeCognomeDocenteLinguaStraniera")){
2573 if(typeof this.userData.nomeCognomeDocenteLinguaStraniera !== "string" || this.userData.nomeCognomeDocenteLinguaStraniera.length == 0){
2574 valid = false
2575 }
2576 }else{
2577 valid = false;
2578 }
2579
2580 if(_.has(this.userData, "emailDocenteLinguaStraniera")){
2581 if(typeof this.userData.emailDocenteLinguaStraniera !== "string" || this.userData.emailDocenteLinguaStraniera.length == 0){
2582 valid = false
2583 }else{
2584 if(this.userData.emailDocenteLinguaStraniera.indexOf("@")>0) {
2585 } else {
2586 valid = false;
2587 }
2588 }
2589 }else{
2590 valid = false;
2591 }
2592 }
2593 }else{
2594 valid = false;
2595 }
2596
2597 return valid;
2598 }
2599 },
2600 methods: {
2601 validateForm() {
2602 console.log("validateForm");
2603 this.isValid =
2604 this.userData.firstName.trim() !== '' &&
2605 this.userData.lastName.trim() !== '' &&
2606 this.userData.phone.trim() !== '' &&
2607 ((/^[0-9]+$/.test(this.userData.phone))==true ) &&
2608 this.userMail.includes('@');
2609 },
2610 isMinimumValid: function(){
2611 var valid = true;
2612 console.log("isMinimumValid");
2613
2614 if(this.userData != null){
2615 if(!this.userData.hasOwnProperty("firstName") || typeof this.userData["firstName"] !== "string" || this.userData["firstName"].length == 0){
2616 valid = false;
2617 }
2618 if(!this.userData.hasOwnProperty("lastName") || typeof this.userData["lastName"] !== "string" || this.userData["lastName"].length == 0){
2619 valid = false;
2620 }
2621 if(!this.userData.hasOwnProperty("phone") || ((/^[0-9]+$/.test(this.userData["phone"]))==false ) || this.userData["phone"].length == 0){
2622 valid = false;
2623 }
2624 if(this.userMail == ""){
2625 valid = false;
2626 }
2627 }else{
2628 valid = false;
2629 }
2630
2631 return valid;
2632 },
2633 isStatoZonaScuolaTreeEmpty: function() {
2634 if(typeof this.selectedProgram !="undefined" && typeof this.selectedProgram.statoZonaScuolaTree !="undefined" && this.selectedProgram.statoZonaScuolaTree.length >0)
2635 return false;
2636 else
2637 return true;
2638 },
2639 isAltriServiziEmpty: function() {
2640 if(typeof this.selectedProgram !="undefined" && typeof this.selectedProgram.servicesAndPrices !="undefined" && this.selectedProgram.servicesAndPrices.length >0)
2641 return false;
2642 else
2643 return true;
2644 },
2645 isAirportAndPricesEmpty: function() {
2646 if(typeof this.selectedProgram !="undefined" && typeof this.selectedProgram.airportsAndPrices !="undefined" && this.selectedProgram.airportsAndPrices.length >0)
2647 return false;
2648 else
2649 return true;
2650 },
2651 isOtherDiscountsEmpty: function() {
2652 if(typeof this.selectedProgram !="undefined" && typeof this.selectedProgram.otherDiscounts !="undefined" && this.selectedProgram.otherDiscounts.length >0)
2653 return false;
2654 else
2655 return true;
2656 },
2657 areServicesMandatory: function(){
2658 return this.selectedProgram?.servicesAndPrices.some(function(serv){
2659 return serv.mandatory;
2660 });
2661 },
2662 isClassic: function() {
2663 var classic=true;
2664 this.selectedProgram.statoZonaScuolaTree.forEach(function(zone){
2665 if(_.has(zone, "children") && zone.children.length>0){
2666 classic=false;
2667 }
2668 });
2669 console.log(this.selectedProgram.statoZonaScuolaTree);
2670 console.log("isClassic:"+classic)
2671
2672 return classic;
2673 },
2674 isSceltaNonDisponibile: function() {
2675 var sceltaNonDisponibile=false;
2676 if(this.selectedProgram.statoZonaScuolaTree.length==1) {
2677 console.log("sceltaNonDisponibile:XXX"+this.selectedProgram.statoZonaScuolaTree[0].id);
2678 sceltaNonDisponibile=this.selectedProgram.statoZonaScuolaTree[0].id=="2052813";
2679 }
2680 return sceltaNonDisponibile;
2681 },
2682 getCategoryName: function(catId){
2683 var that = this;
2684 return this.labels[catId];
2685 },
2686 getVocabularyLabels: function(){
2687 var that = this;
2688
2689 return axios.get("${d40.serviceEndpoint}{'fn':'getProgrammiLabels'}").then(function(res){
2690 that.labels = res.data.result;
2691 console.log(that.labels);
2692 }).catch(function(err){
2693 console.error("err: ", err);
2694 });
2695 },
2696 hasSchools: function(area) {
2697 if(typeof area.children !== "undefined" && area.children.length > 0){
2698 return true;
2699 }
2700
2701 return false;
2702 },
2703 getScontiDisponibili: function(prg) {
2704 var sret="";
2705 var that = this;
2706 prg.otherDiscounts.forEach(function(item){
2707 if(sret.length > 0){
2708 sret += ", ";
2709 }
2710
2711 sret += that.labels[item.description];
2712 });
2713 /*
2714 return sret;
2715 */
2716 return "Procedi e scopri gli sconti e le borse di studio";
2717 },
2718 hasScontiDisponibili: function(prg) {
2719 var that = this;
2720 if(prg.otherDiscounts.length>0)
2721 return true;
2722 else
2723 return false;
2724 },
2725 getAreaPriceIfSet: function(item){
2726 if(typeof item.price != "undefined" && item.price != ""){
2727 var formatter = new Intl.NumberFormat('it-IT', {
2728 style: 'currency',
2729 currency: 'EUR',
2730 });
2731
2732 return " -" + formatter.format(parseFloat(item.price));
2733 }
2734 },
2735 getSelectedAreaAndSchoolLabel: function() {
2736 if(this.selectedArea != null) {
2737 var szret = this.selectedArea.name;
2738
2739 if(this.selectedSchool !=null && typeof this.selectedSchool !== "undefined" && typeof this.selectedSchool.name !== "undefined"){
2740 szret += ", " + this.selectedSchool.name;
2741 }
2742
2743 return szret;
2744 }
2745
2746 return "";
2747 },
2748 getSelectedAreaAndSchoolPrice: function() {
2749 var pret = 0;
2750
2751 if(this.selectedArea != null) {
2752 if(this.selectedArea.price != null && this.selectedArea.price !== "undefined" && this.selectedArea.price != ""){
2753 pret = parseFloat(this.selectedArea.price);
2754 }
2755
2756 if(this.selectedSchool != null && typeof this.selectedSchool !== "undefined" && this.selectedSchool.price != ""){
2757 pret += parseFloat(this.selectedSchool.price);
2758 }
2759
2760 var formatter = new Intl.NumberFormat('it-IT', {
2761 style: 'currency',
2762 currency: 'EUR',
2763 });
2764
2765 return formatter.format(pret);
2766 }
2767
2768 return "";
2769 },
2770 sum: function(num1, num2){
2771 return Number(num1 + num2);
2772 },
2773 openParentModal: function(id){
2774
2775 window.parent.$(id).modal("show");
2776
2777
2778 },
2779 sendRequestMessage: function() {
2780 var that=this;
2781 that.sendingMessageError="";
2782 var portletNamespace="<@portlet.namespace />";
2783 var requestInfo= {
2784 email: this.userMail,
2785 message: "",
2786 firstName:this.userData.firstName,
2787 lastName:this.userData.lastName,
2788 parameters: {
2789 firstName: this.userData.firstName,
2790 lastName: this.userData.lastName,
2791 phone: this.userData.phone,
2792 program:"",
2793 age: "",
2794 destination: "",
2795 startFrom: "",
2796 duration: "",
2797 fromPageName: "${docTitle?js_string}",
2798 fromPageUrl: window.top.location.href,
2799 },
2800 token: "",
2801 component:"PreventivoAnnoEstero",
2802 emailParams: {}
2803 };
2804 this.buildMessage(requestInfo);
2805 console.log("sendRequestMessage:",requestInfo);
2806
2807 function cb(status,msg) {
2808 console.log("cb:",status);
2809 if(status==true) {
2810 var nomeEvento=that.requestType;
2811 nomeEvento=nomeEvento.replaceAll(" ","_");
2812 nomeEvento=nomeEvento.replaceAll("'","_");
2813 console.log("sending event invio_preventivo", that.requestType);
2814 that.addEvent('invio_preventivo',nomeEvento);
2815 that.gotoStep('next');
2816 }
2817 else {
2818 that.sendingMessageError="error durante l'invio del preventivo";
2819 }
2820 }
2821 oneInstanceSendRequest(requestInfo,cb);
2822// that.gotoStep('next');
2823 },
2824 buildMessage: function (requestInfo) {
2825 var that=this;
2826 var msg="";
2827 var rowNomeTariffa="";
2828 var rowArea="";
2829 var rowSchool="";
2830 var rowAirport="";
2831 var rowProgramPrice="";
2832 var rowTotalPrice="";
2833 var rowProgramDiscount="";
2834 var rowsServices=[];
2835 var rowsDiscounts=[];
2836 var szRowsServices="";
2837 var szRowsDiscounts="";
2838 if(typeof this.selectedProgram=="undefined") {
2839 return;
2840 }
2841 console.log("build message");
2842 var docTitle="${docTitle?js_string}";
2843 var selectedProgram=this.selectedProgram;
2844 var selectedArea=this.selectedArea;
2845 var selectedSchool=this.selectedSchool;
2846 var selectedAirport = this.selectedAirport;
2847 var selectedProgram = this.selectedProgram;
2848 var selectedPayment = this.selectedPayment;
2849 var selectedServices = this.selectedServices;
2850 var selectedDiscounts = this.selectedDiscounts;
2851 var programPrice = this.programPrice;// TODO
2852 var programDiscount = this.programDiscount;
2853 var totalPrice = this.totalPrice;
2854 var userData = this.userData;
2855 if(typeof selectedProgram.nomeTariffa!="undefined") {
2856 rowNomeTariffa="<h2>"+ docTitle+" - "+ selectedProgram.nomeTariffa +"</h2>";
2857 }
2858 if(typeof selectedArea!="undefined" && selectedArea !=null && typeof selectedArea.name!="undefined" && typeof selectedArea.price!="undefined" )
2859 rowArea="<tr>"+ "<td>"+selectedArea.name+"</td>" + "<td style='text-align: right;'>"+this.formatPrice(selectedArea.price+"")+"</td>"+"</tr>";
2860
2861 if(selectedSchool!=null)
2862 if(typeof selectedSchool!="undefined" && typeof selectedSchool.name!="undefined" && typeof selectedSchool.price!="undefined" )
2863 rowSchool="<tr>"+ "<td>"+selectedSchool.name+"</td>" + "<td>"+this.formatPrice(selectedSchool.price+"")+"</td>"+"</tr>";
2864 if(selectedAirport!=null)
2865 if(typeof selectedAirport!="undefined" && typeof selectedAirport.airport!="undefined" && typeof selectedAirport.price!="undefined" && selectedAirport.price!="" && selectedAirport.price!=0 )
2866 rowAirport="<tr>"+ "<td>"+selectedAirport.label+"</td>" + "<td>"+this.formatPrice(selectedAirport.price)+"</td>"+"</tr>";
2867 if(typeof programPrice!="undefined" && programPrice!=0)
2868 rowProgramPrice="<tr>"+ "<td>Prezzo base</td>" + "<td style='text-align: right;'>"+this.formatPrice(programPrice)+"</td>"+"</tr>";
2869
2870
2871 if(typeof programDiscount!="undefined" && programDiscount!="" && programDiscount!=0 )
2872 rowProgramDiscount="<tr>"+ "<td>Sconto applicato</td>" + "<td style='text-align: right;'>"+this.formatPrice(programDiscount)+"</td>"+"</tr>";
2873 if(typeof selectedServices!="undefined") {
2874 for(var i=0;i<selectedServices.length;i++) {
2875 var row="<tr>"+ "<td'>"+this.labels[selectedServices[i].service]+"</td>" + "<td style='text-align: right;'>"+this.formatServicePrice(selectedServices[i])+"</td>"+"</tr>";
2876 rowsServices.push(row);
2877 }
2878 }
2879 if(typeof selectedDiscounts!="undefined") {
2880 for(var i=0;i<selectedDiscounts.length;i++) {
2881 console.log(selectedDiscounts[i].label);
2882 var row="<tr>"+ "<td>"+this.labels[selectedDiscounts[i].description]+"</td>" + "<td style='text-align: right;'>"+this.formatPrice(selectedDiscounts[i].discount)+"</td>"+"</tr>";
2883 rowsDiscounts.push(row);
2884 }
2885 }
2886 if(typeof totalPrice!="undefined")
2887 rowTotalPrice="<tr>"+ "<td style='text-align: right;'><strong>TOTALE PREVENTIVO</strong></td>" + "<td style='text-align: right;'><strong>"+this.formatPrice(totalPrice)+"</strong></td>"+"</tr>";
2888
2889 for(var i=0;i<rowsServices.length;i++) {
2890 szRowsServices=szRowsServices+rowsServices[i];
2891 }
2892 for(var i=0;i<rowsDiscounts.length;i++) {
2893 szRowsDiscounts=szRowsDiscounts+rowsDiscounts[i];
2894 }
2895 msg = "<h1>Preventivo</h1>";
2896 msg = msg+ rowNomeTariffa;
2897 msg=msg+ '<table>' +
2898 '<thead>' +
2899 '<tr>' +
2900 '<th scope="col">Servizio</th>' +
2901 '<th scope="col" style="text-align: right;">Prezzo</th>' +
2902 '</tr>' +
2903 '</thead>' +
2904 '<tbody>' +
2905 rowProgramPrice+
2906 rowProgramDiscount+
2907 rowArea+
2908 rowSchool+
2909 rowAirport +
2910 szRowsServices +
2911 szRowsDiscounts +
2912 '<tr style=""><td> </td><td> </td></tr>'+
2913 rowTotalPrice +
2914 '</tbody>' +
2915 '</table>';
2916
2917 requestInfo.message="<p>"+requestInfo.message+"</p>"+"<p>"+msg+"</p>";
2918 },
2919 formatPrice: function(price) {
2920 if(typeof price!="undefined" && price!="") {
2921 var formatter = new Intl.NumberFormat('it-IT', {
2922 style: 'currency',
2923 currency: 'EUR',
2924 });
2925 return formatter.format(parseFloat(price)) ;
2926 }
2927
2928 },
2929 formatServicePrice: function(service) {
2930 console.log("::"+service.price+"::");
2931 if(typeof service !="undefined" && typeof service.price!="undefined" && service.price.trim()!="" && service.price.trim()!="undefined") {
2932 var formatter = new Intl.NumberFormat('it-IT', {
2933 style: 'currency',
2934 currency: 'EUR',
2935 });
2936 return formatter.format(parseFloat(service.price.trim())) ;
2937 }
2938 else
2939 return "";
2940
2941
2942 },
2943 closeParentModal: function(id){
2944 window.parent.$(id).modal("hide");
2945 },
2946 redirectParent: function(url){
2947 window.top.location = "${themeDisplay.getPortalURL()}" + url;
2948 },
2949 gotoStep: function(step){
2950 forward=true;
2951
2952 this.checkOrderAlreadyPresent();
2953 if(typeof(step) == "number"){
2954 this.currentStep = step;
2955 if(this.currentStep > step)
2956 forward=false;
2957 }else{
2958 if(step == "next"){
2959 this.currentStep++;
2960 }
2961 if(step == "prev"){
2962 this.currentStep--;
2963 forward=false;
2964 }
2965 }
2966 console.log("currentStep:"+this.currentStep);
2967 if(this.currentStep==2 && this.isSceltaNonDisponibile()) {
2968 console.log("autoset");
2969 this.selectedArea=this.computedResults[0];
2970 this.selectedSchool=null;
2971 };
2972 if(2 == this.currentStep){
2973 if(this.isStatoZonaScuolaTreeEmpty())
2974 {
2975 this.selectedArea=this.computedResults[0];
2976 this.selectedSchool=null;
2977 if(forward)
2978 this.gotoStep("next");
2979 else
2980 this.gotoStep(1);
2981 }
2982 };
2983 if(3 == this.currentStep){
2984 if(this.isAltriServiziEmpty())
2985 {
2986 if(forward)
2987 this.gotoStep("next");
2988 else
2989 this.gotoStep("prev");
2990 }
2991 }
2992 if(4 == this.currentStep){
2993 if(this.isAirportAndPricesEmpty())
2994 {
2995 if(forward)
2996 this.gotoStep("next");
2997 else
2998 this.gotoStep("prev");
2999 }
3000 }
3001 if(5 == this.currentStep){
3002 if(this.isOtherDiscountsEmpty())
3003 {
3004 if(forward)
3005 this.gotoStep("next");
3006 else
3007 this.gotoStep("prev");
3008
3009 }
3010 }
3011 if(6 == this.currentStep){
3012 oneInstanceRefreshCaptcha();
3013 }
3014 if(8 == this.currentStep){
3015 var that=this;
3016 setTimeout(function(){
3017 $('#payment_step input').each(function(){
3018 if("" == $(this).val())
3019 {
3020 $(this).css({"border":"2px solid red"});
3021 }
3022 });
3023 }, 500);
3024
3025 setTimeout(function(){
3026 $('#payment_step input[type=radio]').each(function(){
3027 $(this).parent().find('.custom-control-label-text').css({
3028 "color":"red"
3029 });
3030 });
3031 }, 500);
3032 setTimeout(function(){
3033 $('#payment_step select').each(function(){
3034 $(this).css({"border":"2px solid red"});
3035 });
3036 }, 500);
3037
3038 setTimeout(function(){
3039 $('#codiceFiscale').each(function(){
3040 var ret=that.controllaCF($(this).val());
3041 if(ret!="") {
3042 $(this).css({"border":"2px solid red"});
3043 }
3044 });
3045 }, 500);
3046 setTimeout(function(){
3047 $('#tutoreCodiceFiscale').each(function(){
3048 var ret=that.controllaCF($(this).val());
3049 if(ret!="") {
3050 $(this).css({"border":"2px solid red"});
3051 }
3052 });
3053 }, 500);
3054
3055
3056 }
3057
3058 if(9 == this.currentStep){
3059 setTimeout(function(){
3060 $('#chose_payment input[type=radio]').each(function(){
3061 $(this).parent().find('.custom-control-label-text').css({
3062 "color":"red"
3063 });
3064 });
3065 }, 500);
3066 }
3067
3068 $('html, body').animate({
3069 scrollTop: $("#pay").offset().top
3070 }, 0);
3071 },
3072 getCity: function(fullString){
3073 return fullString.substr(0, fullString.indexOf('(') === -1 ? fullString.length : fullString.indexOf('('));
3074 },
3075 isBefore: function(data){
3076 return moment(data).isBefore(new Date());
3077 },
3078 isAfter: function(data){
3079 return moment(data).isAfter(new Date());
3080 },
3081 getExternalData: function(message){
3082 var strExtData = JSON.parse(JSON.stringify(message.data));
3083
3084 if(strExtData.source == null){
3085 var extData = JSON.parse(strExtData);
3086 console.log("dati ricevuti da iframe: ", extData);
3087
3088 if(extData.key == "programIndex"){
3089 if(this.selectedProgram != extData){
3090 this.selectProgram(extData.data);
3091 console.log("selected program: ", extData.data);
3092 }else{
3093 console.log("program already selected");
3094 }
3095 }
3096 }
3097 },
3098 setAttachments: function(){
3099 <#list allegati as allegato>
3100 <#assign stringSelector = "dynamic-element[@name='testo']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
3101 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
3102 <#if xPathSelector.selectSingleNode(allegato)??>
3103 <#assign text = xPathSelector.selectSingleNode(allegato).getData()>
3104 </#if>
3105
3106 <#assign stringSelector = "dynamic-element[@name='mandatory']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
3107 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
3108 <#if xPathSelector.selectSingleNode(allegato)??>
3109 <#assign mandatory = xPathSelector.selectSingleNode(allegato).getData()>
3110 </#if>
3111
3112 <#assign stringSelector = "dynamic-element[@name='documento']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
3113 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
3114 <#if xPathSelector.selectSingleNode(allegato)??>
3115 <#assign document = jsonFactoryUtil.createJSONObject(xPathSelector.selectSingleNode(allegato).getData())>
3116 </#if>
3117
3118 var newAttachment = {
3119 title: "${text}",
3120 mandatory: ${mandatory},
3121 fileName: "${document.getString('title')}",
3122 file: "${'/documents/' + document.getString('groupId') + '/0/' + document.getString('title') + '/' + document.getString('uuid')}",
3123 downloaded: false
3124 }
3125
3126 this.attachments.push(newAttachment);
3127 </#list>
3128 },
3129 setAttachmentsContent: function(){
3130 <#list allegatiContent as allegato>
3131 <#assign stringSelector = "dynamic-element[@name='titoloDocContrattuale']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
3132 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
3133 <#assign text="">
3134 <#if xPathSelector.selectSingleNode(allegato)??>
3135 <#assign text = xPathSelector.selectSingleNode(allegato).getData()>
3136 </#if>
3137 <#if text?has_content>
3138 <#assign stringSelector = "dynamic-element[@name='mandatory']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
3139 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
3140 <#if xPathSelector.selectSingleNode(allegato)??>
3141 <#assign mandatory = xPathSelector.selectSingleNode(allegato).getData()>
3142 </#if>
3143 <#if ! mandatory?has_content>
3144 <#assign mandatory ="false">
3145 </#if>
3146
3147 <#assign stringSelector = "dynamic-element[@name='docContrattuale']/dynamic-content[@language-id = '" + themeDisplay.getLocale() + "']">
3148 <#assign xPathSelector = saxReaderUtil.createXPath(stringSelector)>
3149 <#if xPathSelector.selectSingleNode(allegato)??>
3150 <#assign document = jsonFactoryUtil.createJSONObject(xPathSelector.selectSingleNode(allegato).getData())>
3151 </#if>
3152
3153 var newAttachment = {
3154 title: "${text}",
3155 mandatory: ${mandatory},
3156 fileName: "${document.getString('title')}",
3157 file: "${'/documents/' + document.getString('groupId') + '/0/' + document.getString('title') + '/' + document.getString('uuid')}",
3158 downloaded: false
3159 }
3160
3161 this.attachments.push(newAttachment);
3162 </#if>
3163 </#list>
3164 },
3165 downloadAttachment: function(attachment){
3166 var that = this,
3167 config = {
3168 headers: {
3169 "Access-Control-Allow-Origin": "*"
3170 },
3171 responseType: "blob"
3172 };
3173
3174 axios.get(attachment.file, config).then(function(res){
3175 var downLink = window.URL.createObjectURL(new Blob([res.data]));
3176 var link = document.createElement("a");
3177 link.href = downLink;
3178 link.setAttribute("download", attachment.fileName);
3179 document.body.appendChild(link);
3180 link.click();
3181 that.attachments.find(att => att.fileName == attachment.fileName).downloaded = true;
3182 }).catch(function(err){
3183 console.error("Error getting attachment: ", err);
3184 });
3185
3186 setTimeout(function(){
3187 $('#field_att input[type=checkbox]').not(':disabled').each(function(){
3188 $(this).parent().find('.custom-control-label-text').attr('style','color:red');
3189 });
3190 }, 5000);
3191
3192
3193 if($('.fa-download').length == 0){
3194 $('#info_accept').attr('style','color:#000 !important');
3195 }
3196 },
3197 getUserData: function(){
3198 var that = this;
3199
3200 Liferay.Service("/destinazione.d40user/get-user-data", {
3201 groupId: this.groupId,
3202 userId: this.userId
3203 }, function(res){
3204 console.log("Get user data: ", res);
3205
3206 if(res.success){
3207 that.userData = {
3208 tutore: {},
3209 tutore2: {},
3210 ...res.data
3211 };
3212
3213 that.getCountryList();
3214 }else{
3215 console.log("Error getting user data");
3216 }
3217 }).catch(function(err){
3218 console.error("Error getting userData: ", err);
3219 });
3220 },
3221 getOrderStatus: function(){
3222 var that = this;
3223 console.log("getOrderStatus");
3224 if(this.signedIn){
3225 const mongoQry = {
3226 "userId": this.userId,
3227 "orderParameters.selectedProgram.itemId": this.contentId
3228 }
3229
3230 var curId = this.contentId;
3231 Liferay.Service(
3232 '/destinazione.order/get-orders-by-user-id',
3233 {
3234 groupId: this.groupId,
3235 userId: this.userId
3236 },
3237 function (res) {
3238 if (res.success) {
3239
3240 if (res.data?.length > 0) {
3241 that.sameUserOrders=res.data;
3242 }
3243 }
3244 else
3245 console.log("UNSUCCESS");
3246 }
3247 );
3248
3249 }
3250 },
3251 checkOrderAlreadyPresent: function(){
3252 this.orderAlreadyPresent=false;
3253 console.log("checkOrderAlreadyPresent");
3254 if (this.sameUserOrders?.length > 0) {
3255 let i = 0;
3256 while (i < this.sameUserOrders?.length) {
3257 if (this.sameUserOrders[i].itemId == this.contentId)
3258 {
3259 if (this.sameUserOrders[i].orderStatus == "INSERTED" || this.sameUserOrders[i].orderStatus == "PAYED")
3260 {
3261 if(this.sameUserOrders[i].orderParameters.userData.lastName==this.userData.lastName &&
3262 this.sameUserOrders[i].orderParameters.userData.firstName==this.userData.firstName &&
3263 this.sameUserOrders[i].orderParameters.selectedProgram.nomeTariffa ==this.selectedProgram.nomeTariffa) {
3264 console.log("order already present is true");
3265 this.orderAlreadyPresent=true;
3266 return true;
3267 }
3268 }
3269 }
3270 i++;
3271 }
3272 }
3273 return false;
3274 },
3275
3276 getCountryList: function(){
3277 var that = this;
3278
3279 Liferay.Service("/destinazione.d40user/get-country-list", {
3280 language: this.defaultLanguage
3281 }, function(res){
3282 console.log("Get country list: ", res);
3283
3284 if(res.success){
3285 that.countryList = res.data;
3286
3287 if(that.userData.billingCountryId == "0" || that.userData.billingCountryId == null){
3288 that.userData.billingCountryId = that.countryList.find(country => country.ID === that.defaultCountryId).ID;
3289 }else{
3290 that.userData.billingCountryId = that.defaultCountryId;
3291 }
3292
3293 that.getRegionList();
3294 }
3295 }).catch(function(err){
3296 console.error("Error getting countryList: ", err);
3297 });
3298 },
3299 getRegionList: function(){
3300 var that = this,
3301 idToUse = this.defaultCountryId;
3302
3303 if(this.userData.hasOwnProperty("billingCountryId") && typeof this.userData["billingCountryId"] === "string" && this.userData["billingCountryId"].length){
3304 idToUse = this.userData.billingCountryId;
3305 }
3306
3307 Liferay.Service("/destinazione.d40user/get-region-list", {
3308 countryId: idToUse
3309 }, function(res){
3310 console.log("Get region list: ", res);
3311
3312 if(res.success){
3313 that.regionList = res.data;
3314
3315 if(that.userData.billingRegionId == "0" || that.userData.billingRegionId == null){
3316
3317 }
3318 }
3319 }).catch(function(err){
3320 console.error("Error getting regionList: ", err);
3321 });
3322 },
3323 selectProgram: function(program){
3324 var that = this;
3325
3326 console.log("select program with id " + program._id.$oid);
3327
3328 this.resetSelections();
3329
3330 this.selectedProgram = program;
3331 if(typeof this.selectedProgram.basePrice!=="undefined" && this.selectedProgram.basePrice != ""){
3332 this.programPrice = this.selectedProgram?.basePrice;
3333 }else{
3334 this.programPrice = 0;
3335 }
3336
3337 this.programDiscount = 0;
3338 console.log("programPrice: " + this.programPrice);
3339
3340 this.selectedProgram?.purchaseBeforeDiscount.forEach(function(sconto){
3341 if(that.isDiscountValid(sconto) && sconto.discount != 0){
3342 that.programDiscount = Number(sconto.discount);
3343 }
3344 });
3345
3346 this.setMandatoryServices();
3347
3348 setTimeout(function(){
3349 console.log("updating");
3350 that.$forceUpdate();
3351 }, 250);
3352 },
3353 selectProgramId: function(){
3354 var that = this;
3355
3356 var programId = "${programId}";
3357
3358 console.log("select program with id " + programId);
3359
3360 this.selectedAccomodation = null;
3361 this.selectedAirport = null;
3362 this.selectedArea = null;
3363 this.selectedPayment = null;
3364 this.selectedBalance = null;
3365 this.selectedProgram = null;
3366 this.selectedSchool = null;
3367 this.selectedServices = [];
3368 this.paymentLink = "#";
3369 this.voucher = "";
3370 this.programPrice = 0;
3371 this.currentStep = 1;
3372
3373 for(program in this.programs){
3374 var single_program = this.programs[program]
3375 if (single_program._id.$oid == programId)
3376 {
3377 this.selectedProgram = single_program;
3378 }
3379 }
3380
3381 if(typeof this.selectedProgram.basePrice!=="undefined" && this.selectedProgram.basePrice != ""){
3382 this.programPrice = this.selectedProgram?.basePrice;
3383 }else{
3384 this.programPrice = 0;
3385 }
3386
3387 this.programDiscount = 0;
3388 console.log("programPrice: " + this.programPrice);
3389
3390 this.selectedProgram?.purchaseBeforeDiscount.forEach(function(sconto){
3391 var today = new Date(),
3392 valid = false;
3393
3394 if(moment(today).isSameOrAfter(sconto.date) && moment(today).isSameOrBefore(sconto.dateEnd)){
3395 valid = true;
3396 }
3397
3398 if(valid && sconto.discount != 0){
3399 that.programDiscount = Number(sconto.discount);
3400 }
3401 });
3402
3403 this.selectedServices = [];
3404
3405 this.selectedProgram?.servicesAndPrices?.forEach(function(service){
3406 if(service.mandatory){
3407 that.selectedServices.push(service);
3408 }
3409 });
3410
3411 /*setTimeout(function(){
3412 console.log("updating");
3413 that.$forceUpdate();
3414 }, 250);*/
3415 },
3416 getPaymentLabel: function(type){
3417 if(type == "bonifico")
3418 return "Acconto con bonifico bancario";
3419 if(type == "cartaCredito")
3420 return "Carta di credito";
3421 if(type == "cartaCreditoAcconto")
3422 return "Acconto con carta di credito";
3423 },
3424 resetSelections: function(){
3425 this.selectedAccomodation = null;
3426 this.selectedAirport = null;
3427 this.selectedArea = null;
3428 this.selectedPayment = null;
3429 this.selectedBalance = null;
3430 this.selectedProgram = null;
3431 this.selectedSchool = null;
3432 this.selectedServices = [];
3433 this.paymentLink = "#";
3434 this.voucher = "";
3435 this.programPrice = 0;
3436 this.currentStep = 1;
3437 },
3438 select: function(name, obj){
3439 if(name == "airport"){
3440 this.selectedAirport = obj;
3441 }
3442 if(name == "accomodation"){
3443 this.selectedAccomodation = obj;
3444 }
3445 },
3446 checkFavourite: function(){
3447 var that = this;
3448
3449 Liferay.Service('/destinazione.favorite/get-wish-list', {
3450 groupId: Liferay.ThemeDisplay.getScopeGroupId(),
3451 sessionId: String(Liferay.ThemeDisplay.getSessionId()),
3452 userId: String(Liferay.ThemeDisplay.getUserId()),
3453 }, function(res){
3454 console.log("getWishList response: ", res);
3455 if(res.success){
3456 res.data.forEach(function(obj){
3457 if(obj.itemId == that.contentId){
3458 that.favourite = true;
3459 that.oid = obj._id.$oid;
3460 }
3461 });
3462 }
3463 }).catch(function(err){
3464 console.error("Error getting wishlist: ", err);
3465 });
3466 },
3467 checkVoucher: function(){
3468 var that = this,
3469 endPoint = "/servicefeed?p_p_id=Configurable&p_p_lifecycle=2&p_p_resource_id=json&_Configurable_jsonParams=",
3470 params = {
3471 "fn": "validate",
3472 "email": this.userMail,
3473 "articleId": this.contentId,
3474 "nomeTariffa": this.selectedProgram.nomeTariffa,
3475 "vc": this.voucher,
3476 "packageId" : this.selectedProgram._id.$oid,
3477 "amount": this.totalPrice * 100
3478 }
3479
3480 axios.get(endPoint + JSON.stringify(params)).then(function(res){
3481 if(res.data.result.data.valid && res.data.result.data.order.total_discount_amount){
3482 console.log("Voucher res: ", res.data.result.data);
3483 that.voucherValid = true;
3484 that.voucherDiscount = res.data.result.data.order.total_discount_amount / 100;
3485 }else{
3486 console.error("Something went wrong with voucher: ", res.data);
3487 alert("Voucher non valido");
3488 }
3489 }).catch(function(err){
3490 console.error("Error validating voucher: ", err);
3491 });
3492 },
3493 createOrderAndPaymentUrl: function(){
3494 var that = this;
3495
3496 var orderPrice = 0,
3497 orderParams = {
3498 selectedProgram: this.selectedProgram,
3499 selectedArea: this.selectedArea,
3500 selectedSchool: this.selectedSchool,
3501 selectedAccomodation: this.selectedAccomodation,
3502 selectedAirport: this.selectedAirport,
3503 selectedServices: this.selectedServices,
3504 selectedPayment: this.selectedPayment,
3505 selectedBalance: this.selectedBalance,
3506 selectedDiscounts: this.selectedDiscounts,
3507 programPrice: this.programPrice,
3508 programDiscount: this.programDiscount,
3509 voucherDiscount: this.voucherDiscount,
3510 userData: this.userData,
3511 policyContent:this.policyContent,
3512 doppioCheck:this.doppiocheck
3513 };
3514 /*
3515 if(this.selectedPayment?.amount == 0 || this.selectedPayment?.amount === undefined){
3516 orderPrice = this.totalPrice;
3517 }else{
3518 orderPrice = this.selectedPayment?.amount;
3519 }
3520 */
3521 /* this.selectedPayment == "cartaCreditoAcconto" ? orderPrice = this.selectedProgram.depositAmount : orderPrice = this.totalPrice; */
3522 orderPrice = this.selectedProgram.depositAmount;
3523 console.log(this.selectedPayment);
3524 console.log(this.selectedBalance);
3525 console.log(orderPrice);
3526 console.log(this.totalPrice);
3527 console.log(JSON.stringify(orderParams));
3528
3529 if(this.selectedPayment != "bonifico" && this.selectedPayment != "rateale" && this.selectedPayment != "rateale-zv"){
3530 var iframe = window.open("/", "_blank");
3531 }
3532
3533 Liferay.Service("/destinazione.order/add-order-and-get-payment-url", {
3534 groupId: this.groupId,
3535 userId: this.userId,
3536 itemGroupId: Liferay.ThemeDisplay.getScopeGroupId(),
3537 itemId: this.contentId,
3538 totalPrice: this.totalPriceWithVoucher,
3539 params: JSON.stringify(orderParams),
3540 currency: "EUR",
3541 priceToPay: orderPrice,
3542 userEmail: this.userMail,
3543 languageId: "ITA",
3544 description: this.name,
3545 session_id: String(Liferay.ThemeDisplay.getSessionId()),
3546 cart_id: "12",
3547 baseUrl: Liferay.ThemeDisplay.getURLHome().split("/web/")[0],
3548 locsz: ""
3549 }, function(res){
3550 console.log("add order and get payment url res: ", res);
3551
3552 // Sezione redemption voucher
3553 if(that.voucherValid){
3554 var endPoint = "/servicefeed?p_p_id=Configurable&p_p_lifecycle=2&p_p_resource_id=json&_Configurable_jsonParams=",
3555 params = {
3556 "fn": "redemption",
3557 "email": that.userMail,
3558 "articleId": that.contentId,
3559 "nomeTariffa": that.selectedProgram.nomeTariffa,
3560 "vc": that.voucher,
3561 "packageId" : that.selectedProgram._id.$oid,
3562 "amount": that.totalPrice * 100
3563 }
3564
3565 axios.get(endPoint + JSON.stringify(params)).then(function(vRes){
3566 console.log("vRes is ", vRes);
3567 }).catch(function(vErr){
3568 console.error("Error during voucher redemption: ", vErr);
3569 });
3570 }
3571
3572 if(res.success){
3573 that.addEvent("stampa_preventivo","");
3574
3575 if(that.selectedPayment != "bonifico" && that.selectedPayment != "rateale" && that.selectedPayment != "rateale-zv"){
3576 console.log("redirecting...");
3577 iframe.location = res.data.url;
3578 that.closeParentModal("#pay-modal");
3579 }else{
3580 that.currentStep++;
3581 console.log("ordine immesso con bonifico, non ridireziono l'utente");
3582 }
3583
3584 that.orderResult = "Ordine inserito con successo";
3585 }else{
3586 that.orderResult = "C'è stato un problema con l'inserimento dell'ordine. Contattare Zainetto Verde se il problema persiste.";
3587 }
3588 }).catch(function(err){
3589 console.error("Error: ", err);
3590
3591 that.orderResult = "C'è stato un problema con l'inserimento dell'ordine. Contattare Zainetto Verde se il problema persiste.";
3592 });
3593 },
3594 setFavourite: function(){
3595 var that = this;
3596
3597 if(this.signedIn){
3598 Liferay.Service('/destinazione.favorite/add-to-wish-list', {
3599 groupId: Liferay.ThemeDisplay.getScopeGroupId(),
3600 sessionId: String(Liferay.ThemeDisplay.getSessionId()),
3601 userId: String(Liferay.ThemeDisplay.getUserId()),
3602 itemGroupId: 11,
3603 itemId: this.contentId
3604 }, function(res){
3605 if(res.success){
3606 console.log("addToWishList response: ", res);
3607 that.favourite = true;
3608 }
3609 }).catch(function(err){
3610 console.error("Error adding to wishlist: ", err);
3611 });
3612 }else{
3613 this.redirect("login?contentId=${contentId}");
3614 }
3615 },
3616 removeFavourite: function(){
3617 var that = this;
3618
3619 Liferay.Service('/destinazione.favorite/delete-item-from-wish-list', {
3620 oid: this.oid
3621 }, function(res) {
3622 console.log("deleteFromWishList response: ", res);
3623 that.favourite = false;
3624 that.checkFavourite();
3625 }).catch(function(err){
3626 console.error("Error removing from wishlist: ", err);
3627 });
3628 },
3629 selectDate: function(value){
3630 var that = this;
3631
3632 console.log("Data scelta: ", value)
3633 this.calendar.dataSelected = value.date;
3634
3635 this.programs.forEach(function(program){
3636 if(moment(value.date).isBetween(program.startDate, program.endDate)){
3637 console.log(value.date + " è compresa");
3638 program.show = true;
3639 }
3640 });
3641 },
3642 resetDates: function(){
3643 this.calendar.dataSelected = null;
3644 this.programs.forEach(function(program){
3645 program.show = true;
3646 });
3647 },
3648 showResults: function(data){
3649 var that = this;
3650
3651 this.programs.forEach(function(program){
3652 program.show = false;
3653
3654 if(moment(data).isBetween(program.startDate, program.endDate)){
3655 console.log(data + " è compresa");
3656 program.show = true;
3657 }
3658 });
3659 },
3660 setMandatoryServices: function(){
3661 var that = this;
3662
3663 this.selectedServices = [];
3664
3665 this.selectedProgram?.servicesAndPrices?.forEach(function(service){
3666 if(service.mandatory){
3667 that.selectedServices.push(service);
3668 }
3669 });
3670 },
3671 setRequestMessage: function(){
3672 sessionStorage.removeItem("requestMesaage");
3673 console.log("removed old requestMesaage");
3674
3675 var requestMessage = {
3676 message: "testo preventivo da mostrare"
3677 }
3678
3679 sessionStorage.setItem("requestMesaage", JSON.stringify(requestMesaage));
3680 console.log("requestMesaage saved");
3681 },
3682 setProgressData: function(){
3683 var that = this,
3684 depositAmount = "";
3685
3686 localStorage.removeItem("progressProgramData");
3687 console.log("removed old progressProgramData data");
3688
3689 if(this.selectedPayment == "cartaCreditoAcconto"){
3690 depositAmount = this.selectedProgram.depositAmount;
3691 }
3692
3693 var progressData = {
3694 url: window.top.location.href,
3695 docTitle: "${docTitle?js_string}",
3696 selectedProgram: this.selectedProgram,
3697 selectedArea: this.selectedArea,
3698 selectedSchool: this.selectedSchool,
3699 selectedServices: this.selectedServices,
3700 selectedDiscounts: this.selectedDiscounts,
3701 selectedAirport: this.selectedAirport,
3702 selectedPayment: this.selectedPayment,
3703 selectedBalance: this.selectedBalance,
3704 programPrice: this.programPrice,
3705 programDiscount: this.programDiscount,
3706 userData: this.userData,
3707 userMail: this.userMail,
3708 totalPrice: this.totalPrice,
3709 depositAmount: depositAmount
3710 }
3711
3712 progressData.selectedServices.forEach(function(serv){
3713 serv.label = that.labels[serv.service];
3714 });
3715 progressData.selectedDiscounts.forEach(function(dsc){
3716 dsc.label = that.labels[dsc.description];
3717 });
3718
3719 progressData.selectedAirport.label = this.labels[progressData.selectedAirport.airport];
3720
3721 localStorage.setItem("progressProgramData", JSON.stringify(progressData));
3722 console.log("progressProgramData saved");
3723 },
3724 getProgressData: function(){
3725 if(localStorage.getItem("progressProgramData") !== null){
3726 console.log("previous data exists, getting it");
3727
3728 if(JSON.parse(localStorage.getItem("progressProgramData")).url == window.top.location.href){
3729 console.log("previous data is form actual page, restoring it...");
3730
3731 var previousData = JSON.parse(localStorage.getItem("progressProgramData"));
3732
3733 this.selectedProgram=previousData.selectedProgram,
3734 this.selectedArea=previousData.selectedArea,
3735 this.selectedSchool=previousData.selectedSchool,
3736 this.selectedAirport = previousData.selectedAirport;
3737 this.selectedProgram = previousData.selectedProgram;
3738 this.selectedPayment = previousData.selectedPayment;
3739 this.selectedBalance = previousData.selectedBalance;
3740 this.selectedServices = previousData.selectedServices;
3741 this.selectedDiscounts = previousData.selectedDiscounts;
3742 this.programPrice = previousData.programPrice;
3743 this.programDiscount = previousData.programDiscount;
3744 this.userData=previousData.userData;
3745 this.userMail=previousData.userMail;
3746
3747 console.log("previous data restored");
3748
3749 this.currentStep = 7;
3750
3751 localStorage.removeItem("progressProgramData");
3752
3753 //this.openParentModal("#pay-modal");
3754 }else{
3755 console.log("progressProgramData is from a different page");
3756 }
3757 }else{
3758 console.log("no previous data exists");
3759 }
3760 },
3761 isDiscountValid: function(sconto){
3762 var today = new Date(),
3763 valid = false;
3764
3765 if(moment(today).isSameOrAfter(sconto.date) && moment(today).isSameOrBefore(sconto.dateEnd)){
3766 valid = true;
3767 }
3768
3769 return valid;
3770 },
3771 checkEmpty: function(e){
3772 const element = e.target;
3773 if("" != element.value)
3774 {
3775 $('#'+element.id).css({"border":"1px solid #e7e7ed"});
3776 }else{
3777 $('#'+element.id).css({"border":"2px solid red"});
3778 }
3779 },
3780 dateFormat: function (szDate) {
3781 const pattern = /^\d{2}\/\d{2}\/\d{4}$/;
3782 return pattern.test(szDate);
3783 },
3784 checkDateLength: function(e){
3785 const element = e.target;
3786 if("" != element.value && element.value.length==10 && this.dateFormat(element.value))
3787 {
3788 $('#'+element.id).css({"border":"1px solid #e7e7ed"});
3789 }else{
3790 $('#'+element.id).css({"border":"2px solid red"});
3791 }
3792 },
3793 restrictDigitInput: function(e) {
3794 const element = e.target;
3795 const allowedCharacters = /[0-9]/; // Caratteri consentiti: numeri
3796 const stringValue=element.value;
3797 if(e.key=='Backspace' || e.key=='ArrowLeft' || e.key=='ArrowRight' || e.key=='Tab')
3798 return;
3799 if (!allowedCharacters.test(e.key)) {
3800 e.preventDefault();
3801 return;
3802 }
3803 },
3804 restrictDateInput: function(e) {
3805 const element = e.target;
3806 const allowedCharacters = /[0-9]/; // Caratteri consentiti: numeri
3807 const stringValue=element.value;
3808 if(e.key=='Backspace' || e.key=='ArrowLeft' || e.key=='ArrowRight' || e.key=='Tab')
3809 return;
3810 var curPos=e.target.selectionStart;
3811 switch( curPos ) {
3812 case 0: case 1:
3813 if (!allowedCharacters.test(e.key)) {
3814 e.preventDefault();
3815 }
3816 break;
3817 case 2:
3818 if(e.key!="/") {
3819 e.preventDefault();
3820 }
3821 break;
3822 case 3: case 4:
3823 if (!allowedCharacters.test(e.key)) {
3824 e.preventDefault();
3825 }
3826 break;
3827 case 5:
3828 if(e.key!="/")
3829 e.preventDefault();
3830 break;
3831 case 6: case 7: case 8: case 9:
3832 if (!allowedCharacters.test(e.key)) {
3833 e.preventDefault();
3834 }
3835 break;
3836
3837 default:
3838 e.preventDefault();
3839 }
3840
3841 },
3842 checkSelect: function(e){
3843 const element = e.target;
3844 if("" != element.value)
3845 {
3846 $('#'+element.id).css({"border":"1px solid #e7e7ed"});
3847 }else{
3848 $('#'+element.id).css({"border":"2px solid red"});
3849 }
3850 },
3851 checkEmail: function(e){
3852 const mail_el = e.target;
3853 console.log("checkemail");
3854 if("" != mail_el.value)
3855 {
3856 // if(mail_el.value.indexOf("@")>0) {
3857 if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(mail_el.value)) {
3858 $('#'+mail_el.id).css({"border":"1px solid #e7e7ed"});
3859 } else {
3860 $('#'+mail_el.id).css({"border":"2px solid red"});
3861 }
3862 }else{
3863 $('#'+mail_el.id).css({"border":"2px solid red"});
3864 }
3865 },
3866 checkTelefono: function(e) {
3867 const tel_el = e.target;
3868 if("" != tel_el.value)
3869 {
3870 if (/^[0-9]+$/.test(tel_el.value)) {
3871 $('#'+tel_el.id).css({"border":"1px solid #e7e7ed"});
3872 } else {
3873 $('#'+tel_el.id).css({"border":"2px solid red"});
3874 }
3875 }else{
3876 $('#'+tel_el.id).css({"border":"2px solid red"});
3877 }
3878 },
3879 checkCodiceFiscale: function(e) {
3880 const cf_el = e.target;
3881 var cf= cf_el.value;
3882 if(""!= cf) {
3883 // se corretto ok, altrimenti border
3884 var ret=this.controllaCF(cf);
3885 console.log(ret);
3886 if(ret=="") {
3887 this.msgCodiceFiscale=ret;
3888 $('#'+cf_el.id).css({"border":"1px solid #e7e7ed"});
3889 }
3890 else {
3891 this.msgCodiceFiscale=ret;
3892 $('#'+cf_el.id).css({"border":"2px solid red"});
3893
3894 }
3895 }
3896 else{
3897 this.msgCodiceFiscale="codice fiscale non valido";
3898 $('#'+cf_el.id).css({"border":"2px solid red"});
3899 }
3900 },
3901 controllaCF: function (cf) {
3902 console.log(cf);
3903 var validi, i, s, set1, set2, setpari, setdisp;
3904 if (cf == '') return '';
3905 cf = cf.toUpperCase();
3906 if (cf.length != 16)
3907 return "La lunghezza del codice fiscale non è\n"
3908 + "corretta: il codice fiscale dovrebbe essere lungo\n"
3909 + "esattamente 16 caratteri.\n";
3910 validi = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
3911 for (i = 0; i < 16; i++) {
3912 if (validi.indexOf(cf.charAt(i)) == -1)
3913 return "Il codice fiscale contiene un carattere non valido `" +
3914 cf.charAt(i) +
3915 "'.\nI caratteri validi sono le lettere e le cifre.\n";
3916 }
3917 set1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
3918 set2 = "ABCDEFGHIJABCDEFGHIJKLMNOPQRSTUVWXYZ";
3919 setpari = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
3920 setdisp = "BAKPLCQDREVOSFTGUHMINJWZYX";
3921 s = 0;
3922 for (i = 1; i <= 13; i += 2)
3923 s += setpari.indexOf(set2.charAt(set1.indexOf(cf.charAt(i))));
3924 for (i = 0; i <= 14; i += 2)
3925 s += setdisp.indexOf(set2.charAt(set1.indexOf(cf.charAt(i))));
3926 if (s % 26 != cf.charCodeAt(15) - 'A'.charCodeAt(0))
3927 return "Il codice fiscale non è corretto:\n" +
3928 "il codice di controllo non corrisponde.\n";
3929 return "";
3930 },
3931 checkRadio: function(radio_name){
3932 console.log('blur radio');
3933 if ($('input[name='+radio_name+']:checked').length > 0) {
3934 $('input[name='+radio_name+']').each(function(){
3935 $(this).parent().find('.custom-control-label-text').css({
3936 "color":"initial"
3937 })
3938 });
3939 }else{
3940 $('input[name='+radio_name+']').each(function(){
3941 $(this).parent().find('.custom-control-label-text').css({
3942 "color":"red"
3943 })
3944 });
3945 }
3946 },
3947 checkPolicy: function(e){
3948 const check_el = e.target;
3949 console.log('test_change');
3950 if ($('#'+check_el.id).is(':checked')){
3951 $('#'+check_el.id).parent().find('.custom-control-label-text').attr('style','color:initial');
3952 }else{
3953 $('#'+check_el.id).parent().find('.custom-control-label-text').attr('style','color:red');
3954 }
3955 },
3956 checkRadioPayment: function(){
3957 $('#chose_payment input[type=radio]').each(function(){
3958 if($(this).is(':checked')){
3959 $('#chose_payment input[type=radio]').each(function(){
3960 $(this).parent().find('.custom-control-label-text').css({
3961 "color":"initial"
3962 })
3963 });
3964 }
3965 });
3966 },
3967 addEvent: function(eventName,reqType){
3968 window.dataLayer = window.parent.dataLayer || [];
3969 if(reqType != null && reqType!="") {
3970 dataLayer.push({
3971 "event": eventName,
3972 "requestType": reqType
3973 });
3974 }
3975 else {
3976 dataLayer.push({
3977 "event": eventName
3978 });
3979
3980 }
3981 },
3982 getAirportLabel: function(airportKey,index,airportsAndPrices) {
3983 var szRet= this.labels[airportKey];
3984 if(airportKey=="1850639")
3985 szRet=szRet+" (quotazione su richiesta)";
3986 if(index<airportsAndPrices.length-1)
3987 szRet=szRet+",";
3988 return szRet;
3989 }
3990 }
3991 });
3992 });
3993 </script>