An error occurred while processing the template.
The following has evaluated to null or missing:
==> eventName  [in template "68668289766076#51668#1243909" at line 532, column 164]

----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: ${eventName}  [in template "68668289766076#51668#1243909" in macro "buildVisitorCard" at line 532, column 162]
	- Reached through: @buildVisitorCard type=passType price...  [in template "68668289766076#51668#1243909" in macro "buildVisitorPassesListing" at line 330, column 33]
	- Reached through: @buildVisitorPassesListing catalogEnt...  [in template "68668289766076#51668#1243909" at line 953, column 25]
----
1<style> 
2	.section-title{ line-height: 24px; } 
3	.cardPassOfferBtn { 
4    pointer-events: none; 
5
6	.badgeTag { 
7		padding: 0; 
8		background-position: 0 0; 
9
10 
11	.cardPassFive .badgeTag { 
12		left: -3px; 
13		top: -3px; 
14
15 
16	.cardPassFive .badgeTag.exclusive .badgeInnerContent { 
17		top: unset; 
18		left: unset; 
19		pointer-events: none; 
20
21 
22	.badgeTag .badgeInnerContent { 
23		position: relative; 
24		transform: rotate(-47deg) translate(0px, -86px); 
25		top: 0; 
26		left: unset; 
27		text-align: center; 
28		width: 145px; 
29		height: 145px; 
30		display: flex; 
31		justify-content: center; 
32		padding-top: 0; 
33		align-items: flex-end; 
34		justify-content: center; 
35
36 
37	.cardPassFive .badgeTag .badgeInnerContent h6 { 
38		padding: 0 20px; 
39		text-transform: uppercase; 
40
41 
42	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice .price-label, 
43	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice .price-label, 
44	.premium-modal .modal-footer .price-label { 
45		display: none; 
46
47 
48	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice .price-value, 
49	.premium-modal .modal-footer .price-value { 
50		font-weight: var(--fw700); 
51		font-size: var(--fs18) !important; 
52		color: var(--black); 
53		text-decoration: none; 
54
55 
56	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice .price-value { 
57		font-weight: var(--fw700); 
58		font-size: var(--fs18) !important; 
59		color: var(--white); 
60		margin-bottom: var(--m0); 
61		font-family: var(--poppins); 
62		text-align: left; 
63
64 
65	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice h5, 
66	.premium-modal .modal-footer h5 { 
67		display: flex; 
68		gap: 4px; 
69
70 
71	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice .price-value.price-value-promo, 
72	.premium-modal .modal-footer .price-value.price-value-promo { 
73		font-family: var(--poppins); 
74		font-weight: var(--fw700); 
75		font-size: var(--fs18); 
76		line-height: var(--line-height-100Percent); 
77		background-color: var(--black); 
78		color: var(--white); 
79		padding: 6px; 
80		display: inline-block; 
81		border-radius: var(--br6); 
82
83 
84	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice .price-value.price-value-inactive, 
85	.premium-modal .modal-footer .price-value.price-value-inactive { 
86		font-family: var(--poppins); 
87		font-weight: var(--fw400); 
88		font-size: var(--fs18); 
89		line-height: var(--line-height-100Percent); 
90		color: #808080; 
91		margin-right: 4px; 
92		text-decoration: line-through; 
93
94 
95	.premium-modal .modal-footer .h3_vpass { 
96		display: flex; 
97    	gap: 10px; 
98
99	.premium-modal .modal-footer .ticketsDate .para{ 
100		display: flex; 
101    flex-direction: column; 
102    text-transform: uppercase; 
103    font-style: normal; 
104    font-weight: bold; 
105    gap: 3px; 
106
107	.premium-modal .modal-footer .ticketsDate .para span{ 
108		font-size: 10px; 
109    font-weight: 500; 
110    color: #808080; 
111
112	 
113	.availablePassesCard .cardBody .product-full-descriton, .premium-modal .modal-body .cardPassLogoGroup { 
114    display: none; 
115
116	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice span{ 
117		font-size: 12px; 
118
119	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice span{ 
120		font-size: 12px; 
121
122	span.price-value.price-value-promo.price-value-inactive { 
123    display: none !important; 
124
125 
126span.price-value.price-value-discount { 
127    display: none; 
128
129	span.price-value.price-value-final { 
130    display: none !important; 
131
132	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice h5 .price-value.price-value-promo{ 
133		border: 1px solid var(--passbodytext); 
134    padding: var(--p6) var(--p8); 
135    background-color: var(--passtitlebg6); 
136    color: var(--passtitletext); 
137    font-weight: var(--fw700); 
138    font-size: var(--fs18); 
139    color: var(--passtitletext); 
140    font-family: var(--poppins); 
141    border-radius: var(--br6); 
142    display: inline-block; 
143    margin-left: var(--m8); 
144    text-transform: uppercase; 
145
146	.premium-modal .modal-footer .h3_vpass{ 
147	    align-items: center; 
148
149	.checkbox-group input[type=radio] { 
150    opacity: 0; 
151    position: absolute; 
152    left: 0; 
153    top: 0; 
154    width: 100%; 
155    height: 100%; 
156    margin: 0; 
157    cursor: pointer; 
158    z-index: 2; 
159
160	.checkbox-group input[type=radio]:checked + p::before { 
161    background-color: #000000; 
162    border-color: #000000; 
163
164	.checkbox-group input[type=radio]:checked + p::after { 
165    content: ""; 
166    position: absolute; 
167    left: 7px; 
168    top: 4px; 
169    width: 6px; 
170    height: 12px; 
171    border: solid white; 
172    border-width: 0 2px 2px 0; 
173    transform: rotate(45deg); 
174
175	.modal-backdrop .modal-footer-left .h3_vpass .price + b{ 
176		border: 1px solid var(--passbodytext); 
177    padding: var(--p6) var(--p8); 
178    background-color: var(--passtitlebg6); 
179    color: var(--passtitletext); 
180    font-weight: var(--fw700); 
181    font-size: var(--fs18); 
182    color: var(--passtitletext); 
183    font-family: var(--poppins); 
184    border-radius: var(--br6); 
185    display: inline-block; 
186    margin-left: var(--m8); 
187    text-transform: uppercase; 
188
189	.conference-columns{ padding-left: 0;} 
190	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice .price-value.price-value-inactive,  
191	.premium-modal .modal-footer .price-value.price-value-inactive, 
192	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice .price-value.price-value-inactive{ 
193    text-decoration: inherit; 
194    position: relative; 
195    font-weight: bold; 
196    font-size: 16px !important; 
197    overflow: visible; 
198    line-height: 24px; 
199
200	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice .price-value.price-value-inactive:after,  
201	.premium-modal .modal-footer .price-value.price-value-inactive:after, 
202	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice .price-value.price-value-inactive:after{ 
203    background: url('/documents/d/global/promo-curve') no-repeat scroll 0 0; 
204    background-position: 1px 3px; 
205    content: ""; 
206    position: absolute; 
207    width: 100%; 
208    height: 100%; 
209    left: 0; 
210
211	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassPrice span { 
212    font-size: 12px; 
213    color: #BDBDBD; 
214
215	.cardPassFive .cardInner .cardPassFoot .cardPassOuter .cardPassPrice span { 
216    font-size: 12px; 
217    color: #808080; 
218
219	.premium-modal .modal-footer .h3_vpass small { 
220    color: #808080; 
221
222	.cardPassFive .cardInner .cardPassFoot .ticketsDate p{  
223		text-transform: uppercase;  
224		font-style: normal; 
225		align-items: flex-end; 
226
227	.cardPassFive .cardInner .cardPassFoot .ticketsDate p span{  
228		text-transform: capitalize;  
229		    text-transform: capitalize; 
230    font-size: 10px; 
231    color: #808080; 
232
233	.availablePassesCard .cardInner .cardPassFoot .cardPassPriceBtnOuter .cardPassOfferBtn .btn1 { 
234    width: 140px; 
235    font-size: 16px; 
236
237	.subevents-logo-container{ 
238		display: flex; 
239    align-items: flex-start; 
240
241	.subevents-logo-container .cardPassLogo-plusicon{ 
242		margin-bottom: 0; 
243    margin-top: 4px; 
244    margin-right: 8px; 
245
246	.availablePassesCard .cardInner .cardBody .subevents-logo-container .cardPassLogo{ 
247	gap: 8px 0; 
248		flex-wrap: wrap; 
249
250	.availablePassesCard .cardInner .cardBody .cardPassLogo{ 
251	flex-wrap: wrap; 
252
253	.availablePassesCard .cardInner .cardBody .subevents-logo-container .cardPassLogo li{ 
254		padding: 0 4px; 
255
256	.availablePassesCard .cardInner .cardBody .subevents-logo-container .cardPassLogo li:first-child{ 
257		padding-left: 0; 
258
259	span.price-value.price-value-final.show-final-price{ display: flex !important;} 
260</style> 
261 
262<input type="hidden" value="${request.getSession().getId()}" id="ssId"/> 
263 
264<#assign priceLabel = ""/> 
265<#assign expiryDate = "" /> 
266<#assign isoDate ="" /> 
267 
268<#assign vocabLocalService=serviceLocator.findService("com.liferay.asset.kernel.service.AssetVocabularyLocalService") /> 
269<#assign assetPropertyLocalService=serviceLocator.findService("com.liferay.asset.category.property.service.AssetCategoryPropertyLocalService") /> 
270 
271<#assign assetEntryLocalService=serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") 
272	className="com.liferay.asset.kernel.model.AssetCategory" 
273	classNameLocalService=serviceLocator.findService("com.liferay.portal.kernel.service.ClassNameLocalService") 
274	dlUtil=staticUtil["com.liferay.document.library.kernel.util.DLUtil"] 
275	classNameId=classNameLocalService.getClassNameId(className) 
276	commerceChannelLocalService=serviceLocator.findService("com.liferay.commerce.product.service.CommerceChannelLocalService") /> 
277<#assign 
278	cpInstanceLocalService=serviceLocator.findService("com.liferay.commerce.product.service.CPInstanceLocalService") /> 
279<#assign commerceChannels=commerceChannelLocalService.getCommerceChannels(themeDisplay.getCompanyId())> 
280	<#assign commerceChannelGroupId=0 /> 
281	<#assign commerceChannelCurrency="USD" /> 
282 
283<#list commerceChannels as channel> 
284	<#if channel.siteGroupId==themeDisplay.getScopeGroupId()> 
285		<#assign commerceChannelGroupId=channel.getGroupId() /> 
286		<#assign commerceChannelCurrency=channel.commerceCurrencyCode /> 
287		<#break> 
288	</#if> 
289</#list> 
290	 
291<#assign 
292	channelGroupId=commerceChannelLocalService.getCommerceChannelGroupIdBySiteGroupId(themeDisplay.getScopeGroupId())> 
293<#assign visitorPassProducts=[]> 
294<#assign delegatePassProducts=[]> 
295<#assign trainingPassProducts=[]> 
296<#assign otherProducts=[]> 
297 
298<#macro  buildVisitorPassesListing 
299	catalogEntries 
300	passType 
301
302	<div class="container"> 
303	<div class="availablePassFiftyRow mb24"> 
304		<#list catalogEntries as cpCatalogEntry> 
305			<#assign image="" /> 
306			<#assign tagName="" /> 
307			<#assign friendlyURL=cpContentHelper.getFriendlyURL(cpCatalogEntry, themeDisplay) /> 
308			<#assign cpInstance=cpContentHelper.getDefaultCPInstance(cpCatalogEntry) /> 
309			<#assign cProductId = 0 /> 
310			<#if cpInstance??> 
311				<#assign cpDefinition=cpInstance.getCPDefinition() sku=cpInstance.getSku() price=cpInstance.getPrice() /> 
312				<#assign cProductId = cpDefinition.getCProduct().getCProductId() /> 
313				<#assign 
314					classNameId=classNameLocalService.getClassNameId("com.liferay.commerce.product.model.CPDefinition") /> 
315				<#assign assetEntry=assetEntryLocalService.getEntry("com.liferay.commerce.product.model.CPDefinition", cpCatalogEntry.getCPDefinitionId()) /> 
316				<#if (assetEntry.getTags()?size gt 0)> 
317					<#assign tagName=assetEntry.getTags()[0].getName() /> 
318				</#if> 
319				<#assign price=cpInstance.getPrice() /> 
320				<#else> 
321					<#assign cpDefinition="" sku="N/A" price="N/A" /> 
322			</#if> 
323			<#assign name=cpCatalogEntry.getName() /> 
324			<#assign shortDescription=cpCatalogEntry.getShortDescription() /> 
325			<#assign description=cpCatalogEntry.getDescription() /> 
326			<#assign cpDefinitionCDNURL=cpContentHelper.getCPDefinitionCDNURL(cpCatalogEntry.getCPDefinitionId(), request) /> 
327			<#assign 
328				cpSpecValues=cpContentHelper.getCPDefinitionSpecificationOptionValues(cpCatalogEntry.getCPDefinitionId())> 
329	 
330				<@buildVisitorCard  
331					type=passType  
332					price=price  
333					tagName=tagName  
334					cpSpecValues=cpSpecValues  
335					name=name 
336					shortDescription=shortDescription  
337					productId=cpInstance.getCPInstanceId()  
338					description=description 
339					cpCatalogEntry=cpCatalogEntry  
340					cProductId=cProductId 
341				/> 
342		</#list> 
343	</div> 
344	<div>		 
345</#macro> 
346	 
347<#macro buildOtherPassListing 
348	catalogEntries 
349	passType 
350
351	<div class="availablePassThirtyRow mb24"> 
352		<#list catalogEntries as cpCatalogEntry> 
353			<#assign image="" /> 
354			<#assign tagName="" /> 
355			<#assign passTypeProperty = passType /> 
356			<#assign friendlyURL=cpContentHelper.getFriendlyURL(cpCatalogEntry, themeDisplay) /> 
357			<#assign cpInstance=cpContentHelper.getDefaultCPInstance(cpCatalogEntry) /> 
358			<#assign cProductId = 0 /> 
359			<#if cpInstance??> 
360				<#assign cpDefinition=cpInstance.getCPDefinition() sku=cpInstance.getSku() price=cpInstance.getPrice() /> 
361				<#assign cProductId = cpDefinition.getCProduct().getCProductId() /> 
362				<#assign classNameId=classNameLocalService.getClassNameId("com.liferay.commerce.product.model.CPDefinition") /> 
363				<#assign assetEntry=assetEntryLocalService.getEntry("com.liferay.commerce.product.model.CPDefinition", cpCatalogEntry.getCPDefinitionId()) /> 
364				 
365				<#assign constVocabOfContentType="Pass Type Category" />     
366         		<#list assetEntry.getCategories() as category> 
367                    <#assign vocabName=vocabLocalService.getVocabulary(category.vocabularyId).getTitle("en_US") />         
368                    <#if vocabName==constVocabOfContentType> 
369                        <#assign categoryName=category.getTitle(themeDisplay.getLocale()) /> 
370                        <#assign categoryId=category.getCategoryId()/>             
371                         
372                        <#if assetPropertyLocalService.fetchCategoryProperty(categoryId, 'title')??> 
373                            <#assign passTypeProperty =  assetPropertyLocalService.fetchCategoryProperty(categoryId, 'title').getValue() /> 
374                        </#if> 
375                    </#if> 
376                </#list> 
377 
378				<#if (assetEntry.getTags()?size gt 0)> 
379					<#assign tagName=assetEntry.getTags()[0].getName() /> 
380				</#if> 
381				<#assign price=cpInstance.getPrice() /> 
382				<#else> 
383					<#assign cpDefinition="" sku="N/A" price="N/A" /> 
384			</#if> 
385			<#assign name=cpCatalogEntry.getName() /> 
386			<#assign description = cpCatalogEntry.getDescription() /> 
387			<#assign cpDefinitionCDNURL=cpContentHelper.getCPDefinitionCDNURL(cpCatalogEntry.getCPDefinitionId(), request) /> 
388			<#assign cpSpecValues = cpContentHelper.getCPDefinitionSpecificationOptionValues(cpCatalogEntry.getCPDefinitionId())> 
389			<@buildOtherCard  
390				type=passTypeProperty  
391				price=price  
392				tagName=tagName  
393				cpSpecValues=cpSpecValues  
394				name=name  
395				productId=cpInstance.getCPInstanceId()  
396				description=description 
397				cpCatalogEntry=cpCatalogEntry 
398				cProductId=cProductId 
399			/> 
400		</#list> 
401	</div> 
402</#macro> 
403	 
404		 
405<#macro buildVisitorCard 
406	tagName 
407	type 
408	price 
409	cpSpecValues 
410	name 
411	shortDescription 
412	productId 
413	description 
414	cpCatalogEntry 
415	cProductId 
416
417	<span class="price lfr-tooltip-scope d-none" id="price"><span class="price-label">List Price</span><span 
418			class="price-value"></span></span> 
419	<div class="availablePassesCard"> 
420		<div class="cardInner"> 
421			<div class="cardHead"> 
422				<div class="cardCommonHeading"> 
423					<h6>${htmlUtil.escape(name)}</h6> 
424					<h6> Visitor Pass</h6> 
425					<a href="javascript:void(0);" class="viewDetails trigger" data-target="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}"> 
426						<span>VIEW DETAILS</span> 
427						<img src="/o/registration-portal-theme-css/images/icons/right-arrow.svg" alt="right-arrow"> 
428					</a> 
429				</div> 
430	 
431			</div> 
432			<div class="cardBody"> 
433				<p> 
434					${shortDescription} 
435				</p> 
436				<div class="logo-container"> 
437					${description} 
438				</div> 
439				 
440			</div> 
441			<div class="cardPassFoot"> 
442				<div class="cardPassPriceBtnOuter"> 
443					<div class="cardPassPrice"> 
444	 
445						<h5 class="align-items-center"> 
446							${commerceChannelCurrency} 
447							<#list cpCatalogEntry.getCPSkus() as sku> 
448								 
449								<@liferay_commerce_ui["price"] CPCatalogEntry=cpCatalogEntry 
450									CPDefinitionId=cpCatalogEntry.getCPDefinitionId() CPInstanceId=sku.getCPInstanceId() 
451									showDiscount=false /> 
452							</#list> 
453							<b class="d-none">Free</b> 
454						</h5> 
455						<span class="font-weight-normal vat-info">Incl. 5% VAT</span> 
456					</div> 
457					 
458					<#if tagName !=""> 
459						<div class="cardPassOfferBtn"> 
460							<a href="javascript:void(0;)" class="btn1 br50">${tagName}</a> 
461						</div> 
462					</#if> 
463					 
464					<div class="cardPassOfferBtn cardPassOfferBtn-promo d-none"> 
465          	<a href="javascript:void(0;)" class="btn1 br50">EARLY BIRD</a> 
466          </div> 
467	 
468				</div> 
469				<div class="cardPassBtn"> 
470					<button type="button"  
471									class="btn1 h40 custom-addcart-btn"  
472									data-product="${productId}"  
473									data-cproductid="${cProductId}" 
474									data-type="${type}"  
475									data-cpdefinationid="${cpCatalogEntry.getCPDefinitionId()}" 
476									data-target="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}_mquestion" 
477						>buy now</button> 
478				</div> 
479				 
480			</div> 
481		</div> 
482		 
483		<!-- modal for view detail start  --> 
484		<div class="modal-backdrop" id="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}"> 
485			<div class="premium-modal"> 
486				<div class="modal-header"> 
487					<h2>${htmlUtil.escape(name)}</h2> 
488					<!-- <span>Subject to approval</span>  --> 
489					<button class="close-btn"> 
490						<img src="/o/registration-portal-theme-css/images/icons/line-cross-circle.svg" alt="cross-circle" 
491							class="img-fluid"> 
492					</button> 
493				</div> 
494				<div class="modal-body"> 
495					${description} 
496				</div> 
497				<div class="modal-footer modal-footer-col"> 
498					<div class="modal-footer-left"> 
499						<p class="para"> 
500						</p> 
501						<h3 class="h3_vpass"> 
502							${commerceChannelCurrency} 
503							<#list cpCatalogEntry.getCPSkus() as sku> 
504								<@liferay_commerce_ui["price"] CPCatalogEntry=cpCatalogEntry 
505									CPDefinitionId=cpCatalogEntry.getCPDefinitionId() CPInstanceId=sku.getCPInstanceId() 
506									showDiscount=false /> 
507							</#list> 
508							<b class="d-none">Free</b> 
509							<small class="font-weight-normal vat-info">incl. 5% VAT</small> 
510						</h3> 
511					</div> 
512					<div class="modal-footer-right"> 
513						<button class="btn1 borderHover open-modal-btn" data-product="${productId}" data-cproductid="${cProductId}" data-type="${type}" data-cpdefinationid="${cpCatalogEntry.getCPDefinitionId()}" data-target="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}_mquestion">buy now</button> 
514					</div> 
515				</div> 
516			</div> 
517		</div> 
518		<!-- modal for view detail end  --> 
519		 
520		<!-- modal for marketing question start  --> 
521		<div class="modal-backdrop marketing-modal" id="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}_mquestion"> 
522         <div class="premium-modal"> 
523            <div class="modal-header"> 
524               <h2>${htmlUtil.escape(name)}</h2> 
525               <button class="close-btn"> 
526									<img src="/o/registration-portal-theme-css/images/icons/line-cross-circle.svg" alt="cross-circle" 
527											 class="img-fluid" /> 
528								</button> 
529            </div> 
530            <div class="modal-body"> 
531               <div class="section-card-para"> 
532                  <p class="ev-name-container">The <strong>${htmlUtil.escape(name)}</strong> grants you access to all Conference tracks at <span class="ev-name">${eventName}</span></p> 
533               </div> 
534 
535               <div class="section-card"> 
536                  <div class="section-title"> 
537                     <strong>To help deliver a better experience,<br> select your most preferred conference(s).</strong> 
538                  </div> 
539 
540                  <div class="conference-columns"> 
541                     <!-- GITEX GLOBAL --> 
542                     <div class="conference-group conference-group-gitex d-none"> 
543                        <h3>GITEX Global 2025<br> 
544                           <span><b>13 - 17 Oct 2025</b> <span>10AM - 5PM</span></span><br> 
545                            <a class="text-decoration-none" href="https://shorturl.at/DewBj" rel="noopener noreferrer" target="_blank"><span class="location">📍 Dubai World Trade Centre</span> </a> 
546                        </h3> 
547                        <div class="checkbox-group checkbox-group-gitex"></div> 
548                     </div> 
549					 <div class="conference-group conference-group-northstar d-none"> 
550                        <h3>Expand North Star+<br> 
551                           	<span><b>12- 15 October 2025</b> <span>10AM - 6PM</span> </span><br> 
552                        	<a class="text-decoration-none" href="https://shorturl.at/ABawS" rel="noopener noreferrer" target="_blank"><span class="location">📍 Dubai Harbour</span> </a> 
553                        </h3> 
554                        <div class="checkbox-group checkbox-group-northstar"></div> 
555                     </div> 
556                  </div> 
557               </div> 
558 
559            </div> 
560            <div class="modal-footer space-right"> 
561               <div class="space-left"> 
562 
563               </div> 
564               <div class="space-right"> 
565                  <button class="cancel-btn">Cancel</button> 
566                  <button class="confirm-btn" data-cproductid="${cProductId}" data-product="${productId}" data-type="${type}" data-cpdefinationid="${cpCatalogEntry.getCPDefinitionId()}" disabled>Confirm selection</button> 
567               </div> 
568            </div> 
569         </div> 
570      </div> 
571			<!-- modal for marketing question end  -->	 
572		 
573		 
574	</div> 
575</#macro> 
576		 
577<#macro buildOtherCard 
578	tagName 
579	type 
580	price 
581	cpSpecValues 
582	name 
583	productId 
584	description 
585	cpCatalogEntry 
586	cProductId 
587
588 
589<#assign assetEntry = assetEntryLocalService.getEntry("com.liferay.commerce.product.model.CPDefinition", cpCatalogEntry.getCPDefinitionId()) /> 
590            <#assign categoryNames = []> 
591            <#list assetEntry.getCategories() as cat> 
592                <#assign categoryNames += [cat.getName()?lower_case] /> 
593            </#list> 
594 
595		<span class="price lfr-tooltip-scope d-none" id="price"><span class="price-label">List Price</span><span 
596			class="price-value"></span></span> 
597<div class="cardPass cardPassFive ${(type == 'training')?then('gradientClrGreen', '')}"> 
598	<#if tagName !=""> 
599		<div class="badgeTag exclusive"> 
600			<div class="badgeInnerContent"> 
601				<h6>${tagName}</h6> 
602			</div> 
603		</div> 
604	</#if> 
605 
606	<#assign extraClass=tagName?has_content?then('', 'pl-3' )> 
607		<div class="cardInner"> 
608 
609			<div class="cardHead ${extraClass}"> 
610				<h6>${htmlUtil.escape(name)}</h6> 
611				<a href="javascript:void(0);" class="viewDetails trigger" data-target="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}"> 
612					<span>VIEW DETAILS</span> 
613					<img src="/o/registration-portal-theme-css/images/icons/right-arrow.svg" alt="right-arrow"> 
614				</a> 
615			</div> 
616			<div class="cardBody"> 
617				<div class="cardPassList"> 
618					<#list cpSpecValues as spec> 
619						<span class="greenTickList"> 
620							<span class="greenTickIcon"> 
621								<img src="/o/registration-portal-theme-css/images/icons/circle-tick.svg" 
622									alt="circle-tick" class="img-fluid"> 
623							</span> 
624							<span class="greenTickListTxt"> 
625								<p class="mb-0">${spec.value}</p> 
626							</span> 
627						</span> 
628					</#list> 
629				</div> 
630			</div> 
631			<div class="cardPassFoot"> 
632 
633				<#if categoryNames?seq_contains("approval")> 
634                    <div class="ticketsDate approval-price-label"> 
635                            <p>SUBJECT TO APPROVAL</p> 
636                        </div> 
637                <#else> 
638                    <#if type=="Delegate"> 
639											<#if htmlUtil.escape(name) !="Digital Assets Forum"> 
640                        <div class="ticketsDate standard-price-label d-none"> 
641                            <p>Exclusive to 50 tickets only...</p> 
642                        </div> 
643												</#if> 
644                        <div class="ticketsDate promo-price-label d-none"> 
645                            <p>Early Bird Rate  
646                                <span>Expires 31 Aug 2025</span> 
647                            </p> 
648                        </div> 
649                    </#if> 
650                </#if> 
651 
652				 
653				<div class="cardPassOuter"> 
654					<div class="cardPassPrice"> 
655						<h6> 
656							${commerceChannelCurrency} 
657							<#list cpCatalogEntry.getCPSkus() as sku> 
658								<@liferay_commerce_ui["price"] CPCatalogEntry=cpCatalogEntry 
659									CPDefinitionId=cpCatalogEntry.getCPDefinitionId() CPInstanceId=sku.getCPInstanceId() 
660									showDiscount=false /> 
661							</#list> 
662							<b class="d-none">Free</b> 
663						</h6> 
664						<span class="font-weight-normal vat-info">Incl. 5% VAT</span> 
665					</div> 
666				</div> 
667				<div class="cardPassBtn"> 
668					<#assign isApproval=""/> 
669					<#if categoryNames?seq_contains("approval")> 
670						<#assign isApproval="forApproval"/> 
671					</#if> 
672					<button type="button"  
673									class="btn1 borderHover h40 custom-addcart-btn"  
674									data-approval="${isApproval}" 
675									data-cproductid="${cProductId}" 
676									data-product="${productId}" data-type="${type}" data-cpdefinationid="${cpCatalogEntry.getCPDefinitionId()}" 
677									data-target="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}_mquestion" 
678						>buy now</button> 
679				</div> 
680			</div> 
681		</div> 
682		 
683		<!-- modal for view detail start  --> 
684		 
685		<div class="modal-backdrop" id="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}"> 
686			<div class="premium-modal"> 
687				<div class="modal-header"> 
688					<h2>${htmlUtil.escape(name)}</h2> 
689					<button class="close-btn"> 
690						<img src="/o/registration-portal-theme-css/images/icons/line-cross-circle.svg" alt="cross-circle" 
691								 class="img-fluid" /> 
692					</button> 
693				</div> 
694				<div class="modal-body"> 
695					${description} 
696				</div> 
697				<div class="modal-footer modal-footer-col"> 
698					<div class="modal-footer-left"> 
699 
700						<#if categoryNames?seq_contains("approval")> 
701                            <div class="ticketsDate approval-price-label"> 
702                                    <p class="para">SUBJECT TO APPROVAL</p> 
703                                </div> 
704                        <#else> 
705                            <#if type=="Delegate"> 
706															<#if htmlUtil.escape(name) !="Digital Assets Forum"> 
707                                <div class="ticketsDate standard-price-label d-none"> 
708                                        <p class="para">Exclusive to 50 tickets only...</p> 
709                                    </div> 
710																</#if> 
711                                    <div class="ticketsDate promo-price-label d-none"> 
712                                        <p class="para">Early Bird Rate  
713                                            <span>Expires 31 Aug 2025</span> 
714                                        </p> 
715                                    </div> 
716                            </#if> 
717                        </#if> 
718 
719 
720 
721						<h3 class="h3_vpass"> 
722							${commerceChannelCurrency} 
723							<#list cpCatalogEntry.getCPSkus() as sku> 
724								<@liferay_commerce_ui["price"] CPCatalogEntry=cpCatalogEntry 
725																			 CPDefinitionId=cpCatalogEntry.getCPDefinitionId() CPInstanceId=sku.getCPInstanceId() 
726																			 showDiscount=false /> 
727								</#list> 
728							<b class="d-none">Free</b> 
729							<small class="font-weight-normal vat-info">incl. 5% VAT</small> 
730						</h3> 
731					</div> 
732					<div class="modal-footer-right"> 
733						<#assign isApproval=""/> 
734						<#if categoryNames?seq_contains("approval")> 
735							<#assign isApproval="forApproval"/> 
736						</#if> 
737						<button class="btn1 borderHover open-modal-btn"  
738										data-product="${productId}"  
739										data-cproductid="${cProductId}" 
740										data-approval="${isApproval}" 
741										data-type="${type}"  
742										data-cpdefinationid="${cpCatalogEntry.getCPDefinitionId()}"  
743										data-target="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}_mquestion">buy now</button> 
744					</div> 
745				</div> 
746			</div> 
747		</div> 
748		 
749		<!-- modal for view detail end  --> 
750		<!-- modal for marketing question start  --> 
751		<div class="modal-backdrop marketing-modal" id="${htmlUtil.escape(name)?lower_case?replace(" ", "_")}_${productId}_mquestion"> 
752         <div class="premium-modal"> 
753            <div class="modal-header"> 
754               <h2>${htmlUtil.escape(name)}</h2> 
755               <button class="close-btn"> 
756									<img src="/o/registration-portal-theme-css/images/icons/line-cross-circle.svg" alt="cross-circle" 
757											 class="img-fluid" /> 
758								</button> 
759            </div> 
760            <div class="modal-body"> 
761               <div class="section-card-para"> 
762								 <p class="ev-name-container">The <strong>${htmlUtil.escape(name)}</strong> grants you access to all Conference tracks at <span class="ev-name">${eventName}</span></p> 
763               </div> 
764 
765               <div class="section-card"> 
766                  <div class="section-title"> 
767                     <strong>To help deliver a better experience,<br> select your most preferred conference(s).</strong> 
768                  </div> 
769 
770                  <div class="conference-columns"> 
771                     <!-- GITEX GLOBAL --> 
772                     <div class="conference-group conference-group-gitex"> 
773                        <h3>GITEX Global 2025<br> 
774                           <span><b>13 - 17 Oct 2025</b> <span>10AM - 5PM</span></span><br> 
775                            <a class="text-decoration-none" href="https://shorturl.at/DewBj" rel="noopener noreferrer" target="_blank"><span class="location">📍 Dubai World Trade Centre</span> </a> 
776                        </h3> 
777                        <div class="checkbox-group checkbox-group-gitex"></div> 
778                     </div> 
779					 <div class="conference-group conference-group-northstar d-none"> 
780                        <h3>Expand North Star+<br> 
781                           	<span><b>12- 15 October 2025</b> <span>10AM - 6PM</span> </span><br> 
782                        	<a class="text-decoration-none" href="https://shorturl.at/ABawS" rel="noopener noreferrer" target="_blank"><span class="location">📍 Dubai Harbour</span> </a> 
783                        </h3> 
784                        <div class="checkbox-group checkbox-group-northstar"></div> 
785                     </div> 
786                  </div> 
787               </div> 
788 
789            </div> 
790            <div class="modal-footer space-right"> 
791               <div class="space-left"> 
792 
793               </div> 
794               <div class="space-right"> 
795								 <#assign isApproval=""/> 
796									<#if categoryNames?seq_contains("approval")> 
797										<#assign isApproval="forApproval"/> 
798									</#if> 
799                  <button class="cancel-btn">Cancel</button> 
800                  <button class="confirm-btn"  
801													data-product="${productId}"  
802													data-cproductid="${cProductId}" 
803													data-type="${type}"  
804													data-approval="${isApproval}" 
805													data-cpdefinationid="${cpCatalogEntry.getCPDefinitionId()}"  
806													disabled>Confirm selection</button> 
807               </div> 
808            </div> 
809         </div> 
810      </div> 
811			<!-- modal for marketing question end  -->	 
812</div> 
813	 
814	 
815	 
816</#macro> 
817 
818		 
819<div class="modal-backdrop add-to-cart-prompt" id="info-prompt"> 
820         <div class="premium-modal"> 
821            <div class="modal-header"> 
822               <h2>Add Product</h2> 
823            </div> 
824            <div class="modal-body"> 
825               <div class="section-card-para"> 
826                  <p class="ev-name-container">You already have item in your order. Continue to billing, or confirm to replace it (your previous selection will be cleared).</p> 
827               </div> 
828            </div> 
829            <div class="modal-footer space-right justify-content-center"> 
830               <div class="space-left"></div> 
831               <div class="space-right"> 
832								 <a href="" class="btn1 billing-btn" id="billing-btn">Proceed to Billing</a> 
833                  <button class="btn1 cancel-order-btn" id="cancel-order-btn">Confirm &amp; Replace it</button> 
834               </div> 
835            </div> 
836         </div> 
837</div> 
838	 
839<#if paramUtil.getString(request, 'commerceCatalogId')?has_content> 
840	<#assign selectedEventId = paramUtil.getString(request, 'eventId') /> 
841	<#assign eventName = "" /> 
842	<#assign eventEndDate = "" /> 
843	<#assign eventStartDate = "" /> 
844	<#if selectedEventId?has_content> 
845		<#assign eventDetail = (restClient.get("/c/events/${selectedEventId}?restrictFields=actions")) /> 
846		<#if eventDetail?has_content> 
847			<#assign eventName = eventDetail.eventTitle /> 
848			<#assign eventEndDate = eventDetail.endDate?date("yyyy-MM-dd") /> 
849			<#assign eventStartDate = eventDetail.startDate?date("yyyy-MM-dd") /> 
850		</#if> 
851	</#if> 
852	<#assign catalogId = paramUtil.getString(request, 'commerceCatalogId') /> 
853	 
854<div>${themeDisplay.isImpersonated()?c}</div> 
855<div>${themeDisplay.getRealUserId()}</div>		 
856<#-- admin bypass disabled --> 
857<#assign skipFiltering = false /> 
858 
859  <#-- ===================== ROLE-BASED VISIBILITY (case-insensitive CONTAINS) ===================== --> 
860<#assign VISIBILITY_VOCAB = "Agent Product Visibility Roles" /> 
861 
862<#-- Collect user roles, normalized to lowercase --> 
863<#assign userRolesLC = [] /> 
864<#if themeDisplay.isSignedIn()> 
865    <#assign realUserId = themeDisplay.getRealUserId() /> 
866    <#assign myUser = (restClient.get("/headless-admin-user/v1.0/user-accounts/${realUserId}") )!{} /> 
867	   <div> 
868			 <div> 
869  User ID: ${myUser.id?c}<br/> 
870  Email: ${myUser.emailAddress?html}<br/> 
871  Full name: ${myUser.name?html}<br/> 
872  Impersonated: ${themeDisplay.isImpersonated()?c} 
873</div> 
874	</div> 
875    <#if myUser?has_content && myUser.roleBriefs?has_content> 
876        <#list myUser.roleBriefs as rb> 
877            <#assign r = (rb.name!'')?string?lower_case?trim /> 
878       <#if r == "administrator" || r == "agent backoffice manager"> 
879            <#assign skipFiltering = true /> 
880            <#break> 
881           </#if> 
882            <#if r?has_content><#assign userRolesLC += [r] /></#if> 
883        </#list> 
884    </#if> 
885</#if> 
886 
887 
888<#assign filteredEntries = [] /> 
889<#if entries?has_content> 
890    <#list entries as e> 
891        <#assign include = false /> 
892 
893        <#if skipFiltering> 
894            <#assign include = true /> 
895        <#elseif themeDisplay.isSignedIn() && userRolesLC?has_content> 
896            <#assign ae = assetEntryLocalService.getEntry("com.liferay.commerce.product.model.CPDefinition", e.getCPDefinitionId()) /> 
897 
898            <#list ae.getCategories() as cat> 
899                <#-- Optional: restrict to a specific vocabulary --> 
900                <#assign vocabOK = true /> 
901                <#if VISIBILITY_VOCAB?has_content> 
902                    <#assign vocabTitle = (vocabLocalService.getVocabulary(cat.vocabularyId).getTitle("en_US")!"")?lower_case?trim /> 
903                    <#assign vocabOK = (vocabTitle == VISIBILITY_VOCAB?lower_case?trim) /> 
904                </#if> 
905 
906                <#if vocabOK> 
907                    <#-- Normalize category name to lowercase --> 
908                    <#assign catNameLC = (cat.getName()!"")?lower_case?trim /> 
909                    <#if catNameLC?has_content> 
910                        <#-- CASE-INSENSITIVE CONTAINS: roleNameLC contains catNameLC --> 
911                        <#list userRolesLC as roleNameLC> 
912                            <#if roleNameLC == catNameLC> 
913                                <#assign include = true /> 
914                                <#break> 
915                            </#if> 
916                        </#list> 
917                    </#if> 
918                </#if> 
919 
920                <#if include><#break></#if> 
921            </#list> 
922        </#if> 
923 
924        <#if include><#assign filteredEntries += [e] /></#if> 
925    </#list> 
926</#if> 
927 
928<#assign entries = filteredEntries /> 
929</#if> 
930	 
931	<#if entries?has_content> 
932		<#list entries as curCPCatalogEntry> 
933			 
934			<#assign assetEntry = assetEntryLocalService.getEntry("com.liferay.commerce.product.model.CPDefinition", curCPCatalogEntry.getCPDefinitionId()) /> 
935			<#assign categoryNames = []> 
936			<#list assetEntry.getCategories() as cat> 
937				<#assign categoryNames += [cat.getName()?lower_case] /> 
938			</#list> 
939			<#if categoryNames?seq_contains("position - 1")> 
940				<#assign visitorPassProducts += [curCPCatalogEntry] /> 
941			<#elseif categoryNames?seq_contains("position - 2")> 
942				<#assign delegatePassProducts += [curCPCatalogEntry] /> 
943			<#elseif categoryNames?seq_contains("position - 3")> 
944				<#assign trainingPassProducts += [curCPCatalogEntry] /> 
945			<#else> 
946				<#assign otherProducts += [curCPCatalogEntry] /> 
947			</#if> 
948 
949		</#list> 
950 
951 
952		<div class="availablePassFiftyCard"> 
953			<@buildVisitorPassesListing catalogEntries = visitorPassProducts passType="visitor" /> 
954		</div> 
955		<div class="availablePassThirtyCard mb24"> 
956			<@buildOtherPassListing catalogEntries = delegatePassProducts passType="delegate" /> 
957			<@buildOtherPassListing catalogEntries = trainingPassProducts passType="training" /> 
958		</div> 
959		 
960<#if paramUtil.getString(request, 'category')?has_content> 
961				<div class="lookingSomethingElse aos-init aos-animate" data-aos="fade-up"> 
962                        <div class="lookingSomethingElseInner"> 
963                           <div class="lookingSomethingElseHead"> 
964                              <h5>Looking for something else?</h5> 
965                           </div> 
966                           <div class="lookingSomethingElseBtn"> 
967                              <button class="btn1 borderHover h40" onclick="removeCategoryParam();">view all passes</a> 
968                           </div> 
969                        </div> 
970                     </div> 
971	</#if> 
972					 
973	<script> 
974		(function () { 
975            const currentPath = window.location.pathname; 
976            // Utility to read query parameters 
977            const params = new URLSearchParams(window.location.search); 
978            // Utility to read cookie 
979            function getCookie(name) { 
980                const match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)")); 
981                return match ? decodeURIComponent(match[2]) : null; 
982
983            // Utility to set cookie 
984            function setCookie(name, value) { 
985                document.cookie = name+'='+encodeURIComponent(value)+'; path=/'; 
986
987            const eventId = params.get("eventId"); 
988            const commerceCatalogId = params.get("commerceCatalogId"); 
989            if (eventId) setCookie("eventId", eventId); 
990            if (commerceCatalogId) setCookie("commerceCatalogId", commerceCatalogId); 
991        })(); 
992 
993		let questionConfigData = []; 
994		function fetchQuestionConfig(){ 
995			fetch("/o/c/questionconfigs/?filter=r_event_c_eventId eq '${selectedEventId}' and questionCategory eq 'marketing'&nestedFields=questionMasterId&restrictFields=actions,creator", { 
996				headers: { 
997					'accept': 'application/json', 
998					'x-csrf-token': Liferay.authToken, 
999
1000			}) 
1001			.then(resp => resp.json()) 
1002			.then(data => { 
1003					console.log(data); 
1004					questionConfigData = data?.items; 
1005			}) 
1006			.catch(console.error); 
1007
1008		fetchQuestionConfig(); 
1009		 
1010		$(document).ready(function(){ 
1011			$('.availablePassThirtyCard .cardPass').each(function(item){  
1012				if($(this).find('.price-value-promo').length > 0){ 
1013					//$(this).find('.cardPassFoot .ticketsDate.standard-price-label').addClass('d-none'); 
1014					$(this).find('.ticketsDate.promo-price-label').removeClass('d-none'); 
1015				}else{ 
1016					//$(this).find('.ticketsDate.standard-price-label').removeClass('d-none'); 
1017
1018				 
1019				if($(this).find('.price-value-discount').length > 0){ 
1020					const finalPriceText = $(this).find('.price-value.price-value-final').text().trim(); 
1021					var finalePrice = parseFloat(finalPriceText); 
1022					if(finalePrice == 0){ 
1023						$(this).find('.cardPassFoot .cardPassPrice b').removeClass('d-none'); 
1024						$(this).find('.cardPassPrice .vat-info').addClass('d-none'); 
1025					}else{ 
1026						$(this).find('.cardPassFoot .cardPassPrice .price-value.price-value-final').addClass('show-final-price'); 
1027
1028
1029				 
1030			}); 
1031			$('.availablePassFiftyCard .availablePassesCard').each(function(item){  
1032				const priceValueText = $(this).find('.cardPassPrice .price-value').text().trim(); 
1033				var price = parseFloat(priceValueText); 
1034				if (price === 0) { 
1035					//$(this).find('.cardPassPrice h5 b').removeClass('d-none'); 
1036
1037				if($(this).find('.price-value-discount').length > 0){ 
1038					const finalPriceText = $(this).find('.price-value.price-value-final').text().trim(); 
1039					var finalePrice = parseFloat(finalPriceText); 
1040					if(finalePrice == 0){ 
1041						$(this).find('.cardPassFoot .cardPassPrice b').removeClass('d-none'); 
1042						$(this).find('.cardPassPrice .vat-info').addClass('d-none'); 
1043						 
1044						$(this).find('.modal-backdrop .h3_vpass b').removeClass('d-none'); 
1045						$(this).find('.modal-backdrop .vat-info').addClass('d-none'); 
1046
1047
1048				if($(this).find('.price-value-promo').length > 0){ 
1049					console.log("promo   ",$(this).find('.cardPassOfferBtn-promo')); 
1050					$(this).find('.cardPassOfferBtn-promo').removeClass('d-none'); 
1051
1052				 
1053			}) 
1054		}) 
1055		function removeCategoryParam(){ 
1056			const url = new URL(window.location.href); 
1057			url.searchParams.delete('category'); 
1058			window.location.href = url.toString(); 
1059
1060		const accountId = Liferay.CommerceContext.account.accountId; 
1061		const channelId = parseInt(Liferay.CommerceContext.commerceChannelId); 
1062		const currencyCode = Liferay.CommerceContext.currency.currencyCode; 
1063		 
1064		async function request(config) { 
1065			try { 
1066				const { url, method = "GET", headers = {}, body, ...rest } = config; 
1067 
1068				const csrfToken = window.Liferay?.authToken || null; 
1069				const language = 
1070					Liferay?.ThemeDisplay?.getLanguageId()?.replace("_", "-") || "en-US"; 
1071 
1072				const fetchHeaders = { 
1073					"x-csrf-token": csrfToken, 
1074					"Content-Type": "application/json", 
1075					"Accept-Language": language, 
1076					...headers, 
1077				}; 
1078 
1079				const response = await fetch(url, { 
1080					method, 
1081					headers: fetchHeaders, 
1082					body: body ? JSON.stringify(body) : undefined, 
1083					...rest, 
1084				}); 
1085 
1086				if (!response.ok) { 
1087					const errorData = await response.json().catch(() => ({})); 
1088					throw { 
1089						status: response.status, 
1090						statusText: response.statusText, 
1091						data: errorData, 
1092					}; 
1093
1094 
1095				const data = await response.json().catch(() => ({})); 
1096				return { data, status: response.status }; 
1097			} catch (error) { 
1098				console.error("Fetch error:", error); 
1099				throw error; 
1100
1101
1102		 
1103		async function getOpenOrder() { 
1104			try { 
1105				const res = await request({ 
1106					url: "/o/headless-commerce-admin-order/v1.0/orders?filter=orderStatus/any(x:(x eq 1)) and creatorEmailAddress eq '" + themeDisplay.getUserEmailAddress() + "'&page=1&sort=orderDate%3Adesc", 
1107				}); 
1108 
1109				const entries = res?.data?.items ?? []; 
1110				console.log("entries    ",entries); 
1111				try { 
1112					await Promise.all( 
1113						entries.map(entry => updateRegistrantOrderStatus(entry)) // each call returns a Promise 
1114					); 
1115					console.log("✅ All promises resolved"); 
1116 
1117					await Promise.all( 
1118						entries.map(entry => updateOrderStatus(entry)) // each call returns a Promise 
1119					); 
1120 
1121					console.log("✅ All promises resolved for pending orders:::  "); 
1122					return true; 
1123				} catch (error) { 
1124					console.error("❌ At least one promise rejected:", error); 
1125
1126			} catch (err) { 
1127				console.error("Failed to fetch options:", err); 
1128				return []; 
1129
1130
1131		 
1132		async function updateOrderStatus(pendingOrder){ 
1133			try { 
1134				fetch('/o/headless-commerce-admin-order/v1.0/orders/'+pendingOrder.id, { 
1135					method: 'PATCH', 
1136					headers: { 
1137						'accept': 'application/json', 
1138						'Content-Type': 'application/json', 
1139						'x-csrf-token': Liferay.authToken 
1140					}, 
1141					body: JSON.stringify({ 
1142						'orderStatus': 8 
1143					}) 
1144				}); 
1145			} catch (err) { 
1146				console.error("Failed to fetch options:", err); 
1147				return []; 
1148
1149
1150		async function updateRegistrantOrderStatus(pendingOrder){ 
1151			try { 
1152				fetch('/o/c/registrants/'+pendingOrder.id, { 
1153					method: 'PATCH', 
1154					headers: { 
1155						'accept': 'application/json', 
1156						'Content-Type': 'application/json', 
1157						'x-csrf-token': Liferay.authToken 
1158					}, 
1159					// body: '{"orderStatus": "Cancel"}', 
1160					body: JSON.stringify({ 
1161						'orderStatus': 'Cancel' 
1162					}) 
1163				}); 
1164 
1165			} catch (err) { 
1166				console.error("Failed to fetch options:", err); 
1167				return []; 
1168
1169
1170		 
1171		$(document).on("click", ".cancel-order-btn", async function () { 
1172			const targetId = $('#cancel-order-btn').attr('data-target'); 
1173			const productSkuId = $('#cancel-order-btn').attr('data-product'); 
1174			const productId = $('#cancel-order-btn').attr('data-cproductid'); 
1175			const passType = $('#cancel-order-btn').attr('data-type'); 
1176			const cpdefinationId = $('#cancel-order-btn').attr('data-cpdefinationid'); 
1177			const isApproval = $('#cancel-order-btn').attr('data-approval'); 
1178 
1179			const success = await getOpenOrder(); 
1180			if (success) { 
1181				addProductAfterCheckingOrder(targetId, productSkuId, productId, passType, cpdefinationId,isApproval); 
1182			} else { 
1183				console.warn("🚫 Skipping addProductInCart due to failure in getOpenOrder"); 
1184
1185			document.getElementById("info-prompt").classList.remove("active"); 
1186		}); 
1187		 
1188		 
1189		 
1190		//display marketing popup if question otherwise add to cart 
1191		 
1192		$(document).on('click', '.custom-addcart-btn', async function(){ 
1193			let canProceed = true; 
1194			const targetId = $(this).attr('data-target') 
1195			const productSkuId = $(this).attr('data-product'); 
1196			const productId = $(this).attr('data-cproductid'); 
1197			const passType = $(this).attr('data-type'); 
1198			const isApproval = $(this).attr('data-approval'); 
1199			const cpdefinationId = parseInt($(this).attr('data-cpdefinationid')); 
1200			if(Liferay.ThemeDisplay.isSignedIn()){ 
1201					const res = await request({ 
1202						url: "/o/headless-commerce-admin-order/v1.0/orders?filter=orderStatus/any(x:(x eq 1)) and creatorEmailAddress eq '" + themeDisplay.getUserEmailAddress() + "'&page=1&sort=orderDate%3Adesc", 
1203					}); 
1204					const openOrderEntries  = res?.data?.items ?? []; 
1205					if(openOrderEntries .length > 0){ 
1206						canProceed = false; 
1207						 
1208					var urlbilling = '/web/registration-portal/billing-information?eventId=${selectedEventId}&commerceCatalogId=${catalogId}&orderId='+openOrderEntries[0].id 
1209			        const params = new URLSearchParams(window.location.search); 
1210						 
1211						  if (Liferay.ThemeDisplay.isImpersonated()) { 
1212                     urlbilling += "&doAsUserId="+encodeURIComponent(params.get("doAsUserId")); 
1213
1214						 
1215						$('#billing-btn').attr('href', urlbilling) 
1216 
1217						$('#cancel-order-btn').attr('data-target',targetId); 
1218						$('#cancel-order-btn').attr('data-product',productSkuId); 
1219						$('#cancel-order-btn').attr('data-cproductid',productId); 
1220						$('#cancel-order-btn').attr('data-type',passType); 
1221						$('#cancel-order-btn').attr('data-cpdefinationid',cpdefinationId); 
1222						$('#cancel-order-btn').attr('data-approval',isApproval); 
1223 
1224						document.getElementById('info-prompt').classList.add('active'); 
1225
1226
1227			if(canProceed){ 
1228				addProductAfterCheckingOrder(targetId, productSkuId, productId, passType, cpdefinationId,isApproval); 
1229
1230		}) 
1231		 
1232		 
1233		 
1234		$(document).on('click', '.open-modal-btn' ,function () { 
1235				checkPendingOrderBeforeAdd(this); 
1236		}); 
1237		 
1238		/* 
1239		 
1240		document.querySelectorAll('.open-modal-btn').forEach(btn => { 
1241         btn.addEventListener('click', () => { 
1242					 	const targetId = btn.dataset.target; 
1243					 	const productSkuId = btn.dataset.product; 
1244						const productId = btn.dataset.cproductid; 
1245					 	const passType = btn.dataset.type; 
1246					 const isApproval = btn.dataset.approval; 
1247					  const questionData = questionConfigData.filter(e => e.r_pass_CPDefinitionId === parseInt(btn.dataset.cpdefinationid)); 
1248					 console.log("questionData >>>    ",questionData);  
1249					 if(questionData.length > 0){ 
1250							const questionType = questionData[0]?.questionMasterId?.questionType?.name; 
1251							document.querySelectorAll('.modal-backdrop').forEach(function(item){ item.classList.remove('active')})	 
1252							renderQuestionInModal(questionData,targetId); 
1253            	document.getElementById(targetId).classList.add('active'); 
1254							document.getElementById(targetId).setAttribute('data-questiontype', questionType); 
1255						}else{ 
1256							onClickAddToCartBtn(productSkuId,passType,'addToCartFromBtn',isApproval,productId); 
1257
1258         }); 
1259     }); 
1260		 
1261		$(document).on('click', '.custom-addcart-btn', function(){ 
1262			const targetId = $(this).attr('data-target') 
1263			const productSkuId = $(this).attr('data-product'); 
1264			const productId = $(this).attr('data-cproductid'); 
1265			const passType = $(this).attr('data-type'); 
1266			const cpdefinationId = parseInt($(this).attr('data-cpdefinationid')); 
1267			const questionData = questionConfigData.filter(e => e.r_pass_CPDefinitionId === cpdefinationId); 
1268			const isApproval = $(this).attr('data-approval'); 
1269			console.log("questionData >>>    ",questionData);  
1270			if(questionData.length > 0){ 
1271				const questionType = questionData[0]?.questionMasterId?.questionType?.name; 
1272				document.querySelectorAll('.modal-backdrop').forEach(function(item){ item.classList.remove('active')})	 
1273				renderQuestionInModal(questionData,targetId); 
1274				document.getElementById(targetId).classList.add('active'); 
1275				document.getElementById(targetId).setAttribute('data-questiontype', questionType); 
1276			}else{ 
1277				onClickAddToCartBtn(productSkuId,passType,'addToCartFromBtn',isApproval,productId); 
1278
1279		}); 
1280		 
1281		*/ 
1282		 
1283		async function checkPendingOrderBeforeAdd(thisObj){ 
1284				let canProceed = true; 
1285				const targetId = $(thisObj).attr('data-target') 
1286				const productSkuId = $(thisObj).attr('data-product'); 
1287				const productId = $(thisObj).attr('data-cproductid'); 
1288				const passType = $(thisObj).attr('data-type'); 
1289				const cpdefinationId = parseInt($(thisObj).attr('data-cpdefinationid')); 
1290			const isApproval = $(this).attr('data-approval'); 
1291 
1292				if(Liferay.ThemeDisplay.isSignedIn()){ 
1293					const res = await request({ 
1294						url: "/o/headless-commerce-admin-order/v1.0/orders?filter=orderStatus/any(x:(x eq 1)) and creatorEmailAddress eq '" + themeDisplay.getUserEmailAddress() + "'&page=1&sort=orderDate%3Adesc", 
1295					}); 
1296					const openOrderEntries  = res?.data?.items ?? []; 
1297					if(openOrderEntries .length > 0){ 
1298						canProceed = false; 
1299						 
1300						var urlbilling = '/web/registration-portal/billing-information?eventId=${selectedEventId}&commerceCatalogId=${catalogId}&orderId='+openOrderEntries[0].id 
1301			        const params = new URLSearchParams(window.location.search); 
1302						  if (Liferay.ThemeDisplay.isImpersonated()) { 
1303                     urlbilling += "&doAsUserId="+encodeURIComponent(params.get("doAsUserId")); 
1304
1305						 
1306						//<p class="ev-name-container">You already have [Item] in your order. Continue to billing, or confirm to replace it (your previous selection will be cleared).</p> 
1307						$('#billing-btn').attr('href', urlbilling) 
1308 
1309						$('#cancel-order-btn').attr('data-target',targetId); 
1310						$('#cancel-order-btn').attr('data-product',productSkuId); 
1311						$('#cancel-order-btn').attr('data-cproductid',productId); 
1312						$('#cancel-order-btn').attr('data-type',passType); 
1313						$('#cancel-order-btn').attr('data-cpdefinationid',cpdefinationId); 
1314						$('#cancel-order-btn').attr('data-approval',isApproval); 
1315 
1316						document.getElementById('info-prompt').classList.add('active'); 
1317
1318
1319				if(canProceed){ 
1320					addProductAfterCheckingOrder(targetId, productSkuId, productId, passType, cpdefinationId,isApproval); 
1321
1322				console.log("coming here to add product:::::"); 
1323
1324		 
1325		function addProductAfterCheckingOrder(targetId, productSkuId, productId, passType, cpdefinationId,isApproval){ 
1326				const questionData = questionConfigData.filter(e => e.r_pass_CPDefinitionId === cpdefinationId);	 
1327				const isImpersonted = Liferay.ThemeDisplay.isImpersonated() 
1328				if (questionData.length > 0 && !isImpersonted) { 
1329						const questionType = questionData[0]?.questionMasterId?.questionType?.name; 
1330						document.querySelectorAll('.modal-backdrop').forEach(function(item) { 
1331								item.classList.remove('active') 
1332						}) 
1333						renderQuestionInModal(questionData, targetId); 
1334						document.getElementById(targetId).classList.add('active'); 
1335						document.getElementById(targetId).setAttribute('data-questiontype', questionType); 
1336				} else { 
1337						onClickAddToCartBtn(productSkuId, passType, 'addToCartFromBtn',isApproval ,productId); 
1338
1339
1340		 
1341		function onClickAddToCartBtn(productSkuId,pass_Type,addToCartLocation,isApproval,productId) { 
1342			if (themeDisplay.isSignedIn()) { 
1343				if(Liferay.CommerceContext?.order?.orderId){ 
1344					addItemsInCart(Liferay.CommerceContext?.order?.orderId, productSkuId,pass_Type,addToCartLocation,isApproval,productId); 
1345				}else{ 
1346					addNewItemInCart(productSkuId,pass_Type,addToCartLocation,isApproval,productId); 
1347
1348			} else { 
1349				addNewItemInCart(productSkuId,pass_Type,addToCartLocation,isApproval,productId); 
1350
1351
1352		function manageRegistrationRedirection(productId ,data){ 
1353			const params = new URLSearchParams(window.location.search); 
1354        var url = "/web/registration-portal/registration?eventId=${selectedEventId}&commerceCatalogId=${catalogId}&entryClassPK=" + productId; 
1355			   if (params.has("doAsUserId")) { 
1356        url += "&doAsUserId="+encodeURIComponent(params.get("doAsUserId"))+"&orderId="+data.id; 
1357
1358			window.location.href=url; 
1359
1360		 
1361		function addGADataToTable(capturedParams,orderData){ 
1362			console.log("orderData >>   ",orderData?.id); 
1363			fetch('/o/c/gatrackings/', { 
1364				method: 'POST', 
1365				headers: { 
1366				'accept': 'application/json', 
1367				'Content-Type': 'application/json', 
1368				'x-csrf-token': Liferay.authToken 
1369				}, 
1370				body: JSON.stringify({ 
1371					sessionId: document.getElementById('ssId').value, 
1372					utmCampaign: capturedParams.utm_campaign, 
1373					utmContent: capturedParams.utm_content, 
1374					utmMedium: capturedParams.utm_medium, 
1375					utmSource: capturedParams.utm_source, 
1376					utmTerm: capturedParams.utm_term, 
1377					orderId: orderData?.id, 
1378					urnNumber: orderData?.cartItems[0].id 
1379				}) 
1380			}) 
1381			.then(response => { 
1382				if (!response.ok) { 
1383				// Handle HTTP-level errors 
1384				throw new Error('HTTP error! Status:' + response.status); 
1385
1386				return response.json(); // If API returns JSON 
1387			}) 
1388			.then(data => { 
1389				console.log('Success:', data); 
1390			}) 
1391			.catch(error => { 
1392				console.error('Fetch error:', error); 
1393			}); 
1394
1395		 
1396		function manageQestionOrOrderAfterAddToCart(data, pass_Type, addToCartLocation, isApproval, productId) { 
1397			let price = data?.cartItems[0].price?.finalPrice == 0 
1398				? data?.cartItems[0].price?.finalPrice 
1399				: data?.cartItems[0].price?.price; 
1400 
1401			let promoPrice = data?.cartItems[0].price?.finalPrice == 0 
1402				? data?.cartItems[0].price?.finalPrice 
1403				: data?.cartItems[0].price?.promoPrice; 
1404 
1405			const productData = { 
1406				name: data?.cartItems[0].name, 
1407				passType: pass_Type, 
1408				price: price, 
1409				total: data?.cartItems[0].price?.finalPrice, 
1410				promoPrice: data?.cartItems[0].price?.promoPrice, 
1411				isApproval: isApproval, 
1412				productId: productId 
1413			}; 
1414 
1415			const params = new URLSearchParams(window.location.search); 
1416			let capturedParams = {}; 
1417			// Capture UTM params 
1418			["utm_source", "utm_medium", "utm_campaign", "utm_content", "utm_term"].forEach(param => { 
1419				const value = params.get(param); 
1420				if (value) { 
1421					capturedParams[param] = value; 
1422
1423			}); 
1424 
1425			// Push event to GTM dataLayer 
1426			window.dataLayer = window.dataLayer || []; 
1427			window.dataLayer.push({ 
1428				'event': 'PassSelected', 
1429				'eventId': '${selectedEventId}', 
1430				'eventName': '${eventName}', 
1431				'passName': data?.cartItems[0].name, 
1432				'passType': pass_Type, 
1433				'passPrice': price, 
1434				'pageName': 'Pass Selection' 
1435			}); 
1436 
1437			// Store order + productData in cookies 
1438			document.cookie = "com.liferay.commerce.model.CommerceOrder#${channelGroupId}=" + data.externalReferenceCode + "; path=/"; 
1439			document.cookie = "productData=" + encodeURIComponent(JSON.stringify(productData)) + "; path=/"; 
1440 
1441			// Trigger Liferay event 
1442			Liferay.fire("current-order-updated", { order: data }); 
1443 
1444			// Add GA data if params exist 
1445			if (Object.keys(capturedParams).length > 0) { 
1446				addGADataToTable(capturedParams, data); 
1447
1448 
1449			fetch('/o/headless-commerce-delivery-cart/v1.0/cart-items/'+data?.cartItems[0].id, { 
1450				method: 'PATCH', 
1451				headers: { 
1452					'accept': 'application/json', 
1453					'Content-Type': 'application/json', 
1454					'x-csrf-token': Liferay.authToken 
1455				}, 
1456				body: JSON.stringify({ 
1457					'quantity': 1 
1458				}) 
1459			}) 
1460			.then(response => { 
1461						if (!response.ok) { 
1462								throw new Error(response.status); 
1463
1464						return response.json(); // adjust if API doesn’t return JSON 
1465				}) 
1466				.then(updateData => { 
1467						console.log("event id added in order::::  ", updateData); 
1468						if (addToCartLocation === "addToCartFromModal") { 
1469								manageQuestionDataOnSave($(document).find('.marketing-modal.active'), data?.cartItems[0].id, productId); 
1470						} else { 
1471								manageRegistrationRedirection(productId ,data); 
1472
1473				}) 
1474				.catch(error => { 
1475						console.error("Failed to update eventId:", error); 
1476						if (addToCartLocation === "addToCartFromModal") { 
1477								manageQuestionDataOnSave($(document).find('.marketing-modal.active'), data?.cartItems[0].id, productId); 
1478						} else { 
1479								manageRegistrationRedirection(productId , data); 
1480
1481				}) 
1482			 
1483			 
1484			/*fetch('/o/headless-commerce-admin-order/v1.0/orderItems/'+data?.cartItems[0].id, { 
1485				method: 'PATCH', 
1486				headers: { 
1487					'accept': 'application/json', 
1488					'Content-Type': 'application/json', 
1489					'x-csrf-token': Liferay.authToken 
1490				}, 
1491				body: JSON.stringify({ 
1492					'quantity': 1 
1493				}) 
1494			}) 
1495			.then(response => { 
1496						if (!response.ok) { 
1497								throw new Error(response.status); 
1498
1499						return response.json(); // adjust if API doesn’t return JSON 
1500				}) 
1501				.then(updateData => { 
1502						console.log("event id added in order::::  ", updateData); 
1503						if (addToCartLocation === "addToCartFromModal") { 
1504								manageQuestionDataOnSave($(document).find('.marketing-modal.active'), data?.cartItems[0].id, productId); 
1505						} else { 
1506								manageRegistrationRedirection(productId); 
1507
1508				}) 
1509				.catch(error => { 
1510						console.error("Failed to update eventId:", error); 
1511						if (addToCartLocation === "addToCartFromModal") { 
1512								manageQuestionDataOnSave($(document).find('.marketing-modal.active'), data?.cartItems[0].id, productId); 
1513						} else { 
1514								manageRegistrationRedirection(productId); 
1515
1516				});*/ 
1517 
1518				/* 
1519				 
1520				let commerceOrderId = 0; 
1521					if (Liferay.CommerceContext?.order?.orderId) { 
1522							commerceOrderId = Liferay.CommerceContext?.order?.orderId; 
1523					} else { 
1524							commerceOrderId = data?.id; 
1525
1526				 
1527				fetch("https://apimanager-dwtc-prd.lfr.cloud/api/upgradepass/updateEventId?orderId=" + commerceOrderId + "&eventId=${selectedEventId}", { 
1528						method: 'GET', 
1529				}) 
1530				.then(response => { 
1531						if (!response.ok) { 
1532								throw new Error(response.status); 
1533
1534						return response.json(); // adjust if API doesn’t return JSON 
1535				}) 
1536				.then(updateData => { 
1537						console.log("event id added in order::::  ", updateData); 
1538						if (addToCartLocation === "addToCartFromModal") { 
1539								manageQuestionDataOnSave($(document).find('.marketing-modal.active'), data?.cartItems[0].id, productId); 
1540						} else { 
1541								manageRegistrationRedirection(productId); 
1542
1543				}) 
1544				.catch(error => { 
1545						console.error("Failed to update eventId:", error); 
1546						if (addToCartLocation === "addToCartFromModal") { 
1547								manageQuestionDataOnSave($(document).find('.marketing-modal.active'), data?.cartItems[0].id, productId); 
1548						} else { 
1549								manageRegistrationRedirection(productId); 
1550
1551				});*/ 
1552 
1553			 
1554			// Continue flow without API call 
1555			/*if (addToCartLocation === "addToCartFromModal") { 
1556				manageQuestionDataOnSave($(document).find('.marketing-modal.active'), data?.cartItems[0].id, productId); 
1557			} else { 
1558				manageRegistrationRedirection(productId); 
1559			}*/ 
1560
1561 
1562		function addNewItemInCart(skuId,pass_Type,addToCartLocation,isApproval,productId) { 
1563				const eventId= '${selectedEventId}'; 
1564				const customFieldsValue = Liferay.ThemeDisplay.isImpersonated()? { event_Id: eventId+"", Source: "Backend Agent" }: { event_Id: eventId+"" }; 
1565                const createCartBody = { 
1566                  accountId: accountId, 
1567                  cartItems: [{ options: '[]', quantity: 1, replacedSkuId: 0, skuId: skuId.toString() }], 
1568                  currencyCode: currencyCode, 
1569                  customFields: customFieldsValue 
1570                }; 
1571				 
1572			fetch('/o/headless-commerce-delivery-cart/v1.0/channels/' + channelId + '/carts?nestedFields=cartItems', { 
1573				"headers": { 
1574					"accept": "application/json", 
1575					"accept-language": "en-US", 
1576					"content-type": "application/json", 
1577					"x-csrf-token": Liferay.authToken 
1578				}, 
1579				"body": JSON.stringify(createCartBody), 
1580				"method": "POST", 
1581			}).then(response => response.json()) 
1582				.then(data => { 
1583					console.log("fire:::  ", data); 
1584					manageQestionOrOrderAfterAddToCart(data,pass_Type,addToCartLocation,isApproval,productId); 
1585				}) 
1586				.catch(console.error); 
1587
1588	 
1589			function addItemsInCart(cartId, skuId,pass_Type,addToCartLocation,isApproval,productId) { 
1590					const eventId= '${selectedEventId}'  
1591						fetch('/o/headless-commerce-delivery-cart/v1.0/carts/' + cartId + '?nestedFields=cartItems', { 
1592							method: 'GET', 
1593							headers: { 
1594								accept: 'application/json', 
1595								'Content-Type': 'application/json', 
1596								'x-csrf-token': Liferay.authToken 
1597
1598						}) 
1599							.then(r => r.json()) 
1600							.then(data => { 
1601								const items = [...(data.cartItems || []), { options: '[]', quantity: 1, replacedSkuId: 0, skuId }]; 
1602								const customFieldsValue = Liferay.ThemeDisplay.isImpersonated()? { event_Id: eventId+"", Source: "Backend Agent" }: { event_Id: eventId+"" }; 
1603                                    const createCartBody = { 
1604                                    cartItems: [{ options: '[]', quantity: 1, replacedSkuId: 0, skuId: skuId.toString() }], 
1605                                    customFields: customFieldsValue 
1606                                    }; 
1607								 
1608								return fetch('/o/headless-commerce-delivery-cart/v1.0/carts/' + cartId + '?nestedFields=cartItems', { 
1609									method: 'PATCH', 
1610									headers: { 
1611										accept: 'application/json', 
1612										'Content-Type': 'application/json', 
1613										'x-csrf-token': Liferay.authToken 
1614									}, 
1615									body: JSON.stringify(createCartBody) 
1616								}); 
1617							}) 
1618							.then(response => response.json()) 
1619							.then(data => { 
1620								console.log("fire:::  ", data); 
1621								manageQestionOrOrderAfterAddToCart(data,pass_Type,addToCartLocation,isApproval,productId); 
1622							}) 
1623							.catch(console.error); 
1624
1625 
1626					// Open modal 
1627      document.querySelectorAll('.trigger').forEach(btn => { 
1628         manageModal(btn) 
1629      }); 
1630		 
1631			 
1632		 
1633			function renderQuestionInModal(questionData,targetId){ 
1634				const questionLabel = questionData[0]?.questionMasterId?.questionLabel; 
1635				const questionType = questionData[0]?.questionMasterId?.questionType?.name; 
1636				document 
1637					.getElementById(targetId) 
1638					.querySelector('.section-title').setAttribute('data-questionid', questionData[0]?.id); 
1639				document 
1640					.getElementById(targetId) 
1641					.querySelector('.section-title strong') 
1642					.innerHTML = questionLabel; 
1643 
1644				 
1645				let updatedQuestionData = questionData || []; 
1646				// Find the index of the object whose name starts with "North Star-" 
1647				const northStarIndex = updatedQuestionData.findIndex(item => item.questionMasterId?.questionLabel.startsWith('North Star-')); 
1648 
1649				if (northStarIndex !== -1 && northStarIndex !== 1) { 
1650					const [northStarItem] = updatedQuestionData.splice(northStarIndex, 1); 
1651					updatedQuestionData.splice(1, 0, northStarItem); 
1652
1653				console.log(updatedQuestionData); 
1654 
1655				 
1656				const gitexContainer = document.getElementById(targetId).querySelector('.checkbox-group-gitex'); 
1657				gitexContainer.innerHTML = ""; 
1658				const northStarContainer = document.getElementById(targetId).querySelector('.checkbox-group-northstar'); 
1659				northStarContainer.innerHTML = ""; 
1660				if(updatedQuestionData.length > 1){ 
1661					fetchAnswersforQuestion(updatedQuestionData[0]?.questionMasterId?.id, targetId, questionType, gitexContainer); 
1662					fetchAnswersforQuestion(updatedQuestionData[1]?.questionMasterId?.id, targetId, questionType, northStarContainer); 
1663					document.getElementById(targetId).querySelector('.conference-group-northstar').classList.remove('d-none'); 
1664					 
1665				}else if(updatedQuestionData.length == 1){ 
1666					//fetchAnswersforQuestion(updatedQuestionData[0]?.questionMasterId?.id, targetId, questionType, gitexContainer); 
1667					const questionLabel = updatedQuestionData[0]?.questionMasterId?.questionLabel; 
1668					let containerId = gitexContainer; 
1669					if(questionLabel.startsWith('North Star-')){ 
1670						containerId = northStarContainer; 
1671						const parts = questionLabel.split("North Star-"); 
1672						const currentYear = new Date().getFullYear(); 
1673						document.getElementById(targetId).querySelector('.section-title strong').innerHTML = parts[1]; 
1674						document.getElementById(targetId).querySelector('.conference-group-northstar').classList.remove('d-none'); 
1675						document.getElementById(targetId).querySelector('.conference-group-gitex').classList.add('d-none'); 
1676						document.getElementById(targetId).querySelector('.ev-name-container span').innerHTML = 'Expand North Star '+currentYear; 
1677
1678					fetchAnswersforQuestion(updatedQuestionData[0]?.questionMasterId?.id, targetId, questionType, containerId); 
1679
1680
1681 
1682			function fetchAnswersforQuestion(questionMasterId, targetId, questionType, container){ 
1683				console.log("questionType    ",questionType); 
1684				const url = '/o/c/questionmasters/'+questionMasterId+'/question'; 
1685				 Liferay.Util.fetch(url) 
1686					.then((res) => res.json()) 
1687					.then((data) => { 
1688					 console.log("Questions fetched:", data); 
1689					 if(data.items.length > 0){ 
1690						 //const container = document.getElementById(targetId).querySelector('.checkbox-group'); 
1691						 container.innerHTML = ""; 
1692 
1693						 data.items.sort((a, b) => { 
1694                                if (a.answerLabel < b.answerLabel) return -1; 
1695                                if (a.answerLabel > b.answerLabel) return 1; 
1696                                return 0; 
1697                            }); 
1698 
1699						 	data.items.map(item => { 
1700								let checkboxTMPL = ""; 
1701								if(questionType == "SingleSelect"){ 
1702									checkboxTMPL = '<label> <input type="radio" name="marketingAnswers" value="'+item.id+'" data-label="'+item.answerLabel+'"> <p>'+item.answerLabel+'</p> </label>'; 
1703								}else if(questionType == "MultiSelect"){ 
1704									checkboxTMPL = '<label> <input type="checkbox" value="'+item.id+'" data-label="'+item.answerLabel+'"> <p>'+item.answerLabel+'</p> </label>'; 
1705								}else{ 
1706									checkboxTMPL = '<label> <input class="form-control" type="text" data-value="'+item.id+'"></label>'; 
1707
1708								container.insertAdjacentHTML('beforeend', checkboxTMPL); 
1709							}); 
1710
1711					}) 
1712					.catch((error) => { 
1713					 console.error("Error fetching answer:", error); 
1714					}); 
1715
1716		 
1717			function manageModal(btn){ 
1718					btn.addEventListener('click', () => { 
1719					 	document.querySelectorAll('.modal-backdrop').forEach(function(item){ item.classList.remove('active')}) 
1720            const targetId = btn.dataset.target; 
1721            document.getElementById(targetId).classList.add('active'); 
1722         }); 
1723
1724		 
1725 
1726      // Modal logic 
1727			$('.modal-backdrop').each(function () { 
1728				const $modal = $(this); 
1729				const $closeBtn = $modal.find('.close-btn'); 
1730				const $cancelBtn = $modal.find('.cancel-btn'); 
1731				// Close modal on close/cancel click 
1732				$closeBtn.on('click', function () { 
1733					$modal.removeClass('active'); 
1734				}); 
1735 
1736				$cancelBtn.on('click', function () { 
1737					$modal.removeClass('active'); 
1738				}); 
1739			}) 
1740		 
1741			function updateAnswerTransactions(answersArr,productId){ 
1742				fetch('/o/c/answertransactions/batch', { 
1743					method: 'POST', 
1744					headers: { 
1745						'accept': 'application/json', 
1746						'Content-Type': 'application/json', 
1747						'x-csrf-token': Liferay.authToken 
1748					}, 
1749					body: JSON.stringify(answersArr) 
1750				}) 
1751				.then(response => response.json()) 
1752				.then(data => { 
1753					console.log("data   ",data); 
1754					manageRegistrationRedirection(productId); 
1755				}) 
1756				.catch(console.error); 
1757
1758			function saveDataForQuestionSelection($modal, orderLineId, optionType,productId){ 
1759				const questionId = $modal.find('.section-title').attr('data-questionid');			 
1760				const selectedItems = $modal.find('input[type="'+optionType+'"]:checked'); 
1761				const userId = themeDisplay.getUserId(); 
1762				let selectedItemsArr = []; 
1763				selectedItems.each(function(index, item){ 
1764					let answerObj = {}; 
1765					answerObj.answerMasterId = parseInt($(this).attr('value')); 
1766					answerObj.answerValue = $(this).attr('data-label'); 
1767					answerObj.currentUserId = parseInt(userId); 
1768					answerObj.orderLineId = orderLineId; 
1769					answerObj.questionId = parseInt(questionId); 
1770					answerObj.parentAnswerId = 0; 
1771					selectedItemsArr.push(answerObj); 
1772				}); 
1773				updateAnswerTransactions(selectedItemsArr,productId); 
1774
1775		 
1776			function saveDataOfTextQuestions($modal, orderLineId,productId){ 
1777				const questionId = $modal.find('.section-title').attr('data-questionid');			 
1778				const selectedItems = $modal.find('input[type="text"]'); 
1779				const userId = themeDisplay.getUserId(); 
1780				let selectedItemsArr = []; 
1781				selectedItems.each(function(index, item){ 
1782					let answerObj = {}; 
1783					answerObj.answerMasterId = parseInt($(this).attr('value')); 
1784					answerObj.answerValue = $(this).val(); 
1785					answerObj.currentUserId = parseInt(userId); 
1786					answerObj.orderLineId = orderLineId; 
1787					answerObj.questionId = parseInt(questionId); 
1788					answerObj.parentAnswerId = 0; 
1789					selectedItemsArr.push(answerObj); 
1790				}); 
1791				updateAnswerTransactions(selectedItemsArr,productId); 
1792
1793			function manageQuestionDataOnSave($modal, orderItemId,productId){ 
1794				const questionType = $modal.attr('data-questiontype'); 
1795				console.log("questionType    ",questionType); 
1796				console.log("order item id   ",orderItemId); 
1797				if(questionType == "MultiSelect"){ 
1798					saveDataForQuestionSelection($modal, orderItemId, 'checkbox',productId); 
1799				}else if(questionType == "SingleSelect"){ 
1800					saveDataForQuestionSelection($modal, orderItemId, 'radio',productId); 
1801				}else{ 
1802					saveDataOfTextQuestions($modal, orderItemId,productId); 
1803
1804
1805		 
1806			$('.marketing-modal').each(function () { 
1807				const $modal = $(this); 
1808				const questionType = $modal.attr('data-questiontype'); 
1809				const $confirmBtn = $modal.find('.confirm-btn'); 
1810				$confirmBtn.on('click', function (event) {		 
1811					const productSkuId = $(this).attr('data-product'); 
1812					const productId = $(this).attr('data-cproductid'); 
1813					const productType = $(this).attr('data-type'); 
1814					const isApproval = $(this).attr('data-approval'); 
1815					console.log("on confirm btn   "); 
1816					onClickAddToCartBtn(productSkuId, productType, 'addToCartFromModal',isApproval,productId); 
1817				}); 
1818				 
1819				 
1820				// Toggle confirm button based on checkbox count 
1821				function toggleConfirmButton() { 
1822					const checkedCount = $modal.find('input[type="checkbox"]:checked').length; 
1823					if (checkedCount >= 1) { 
1824						$confirmBtn.addClass('enabled').removeAttr('disabled'); 
1825					} else { 
1826						$confirmBtn.removeClass('enabled').attr('disabled', true); 
1827
1828
1829				function toggleConfirmButtonForRadio(){ 
1830					const checkedRadioCount = $modal.find('input[type="radio"]:checked').length; 
1831					console.log("checkedRadioCount", checkedRadioCount); 
1832					if (checkedRadioCount == 1) { 
1833						$confirmBtn.addClass('enabled').removeAttr('disabled'); 
1834					} else { 
1835						$confirmBtn.removeClass('enabled').attr('disabled', true); 
1836
1837
1838				 
1839				function toggleConfirmButtonForText() { 
1840					const textInputItem = $modal.find('input[type="text"]'); 
1841					if (textInputItem.val().length > 0) { 
1842						$confirmBtn.addClass('enabled').removeAttr('disabled'); 
1843					} else { 
1844						$confirmBtn.removeClass('enabled').attr('disabled', true); 
1845
1846
1847 
1848				// Delegate change event for dynamically added checkboxes 
1849				$modal.on('change', 'input[type="checkbox"]', toggleConfirmButton); 
1850				$modal.on('change', 'input[type="radio"]', toggleConfirmButtonForRadio); 
1851				$modal.on('input', 'input[type="text"]', toggleConfirmButtonForText); 
1852 
1853				// Initial state 
1854				toggleConfirmButton(); 
1855			}); 
1856 
1857	</script> 
1858<#else> 
1859	No Result Found 
1860</#if> 
Category