src/Elements/Bundle/DemiFrontendBundle/Resources/views/AdditionalService/products.html.twig line 1

Open in your IDE?
  1. {% set productsCount = products|default([])|length %}
  2. {% if isNew|default(false) %}
  3.     <script type="text/javascript" data-cookieconsent="ignore">
  4.         _config.datepicker = true;
  5.         _config.additionalServices = true;
  6.     </script>
  7.     <div class="js-additional-services-datepicker">
  8.         <div class="js-additional-services-datepicker__picker mb-3" {{ availableDates|default(null) ? 'data-available-dates=' ~ availableDates|json_encode ~'' : '' }}></div>
  9.         <input class="js-additional-services-datepicker__alt-field" type="hidden" id="date" name="date" value="{{ date }}">
  10.     </div>
  11.     <div class="additional-services__date">{{ 'demi.additionalservice.products.selected-date'|trans }} <br> {{ elements_dateFormat(date, 'date-day_date_long') }}</div>
  12.     <ul class="package-group list-unstyled {{ styleModifier|default('') }}">
  13.         {% if products|default([]) is empty or productsCount is same as 0 %}
  14.             <div class="alert alert-danger">{{ "demi.additionalservice.products.no-products"|trans }}</div>
  15.         {% else %}
  16.             {# loop0 => count #}
  17.             {% for productId, data in products %}
  18.                 {% set preparedData = demi_additionalGetProductData(data, productId, service) %}
  19.                 {% set optionsdata = demi_additionalGetProductDatesOptions(preparedData.getPrices, service.getMaxAvailability(), from) %}
  20.                 <li class="my-4 my-md-0">
  21.                     <section
  22.                         {% if pimcore_device().isDesktop() %}
  23.                             class="card-body bg-white offer-teaser js-tracking js-tracking--impression"
  24.                             data-toggle="modal" data-target="#modal-{{ productId }}" data-focus="false"
  25.                         {% else %}
  26.                             class="card-body bg-white offer-teaser  js-overlay__toggle js-tracking js-tracking--impression"
  27.                             data-target="#overlay-{{ productId }}" data-focus="false"
  28.                         {% endif %}
  29.                         data-tracking-name="{{ preparedData.product.parent.parent.name }}"
  30.                         data-tracking-id="{{ loop.index }}"
  31.                         data-tracking-category="{{ preparedData.product.type }}"
  32.                         data-tracking-position="1"
  33.                         data-tracking-brand="{{ preparedData.product.parent.parent.town.name }}"
  34.                         data-tracking-list="Zusatzleistungen"
  35.                         data-tracking-price="{{ optionsdata.price }}"
  36.                         data-tracking-variant="{{ preparedData.product.name }}>"
  37.                     >
  38.                         <div class="row row--gutter-width-20">
  39.                             <div class="col-12 col-md">
  40.                                 <div class="row">
  41.                                     <div class="col-md-12 col ml-md-1">
  42.                                         <h3 class="text-primary package-group__title mb-1">
  43.                                             <button type="button" class="btn-no-styling">{{ preparedData.product.name }}</button>
  44.                                         </h3>
  45.                                     </div>
  46.                                     <div class="col-md-12 col-auto d-md-none">
  47.                                         <div class="text-success fz23 font-medium package-group__price">
  48.                                             {% if optionsdata.price > 0 %}
  49.                                             {{ 'demi.additionalservice.price-from'|trans }}
  50.                                             <span class="price">{{ optionsdata.price }} {{ demi_paymentGetCurrency() }}</span>
  51.                                             {%  else %}
  52.                                                 <span class="price">{{ 'demi.additionalservice.price-free'|trans }}</span>
  53.                                             {% endif %}
  54.                                         </div>
  55.                                     </div>
  56.                                 </div>
  57.                                 
  58.                                 <div class="wysiwyg">{{ preparedData.text }}</div>
  59.                             </div>
  60.                             <div class="col col-md-12 col-auto d-flex flex-column {% if pimcore_device().isDesktop() %} {{ isAdditionalService|default(false) ? '' : 'border-left' }} pl-3{% endif %}">
  61.                                 <div class="text-success fz23 font-medium mb-2 package-group__price d-none d-md-block">
  62.                                     {% if optionsdata.price > 0 %}
  63.                                         {{ 'demi.additionalservice.price-from'|trans }}
  64.                                         <span class="price">{{ optionsdata.price }} {{ demi_paymentGetCurrency() }}</span>
  65.                                     {%  else %}
  66.                                         <span class="price">{{ 'demi.additionalservice.price-free'|trans }}</span>
  67.                                     {% endif %}
  68.                                 </div>
  69.                                 {% if not data.getPrices()[0].getBookable() %}
  70.                                     <button class="btn btn-success mt-md-auto mt-2 package-group__btn" type="button">
  71.                                     <span class="mr-2"
  72.                                           aria-hidden="true"></span>
  73.                                         {{ 'demi.additionalservice.products.enquire'|trans }}
  74.                                     </button>
  75.                                 {% else %}
  76.                                     <button class="btn btn-success mt-md-auto mt-2 package-group__btn" type="button">
  77.                                         <span class="btn__icon demi-icon demi-icon-cart mr-2"
  78.                                               aria-hidden="true"></span>
  79.                                         {{ 'demi.additionalservice.products.add-to-cart'|trans }}
  80.                                     </button>
  81.                                 {% endif%}
  82.                             </div>
  83.                         </div>
  84.                         
  85.                     </section>
  86.                     {% if pimcore_device().isDesktop() %}
  87.                         {{ include('@ElementsDemiFrontend/AdditionalService/includes/offer-detail.desktop.html.twig', {
  88.                             id: 'modal-' ~ productId,
  89.                             productId: productId,
  90.                             title: item|default([]) ? item.title : '',
  91.                             price: optionsdata.price,
  92.                             isPackage: false,
  93.                             position: loop.index,
  94.                             dateFrom: from,
  95.                             dateTo: to,
  96.                             acco: preparedData.product.parent.parent,
  97.                         }) }}
  98.                     {% else %}
  99.                         {{ include('@ElementsDemiFrontend/AdditionalService/includes/offer-detail.mobile.html.twig', {
  100.                             id: 'overlay-' ~ productId,
  101.                             productId: productId,
  102.                             title: item|default([]) ? item.title : '',
  103.                             price: optionsdata.price,
  104.                             isPackage: false,
  105.                             position: loop.index,
  106.                             dateFrom: from,
  107.                             dateTo: to,
  108.                             acco: preparedData.product.parent.parent,
  109.                         }) }}
  110.                     {% endif %}
  111.                 </li>
  112.             {% endfor %}
  113.         {% endif %}
  114.     </ul>
  115. {% else %}
  116.     <div>
  117.         <section class="">
  118.             <div class="">
  119.                 <div class="">
  120.                     {% if products|default([]) is empty or products|length is same as 0 %}
  121.                         <div class="alert alert-danger">{{ "demi.additionalservice.products.no-products"|trans }}</div>
  122.                     {% endif %}
  123.                 </div>
  124.                 <div class="package-group" role="tablist">
  125.                     {% if not products|default([]) is empty %}
  126.                         {% for productId, data in products %}
  127.                             {% set preparedData = demi_additionalGetProductData(data, productId, service) %}
  128.                             {% set maxCount = preparedData.maxCount %}
  129.                             <div class="js-package-container card-body bg-white offer-teaser"
  130.                                  data-package-id="{{ productId  }}"
  131.                                  data-url="{{ demi_demiUrl({
  132.                                      path: document.fullPath
  133.                                  },  'demi_additionalservice_productlist_ajaxreload') }}"
  134.                             >
  135.                                 <form
  136.                                     action="{{ demi_demiUrl({
  137.                                             path: document.fullPath
  138.                                         },  'demi_additionalservice_add_additional_item')
  139.                                     }}"
  140.                                     class="js-additionalservice-add-form additionalservice-form js-package"
  141.                                     data-tracking-id="{{ service.parent.id }}"
  142.                                     data-tracking-name="{{ demi_impressionName(service.parent) }}"
  143.                                     data-tracking-variant="{{ demi_impressionVariant(preparedData.product, null) }}>"
  144.                                     data-tracking-category="{{ demi_impressionCategory(service.getParent(), null, null, null, preparedData.product) }}"
  145.                                     data-tracking-brand="{{ demi_impressionBrand(service.getParent()) }}"
  146.                                     data-tracking-price="{{ preparedData.getPrices[0].getPrice() }}"
  147.                                 >
  148.                                     <div class="row row--gutter-width-20">
  149.                                         <div>
  150.                                             <input type="hidden" name="products[{{ productId }}][settlerCode]"
  151.                                                    value="{{ data.getSettlerCode( )}}">
  152.                                             <div class="card-header">
  153.                                                 <div class="row row--gutter-with-0" role="tab"
  154.                                                      id="heading-{{ productId }}">
  155.                                                     <div class="col-12 col-md">
  156.                                                        {{ preparedData.product.name }}
  157.                                                     </div>
  158.                                                 </div>
  159.                                             </div>
  160.                                             <div class="card-body">
  161.                                                 <div class="row row--gutter-with-0" role="tab"
  162.                                                      id="body-{{ productId }}">
  163.                                                     <div class="col-md-4 col-12 align-self-center mb-2 mb-md-0">
  164.                                                     <span
  165.                                                         class="float-left additionalservice-booking__price">{{ preparedData.getPrices[0].price is null ? '' : demi_paymentGetPriceObject(preparedData.getPrices[0].price) }}</span>
  166.                                                     </div>
  167.                                                     <div class="col-12 col-md-3 align-self-center mb-2 mb-md-0">
  168.                                                         <select name="products[{{ productId }}][date]"
  169.                                                                 id="package-{{ productId }}-Date"
  170.                                                                 class="custom-select js-package__update form-control">
  171. {#                                                           Explanation:
  172.                                                              $this->services holds all the valid single dates that we can request within the given timerange set for the initial Demi request in the controller.
  173.                                                              Those dates will be put up for selection. The corresponding prices are not yet valid though. The deskline rule states that only the _one_ price is valid
  174.                                                              that belongs to the from-date in the request.
  175.                                                              This means that within a range of - let's say - Monday, 1.4 to Monday 1.5 we get 4 valid dates - one for every wednesday in between with a price of 15€ each.
  176.                                                              In this case, the 15€ for the first wednesday (3.4.) are not necessarily valid because the range-from-date (mon, 1.4) != first-valid-date (wed, 3.4).
  177.                                                              So we have to make a new request with the wednesday, 3.4. as from-date.
  178.                                                              If mon, 1.4 was a valid date already, then we can use the price initially without making a new request.#}
  179.                                                             {% set optionsdata = demi_additionalGetProductDatesOptions(preparedData.getPrices, service.getMaxAvailability(), from) %}
  180.                                                             {% if optionsdata.maxCount %}{# if null => no override #}
  181.                                                                 {% set maxCount = optionsdata.maxCount %}
  182.                                                             {% endif %}
  183.                                                             {% set price = optionsdata.price %}
  184.                                                             {% set day = optionsdata.day %}
  185.                                                             {{ optionsdata.options|raw }}
  186.                                                         </select>
  187.                                                         <input type="hidden"
  188.                                                                name="products[{{ productId }}][durationType]"
  189.                                                                value="{{ productId }}"
  190.                                                         >
  191.                                                     </div>
  192.                                                     {% set durationPriceData = demi_additionalGetDurationPriceData(preparedData.product, day) %}
  193.                                                     {% if not durationPriceData is empty %}
  194.                                                         {% set price = price is numeric ? price : 1 %}
  195.                                                         {% if durationPriceData|length > 1 %}
  196.                                                             <div class="col-12 col-md-3">
  197.                                                                 <select name="products[{{ productId }}][days]"
  198.                                                                         id="package-{{ productId }}-Days"
  199.                                                                         class="custom-select form-control">
  200.                                                                     {% for numDays, pricePerUnit in durationPriceData %}
  201.                                                                         {% set suffix = numDays == 1 ? 'demi.additionalservice.products.additionalservice.single-day'|trans : 'demi.additionalservice.products.additionalservice.multiple-days'|trans %}
  202.                                                                         <option
  203.                                                                             value="{{ numDays }};{{ pricePerUnit / price }};{{ pricePerUnit|number_format(2,'.', ',') }}"
  204.                                                                             data-price="{{ pricePerUnit|number_format(2,'.', ',') }} CHF">{{ numDays }} {{ suffic }}>
  205.                                                                             (CHF {{ (pricePerUnit/numDays)|number_format(2,'.', ',') }} {{ 'demi.additionalservice.products.additionalservice.per_unit'|trans }}
  206.                                                                             )
  207.                                                                         </option>
  208.                                                                     {% endfor %}
  209.                                                                 </select>
  210.                                                             </div>
  211.                                                         {% else %}
  212.                                                             {% for numDays, pricePerUnit in durationPriceData %}
  213.                                                                 <input type="hidden"
  214.                                                                        name="products[{{ productId }}][days]"
  215.                                                                        value="{{ numDays }};{{ pricePerUnit / price }};{{ pricePerUnit|number_format(2,'.', ',') }}"
  216.                                                                        data-price="{{ pricePerUnit|number_format(2,'.', ',') }} CHF">
  217.                                                             {% endfor %}
  218.                                                         {% endif %}
  219.                                                     {% endif %}
  220.                                                     <div class="col-12 col-md-2">
  221.                                                         <label for="package-{{ productId }}-count"
  222.                                                                class="sr-only">{{ "sr.demi.additionalservice.products.additionalservice.product_count"|trans }}
  223.                                                         </label>
  224.                                                         <div class="js-number-spinner number-spinner">
  225.                                                             <button type="button"
  226.                                                                     class="btn btn-link js-number-spinner__down number-spinner__down"
  227.                                                             >
  228.                                                                 <span class="icon icon-minus"
  229.                                                                       aria-label="minus"></span>
  230.                                                             </button>
  231.                                                             <input name="products{{ productId }}][count]"
  232.                                                                    id="package-{{ productId }}-count" type="text"
  233.                                                                    class="form-control js-number-spinner__input spinner-input"
  234.                                                                    readonly value="1"
  235.                                                                    data-spinner-max="{{ maxCount }}">
  236.                                                             <button type="button"
  237.                                                                     class="btn btn-link js-number-spinner__up number-spinner__up">
  238.                                                                 <span class="icon icon-plus"
  239.                                                                       aria-label="plus"></span>
  240.                                                             </button>
  241.                                                         </div>
  242.                                                         <script>
  243.                                                             _config.addPackages = true;
  244.                                                             _config.maxValue = {{ maxCount }};
  245.                                                         </script>
  246.                                                     </div>
  247.                                                     {% if maxCount < service.getMaxAvailability() and maxCount >= 0 %}
  248.                                                         <div class="col-md-auto col-12 align-self-center mb-2 mb-md-0">
  249.                                                             <span class="float-left additionalservice-booking__price">
  250.                                                                 {{ 'demi.additionalservice.products.units-free'|trans }}: {{ maxCount }}
  251.                                                             </span>
  252.                                                         </div>
  253.                                                     {% endif %}
  254.                                                 </div>
  255.                                             </div>
  256.                                         </div>
  257.                                     </div>
  258.                                     {% if maxCount > 0 or service.getMaxAvailability() <= 0 %}
  259.                                         <div class="js-additionalservice-add-form__result additionalservice-add-form__result text-right mb-4">
  260.                                             <div class="text-right">
  261.                                                 <a href="" class="js-additionalservice-add-form-btn btn btn-cta">
  262.                                                     {{ 'demi.additionalservice.products.add-to-cart'|trans }}
  263.                                                 </a>
  264.                                             </div>
  265.                                         </div>
  266.                                     {% endif %}
  267.                                 </form>
  268.                             </div>
  269.                         {% endfor %}
  270.                     {% endif %}
  271.                 </div>
  272.             </div>
  273.         </section>
  274.     </div>
  275. {% endif %}