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