Se ha producido un error al procesar la plantilla.
The following has evaluated to null or missing:
==> cpCatalogEntry [in template "20097#20123#51764" at line 10, column 140]
----
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: #assign CPDefinitionSpecificationOpti... [in template "20097#20123#51764" at line 10, column 1]
----
1<#assign pricesService = serviceLocator.findService("com.bti.commerce.integration.api.services.ext.PricesServiceExt")>
2<#assign CPDefinitionLocalService = serviceLocator.findService("com.liferay.commerce.product.service.CPDefinitionLocalService")>
3<#assign dlurlHelper = serviceLocator.findService("com.liferay.document.library.util.DLURLHelper")>
4<#assign cPDefinitions = []>
5<#assign PortalUtil = serviceLocator.findService("com.liferay.portal.kernel.util.PortalUtil")>
6<#assign httpServletRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest))>
7<#assign commerceContext = renderRequest.getAttribute("COMMERCE_CONTEXT")>
8<#assign commerceOrderId = (commerceContext.getCommerceOrder().commerceOrderId)!0>
9<#assign CPDefinitionSpecificationOptionValueLocalService = serviceLocator.findService("com.liferay.commerce.product.service.CPDefinitionSpecificationOptionValueLocalService")>
10<#assign CPDefinitionSpecificationOptionValues = CPDefinitionSpecificationOptionValueLocalService.getCPDefinitionSpecificationOptionValues(cpCatalogEntry.getCPDefinitionId(),0)>
11<#assign cPDefinition1 = CPDefinitionLocalService.getCPDefinition(cpCatalogEntry.getCPDefinitionId())>
12<#assign fileEntryLocalService = serviceLocator.findService("com.liferay.document.library.kernel.service.DLAppLocalService")>
13<#assign jsonFactoryUtil = serviceLocator.findService("com.liferay.portal.kernel.json.JSONFactoryUtil")>
14
15<#assign jsessionId = "">
16<#if themeDisplay.isSignedIn()>
17 <#list request.getCookies() as cookie>
18 <#if cookie.getName() == "JSESSIONID">
19 <#assign jsessionId = cookie.getValue()>
20 </#if>
21 </#list>
22</#if>
23
24<#assign blocked = renderRequest.getAttribute("COMMERCE_CONTEXT").getAccountEntry().getExpandoBridge().getAttribute("Blocked")/>
25
26<#assign cPDefinitions = [CPDefinitionLocalService.getCPDefinition(cpCatalogEntry.getCPDefinitionId())]>
27
28<#if themeDisplay.isSignedIn()>
29 <#assign priceSimple = pricesService.getPricesWithDiscount(cPDefinitions, false, renderRequest.getAttribute("COMMERCE_CONTEXT"))?values[0]>
30</#if>
31
32<#assign diameterMessage = languageUtil.get(locale, "widget-template-product-detail-message-diameter") />
33<#assign lengthMessage = languageUtil.get(locale, "widget-template-product-detail-message-length")/>
34<#assign typeOfRestorationMessage = languageUtil.get(locale, "widget-template-product-detail-message-type-of-restoration")/>
35
36
37<div class="page_content">
38 <section class="detail_catalogo container">
39 <div class="row">
40 <div class="col-12 col-md-6 left">
41 <div class="image">
42 <#assign productImage = cPDefinitions[0].getCPAttachmentFileEntries(0, -1)>
43 <#assign fileEntry = ""/>
44
45 <#if productImage?has_content>
46 <#assign sortedProductImage = productImage?sort_by("createDate")?last>
47 <#assign fileEntry = fileEntryLocalService.getFileEntry(sortedProductImage.getFileEntryId())>
48
49 <img src="${dlurlHelper.getDownloadURL(fileEntry, fileEntry.getFileVersion(), themeDisplay, "")}"
50 alt="Imagen de producto">
51 <#else>
52 <img src="${cpContentHelper.getDefaultImageFileURL(commerceContext.getAccountEntry().getAccountEntryId(), cPDefinitions[0].getCPDefinitionId())}"
53 alt="Imagen de producto">
54 </#if>
55 </div>
56 </div>
57 <div class="col-12 col-md-6 right">
58 <div class="actions">
59 <@liferay_commerce_ui["compare-checkbox"] CPCatalogEntry = cpCatalogEntry label = "Comparar"/>
60 <#if themeDisplay.isSignedIn()>
61 <@liferay_commerce_ui["add-to-wish-list"] CPCatalogEntry = cpCatalogEntry />
62 </#if>
63 </div>
64 <div class="content_product">
65 <h2 class="heading_80">${cpCatalogEntry.getName()}</h2>
66 <p class="reference">
67 <b><@liferay_ui["message"] key="widget-template-product-detail-message-reference-short"/></b> ${cPDefinitions[0].getCProduct().getExternalReferenceCode()}
68 </p>
69 <div class="content_text_small">
70 <p>${cpCatalogEntry.getShortDescription()}</p>
71 </div>
72 <#if themeDisplay.isSignedIn()>
73 <#if cpCatalogEntry.getProductTypeName() ="simple" && (priceSimple.getUnitValue() > 0)>
74 <div class="block_price">
75 <#if priceSimple.getUnitValueOriginal() gt priceSimple.getUnitValue()>
76 <p class="price_old">${pricesService.formatValue(priceSimple.getUnitValueOriginal())}</p>
77 </#if>
78 <p class="price heading_80">${pricesService.formatValue(priceSimple.getUnitValue())}</p>
79 </div>
80 </#if>
81 </#if>
82 <div class="add_info content_text_small">
83 <p>
84 <svg class="svg-inline--fa fa-truck" aria-hidden="true" focusable="false" data-prefix="fas"
85 data-icon="truck" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"
86 data-fa-i2svg="">
87 <path fill="currentColor"
88 d="M368 0C394.5 0 416 21.49 416 48V96H466.7C483.7 96 499.1 102.7 512 114.7L589.3 192C601.3 204 608 220.3 608 237.3V352C625.7 352 640 366.3 640 384C640 401.7 625.7 416 608 416H576C576 469 533 512 480 512C426.1 512 384 469 384 416H256C256 469 213 512 160 512C106.1 512 64 469 64 416H48C21.49 416 0 394.5 0 368V48C0 21.49 21.49 0 48 0H368zM416 160V256H544V237.3L466.7 160H416zM160 368C133.5 368 112 389.5 112 416C112 442.5 133.5 464 160 464C186.5 464 208 442.5 208 416C208 389.5 186.5 368 160 368zM480 464C506.5 464 528 442.5 528 416C528 389.5 506.5 368 480 368C453.5 368 432 389.5 432 416C432 442.5 453.5 464 480 464z"></path>
89 </svg>
90
91 <@liferay_ui["message"] key="widget-template-product-detail-message-24h-shipping"/>
92 </p>
93 <p>
94 <svg class="svg-inline--fa fa-clock" aria-hidden="true" focusable="false" data-prefix="fas"
95 data-icon="clock" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"
96 data-fa-i2svg="">
97 <path fill="currentColor"
98 d="M256 512C114.6 512 0 397.4 0 256C0 114.6 114.6 0 256 0C397.4 0 512 114.6 512 256C512 397.4 397.4 512 256 512zM232 256C232 264 236 271.5 242.7 275.1L338.7 339.1C349.7 347.3 364.6 344.3 371.1 333.3C379.3 322.3 376.3 307.4 365.3 300L280 243.2V120C280 106.7 269.3 96 255.1 96C242.7 96 231.1 106.7 231.1 120L232 256z"></path>
99 </svg>
100 <@liferay_ui["message"] key="widget-template-product-detail-message-shipping-before"/>
101 </p>
102 </div>
103
104 <#if cpCatalogEntry.getProductTypeName() ="grouped">
105 <#attempt>
106 <div class="cantidad_compleja">
107 <div class="content_tabla_01">
108 <div class="table-responsive table_bti">
109 <table class="table table-hover">
110 <thead>
111 <#assign childCPDefinitionsGroupedEntries = groupedCPTypeHelper.getCPDefinitionGroupedEntry(commerceContext.getAccountEntry().getAccountEntryId(), commerceContext.getCommerceChannelGroupId(),cpCatalogEntry.getCPDefinitionId())>
112 <#assign diameterValues = {}>
113 <#assign lengthValuesHash = {}>
114 <#assign cPDefinitionsGroupedEntryHash = {}>
115 <#assign lengthValuesArray = []>
116 <#assign filterValues = {}>
117 <#assign childCpDefinitions = []>
118 <#assign error = false >
119 <#assign duplicateError = false>
120 <#list childCPDefinitionsGroupedEntries as cpDefinitionGroupedEntry>
121 <#assign childCpDefinitions = childCpDefinitions + [CPDefinitionLocalService.getCPDefinition(cpDefinitionGroupedEntry.getEntryCProduct().getPublishedCPDefinitionId())]>
122 <#assign CPDefinitionSpecificationOptionValuesChilds = CPDefinitionSpecificationOptionValueLocalService.getCPDefinitionSpecificationOptionValues(cpDefinitionGroupedEntry.getEntryCProduct().getPublishedCPDefinitionId(),0)>
123 <#list CPDefinitionSpecificationOptionValuesChilds as CPDefinitionSpecificationOptionValuesChild>
124 <#assign key = CPDefinitionSpecificationOptionValuesChild.getCPSpecificationOption().getKey()>
125 <#if key == "diameter">
126 <#assign diameterValues = diameterValues + {cpDefinitionGroupedEntry : CPDefinitionSpecificationOptionValuesChild.getValueCurrentValue()}>
127 </#if>
128 <#if key == "length">
129 <#assign lengthValuesHash = lengthValuesHash + {cpDefinitionGroupedEntry : CPDefinitionSpecificationOptionValuesChild.getValueCurrentValue()}>
130 <#assign cPDefinitionsGroupedEntryHash = cPDefinitionsGroupedEntryHash + {CPDefinitionSpecificationOptionValuesChild.getValueCurrentValue() : cpDefinitionGroupedEntry}>
131 <#assign lengthValuesArray = lengthValuesArray + [CPDefinitionSpecificationOptionValuesChild.getValueCurrentValue()]>
132 </#if>
133 <#if key == "filter">
134 <#assign filterValues = filterValues + {cpDefinitionGroupedEntry : CPDefinitionSpecificationOptionValuesChild.getValueCurrentValue()}>
135 </#if>
136 </#list>
137 </#list>
138 <#assign cpDefinitionGroupedEntrySorted = []>
139 <#if (lengthValuesArray?size > 0)>
140 <#assign lengthValuesArraySorted = lengthValuesArray?map(s -> s?number)?sort?map(s -> s?string)>
141 <#list lengthValuesArraySorted as length>
142 <#assign cpDefinitionGroupedEntrySorted = cpDefinitionGroupedEntrySorted + [cPDefinitionsGroupedEntryHash[length]]>
143 </#list>
144 </#if>
145 <#if (childCPDefinitionsGroupedEntries?size > 0)>
146 <tr>
147 <th scope="col">
148 <label class="checkbox">
149 <span class="sr-only"><@liferay_ui["message"] key="widget-template-product-detail-message-select-all"/></span>
150 <input type="checkbox" id="selectAllCheckBox"
151 onclick="toggleSelectAll()">
152 <span class="check"></span>
153 </label>
154 </th>
155 <th scope="col"><@liferay_ui["message"] key="widget-template-product-detail-message-reference"/></th>
156 <#if (diameterValues?size > 0)>
157 <th scope="col"><@liferay_ui["message"] key="widget-template-product-detail-message-diameter"/></th>
158 </#if>
159 <#if (lengthValuesArray?size > 0)>
160 <th scope="col"><@liferay_ui["message"] key="widget-template-product-detail-message-length"/></th>
161 </#if>
162 <#if (filterValues?size > 0)>
163 <th scope="col"><@liferay_ui["message"] key="widget-template-product-detail-message-type-of-restoration"/></th>
164 </#if>
165 <th scope="col"><@liferay_ui["message"] key="widget-template-product-detail-message-quantity"/> </th>
166 <#if themeDisplay.isSignedIn()>
167 <th scope="col"><@liferay_ui["message"] key="widget-template-product-detail-message-price"/> </th>
168 </#if>
169 </tr>
170 </#if>
171 </thead>
172 <tbody>
173 <#if themeDisplay.isSignedIn()>
174 <#assign pricesGrouped = pricesService.getPricesWithDiscount(childCpDefinitions, false, renderRequest.getAttribute("COMMERCE_CONTEXT"))>
175 </#if>
176 <#if (cpDefinitionGroupedEntrySorted?size > 0)>
177 <#assign cpDefinitionERC = [] />
178 <#assign duplicateError = false />
179
180 <#list cpDefinitionGroupedEntrySorted as cpDefitionGroupedEntry>
181 <#assign erc = cpDefitionGroupedEntry.getEntryCProduct().getExternalReferenceCode()>
182 <#if cpDefinitionERC?seq_contains(erc)>
183 <#assign duplicateError = true />
184 <#else>
185 <#assign cpDefinitionERC = cpDefinitionERC + [erc]>
186 </#if>
187 </#list>
188 <#if (duplicateError == false) >
189 <#assign childCPDefinitionsGroupedEntries = cpDefinitionGroupedEntrySorted>
190 </#if>
191 </#if>
192 <#list childCPDefinitionsGroupedEntries as cpDefinitionGroupedEntry>
193 <#assign
194 cProduct = cpDefinitionGroupedEntry.getEntryCProduct()
195 ExtRefCode = cProduct.getExternalReferenceCode()
196 CPDefinition = cpDefinitionGroupedEntry.getEntryCPDefinition()
197 CPDefinitionSpecificationOptionValuesChilds = CPDefinitionSpecificationOptionValueLocalService.getCPDefinitionSpecificationOptionValues(CPDefinition.getCPDefinitionId(),0)>
198 <tr>
199 <td>
200 <label class="checkbox">
201 <span class="sr-only"><@liferay_ui["message"] key="widget-template-product-detail-message-select"/></span>
202 <input type="checkbox" class="groupedItem"
203 data-atc="${CPDefinition.getCPInstances()[0].getCPInstanceId()}">
204 <span class="check"></span>
205 </label>
206 </td>
207 <td>${ExtRefCode}</td>
208 <#if (diameterValues?size > 0)>
209 <td>
210 <#if (diameterValues[cpDefinitionGroupedEntry]?has_content)>
211 ${diameterValues[cpDefinitionGroupedEntry]}
212 <#else>
213 ${"-"}
214 </#if>
215 </td>
216 </#if>
217 <#if (lengthValuesHash?size > 0)>
218 <td>
219 <#if (lengthValuesHash[cpDefinitionGroupedEntry]?has_content)>
220 ${lengthValuesHash[cpDefinitionGroupedEntry]}
221 <#else>
222 ${"-"}
223 </#if>
224 </td>
225 </#if>
226 <#if (filterValues?size > 0)>
227 <td>
228 <#if (filterValues[cpDefinitionGroupedEntry]?has_content)>
229 ${filterValues[cpDefinitionGroupedEntry]}
230 <#else>
231 ${"-"}
232 </#if>
233 </td>
234 </#if>
235 <td class="quantity atc${CPDefinition.getCPInstances()[0].getCPInstanceId()}">
236 <input max="10000" min="1" step=""
237 class="form-control form-control-md quantity-selector"
238 id="qty${CPDefinition.getCPInstances()[0].getCPInstanceId()}"
239 type="number" value="1">
240 </td>
241 <#if themeDisplay.isSignedIn()>
242 <td class="text_nowrap">
243 <#assign unitValue = pricesGrouped?values[cpDefinitionGroupedEntry?index].unitValue>
244 <#assign unitValueOriginal = pricesGrouped?values[cpDefinitionGroupedEntry?index].unitValueOriginal>
245 <#if (unitValue < unitValueOriginal)>
246 <span class="precio_old">
247 ${pricesService.formatValue(unitValueOriginal)}
248 </span>
249 <span class="precio_sale">
250 ${pricesService.formatValue(unitValue)}
251 </span>
252 <#else>
253 <span class="precio_sale">
254 ${pricesService.formatValue(unitValueOriginal)}
255 </span>
256 </#if>
257 </td>
258 </#if>
259 </tr>
260 </#list>
261 </tbody>
262 </table>
263 </div>
264 </div>
265 </div>
266 <#recover>
267 <p><@liferay_ui["message"] key="guided-purchase-message-product-not-available"/></p>
268 <#assign error = true >
269 </#attempt>
270 </div>
271
272 <#if cPDefinition1.getExpandoBridge().getAttribute("notes")?has_content && cPDefinition1.getExpandoBridge().getAttribute("notes") != '{"de":"","pt":"","en":"","it":"","fr":"","es":""}'>
273 <#attempt>
274 <#assign notes = cPDefinition1.getExpandoBridge().getAttribute("notes")?eval>
275 <div class="aviso">
276 <div class="content_text_small">
277 ${notes[locale?split("_")[0]]}
278 </div>
279 </div>
280 <#recover>
281 </#attempt>
282 </#if>
283
284 <#if themeDisplay.isSignedIn()>
285 <div class="actions_select" <#if cpCatalogEntry.getProductTypeName() ="grouped" && (childCPDefinitionsGroupedEntries?size = 0) || error> style="display: none"</#if> >
286 <div class="add-to-cart mb-2 lfr-tooltip-scope" id="addToCartButton">
287 <div class="add-to-cart-wrapper align-items-center d-flex flex-column">
288 <button class="mt-3 btn-md btn-add-to-cart btn btn-primary" type="button"
289 onclick="addToCart()">
290 <span class="text-truncate-inline">
291 <span class="text-truncate"><@liferay_ui["message"] key="widget-template-product-detail-message-add-to-cart"/></span>
292 </span>
293 <span class="cart-icon">
294 <svg class="lexicon-icon lexicon-icon-shopping-cart" role="presentation">
295 <use xlink:href="https://shop.bti-biotechnologyinstitute.com/o/bti-theme/images/clay/icons.svg#shopping-cart"></use>
296 </svg>
297 </span>
298 </button>
299 </div>
300 </div>
301 </div>
302 </#if>
303 <#elseif cpCatalogEntry.getProductTypeName() = "simple">
304 <#if cPDefinition1.getExpandoBridge().getAttribute("notes")?has_content && cPDefinition1.getExpandoBridge().getAttribute("notes") != '{"de":"","pt":"","en":"","it":"","fr":"","es":""}'>
305 <#attempt>
306 <#assign notes = cPDefinition1.getExpandoBridge().getAttribute("notes")?eval>
307 <div class="aviso">
308 <div class="content_text_small">
309 ${notes[locale?split("_")[0]]}
310 </div>
311 </div>
312 <#recover>
313 </#attempt>
314 </#if>
315 <#if themeDisplay.isSignedIn()>
316 <#if (priceSimple.getUnitValue() <= 0)>
317 <div class="actions_button">
318 <a href="#" class="button_first_small disabled">
319 <span class="text"><@liferay_ui["message"] key="widget-template-product-detail-message-product-not-available"/></span>
320 </a>
321 </div>
322 <#else>
323 <div class="actions_select">
324 <#if !blocked>
325 <@liferay_commerce_ui["add-to-cart"] CPCatalogEntry = cpCatalogEntry
326 cPInstanceId = CPDefinitionLocalService.getCPDefinition(cpCatalogEntry.CPDefinitionId).getCPInstances()[0].getCPInstanceId()
327 />
328 </#if>
329 </div>
330 </#if>
331 </#if>
332 </#if>
333 </div>
334 </div>
335 </section>
336
337 <#if cpCatalogEntry.getDescription()?has_content || CPDefinitionSpecificationOptionValues?has_content || cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications")?has_content && cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications") != '{"de":"","pt":"","en":"","it":"","fr":"","es":""}'>
338 <section class="tabs_info">
339 <div class="container">
340 <div id="accordion" class="content_tabs">
341 <ul class="list_tabs">
342 <#if cpCatalogEntry.getDescription()?has_content>
343 <li class="item">
344 <button class="button_tab" data-toggle="collapse" data-target="#tab-01"
345 aria-expanded="true"
346 aria-controls="tab-01">
347 <@liferay_ui["message"] key="widget-template-product-detail-message-description"/>
348 </button>
349 </li>
350 </#if>
351 <#if CPDefinitionSpecificationOptionValues?has_content && cpCatalogEntry.getProductTypeName() != "grouped">
352 <li class="item">
353 <button class="button_tab collapsed" data-toggle="collapse" data-target="#tab-02"
354 aria-expanded="false" aria-controls="tab-02">
355 <@liferay_ui["message"] key="widget-template-product-detail-message-specification"/>
356 </button>
357 </li>
358 </#if>
359 <#if cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications")?has_content && cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications") != '{"de":"","pt":"","en":"","it":"","fr":"","es":""}'>
360 <#attempt>
361 <#assign clinicalIndicationsJson = cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications")>
362 <#assign clinicalIndications = jsonFactoryUtil.createJSONObject(clinicalIndicationsJson)>
363 <li class="item">
364 <button class="button_tab collapsed" data-toggle="collapse" data-target="#tab-03"
365 aria-expanded="false" aria-controls="tab-03">
366 <@liferay_ui["message"] key="widget-template-product-detail-message-more-info"/>
367 </button>
368 </li>
369 <#recover>
370 </#attempt>
371 </#if>
372 </ul>
373
374 <div id="tab-01" class="content_tab collapse show" aria-labelledby="tab-01"
375 data-parent="#accordion">
376 <div class="content_tab">
377 <div class="content_text_small">
378 <#if cpCatalogEntry.getDescription()?has_content>
379 <p>${cpCatalogEntry.getDescription()}</p>
380 </#if>
381 </div>
382 </div>
383 </div>
384 <#if CPDefinitionSpecificationOptionValues?has_content >
385 <div id="tab-02" class="content_tab collapse" aria-labelledby="tab-02"
386 data-parent="#accordion">
387 <div class="content_tab">
388 <div class="content_text_small table-responsive table_bti">
389 <table class="table table-hover">
390 <thead>
391 <tr>
392 <th scope="col"><@liferay_ui["message"] key="widget-template-product-detail-message-description"/></th>
393 <th scope="col"
394 style="text-align: right"><@liferay_ui["message"] key="widget-template-product-detail-message-value"/></th>
395 </tr>
396 </thead>
397 <tbody>
398 <#assign textValue = "">
399 <#list CPDefinitionSpecificationOptionValues as CPDefinitionSpecificationOptionValue>
400 <#if textValue = "">
401 <#assign textValue = CPDefinitionSpecificationOptionValue.getValueCurrentValue()>
402 </#if>
403 <#if CPDefinitionSpecificationOptionValue_index < CPDefinitionSpecificationOptionValues?size-1 >
404 <#assign nextCPDefinitionSpecificationOptionValue = CPDefinitionSpecificationOptionValues[CPDefinitionSpecificationOptionValue_index + 1]>
405 <#if CPDefinitionSpecificationOptionValue.getCPSpecificationOption().getTitleCurrentValue() = nextCPDefinitionSpecificationOptionValue.getCPSpecificationOption().getTitleCurrentValue() >
406 <#assign textValue = textValue +", "+ nextCPDefinitionSpecificationOptionValue.getValueCurrentValue()>
407 <#else>
408 <tr>
409 <td>
410 ${CPDefinitionSpecificationOptionValue.getCPSpecificationOption().getTitleCurrentValue()}
411 </td>
412 <td style="text-align: right">
413 ${textValue}
414 </td>
415 </tr>
416 <#assign textValue = "">
417 </#if>
418 <#else>
419 <tr>
420 <td>
421 ${CPDefinitionSpecificationOptionValue.getCPSpecificationOption().getTitleCurrentValue()}
422 </td>
423 <td style="text-align: right">
424 ${textValue}
425 </td>
426 </tr>
427 </#if>
428
429 </#list>
430
431 </tbody>
432 </table>
433
434 </div>
435 </div>
436 </div>
437 </#if>
438 <#if cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications")?has_content && cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications") != '{"de":"","pt":"","en":"","it":"","fr":"","es":""}'>
439 <#attempt>
440 <#assign clinicalIndicationsJson = cPDefinition1.getExpandoBridge().getAttribute("clinicalIndications")>
441 <#assign clinicalIndications = jsonFactoryUtil.createJSONObject(clinicalIndicationsJson)>
442 <div id="tab-03" class="content_tab collapse" aria-labelledby="tab-03"
443 data-parent="#accordion">
444 <div class="content_tab">
445 <div class="content_text_small">
446 <p><@liferay_ui["message"] key="widget-template-product-detail-message-clinical-indication"/>
447 :
448 <#assign localeParts = locale?split("_")>
449 <#assign shortLocale = localeParts[0]>
450 ${clinicalIndications[shortLocale]}</p>
451 </div>
452 </div>
453 </div>
454 <#recover>
455 </#attempt>
456 </#if>
457 </div>
458 </div>
459 </section>
460 </#if>
461</div>
462
463<script>
464 var isBusy = false;
465 var skus = [];
466
467 function addToCart() {
468 isBusy = false;
469 var time = 0;
470 var noProductos = 0;
471
472 $.each($(".groupedItem"), function () {
473 //var selector = ".atc" + $(this).attr("data-atc") + "> .add-to-cart > .add-to-cart-wrapper > button";
474 if ($(this).is(":checked")) {
475 var sku = $(this).attr("data-atc")
476 skus.push(sku);
477 }
478 });
479
480 console.log(skus);
481 if (skus.length === 0) {
482 return;
483 }
484
485 addToCartCall()
486 }
487
488 async function addToCartCall() {
489 if (skus.length === 0) {
490 console.log("No hay productos seleccionados");
491 return; // No hacer nada ni mostrar alert
492 }
493 let myHeaders = new Headers();
494 myHeaders.append("Content-Type", "application/json");
495 myHeaders.append("Cookie", "${jsessionId}");
496 myHeaders.append("x-csrf-token", Liferay.authToken);
497
498 for (const skuId of skus) {
499 var quantity = $("#qty" + skuId).val();
500
501 console.log("skuIdR:" + skuId);
502 console.log("qty:" + quantity);
503 var body = JSON.stringify({"options": "[]", "skuId": skuId, "quantity": quantity});
504
505 let requestOptions = {
506 method: 'POST',
507 headers: myHeaders,
508 body: body,
509 redirect: 'follow'
510 };
511
512 console.log(body);
513 const response = await fetch("/o/headless-commerce-delivery-cart/v1.0/carts/" + ${commerceOrderId} + "/items/", requestOptions);
514 const data = await response.json();
515 console.log(data);
516 }
517
518 alert("Productos agregados")
519 }
520
521 $(document).ready(function () {
522 updateAddToCartButton();
523 $('.groupedItem').change(function () {
524 var allSelected = true;
525
526 if ($(this).prop("checked") == false) {
527 $('#selectAllCheckBox').prop('checked', false);
528 } else {
529 $.each($('.groupedItem'), function (i, l) {
530 allSelected = $(l).is(':checked') && allSelected;
531 });
532 $("#selectAllCheckBox").prop('checked', allSelected);
533 }
534 updateAddToCartButton();
535 });
536 });
537
538 function toggleSelectAll() {
539 $(".groupedItem").prop('checked', $("#selectAllCheckBox").is(':checked'));
540 updateAddToCartButton();
541 }
542
543 function updateAddToCartButton() {
544 var hasSelected = false;
545 $.each($('.groupedItem'), function () {
546 if ($(this).is(':checked')) {
547 hasSelected = true;
548 return false;
549 }
550 });
551
552 $('#addToCartButton button').prop('disabled', !hasSelected);
553 if (hasSelected) {
554 $('#addToCartButton button').removeClass('disabled');
555 } else {
556 $('#addToCartButton button').addClass('disabled');
557 }
558 }
559
560 var step = 100;
561
562 var countDownDate = new Date();
563 countDownDate.setUTCHours(16);
564 countDownDate.setUTCMinutes(0);
565
566 setCountDownDate();
567 setInterval(function () {
568 setCountDownDate()
569 }, 60000);
570
571 function setCountDownDate() {
572 let nowUser = new Date(); // 1:45
573 let nowMadrid = new Date(new Date().toLocaleString("en-US", {timeZone: "Europe/Madrid"}));
574 let countDownDate = new Date(nowMadrid);
575 countDownDate.setHours(17, 0, 0, 0);
576
577 let distance = countDownDate.getTime() - nowMadrid.getTime();
578
579 if (distance < 0) {
580 countDownDate.setDate(countDownDate.getDate() + 1);
581 distance = countDownDate.getTime() - nowMadrid.getTime();
582 }
583
584 let hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); //15:15
585 let minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
586
587 let userHours = nowUser.getHours();
588 let userMinutes = nowUser.getMinutes();
589
590 if (userHours >= 17) {
591 let diff = userHours - nowMadrid.getHours();
592 if ((17 + diff) > 24) {
593 $("#hours").text((24 - (17 + diff)).toString().substring(1) + ":00");
594 } else {
595 $("#hours").text((17 + diff) + ":00");
596 }
597 } else {
598 if (userMinutes > 0 || minutes > 0) {
599 userHours++;
600 }
601 $("#hours").text(userHours + hours + ":00");
602 }
603 $("#countdown").text(hours + "h " + minutes + "m");
604 }
605
606</script>