templates/Shop/ProductDetails/productDetail.html.twig line 1

Open in your IDE?
  1. {# @var product \AppBundle\Model\DefaultProduct #}
  2. {# @var marca \AppBundle\Model\DefaultMarca #}
  3. {% extends 'layout/layout.html.twig' %}
  4. {% block CONTENT %}
  5.     {# Define authentication variable #}
  6.     {% set is_authenticated = is_granted('IS_AUTHENTICATED_FULLY') %}
  7.     {# Check if there is an error in the product #}
  8.     {% set haveProductErrors = app_product_haveError(product) %}
  9.     {% if haveProductErrors %}
  10.         {% set haveDiscount =  false %}
  11.     {% else %}
  12.         {% if is_authenticated %}
  13.             {#  START PRICE WITH DISCOUNT BLOCK  #}
  14.             {% set defaultPriceWithDiscount = app_product_default_price_with_discount(product, userIdSage) %}
  15.             {% set haveDiscount = defaultPriceWithDiscount.original_price != defaultPriceWithDiscount.end_price  and defaultPriceWithDiscount.error is null and defaultPriceWithDiscount.end_price is not null %}
  16.             {#  END PRICE WITH DISCOUNT BLOCK  #}
  17.         {% endif %}
  18.     {% endif %}
  19.     {% set data = app_product_generate_data(product) %}
  20.     {% set variants = data.variants %}
  21. {#    {% set tableAttributes = app_product_variants_attributes(data) %}#}
  22.     {% set SKU = false %}
  23. {#    {{ dump(app_product_unpublished_variants_check(product)) }}#}
  24.     {#   Does it have variants?#}
  25.     {% if ( ( data.variants | length ) > 1 )  %}
  26.         {% set haveVariants =  true %}
  27.     {% else %}
  28.         {% set haveVariants = false %}
  29.         {% set SKU = ( data.variants | first ) %}
  30.         {% set SKU = SKU.bsncode %}
  31.     {% endif %}
  32.     {% set productID = (data.variants | first).id %}
  33.     {% set defaultPrice = app_product_default_price(product) %}
  34.     {% set attributesRows = app_product_attributes_rows(product, data) %}
  35.     {% set typesRows = app_product_types_rows(product, data) %}
  36.     {% set documents = app_product_documents(product) %}
  37.     {% set link = product.getDetailUrl({'document': document, 'prefix':app.request.locale}) %}
  38.     {% set title = product.getName() %}
  39.     {% set empresa = pimcore_website_config('empresa') %}
  40.     {% set titlePostFix = empresa.getTitle() %}
  41.     {% do pimcore_head_title().set(title ~ ' :: ' ~ titlePostFix) %}
  42.     {% if product.getSeodescription is not empty %}
  43.         {% do pimcore_head_meta().appendName('description', product.getSeodescription()) %}
  44.     {% endif %}
  45.     {% do pimcore_head_link({rel: 'canonical', href: app.request.schemeAndHttpHost ~ link }) %}
  46.                 <!--Breadcrumbs-->
  47.             {% set lang = app.request.getLocale() %}
  48.             <input type="hidden" class="lang" lang="{{ lang }}">
  49.                 <div class="breadcrumbs-wrapper text-uppercase">
  50.                     <div class="container">
  51.                         <div class="breadcrumbs"><a href="{{navStartNode}}" title="{{ 'general.content.back_home_translations' |trans }}">{{ 'general.content.breadcrumbs_home_translations' |trans }}</a><span>|</span><span class="fw-bold">{{ 'product_detail.content.breadcrumbs_product_detail_translations' |trans }}</span></div>
  52.                     </div>
  53.                 </div>
  54.                 <!--End Breadcrumbs-->
  55.                 <!--Main Content-->
  56.                 <div class="container">
  57.                     <!--Product Content-->
  58.                     <div class="product-single">
  59.                         <div class="row">
  60.                             <div class="col-lg-6 col-md-6 col-sm-12 col-12">
  61.                                 {% set image = product.getFirstImageAsset() %}
  62.                                 {% set hasVariantKits = product.hasVariantKits() %}
  63.                                 <div class="product-details-img product-details-img-indaba product-horizontal-style clearfix mb-3 mb-md-0">
  64.                                     <div class="zoompro-wrap product-zoom-right product-zoom-right-indaba w-100 p-0">
  65.                                         {% if image is not null %}
  66.                                         <div class="kit-icon-container-product {% if not kit and not hasVariantKits %} d-none {% endif%}" id="previewKitIcon">
  67.                                             <img src="{{ asset(pimcore_asset_by_path('/iconos/kit-icon.png').thumbnail('IconKit')) }}">
  68.                                         </div>
  69.                                         <div class="zoompro-span img-father"><img class="img-product" id="zoompro" {# class="zoompro" #} src="{{ image.thumbnail('ProductImages') }}" data-zoom-image="" alt="product" /></div>
  70.                                         {% endif %}
  71.                                     </div>
  72.                                 </div>
  73.                             </div>
  74.                             <div class="col-lg-6 col-md-6 col-sm-12 col-12 product-info-container">
  75.                                 <!-- Product Info -->
  76.                                 <div class="product-single__meta">
  77.                                     {% if product.getName is not empty %}
  78.                                         <h1 class="product-single__title">{{ product.getName }}</h1>
  79.                                     {% endif %}
  80.                                     <!-- Product Info -->
  81.                                     {% if is_authenticated %}
  82.                                     <div class="prInfoRow product-info mt-2 d-flex-wrap">
  83.                                         <p class="product-sku fs-6" style="display: {{ (haveVariants) ? 'none' : '' }};">SKU: <span class="variant-sku">{{ SKU}}</span></p>
  84.                                     </div>
  85.                                     {% endif %}
  86.                                     <!-- End Product Info -->
  87.                                     <!-- Product Price -->
  88.                                     {% if is_authenticated %}
  89.                                         <div class="product-single__price pb-1">
  90.                                             <p class="spacing fs-6 fw-bold" style="display: {{ (haveVariants) ? 'inline' : 'none' }};">{{ lang == 'en' ? 'FROM: ' : 'DESDE: ' }}</p>
  91.                                             <span class="visually-hidden">Regular price</span>
  92.                                             <span class="product-price__sale--single">
  93.                                                 {% set originalPrice = haveDiscount ? defaultPriceWithDiscount.original_price : defaultPrice %}
  94.                                                 {% set endPrice = haveDiscount ? defaultPriceWithDiscount.end_price : defaultPrice %}
  95.                                                 {% set discountAmount = defaultPriceWithDiscount.original_price - defaultPriceWithDiscount.end_price %}
  96.                                                 {% set displayClass = haveDiscount ? '' : 'd-none' %}
  97.                                                 {% set displayClassPercent = defaultPriceWithDiscount.discount != '.00' ? '': 'd-none' %}
  98.                                                  <span class="product-price-old-price {{ displayClass }}">
  99.                                                     {{ app_helper_price_format_spain(originalPrice) }}€
  100.                                                 </span>
  101.                                                 <span class="product-price__price product-price__sale">
  102.                                                     {{ app_helper_price_format_spain(endPrice) }}€
  103.                                                 </span>
  104.                                                  <span class="discount-badge {{ displayClass }}">
  105.                                                         <span class="devider me-2">|</span>
  106.                                                         <span>{{ 'Descuento' | trans }}:</span>
  107.                                                         <span class="product-single__save-amount">
  108.                                                             <span class="money">{{ app_helper_price_format_spain(discountAmount) }}€</span>
  109.                                                         </span>
  110.                                                         <span class="off ms-1 percentage-span {{ displayClassPercent }}">(<span class="percentage">{{ defaultPriceWithDiscount.discount is not null ?  app_helper_price_format_spain(defaultPriceWithDiscount.discount): '' }}</span>%)</span>
  111.                                                     </span>
  112.                                             </span>
  113.                                         </div>
  114.                                         <!-- End Product Price -->
  115.                                     {% else %}
  116.                                         {# if product have propspeed brand hide price #}
  117.                                         {% if product.marca == 15663 %}
  118.                                             <div class="product-single__price pb-1">
  119.                                                 <span class="visually-hidden"></span>
  120.                                                 <span class="product-price__price product-price__sale"></span>
  121.                                             </div>
  122.                                         {% else %}
  123.                                             <div class="product-single__price pb-1">
  124.                                                     <p class="spacing fs-6 fw-bold" style="display: {{ (haveVariants) ? 'inline' : 'none' }};">{{ lang == 'en' ? 'FROM: ' : 'DESDE: ' }}</p>
  125.                                                 <span class="visually-hidden">Regular price</span>
  126.                                                 <span class="product-price__price product-price__sale">
  127.                                                         {{ app_helper_price_format_spain(defaultPrice) }}€
  128.                                                     </span>
  129.                                             </div>
  130.                                         {% endif %}
  131.                                     {% endif %}
  132.                                 </div>
  133.                                 <!-- End Product Info -->
  134.                                 {% set longDescription = product.getLongdescription() %}
  135.                                 {% set shortDescription = product.getShortdescription() %}
  136.                                 {% set description = shortDescription is not empty ? shortDescription : longDescription %}
  137.                                 <div class="product-single__description rte">
  138.                                     {% if description matches '/<[^>]+>/' %}
  139.                                         <div class="mb-2 fs-6">
  140.                                             {% for paragraph in description | split('</p>') %}
  141.                                                 {% if paragraph | trim %}
  142.                                                     {{ paragraph | trim | raw }}</p>
  143.                                                 {% endif %}
  144.                                             {% endfor %}
  145.                                         </div>
  146.                                     {% else %}
  147.                                         <p class="mb-2 fs-6">{{ description | nl2br | raw }}</p>
  148.                                     {% endif %}
  149.                                     <div id="featuresContainer" class="{{ (kit and is_authenticated) ? '': 'd-none'}}">
  150.                                         {% if kit and is_authenticated%}
  151.                                             {% set kitTotalPrice = endPrice %}
  152.                                             <div class="border rounded-1 p-3">
  153.                                                 <div class="kit-icon-container">
  154.                                                     <img src="{{ asset(pimcore_asset_by_path('/iconos/kit-icon.png').thumbnail('IconKit')) }}">
  155.                                                 </div>
  156.                                                 <div class="row">
  157.                                                     <div class="col-9">
  158.                                                         <h3 class="mb-4" style="color: #e95144; margin-right: 30px;">{{ 'product_detail.content.kit_product_disclaimer_translations'| trans }}</h3>
  159.                                                         {% for kitProduct in kit %}
  160.                                                                 {% set defaultPriceWithDiscount = app_product_default_price_with_discount(kitProduct, userIdSage) %}
  161.                                                                 {% set haveDiscount = defaultPriceWithDiscount.original_price != defaultPriceWithDiscount.end_price  and defaultPriceWithDiscount.error is null and defaultPriceWithDiscount.end_price is not null %}
  162.                                                                 {% set defaultPrice = app_product_default_price(kitProduct) %}
  163.                                                             <div class="row" style="margin-left: 20px">
  164.                                                                 <div class="col-3">
  165.                                                                 {% set imagekit = kitProduct.getFirstImageAsset() %}
  166.                                                                 <div class="product-details-img product-details-img-indaba product-horizontal-style clearfix mb-3 mb-md-0">
  167.                                                                     <div class="zoompro-wrap product-zoom-right product-zoom-right-indaba w-100 p-0">
  168.                                                                         {% if imagekit is not null %}
  169.                                                                             <div class="zoompro-span"><img class="img-product" id="zoompro"  style="max-width: 120px" {# class="zoompro" #} src="{{ imagekit.thumbnail('ProductImages') }}" data-zoom-image="" alt="product" /></div>
  170.                                                                         {% endif %}
  171.                                                                     </div>
  172.                                                                 </div>
  173.                                                             </div>
  174.                                                                 <div class="col-9 product-info-container">
  175.                                                                 <div class="product-single__meta" style="margin-bottom: 0">
  176.                                                                 {% if kitProduct.getName is not empty %}
  177.                                                                     <h1 class="product-single__title">{{ kitProduct.getName }}</h1>
  178.                                                                 {% endif %}
  179.                                                                 <!-- Product Info -->
  180.                                                                 <div class="prInfoRow product-info mt-2 d-flex-wrap">
  181.                                                                     <p class="product-sku fs-6">SKU: <span class="variant-sku">{{ SKU}}</span></p>
  182.                                                                 </div>
  183.                                                                 <!-- End Product Info -->
  184.                                                                 <!-- Product Price -->
  185.                                                                 {% if is_authenticated %}
  186.                                                                     <div class="product-single__price pb-1">
  187.                                                                         <p class="spacing fs-6 fw-bold" style="display: {{ (haveVariants) ? 'inline' : 'none' }};">{{ lang == 'en' ? 'FROM: ' : 'DESDE: ' }}</p>
  188.                                                                         <span class="visually-hidden">Regular price</span>
  189.                                                                         <span class="product-price__sale--single">
  190.                                                                 {% set originalPrice = haveDiscount ? defaultPriceWithDiscount.original_price : defaultPrice %}
  191.                                                                             {% set productKitEndPrice = haveDiscount ? defaultPriceWithDiscount.end_price : defaultPrice %}
  192.                                                                             {% set discountAmount = defaultPriceWithDiscount.original_price - defaultPriceWithDiscount.end_price %}
  193.                                                                             {% set displayClass = haveDiscount ? '' : 'd-none' %}
  194.                                                                             {% set displayClassPercent = defaultPriceWithDiscount.discount != '.00' ? '': 'd-none' %}
  195.                                                                             {% set kitTotalPrice = kitTotalPrice + productKitEndPrice %}
  196.                                                                  <span class="product-price-old-price {{ displayClass }}">
  197.                                                                     {{ app_helper_price_format_spain(originalPrice) }}€
  198.                                                                 </span>
  199.                                                                 <span class="product-price__price product-price__sale">
  200.                                                                     {{ app_helper_price_format_spain(productKitEndPrice) }}€
  201.                                                                 </span>
  202.                                                                  <span class="discount-badge {{ displayClass }}">
  203.                                                                         <span class="devider me-2">|</span>
  204.                                                                         <span>{{ 'Descuento' | trans }}:</span>
  205.                                                                         <span class="product-single__save-amount">
  206.                                                                             <span class="money">{{ app_helper_price_format_spain(discountAmount) }}€</span>
  207.                                                                         </span>
  208.                                                                         <span class="off ms-1 percentage-span {{ displayClassPercent }}">(<span class="percentage">{{ defaultPriceWithDiscount.discount is not null ?  app_helper_price_format_spain(defaultPriceWithDiscount.discount): '' }}</span>%)</span>
  209.                                                                     </span>
  210.                                                             </span>
  211.                                                                     </div>
  212.                                                                     <!-- End Product Price -->
  213.                                                                 {% else %}
  214.                                                                     {# if product have propspeed brand hide price #}
  215.                                                                     {% if kitProduct.marca == 15663 %}
  216.                                                                         <div class="product-single__price pb-1">
  217.                                                                             <span class="visually-hidden"></span>
  218.                                                                             <span class="product-price__price product-price__sale"></span>
  219.                                                                         </div>
  220.                                                                     {% else %}
  221.                                                                         <div class="product-single__price pb-1">
  222.                                                                             <p class="spacing fs-6 fw-bold" style="display: {{ (haveVariants) ? 'inline' : 'none' }};">{{ lang == 'en' ? 'FROM: ' : 'DESDE: ' }}</p>
  223.                                                                             <span class="visually-hidden">Regular price</span>
  224.                                                                             <span class="product-price__price product-price__sale">
  225.                                                                         {{ app_helper_price_format_spain(defaultPrice) }}€
  226.                                                                     </span>
  227.                                                                         </div>
  228.                                                                     {% endif %}
  229.                                                                 {% endif %}
  230.                                                             </div>
  231.                                                             </div>
  232.                                                             </div>
  233.                                                         {% endfor %}
  234.                                                         <div class="fs-5 mt-4 text-end">
  235.                                                             {{ 'product_detail.content.product_total_price_translations' | trans | upper }}:
  236.                                                             <span style="color: #e95144;">{{ app_helper_price_format_spain(kitTotalPrice) }}€</span>
  237.                                                         </div>
  238.                                                     </div>
  239.                                                 </div>
  240.                                             </div>
  241.                                         {% endif %}
  242.                                     </div>
  243.                                     <ul class="checkmarkList {{ (kit and is_authenticated) ? 'd-none': ''}}" id="parentFeatures">
  244.                                         {% if attributesRows | length > 0 or typesRows | length > 0 %}
  245.                                             <table class="table table-striped">
  246.                                                 {% for row in attributesRows %}
  247.                                                     {{ row | raw }}
  248.                                                 {% endfor %}
  249.                                                 {% for row in typesRows %}
  250.                                                     {{ row | raw }}
  251.                                                 {% endfor %}
  252.                                             </table>
  253.                                         {% endif %}
  254.                                     </ul>
  255.                                 </div>
  256.                                 <!-- Product Form -->
  257.                                 <form method="post" action="#" class="product-form form-bordered hidedropdown">
  258.                                     <!-- Product Action -->
  259.                                     <div class="product-action w-100 clearfix">
  260.                                         {% if is_authenticated %}
  261.                                             <div class="product-form__item--quantity d-flex-center mb-2">
  262.                                                 <div class="qtyField d-none" id="{{ productID }}">
  263.                                                     <a class="qtyBtn minus" href="javascript:void(0);"><i class="icon an an-minus-r" aria-hidden="true"></i></a>
  264.                                                     <input type="text" name="quantity" value="1" class="product-form__input qty rounded-0">
  265.                                                     <a class="qtyBtn plus" href="javascript:void(0);"><i class="icon an an-plus-r" aria-hidden="true"></i></a>
  266.                                                 </div>
  267.                                                 <div class="pro-stockLbl d-flex">
  268.                                                     <span class=" stockLbl instock fs-6 d-none ms-3"  title="Click para ver info"><i class="icon an an-check-cil"></i><span class="stockText">En stock <span class="items"></span></span></span>
  269.                                                     <span class=" stockLbl outstock infostock fs-6 d-none ms-3" title="Click para ver info"><i class="icon an an-times-cil"></i>
  270.                                                         <span>{{ 'product_detail.content.not_available' | trans }}</span>
  271.                                                     </span>
  272.                                                     <span class=" stockLbl preorder nostock infostock fs-6 d-none ms-3" title="Click para ver info"><i class="icon an an-clock-r"></i><span class="differenceText"> Pre-order Now</span></span>
  273.                                                     <span><i class="an an-info-cil fa-beat icon-info infostock ms-1 d-none" style="color: #0a53be"></i></span>
  274.                                                     <span class=" stockLbl preorder deliveryTime  infostock fs-6 d-none ms-3" title="Click para ver info"><i class="icon an an-truck-l"></i><span class="deliveryTimeText">En Llegar</span></span>
  275.                                                 </div>
  276.                                             </div>
  277.                                             <div class="pro-stockLbl info-stock-container">
  278.                                                 <span class="stock-warehouse stock-animation mb-3 {{ haveVariants ? 'd-none':'' }}">{{'product.detail-stock_by_warehouse' | trans}}</span>
  279.                                                 <div class="stock-info-container"></div>
  280.                                             </div>
  281.                                         {% endif %}
  282.                                         {% if haveVariants %}
  283.                                             <div class="product-form__item--submit">
  284.                                                 <a href="#sizechart" class="sizelink link-underline text-uppercase ms-auto text-decoration-none">
  285.                                                     <i class="icon an an-ruler d-none"></i>
  286.                                                     <button id="btnTableVariants" type="submit" name="add" class="btn rounded btn-outline-primary product-form__cart-submit">
  287.                                                             <span>{{ 'product_detail.content.variants_table_header_translations' |trans }}</span>
  288.                                                     </button>
  289.                                                 </a>
  290.                                             </div>
  291.                                         {% endif %}
  292.                                         <div class="product-form__item--buyit clearfix add-item-cart d-none" id="">
  293.                                             <button type="button" class="btn rounded proceed-to-checkout" id="addToCartBtn">
  294.                                                 {% if lang == 'en' %}
  295.                                                     <span>Add to Cart</span>
  296.                                                 {% else %}
  297.                                                     <span>Agregar al carrito</span>
  298.                                                 {% endif %}
  299.                                             </button>
  300.                                         </div>
  301.                                     </div>
  302.                                     <!-- End Product Action -->
  303.                                 </form>
  304.                                 <!-- End Product Form -->
  305.                             </div>
  306.                         </div>
  307.                     </div>
  308.                     {# Product Bundle Button #}
  309.                     {% if  is_authenticated %}
  310.                     <!-- Modal -->
  311.                     <div class="modal fade" id="relatedProducts-modal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  312.                         <div class="modal-dialog modal-lg">
  313.                             <div class="modal-content">
  314.                                 <div class="modal-body">
  315.                                     {% set dataRelatedProducts = [] %}
  316.                                     {% set variantsRelatedProducts = [] %}
  317.                                     {% set showCapacityColumn = false %}
  318.                                     {% set showColorColumn = false %}
  319.                                     {% for relatedProduct in relatedProducts %}
  320.                                         {% set dataRelatedProducts = app_product_generate_data(relatedProduct) %}
  321.                                         {% set variantsRelatedProducts = variantsRelatedProducts|merge(dataRelatedProducts.variants) %}
  322.                                         {% if dataRelatedProducts.attributes['capacidad'] is defined and dataRelatedProducts.attributes['capacidad'].value is not empty %}
  323.                                             {% set showCapacityColumn = true %}
  324.                                         {% endif %}
  325.                                         {% if dataRelatedProducts.attributes['color'] is defined and dataRelatedProducts.attributes['color'].value is not empty %}
  326.                                             {% set showColorColumn = true %}
  327.                                         {% endif %}
  328.                                     {% endfor %}
  329.                                     {% if relatedProducts | length > 0 %}
  330.                                         <table class="table table-bordered border-primary product-related-table">
  331.                                             <thead>
  332.                                             <tr>
  333.                                                 <th class="text-center align-middle">{{ 'nombre' | trans }}</th>
  334.                                                 <th class="text-center align-middle">{{ 'imagen' | trans }}</th>
  335.                                                 {% if showCapacityColumn %}
  336.                                                     <th class="text-center align-middle">{{ 'capacidad' | trans }}</th>
  337.                                                 {% endif %}
  338.                                                 {% if showColorColumn %}
  339.                                                     <th class="text-center align-middle">{{ 'Color' | trans }}</th>
  340.                                                 {% endif %}
  341.                                                 <th class="text-center align-middle">{{ 'importe' | trans }}</th>
  342.                                                 <th class="text-center align-middle">{{ 'accion' | trans }}</th>
  343.                                             </tr>
  344.                                             </thead>
  345.                                             <tbody>
  346.                                             {% for variantRelatedProduct in variantsRelatedProducts %}
  347.                                                 {% set imageVariant = variantRelatedProduct.getFirstImageAsset() %}
  348.                                                 {% set endPrice = variantRelatedProduct.price %}
  349.                                                 {% set variantAttributes = app_product_generate_data(variantRelatedProduct).attributes %}
  350.                                                 <tr>
  351.                                                     <td class="text-center align-middle">{{ variantRelatedProduct.name }}</td>
  352.                                                     <td class="text-center align-middle">
  353.                                                         <img class="img-product" id="zoompro" width="50px" height="50px"
  354.                                                              src="{{ imageVariant.thumbnail('ProductImages') }}" alt="product" />
  355.                                                     </td>
  356.                                                     {% if showCapacityColumn %}
  357.                                                         <td class="text-center align-middle">
  358.                                                             {% set capacidadValue = variantAttributes['capacidad'].value %}
  359.                                                             {% if capacidadValue is not empty %}
  360.                                                                 {{ capacidadValue|first|raw }}
  361.                                                             {% endif %}
  362.                                                         </td>
  363.                                                     {% endif %}
  364.                                                     {% if showColorColumn %}
  365.                                                         <td class="text-center align-middle">
  366.                                                             {{ variantAttributes['color'].value | default('') }}
  367.                                                         </td>
  368.                                                     {% endif %}
  369.                                                     <td class="text-center align-middle">{{ app_helper_price_format_spain(endPrice) }}€</td>
  370.                                                     <td class="text-center align-middle">
  371.                                                         <button class="btn btn-primary rounded btn-add-product deselected"
  372.                                                                 id="{{ variantRelatedProduct.id }}">
  373.                                                             {{ 'seleccionar' | trans }}
  374.                                                         </button>
  375.                                                     </td>
  376.                                                 </tr>
  377.                                             {% endfor %}
  378.                                             </tbody>
  379.                                         </table>
  380.                                     {% endif %}
  381.                                 </div>
  382.                                 <div class="modal-footer">
  383.                                     <button type="button" class="btn btn-secondary rounded close-modal-of-related-products" data-bs-dismiss="modal">{{ 'no-gracias' | trans }}</button>
  384.                                     <button type="button" class="btn btn-primary rounded add-ids-of-products" data-bs-dismiss="modal" disabled>{{ 'product_detail.content.button_text_translations' | trans  }} </button>
  385.                                 </div>
  386.                             </div>
  387.                         </div>
  388.                     </div>
  389.                     {% endif %}
  390.                     {# Product Bundle Button #}
  391.                     <!--Product Tabs-->
  392.                     {% include 'Shop/includes/documentsbuttons.html.twig' %}
  393.                     <!--End Product Tabs-->
  394.                 </div>
  395.                 <!--End Container-->
  396.     {% if relatedProducts | length > 0 %}
  397.         <!--You May Also Like Products-->
  398.         <section class="section product-slider pb-2">
  399.             <div class="container">
  400.                 <div class="row">
  401.                     <div class="section-header col-12">
  402.                         <h2 class="text-transform-none">{{ 'product_detail.content.title_related_products_translations' |trans }}</h2>
  403.                     </div>
  404.                 </div>
  405.                 {% include 'Shop/includes/relatedproducts.html.twig' %}
  406.             </div>
  407.         </section>
  408.         <!--End You May Also Like Products-->
  409.     {% endif %}
  410.     <!--Recently Viewed Products-->
  411.     {% if lastVisitedProducts | length > 1 %}
  412.         {% include 'Shop/includes/recentlyViewedProducts.html.twig' %}
  413.     {% endif %}
  414.     <!--End Recently Viewed Products-->
  415.     <!--Size Chart-->
  416.     {% include 'Shop/includes/articletable2.html.twig' %}
  417.     <!--End Size Chart-->
  418.     <!--Scoll Top-->
  419.     <span id="site-scroll"><i class="icon an an-chevron-up"></i></span>
  420.     <!--End Scoll Top-->
  421. {% endblock %}
  422. {% block PAGE_JS %}
  423.     {% set is_authenticated = is_granted('IS_AUTHENTICATED_FULLY') %}
  424.     {% set data = app_product_generate_data(product) %}
  425.     {% set variants = data.variants %}
  426. {#    {% set tableAttributes = app_product_variants_attributes(data) %}#}
  427.     {% set haveProductErrors = 0 %}
  428.     {# CHECK IF THE PRODUCT HAVE ERRORS #}
  429.     {% if is_authenticated %}
  430.         {% set haveProductErrors = app_product_haveError(product) %}
  431.         {# This is just so that js understand the boolean value   #}
  432.         {% if haveProductErrors %}
  433.             {% set haveProductErrors = 1 %}
  434.         {% else %}
  435.             {% set haveProductErrors = 0 %}
  436.         {% endif %}
  437.     {% endif %}
  438.     {% set companyMail = company.mail %}
  439.     {% if ( ( data.variants | length ) > 1 )  %}
  440.         {% set haveVariants =  1 %}
  441.     {% else %}
  442.         {% set haveVariants = 0 %}
  443.     {% endif %}
  444.     {% if is_authenticated %}
  445.         <script>
  446.             let title = '{{ 'titleTranslation' |trans}}'
  447.             let content = '{{ 'contentTranslation' |trans}}'
  448.             let buttonText ='{{ 'buttonTextTranslation' |trans}}'
  449.         </script>
  450.         <script>
  451.             let haveVariants = {{ haveVariants }};
  452.             $(document).ready(function () {
  453.                 let haveProductErrors = {{ haveProductErrors }} ;
  454.                 if (haveProductErrors) {
  455.                     Swal.fire({
  456.                         icon: 'warning',
  457.                         title: 'Oops...',
  458.                         showCancelButton: true,
  459.                         confirmButtonColor: '#106eea',
  460.                         cancelButtonColor: '#38b000',
  461.                         confirmButtonText: 'Entendido!',
  462.                         cancelButtonText: 'Contactar',
  463.                         html: 'La información del producto se esta actualizando, cualquier duda puede comunicarse a soporte.'
  464.                     })
  465.                     //Hide SKU, price, quantity, and add to cart button
  466.                     $('.product-price__price').hide();
  467.                     $('.product-form').hide();
  468.                     $('.proceed-to-checkout').hide();
  469.                     $('.product-sku').hide()
  470.                 }
  471.                 $('.swal2-cancel').click(function () {
  472.                     var email = '{{ companyMail }}';
  473.                     var subject = 'Soporte';
  474.                     var emailBody = 'Hi';
  475.                     window.location = 'mailto:' + email + '?subject=' + subject + '&body=' + emailBody;
  476.                 })
  477.                 // If the product doesn't have variants
  478.                 if (haveVariants === 0) {
  479.                     let qtyButton = $('.qtyField');
  480.                     //ID of the product
  481.                     let productID = qtyButton.attr('id');
  482.                     // Selected value of the quantity button
  483.                     let qtyValue = $('.product-form__input').val();
  484.                     // Display add to cart button
  485.                     $('.product-form__item--buyit').removeClass('d-none');
  486.                     // Display the quantity button
  487.                     qtyButton.removeClass('d-none');
  488.                     $('.product-form__item--buyit').attr('id',productID);
  489.                     getStockAjax(productID, qtyValue);
  490.                 }
  491.                 // Keep a reference to the button that was selected
  492.                 let selectedButton = null;
  493.                 function getPriceFormatSpain(price) {
  494.                     return parseFloat(price).toLocaleString('es-ES', {
  495.                         minimumFractionDigits: 2,
  496.                         maximumFractionDigits: 2
  497.                     });
  498.                 }
  499.                 $('table tbody').on('click', '.btn-ver-datatable', function() {
  500.                     let idVariant = $(this).attr('id');
  501.                     let qtyValue = $('.product-form__input').val();
  502.                     let qtyButton = $('.qtyField');
  503.                     let warehouseText = $('.stock-warehouse.stock-animation')
  504.                     $('.proceed-to-checkout').css('font-weight','600');
  505.                     $('.product-form__cart-submit').css('opacity','0.5');
  506.                     $('.spacing').removeClass('d-inline');
  507.                     $('.spacing').addClass('d-none');
  508.                     $('.product-form__item--buyit').removeClass('d-none');
  509.                     $('.product-form__item--buyit').attr('id',idVariant);
  510.                     $('.mfp-close').click();
  511.                     // If there is a selected button, reset its state
  512.                     if (selectedButton) {
  513.                         selectedButton.text('VER');
  514.                         selectedButton.css('filter', 'brightness(100%)');
  515.                     }
  516.                     // Change the text and style of the clicked button and save it as the selected button
  517.                     $(this).text('Seleccionado');
  518.                     $(this).css('font-weight','bold');         // Make the font bold
  519.                     $(this).css('filter','brightness(100%)');
  520.                     selectedButton = $(this);
  521.                     // This return info of variant selected
  522.                     $.ajax({
  523.                         method: 'POST',
  524.                         url: '/ajax_variant_info',
  525.                         datatype: 'json',
  526.                         data: {
  527.                             id: idVariant,
  528.                         },
  529.                         success: function (data) {
  530.                             newImageAjax(idVariant);
  531.                             // Display the quantity button
  532.                             qtyButton.removeClass('d-none');
  533.                             warehouseText.removeClass('d-none')
  534.                             // Put the id of the variant in qtyField element
  535.                             qtyButton.attr('id', idVariant);
  536.                             // Display SKU of the variant product
  537.                             $('.variant-sku').html(data.bsnCode);
  538.                             $('.product-sku').show();
  539.                             // Check if the product has discount
  540.                             const { original_price, end_price, error, discount } = data.priceWithDiscount;
  541.                             if (original_price !== end_price && error === null) {
  542.                                 // Set old price
  543.                                 $('.product-price-old-price')
  544.                                     .text(getPriceFormatSpain(original_price) + '€')
  545.                                     .removeClass('d-none');
  546.                                 $('.discount-badge').removeClass('d-none');
  547.                                 // Set new price
  548.                                 const truncatedPrice = parseFloat(end_price).toFixed(2);
  549.                                 $('.product-price__sale').text(getPriceFormatSpain(truncatedPrice) + '€');
  550.                                 // Set discount
  551.                                 const discountAmount = original_price - end_price;
  552.                                 $('.money').text(getPriceFormatSpain(discountAmount.toFixed(2)) + '€');
  553.                                 if (discount !== '.00') {
  554.                                     $('.percentage').text(getPriceFormatSpain(discount));
  555.                                     $('.percentage-span').removeClass('d-none');
  556.                                 } else {
  557.                                     $('.percentage-span').addClass('d-none');
  558.                                 }
  559.                             } else {
  560.                                 // If there is no discount or there is an error
  561.                                 $('.product-price__sale').html(data.price + '€');
  562.                                 $('.product-price-old-price').addClass('d-none');
  563.                                 $('.discount-badge').addClass('d-none');
  564.                             }
  565.                             // Update stock information
  566.                             getStock(data.stock, qtyValue, data.deliveryTime);
  567.                         },
  568.                         error: function () {
  569.                             alert('ERROR: Unable to fetch variant information.');
  570.                         }
  571.                     });
  572.                     //This returns the product kits of a variant
  573.                     $.ajax({
  574.                         method: 'POST',
  575.                         url: '/ajax_variant_kit',
  576.                         datatype: 'json',
  577.                         data: {
  578.                             id: idVariant,
  579.                         },
  580.                         success: function (data) {
  581.                             const featuresContainer = document.getElementById('featuresContainer')
  582.                             const parentFeatures = document.getElementById('parentFeatures')
  583.                             const previewKitIcon = document.getElementById('previewKitIcon')
  584.                             const descriptionIL = document.querySelector('.descriptionIL')
  585.                             const featuresIL = document.querySelector('.featuresIL')
  586.                             const features = document.querySelector('.features')
  587.                             featuresContainer.innerHTML = data
  588.                             if(data){
  589.                                 featuresContainer.classList.remove('d-none')
  590.                                 previewKitIcon.classList.remove('d-none')
  591.                                 featuresIL.classList.remove('d-none')
  592.                                 features.classList.remove('d-none')
  593.                                 parentFeatures.classList.add('d-none')
  594.                                 featuresIL.click()
  595.                             } else {
  596.                                 featuresContainer.classList.add('d-none')
  597.                                 previewKitIcon.classList.add('d-none')
  598.                                 parentFeatures.classList.remove('d-none')
  599.                                 featuresIL.classList.add('d-none')
  600.                                 features.classList.add('d-none')
  601.                                 descriptionIL.click()
  602.                             }
  603.                         },
  604.                         error: function () {
  605.                             alert('ERROR: Unable to fetch variant information.');
  606.                         }
  607.                     });
  608.                 });
  609.                 function newImageAjax(idVariant){
  610.                     // This return info of variant selected
  611.                     $.ajax({
  612.                         method: 'POST',
  613.                         url: '/ajax_productDetail_new_asset',
  614.                         datatype: 'html',
  615.                         data: {
  616.                             id: idVariant,
  617.                         },
  618.                         success: function (data) {
  619.                             $('.img-father').html(data);
  620.                         },
  621.                         error: function () {
  622.                             alert('ERROR');
  623.                         }
  624.                     });
  625.                 }
  626.                 let timer = false;
  627.                 // Detect clicks on plus and minus buttons
  628.                 $('.qtyBtn').click(function () {
  629.                     let qtyField = $(this).closest('.qtyField');
  630.                     let productID = qtyField.attr('id');
  631.                     let qtyValue = parseInt(qtyField.find('.product-form__input').val(), 10);
  632.                     // Ensure qtyValue is a valid number and greater than or equal to 1 before making request
  633.                     if (!isNaN(qtyValue) && qtyValue >= 1) {
  634.                         clearTimeout(timer);
  635.                         timer = setTimeout(getStockAjax, 300, productID, qtyValue);
  636.                     }
  637.                 });
  638.                 // Detect changes in the input field and allow only numeric values
  639.                 $('.product-form__input').on('input', function () {
  640.                     let qtyField = $(this).closest('.qtyField');
  641.                     let productID = qtyField.attr('id');
  642.                     let qtyValue = $(this).val();
  643.                     // Allow only numeric input
  644.                     qtyValue = qtyValue.replace(/\D/g, '');  // Remove any non-numeric characters
  645.                     $(this).val(qtyValue);  // Update the input field with the cleaned value
  646.                     // Parse the value as an integer (but allow empty input while typing)
  647.                     if (qtyValue !== "") {
  648.                         qtyValue = parseInt(qtyValue, 10);
  649.                         // Ensure the value is greater than or equal to 1 before making the request
  650.                         if (!isNaN(qtyValue) && qtyValue >= 1) {
  651.                             clearTimeout(timer);
  652.                             timer = setTimeout(getStockAjax, 300, productID, qtyValue);
  653.                         }
  654.                     }
  655.                 });
  656.                 function getStockAjax(productID, qtyValue) {
  657.                     $.ajax({
  658.                         method: 'POST',
  659.                         url: '/ajax_productDetail_getStock',
  660.                         datatype: 'json',
  661.                         data: {
  662.                             id: productID
  663.                         },
  664.                         success: function (data) {
  665.                             getStock(data.stock, qtyValue, data.deliveryTime);
  666.                         },
  667.                         error: function () {
  668.                             alert('ERROR');
  669.                         }
  670.                     });
  671.                 }
  672.                 $('.infostock').click(function () {
  673.                     // Obtén el idioma del usuario de la variable lang
  674.                     const lang = $('.lang').attr('lang');
  675.                     Swal.fire({
  676.                         icon: 'info',
  677.                         title: title,
  678.                         confirmButtonColor: '#106eea',
  679.                         confirmButtonText: buttonText,
  680.                         html: content
  681.                     });
  682.                 });
  683.                 function getStock(stock, qtyField, deliveryTime) {
  684.                     $('.preorder.nostock').addClass('d-none');
  685.                     $('.stockText').text(stock.total + ' {{ 'En stock' | trans }}');
  686.                     $('.instock').addClass('d-none');
  687.                     $('.outstock').addClass('d-none');
  688.                     $('.differenceText').text('{{ 'Por entregar' |trans }}');
  689.                     $('.deliveryTime').addClass('d-none');
  690.                     $('.icon-info').addClass('d-none');
  691.                     const lang = $('.lang').attr('lang');
  692.                     let diferrence = ((stock.total - qtyField) * -1);
  693.                     let warehouseHtml = '';
  694.                     if (stock.warehouse[3] !== undefined || stock.warehouse[5] !== undefined) {
  695.                         warehouseHtml += '<div class="stock-info-table card p-2 position-absolute">';
  696.                         warehouseHtml += '<div class="header text-center mb-2">{{ 'Stock available in' | trans }}:</div>';
  697.                         if (stock.warehouse[3] !== undefined) {
  698.                             warehouseHtml += '<div class="row no-gutters first-row">';
  699.                             warehouseHtml += '<div class="col-6 bg-primary text-white">{{ 'warehouse_barcelona' | trans }}</div>';
  700.                             warehouseHtml += '<div class="col-6 bg-white text-dark">' + stock.warehouse[3] + '</div>';
  701.                             warehouseHtml += '</div>';
  702.                         }
  703.                         if (stock.warehouse[5] !== undefined) {
  704.                             warehouseHtml += '<div class="row no-gutters last-row">';
  705.                             warehouseHtml += '<div class="col-6 bg-primary text-white">{{ 'warehouse_palma' | trans}}</div>';
  706.                             warehouseHtml += '<div class="col-6 bg-white text-dark">' + stock.warehouse[5] + '</div>';
  707.                             warehouseHtml += '</div>';
  708.                         }
  709.                         warehouseHtml += '</div>';
  710.                     }
  711.                     $('.stock-info-container').html(warehouseHtml);
  712.                     const stockContainer = document.querySelector('.stock-animation');
  713.                     const stockTable = document.querySelector('.stock-info-table');
  714.                     stockContainer.addEventListener('mouseover', function() {
  715.                         stockTable.style.display = 'flex';
  716.                     });
  717.                     stockContainer.addEventListener('mouseout', function() {
  718.                         stockTable.style.display = 'none';
  719.                     });
  720.                     if (stock.total > 0) {
  721.                         if (qtyField > 0) {
  722.                             if (qtyField <= stock.total) {
  723.                                 $('.instock').removeClass('d-none');
  724.                             } else {
  725.                                 $('.instock').removeClass('d-none');
  726.                                 $('.stockText').text(stock.total + ' {{ 'En stock' | trans }}');
  727.                                 $('.preorder.nostock').removeClass('d-none');
  728.                                 $('.differenceText').text(diferrence + ' {{ 'Por entregar' | trans }}');
  729.                                 $('.icon-info').removeClass('d-none');
  730.                                 if (deliveryTime) {
  731.                                     $('.deliveryTime').removeClass('d-none');
  732.                                     $('.deliveryTimeText').text(deliveryTime + ' {{ 'En llegar' | trans }}');
  733.                                 } else {
  734.                                     console.log('No hay info en el PIM');
  735.                                 }
  736.                             }
  737.                         } else {
  738.                             $('.instock').removeClass('d-none');
  739.                         }
  740.                     } else {
  741.                         if (deliveryTime) {
  742.                             $('.deliveryTime').removeClass('d-none');
  743.                             $('.deliveryTimeText').text(deliveryTime + (lang === 'en' ? ' To arrive' : ' En llegar'));
  744.                         } else {
  745.                             console.log('No hay info en el PIM');
  746.                         }
  747.                         $('.outstock').removeClass('d-none');
  748.                     }
  749.                 }
  750.             });
  751.             //PRODUCT BUNDLE
  752.             let buttons = document.getElementsByClassName("btn-add-product");
  753.             let idsArray = [];
  754.             for (let i = 0; i < buttons.length; i++) {
  755.                 buttons[i].addEventListener("click", function() {
  756.                     let id = this.getAttribute("id");
  757.                     let index = idsArray.indexOf(id);
  758.                     if (index !== -1) {
  759.                         idsArray.splice(index, 1);
  760.                         this.classList.remove("selected");
  761.                         this.classList.add("deselected");
  762.                         this.textContent = "Seleccionar";
  763.                     } else {
  764.                         idsArray.push(id);
  765.                         this.classList.add("selected");
  766.                         this.classList.remove("deselected");
  767.                         this.textContent = "Seleccionado";
  768.                     }
  769.                     if ( Array.isArray(idsArray) && idsArray.length){
  770.                         $('.add-ids-of-products').removeAttr('disabled');
  771.                     } else {
  772.                         $('.add-ids-of-products').attr('disabled', true);
  773.                     }
  774.                 });
  775.             }
  776.             $('.add-ids-of-products').click(function() {
  777.                 let productsIds = JSON.stringify(idsArray); // Convert the array to a JSON string
  778.                 let mainProductId = $('.add-item-cart').attr('id');
  779.                 let mainProductQtyValue = $('.product-form__input').val();
  780.                 // Show minicart immediately with current content
  781.                 $('#minicart-drawer').modal('show');
  782.                 
  783.                 // Show loading modal immediately
  784.                 setTimeout(() => {
  785.                     showLoadingModal();
  786.                 }, 200);
  787.                 $.ajax({
  788.                     url: '/add-to-cart-products-array-ajax',
  789.                     type: 'POST',
  790.                     dataType: 'JSON',
  791.                     data: {
  792.                         mainProductId : mainProductId,
  793.                         mainProductQtyValue : mainProductQtyValue,
  794.                         ids: productsIds
  795.                     }, // Pass the data as an object with a key-value pair
  796.                     success: function(data, status) {
  797.                         if(data.success === true) {
  798.                             $('.add-ids-of-products').addClass('opacity-50')
  799.                             $('.site-cart-count').text(data.itemsOnCart);
  800.                             $.ajax({
  801.                                 url: '/' + $('html').attr('lang') + '/shopping-header-cart',
  802.                                 type: 'POST',
  803.                                 dataType: 'html',
  804.                                 data: [],
  805.                                 success: function (cartData) {
  806.                                     $('#cart-drawer').html(cartData);
  807.                                 },
  808.                                 complete: function() {
  809.                                     Swal.close();
  810.                                 }
  811.                             });
  812.                         } else {
  813.                             alert(data.error);
  814.                             Swal.close();
  815.                         }
  816.                     },
  817.                     error: function(xhr, desc, err) {
  818.                         console.log("error");
  819.                         Swal.close();
  820.                     }
  821.                 });
  822.             });
  823.         </script>
  824.     {% endif %}
  825.     <script>
  826.         let relatedProducts = '{{ 'related-products' | trans | raw }}';
  827.         let relatedProductsDescription = '{{ 'related-products-description' | trans | raw }}';
  828.     </script>
  829.     <script src="{{ asset('assets/js/shared/loading-modal.js') }}"></script>
  830.     <script src="{{ asset('assets/js/shop/product-detail.js') }}"></script>
  831.     {#  if product not have Errors load the Datatable  #}
  832.     {% if not haveProductErrors %}
  833.         <script src="{{ asset('../assets/js/dataTables/TableProduct.js') }}"></script>
  834.     {% endif %}
  835. {% endblock %}