{#
/**
* @var \\Pimcore\\Templating\\GlobalVariables app
* #
* @var productData array
* @var accommodation \\Elements\\Demi\\Model\\AccommodationServiceProvider
* @var settlerCode string
* @var bookOnRequest bool
* @var availabilityIsChecked bool
* @var hasSingleRoomRow bool
* @var searchParam \\Elements\\Demi\\Accommodation\\Search\\Parameter
*/ #}
{% if searchParam is not defined or searchParam.getDateFrom() is empty %}
{% set fromDate = null %}
{% else %}
{% set fromDate = demi_getSearchFrom() %}
{% endif %}
{% if productData is iterable and productData.roomRow[0] is defined and productData.products[0] is defined %}
{% set possibleIndices = productData.roomRow | keys %}
{% set i = possibleIndices | first %}
{% set roomRow = productData.roomRow[i].getRowObject() %}
{% set product = productData.products[i] %}
{% set accommodationProduct = pimcore_object(product.getProductId()) %}
{% if accommodationProduct and accommodationProduct.isPublished() %}
<li>
{% set id = product.getProductId() %}
{% set title = accommodationProduct.getName() %}
{% if product is not null and roomRow is not null %}
{% set priceData = product.getPriceData() %}
{% set price = product.getPrice() %}
{% set showVacancy = true %}
{% set showSelection = true %}
{% set vacancyCount = product.getUnits() %}
{% set promotionText = null %}
{% if product.getCancellationInformation() is not empty %}
{% set cancellationInformation = product.getCancellationInformation() %}
{% set displayInfo = demi_getCancellationDisplayInfo(cancellationInformation,searchParam.getDateFrom()) %}
{% set freeCancelText = displayInfo.getFreeCancellationText() %}
{% set promotionText = freeCancelText == "" ? null : freeCancelText %}
{% endif %}
{% elseif product is not null %}
{% set price = product.getBasePrice() %}
{% set showVacancy = false %}
{% set showSelection = false %}
{% set vacancyCount = 0 %}
{% set priceInfo = product.getPriceInfo() %}
{% if priceInfo is not empty %}
{% set priceInfoText = include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type': priceInfo['type'], 'nights': priceInfo['nights']}) %}
{% endif %}
{% endif %}
{% if searchParam.getDateFrom() is not null %}
{% if searchParam is instanceof('\Elements\Demi\Lts\Accommodation\Search\Parameter') %}
{% set mealArray = product.getPossibleMealCodes() %}
{% elseif searchParam is instanceof('\Elements\Demi\Package\Search\Parameter') %}
{% set mealArray = [] %}
{% else %}
{% set mealArray = accommodationProduct.getValidMeals(searchParam.getPeriod(), searchParam.getDateFrom()) %}
{% endif %}
{% set liveMeal = product.getMealCode() %}
{% set liveMealObj = demi_getClassByStringAndIdentifier("\\Elements\\Demi\\Model\\MealType", "getByFid", liveMeal) %}
{% if liveMeal not in mealArray|keys %}
{% set mealArray = mealArray|merge([liveMealObj]) %}
{% endif %}
{% else %}
{% set mealArray = accommodationProduct.getValidMeals(0) %}
{% endif %}
{% set images = accommodationProduct is not null ? demi_getRoomPictures(accommodationProduct,fromDate) : [] %}
<div id="room-row-collapse-parent-{{ product.getProductId() }}"
class="js-room-selection__room"
data-availability-reference-id="{{ product.getAvailabilityReference() is same as "Service" ? product.getServiceId() : product.getProductId() }}"
data-room-id="{{ product.getProductId() }}"
data-tracking-variant="{{ demi_impressionVariant(accommodationProduct ?: product, tvbPackage) }}"
data-tracking-variant-id="{{ product.getProductId() }}"
data-settler-code="{{ settlerCode }}"
data-booking-type="{{ product.getBookable() ? 'bookable' : 'onrequest' }}">
<div class="card box-shadow mt-3 {{ hasSingleRoomRow ? 'js-room-selection__room-row' : 'z-1' }}"
{% if hasSingleRoomRow %}
{% if productData is iterable and productData['products'] is iterable and productData['roomRow'] is iterable %}
{% set done = false %}
{% for productIndex, product in productData['products'] %}
{% if not done %}
{% set roomRowIndexSingleRoom = productData['roomRow'][productIndex].getIndex() %}
{% set done = true %}
{% endif %}
{% endfor %}
{% else %}
{% set roomRowIndexSingleRoom = 0 %}
{% endif %}
data-room-row-id="{{ roomRowIndexSingleRoom is defined ? roomRowIndexSingleRoom : 0 }}"
data-initial-price="{{ price | number_format(2, '.', '') }}"
{% if priceData is defined and priceData is not null and priceData.getPriceBeforeSpecial() > product.getPrice() %}
data-initial-price-before-special="{{ priceData.getPriceBeforeSpecial() | number_format(2, '.', '') }}"
{% endif %}
data-room-row-title="{{ title|escape }}"
{% endif %}
>
<section class="teaser teaser--body-padding">
<div class="row row--gutter-width-10">
<div class="col-4 d-flex flex-column">
{% if priceData is defined and priceData is not null and priceData.getSpecialPriceType() is same as "None" and priceData.getSpecialPriceName() is not empty %}
<div class="teaser__label bg-warning text-center p-1 small text-white strong">
{% if priceData.getSplitPay() and priceData.getSplitStay() and priceData.getSplitPay() != priceData.getSplitStay() %}
{{ demi_fillTranslation({
'[STAY]' : priceData.getSplitStay(),
'[PAY]' : priceData.getSplitPay()
}, 'demi.price-special-type.splitpay') }}
{% else %}
{{ priceData.getSpecialPriceName() }}
{% endif %}
</div>
{% endif %}
{% if priceData is defined and priceData is not null and priceData.getSpecialPriceType() and priceData.getSpecialPriceType()!= priceData.getSpecialPriceName() and priceData.getSpecialPriceType() is not same as "None" %}
<div class="teaser__label bg-warning text-center p-1 small text-white strong">
{{ ("demi.price-special-type." ~ priceData.getSpecialPriceType() | lower) | trans }}
</div>
{% endif %}
{% set galUrl = '#' ~ (accommodationProduct is not null ? accommodationProduct.getId() : '') ~ '-imgs-overlay' %}
{% if images|length == 0 %}
{% set images = [demi_core_configuration('getTeaserFallbackImage',[])] %}
{% set galUrl = '' %}
{% endif %}
<button type="button" class="teaser__img btn-no-styling js-overlay__toggle figure js-tracking--click-piwik"
data-target="{{ galUrl }}"
data-tracking-category="Gallery"
data-tracking-action="open"
{% if (images[0]) %}
style="background-image:url({{ images[0].getThumbnail('demi-mobile-room-teaser') }});">
{{ images[0].getThumbnail('demi-mobile-room-teaser').getHTML({ 'imgAttributes': {'class': 'sr-only', 'alt': 'demi.image-alt-prefix'|trans ~ ' '~ (accommodationProduct is not null ? accommodationProduct.getName() : product.getDescription()) }})|raw }}
{% if images|length > 1 %}
<span class="figure__overlay p-1">1/{{ images|length }}</span>
{% endif %}
{% endif %}
</button>
</div>
<div class="col-8 teaser__body collapsed js-tracking--click-piwik"
data-toggle="collapse"
data-target="#detail-{{ id }}"
data-tracking-category="Product"
data-tracking-action="click detail"
data-tracking-label="{{ id }}"
>
<div class="teaser__main-body">
<h3 class="mb-1 text-primary">
<a href="#detail-{{ id }}"
aria-controls="detail-{{ id }}"
aria-expanded="false"
data-toggle="collapse"
class="collapsed"
>{{ title }}</a>
</h3>
{% if hasSingleRoomRow %}
<div class="mb-1 small text-muted">
<div class="media">
<div class="demi-icon demi-icon-person mr-1 icon-in-text"
aria-hidden="true"></div>
<div class="media-body">
{% if roomRow is not null %}
{% set adults = roomRow.getAdults() %}
{% set children = roomRow.getChildAges()|length %}
{% set adultsStr = adults > 1 ? adults ~ " " ~ 'demi.detail.room.occupancy.adults'|trans : adults ~ " " ~ 'demi.detail.room.occupancy.adult'|trans %}
{% set childrenStr = children > 1 ? children ~ " " ~ 'demi.detail.room.occupancy.children'|trans : children ~ " " ~ 'demi.detail.room.occupancy.child'|trans %}
{% else %}
{% set adultsStr = accommodationProduct.getBedsMin() ~ "-" ~ accommodationProduct.getBedsMax() ~ " " ~ 'demi.detail.room.occupancy.persons'|trans %}
{% endif %}
{{ adultsStr }}
{% if children is defined and children|length > 0 %}
, {{ childrenStr }}
{% endif %}
</div>
</div>
</div>
{% endif %}
{% if showVacancy %}
{{ include('@ElementsDemiFrontend/Includes/elements/vacancy-info.html.twig', {'vacancyCount':vacancyCount, 'tvbPackage':tvbPackage}) }}
{% endif %}
</div>
{% if hasSingleRoomRow %}
<hr class="my-1">
<div>
{% if liveMealObj is defined and liveMealObj is not empty %}
<div class="mb-1 small text-muted">
<span class="js-room-selection__meal-text">
{{ liveMealObj.getText() }}
</span>
{% if mealArray|length > 1 %}
<label for="meal-selector-{{ product.getProductId() }}" tabindex="0"
class="btn-no-styling increased-click-area js-room-selection__add">
<span class="demi-icon demi-icon-edit icon-in-text"
title="{{ "demi.detail.change-meal"|trans }}"
aria-label="{{ "demi.detail.change-meal"|trans }}"></span>
</label>
{% endif %}
</div>
{% endif %}
<div class="row align-items-baseline">
<div class="col">
{% if priceData is defined and priceData is not null and priceData.getPriceBeforeSpecial() > product.getPrice() %}
<span class="sr-only">{{ 'demi.detail.room.old-price'|trans }}</span>
<s class="text-muted js-room-selection__price-before-special">{{ demi_paymentGetPriceObject(priceData.getPriceBeforeSpecial(), accommodation) }}</s>
{% endif %}
{% if priceInfoText is defined %}
<div class="small text-muted">
{{ priceInfoText }}
</div>
{% endif %}
</div>
{% if (price is not null and price > 0) %}
<strong class="col col-auto mr-auto">
<span class="price text-success" aria-live="polite">
<span class="js-room-selection__price">
{% if roomRow is empty %}
{{ 'demi.price-from-short'|trans }}
{% endif %} {{ demi_paymentGetPriceObject(price, accommodation) }}
</span>
<span class="js-room-selection__price-loading" hidden>
<span class="circle-spinner circle-spinner--small float-left mr-1"
aria-label="{{ 'demi.content-loading'|trans }}"
title="{{ 'demi.content-loading'|trans }}"></span>
</span>
</span>
{% if priceData is defined and priceData is not null %}
<button type="button" data-target="#price-info-{{ id }}-room-row-0"
class="btn-no-styling increased-click-area js-overlay__toggle text-gray-medium js-tracking--click-piwik"
data-tracking-category="Product"
data-tracking-action="click price"
data-tracking-label="{{ id }}"
>
<span class="demi-icon demi-icon-info-circle icon-in-text"
title="{{ 'demi.detail.room.price-info'|trans }}"
aria-label="{{ 'demi.detail.room.price-info'|trans }}"></span>
</button>
{% endif %}
</strong>
{% endif %}
</div>
</div>
{% endif %}
<a class="teaser__collapse-arrow collapsed demi-icon demi-icon-chevron-down"
aria-expanded="false"
aria-controls="detail-{{ id }}"
href="#detail-{{ id }}"
data-toggle="collapse"
title="{{ 'demi.detail.room.show-details'|trans }}"
aria-label="{{ 'demi.detail.room.show-details'|trans }}"></a>
</div>
</div>
</section>
{{ include("@ElementsDemiFrontend/Includes/teaser/room-details.html.twig", {
"accommodationProduct": accommodationProduct,
"images": images,
"availabilityIsChecked": availabilityIsChecked,
"dateFrom": searchParam.getDateFrom()
}) }}
{% if hasSingleRoomRow %}
<div class="card-body">
{{ include("@ElementsDemiFrontend/Includes/teaser/room-buttons.html.twig", {
'accommodationProduct': accommodationProduct,
'product': product,
'mealArray': mealArray,
'liveMealObj': liveMealObj is defined ? liveMealObj : null,
'availabilityIsChecked': availabilityIsChecked,
'promotionText': promotionText is defined ? promotionText : null
}) }}
</div>
{% if priceData is defined and priceData is not null %}
{{ include('@ElementsDemiFrontend/Includes/overlays/price-info.html.twig', {
'title': 'demi.detail.room.price-info'|trans ,
'id': 'price-info-' ~ id ~ '-room-row-0',
'priceData': priceData,
'accommodationProduct': accommodationProduct,
'roomRow': roomRow,
'roomRowIndex': 0,
'productSet': product,
}) }}
<script>
_config.ajaxOverlay = true;
</script>
{% endif %}
{% endif %}
</div>
{% if not hasSingleRoomRow %}
<div class="teaser-detail mx-2">
<div class="card box-shadow">
{% for productIndex, product in productData['products'] %}
{% set roomRow = productData['roomRow'][productIndex].getRowObject() %}
{% set accommodationProduct = pimcore_object(product.getProductId()) %}
{% set id = accommodationProduct ? accommodationProduct.getId() : product.getProductId() %}
{% set title = accommodationProduct.getName() %}
{% if product is not null and roomRow is not null %}
{% set priceData = product.getPriceData() %}
{% set price = product.getPrice() %}
{% set showVacancy = true %}
{% set showSelection = true %}
{% set vacancyCount = product.getUnits() %}
{% elseif product is not null %}
{% set price = product.getBasePrice() %}
{% set showVacancy = false %}
{% set showSelection = false %}
{% set vacancyCount = 0 %}
{% set priceInfo = product.getPriceInfo() %}
{% set priceInfoText = include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type': priceInfo['type'], 'nights': priceInfo['nights']}) %}
{% endif %}
{% if searchParam.getDateFrom() is not null %}
{% if searchParam is instanceof('\Elements\Demi\Package\Search\Parameter') %}
{% set mealArray = [] %}
{% else %}
{% set mealArray = accommodationProduct.getValidMeals(searchParam.getPeriod(), fromDate) %}
{% endif %}
{% set liveMeal = product.getMealCode() %}
{% set liveMealObj = demi_getClassByStringAndIdentifier("\\Elements\\Demi\\Model\\MealType", "getByFid", liveMeal) %}
{% if liveMeal not in mealArray|keys %}
{% set mealArray = mealArray|merge([liveMealObj]) %}
{% endif %}
{% else %}
{% set mealArray = accommodationProduct.getValidMeals(0, fromDate) %}
{% endif %}
{% set serviceImages = accommodationProduct.getService().getImages(null, fromDate) %}
{% set productImages = accommodationProduct.getImages(null, fromDate) %}
{% set images = productImages|merge(serviceImages) %}
<div class="js-room-selection__room-row"
data-room-row-id="{{ productIndex }}"
data-initial-price="{{ product.getPrice() | number_format(2, '.', '') }}"
{% if (priceData and priceData.getPriceBeforeSpecial() > product.getPrice()) %}
data-initial-price-before-special="{{ priceData.getPriceBeforeSpecial() | number_format(2, '.', '') }}"
{% endif %}
data-room-row-title="{{ title|escape }}">
{% if (productIndex) %}
<hr class="m-0">
{% endif %}
<div class="card-body p-2">
{% set translation = 'demi.detail.room.select-headline-'~ (accommodationProduct.getAccommodationType()|lower) %}
<h4 class="h3 font-medium">{{ translation|trans }} {{ productIndex + 1 }}</h4>
<div class="mb-1 small text-muted">
<div class="media">
<div class="demi-icon demi-icon-person mr-1 icon-in-text" aria-hidden="true"></div>
<div class="media-body">
{% if roomRow is not null %}
{% set adults = roomRow.getAdults() %}
{% set children = roomRow.getChildAges()|length %}
{% set adultsStr = adults > 1 ? adults ~ " " ~ 'demi.detail.room.occupancy.adults'|trans : adults ~ " " ~ 'demi.detail.room.occupancy.adult'|trans %}
{% set childrenStr = children > 1 ? children ~ " " ~ 'demi.detail.room.occupancy.children'|trans : children ~ " " ~ 'demi.detail.room.occupancy.child'|trans %}
{% else %}
{% set adultsStr = accommodationProduct.getBedsMin() ~ "-" ~ accommodationProduct.getBedsMax()~ " ".translate('demi.detail.room.occupancy.persons') %}
{% endif %}
{{ adultsStr }}
{% if (children > 0) %}
, {{ childrenStr }}
{% endif %}
</div>
</div>
</div>
{% if (liveMealObj) %}
<div class="mb-1 small text-muted">
<span class="js-room-selection__meal-text">
{{ liveMealObj.getText() }}
</span>
{% if mealArray|length > 1 %}
<label for="meal-selector-{{ product.getProductId() }}" tabindex="0"
class="btn-no-styling increased-click-area js-room-selection__add">
<span class="demi-icon demi-icon-edit icon-in-text"
title="{{ 'demi.detail.change-meal'|trans }}"
aria-label="{{ 'demi.detail.change-meal'|trans }}"></span>
</label>
{% endif %}
</div>
{% endif %}
<div class="row align-items-baseline">
<div class="col">
{% if priceData is not null and priceData.getPriceBeforeSpecial() > product.getPrice() %}
<span class="sr-only">{{ 'demi.detail.room.old-price'|trans }}</span>
<s class="text-muted js-room-selection__price-before-special">{{ demi_paymentGetPriceObject(priceData.getPriceBeforeSpecial(), accommodation) }}</s>
{% endif %}
{% if priceInfoText is not empty %}
<div class="small text-muted">
{{ priceInfoText }}
</div>
{% endif %}
</div>
{% if price is defined and price > 0 %}
<strong class="col col-auto mr-auto">
<span class="price text-success" aria-live="polite">
<span class="js-room-selection__price">
{% if roomRow is null %}
{{ 'demi.price-from-short'|trans }}
{% endif %} {{ demi_paymentGetPriceObject(price, accommodation) }}
</span>
<span class="js-room-selection__price-loading" hidden>
<span class="circle-spinner circle-spinner--small float-left mr-1"
aria-label="{{ 'demi.content-loading'|trans }}"
title="{{ 'demi.content-loading'|trans }}"></span>
</span>
</span>
{% if priceData is not null %}
<button type="button" data-target="#price-info-{{ id }}-room-row-{{ productIndex }}"
class="btn-no-styling increased-click-area js-overlay__toggle text-gray-medium">
<span class="demi-icon demi-icon-info-circle icon-in-text"
title="{{ 'demi.detail.room.price-info'|trans }}"
aria-label="{{ 'demi.detail.room.price-info'|trans }}"></span>
</button>
{% endif %}
</strong>
{% endif %}
</div>
<div class="mt-2">
{{ include("@ElementsDemiFrontend/Includes/teaser/room-buttons.html.twig", {
'accommodationProduct': accommodationProduct,
'product': product,
'mealArray': mealArray,
'liveMealObj': liveMealObj,
'availabilityIsChecked': availabilityIsChecked,
'showSelection': showSelection,
'promotionText': promotionText
}) }}
</div>
</div>
{% if priceData is not null %}
{{ include('@ElementsDemiFrontend/Includes/overlays/price-info.html.twig',
{
'title': 'demi.detail.room.price-info'|trans,
'id': 'price-info-' ~ id ~ '-room-row-' ~ productIndex,
'priceData': priceData,
'accommodationProduct': accommodationProduct,
'roomRow': roomRow,
'roomRowIndex': productIndex,
'productSet': product
}) }}
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{{ include('@ElementsDemiFrontend/Includes/overlays/img-gallery.html.twig', {
'imagesTypes': ['Service', 'Product'],
'accommodation': accommodation,
'accommodationProduct': accommodationProduct,
'lazyLoadAll': true
}) }}
</div>
</li>
{% endif %}
{% endif %}