{% if freeCancellationInList %}
{% set freeCancellationInList = accommodationItem.getHasFreeCancellation(searchParam.getDateFrom(), searchParam.getDateTo()) %}
{% endif %}
{% set isWhiteLabel = demi_core_configuration("getIsWhitelabel",[]) %}
{% set isFused = isFused is defined ? isFused : false %}
{% set detailUrl = '' %}
{% set isPackageSearch = isPackageSearch is defined ? isPackageSearch : false %}
{% if noDate %}
{% set fromDate = null %}
{% else %}
{% set fromDate = demi_getSearchFrom().getTimeStamp() %}
{% endif %}
{% if accommodationItem %}
{% set accommodation = pimcore_object(accommodationItem.getAccommodationId()) %}
{% set minPriceProducts = accommodationItem.getMinPriceProductSets() %}
{% set totalVacancies = accommodationItem.getTotalVacanciesAndOffers().getTotalVacancies() %}
{% set totalOffers = accommodationItem.getTotalVacanciesAndOffers().getTotalOffers() %}
{% set actualBookable = accommodationItem.getActualBookable() %}
{% set price = noDate ? accommodationItem.getMinPriceBase() : accommodationItem.getMinPrice() %}
{% set priceBeforeSpecial = null %}
{% set hasMinprice = null %}
{% set minPriceMeal = null %}
{% if tvbPackage is defined and minPriceProducts | length > 0 %}
{% set mealCode = minPriceProducts.0.getMealCode() %}
{% endif %}
{% endif %}
{% if tvbPackage is defined and tvbPackage is not null %}
{% set detailUrl = demi_demiUrl({"accommodation" : accommodation, "package" : tvbPackage, "locale" : app.request.locale},
'demi_acco_detail_tvbpackage_page', noDate and app.request().get('nearbySearchId') is not defined) %}
{% set imageGalleryId = "id_" ~ accommodation.getId() %}
{% elseif isPackageSearch %}
{% set housePackageMaster = pimcore_object(accommodationItem.getHousePackageMasterId()) %}
{% set detailUrl = demi_demiUrl({'accommodation' : accommodation, 'package' : housePackageMaster, "locale" : app.request.locale},
'demi_acco_detail_package_page', noDate and app.request().get('nearbySearchId') is not defined) %}
{% set imageGalleryId = "id_" ~ housePackageMaster.getId() %}
{% else %}
{% set detailUrl = pimcore_url({'object' : accommodation, "language": app.request.locale},
'demi_acco_detail_page', noDate and app.request().get('nearbySearchId') is not defined) %}
{% set imageGalleryId = "id_" ~ accommodation.getId() %}
{% endif %}
{% set lightboxTopBarUrl = url('demi_lightbox_topbar_content', {
'path' : document.getFullPath | trim('/', 'right')
}) %}
{% set maxRatingValue = demi_core_configuration("getMaxRatingValue", {}) ?: 5 %}
{% set maxRatingNormalized = demi_core_configuration("getMaxRatingNormalized", {}) ?: 5 %}
{% if noDate and isPackageSearch %}
{% set myMinPrice = 0 %}
{% for accommodationProduct in accommodationItem.getProducts() %}
{% if accommodationProduct.getBasePrice() is not null and (myMinPrice == 0 or myMinPrice > accommodationProduct.getBasePrice()) %}
{% set myMinPrice = accommodationProduct.getBasePrice() %}
{% endif %}
{% endfor %}
{% set price = myMinPrice %}
{% endif %}
{% set targetBlank = '' %}
{% if not isWhiteLabel and not pimcore_device().isPhone() %}
{% set targetBlank = 'target="_blank"' %}
{% endif %}
{% set isMapAllowed = not pimcore_checkbox('noMapAllowed').isChecked() %}
{% set accoPosition = accommodation.getPosition() %}
<section
class="teaser {{ bodyPadding is defined and bodyPadding ? 'teaser--body-padding' : '' }} isClickable {{ styleModifier }} js-tracking js-tracking--impression"
data-acco-id="{{ accommodation.getId() }}"
{% if accoPosition is not null and (searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getIsAlternative()) %}
data-acco-lat="{{ accoPosition.getLatitude() }}"
data-acco-lon="{{ accoPosition.getLongitude() }}"
{% endif %}
data-tracking-name="{{ demi_impressionName(accommodation) }}"
data-tracking-id="{{ accommodation.getId() }}"
data-tracking-category="{{ demi_impressionCategory(accommodation,housePackageMaster is defined ? housePackageMaster : null ,searchParam,tvbPackage is defined ? tvbPackage : null) }}"
data-tracking-position="{{ position }}"
data-tracking-brand="{{ demi_impressionBrand(accommodation) }}"
data-tracking-list="{{ demi_impressionListType(searchParam) }}"
data-tracking-price="{{ price is defined ? (price | number_format(2, '.', '')) : '' }}"
>
<div class="row {{ pimcore_device().isPhone() ? 'row--gutter-width-10' : 'row--gutter-width-20' }}">
{# Image Column (left) #}
<div class="col-4 col-md-3 d-flex flex-column">
{% set gallerySrcUrl = demi_demiUrl({
'path' : 'demi',
'objectId' : isPackageSearch ? housePackageMaster.getId() : accommodation.getId(),
'fallbackId' : isPackageSearch ? accommodation.getId() : '',
'thumbnail' : 'demi-desktop-gallery',
'thumbSmall' : 'demi-desktop-gallery-small',
'dateFrom' : fromDate ?: ''
}, 'demi_images') %}
{% set useHpmImage = (tvbPackage is not defined or tvbPackage is null) and housePackageMaster is defined and housePackageMaster is not null and housePackageMaster.getPackagetype()!='HousePackageMasterSelfAssign' %}
{% set firstImageUrl = demi_demiUrl({
'path' : 'demi',
'objectId' : useHpmImage ? housePackageMaster.getId() : accommodation.getId(),
'fallbackId' : isPackageSearch ? accommodation.getId() : '',
'thumbnail' : 'demi-hotel-list-teaser',
'dateFrom' : fromDate ?: ''
}, 'demi_image') %}
<script type="text/javascript" data-cookieconsent="ignore">
_config.lightbox = true
_config.lazyImg = true
</script>
<div class="teaser__img btn-show-gallery-container js-lazy-img js-lazy-img--bg"
data-img-url="{{ firstImageUrl }}"
role="img"
aria-label="{{ accommodation.getName() | replace({"*" : ""}) }}">
{% if not pimcore_device().isPhone() %}
<button type="button"
class="btn-show-gallery btn-no-styling js-lightbox-group-dyn js-tracking--click-piwik"
aria-label="{{ 'demi.detail.open-gallery' | trans }}"
title="{{ 'demi.detail.open-gallery' | trans }}"
data-lightbox-id="{{ imageGalleryId }}"
data-lightbox-src-url="{{ gallerySrcUrl }}"
data-lightbox-topbar-content-url="{{ lightboxTopBarUrl }}?ajax=1&id={{ accommodation.getId() }}{{ housePackageMaster ? '&pid='~housePackageMaster.getId() : '' }}{{ tvbPackage ? '&tid='~tvbPackage.getId():'' }}"
data-lightbox-topbar-wrapper="#lightboxTopBar"
data-tracking-category="{{ isPackageSearch ? 'Package list': 'Accommodation list' }}"
data-tracking-action="open gallery">
<span class="js-lightbox-group-dyn__icon demi-icon demi-icon-search btn-show-gallery__icon"
aria-hidden="true"></span>
<span class="js-lightbox-group-dyn__loading" hidden>
<span class="text-center d-block">
<span class="circle-spinner circle-spinner--white"
aria-label="{{ 'demi.content-loading' | trans }}"
title="{{ 'demi.content-loading' | trans }}"></span>
</span>
</span>
</button>
{% endif %}
</div>
{# // Min Price #}
{% if hasMinPrice is defined and hasMinPrice %}
{% for special in demiAccommodationResultSetHelper.getMinPriceProductSpecials(accommodationItem) %}
<div class="teaser__label bg-warning text-center p-1 small text-white strong">
{{ special }}
</div>
{% endfor %}
{% endif %}
</div>
{#
// Desktop Center Column / Mobile right col
#}
<div class="{{ pimcore_device().isPhone() ? "col-8" : "col" }} teaser__body">
<div class="teaser__main-body">
{% if accommodation.getIsTesthotel() %}
<div class="demi-test-acco-notice text-danger"><strong>Testbetrieb</strong> nur für Debug/aktive
Pimcore User sichtbar
</div>
{% endif %}
{% if isPackageSearch %}
<h3 class="mb-1 text-primary teaser__acco-title">
<a href="{{ detailUrl }}" {{ targetBlank|raw }}>{{ housePackageMaster.getName() }} </a>
</h3>
{% endif %}
<h3 class="mb-1{{ isPackageSearch ? '' : ' text-primary teaser__acco-title' }}">
{% if not isPackageSearch %}
<a href="{{ detailUrl }}" {{ targetBlank|raw }}>{{ demi_getAccoNameWithStars(accommodation)|raw }}</a>
{% else %}
{{ demi_getAccoNameWithStars(accommodation) }}
{% endif %}
</h3>
{% if accommodation.getRatingSystem() is same as "TrustYou" %}
{% set normalizedRating = demi_ratingGetNormalized(accommodation, maxRatingValue, maxRatingNormalized) %}
{% if pimcore_device().isPhone() and normalizedRating %}
{{ include('@ElementsDemiFrontend/Includes/rating.html.twig', {
"score" : normalizedRating,
"text" : accommodation.getRatingScoreDescription(),
"styleModifier" : "mb-1 text-success",
"isTextWhite" : false
}) }}
{% endif %}
{% endif %}
<div class="mb-1">
{{ accommodation.getCategoryNames() }}
</div>
<div class="mb-1">
{{ include('@ElementsDemiFrontend/Includes/accoClassifications.html.twig', {
'classifications' : accommodation.getClassifications()
}) }}
</div>
<div class="mb-1 small text-muted">
{% if accommodation.getTown() and accommodation.getTown().getName() %}
<div class="media">
<div class="demi-icon demi-icon-marker mr-1 icon-in-text"
title="{{ 'demi.list.town' | trans }}"
aria-label="{{ 'demi.list.town' | trans }}"></div>
<div class="media-body">
{{ accommodation.getTown().getName() }}
</div>
</div>
{% elseif accommodation.getDistrict() and (accommodation.getDistrict().getNameLocalized(app.request.locale) or accommodation.getDistrict().getName()) %}
<div class="media">
<div class="demi-icon demi-icon-marker mr-1 icon-in-text"
title="{{ 'demi.list.town' | trans }}"
aria-label="{{ 'demi.list.town' | trans }}"></div>
<div class="media-body">
{{ accommodation.getDistrict().getNameLocalized(app.request.locale) ?? accommodation.getDistrict().getName() }}
</div>
</div>
{% endif %}
</div>
{% if searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getIsAlternative() %}
<div class="text-primary small font-medium">
{% set nights = searchParam.getNights() %}
{% set array = {"[FROM-TO]" : min(nights) ~ '-' ~ max(nights),
"[FROM-DATE]" : elements_dateFormat(searchParam.getDateFrom().getTimestamp(), 'date-long'),
"[TO-DATE]" : elements_dateFormat(searchParam.getDateTo().getTimestamp(), 'date-long')} %}
{{ demi_fillTranslation(array, "demi.detail.alternative-search-suggestion", app.request.locale) }}
</div>
{% endif %}
{% if nearbySearchName is defined and nearbySearchName is not null and accoPosition is not null %}
{% set latAcco = accoPosition.getLatitude() %}
{% set longAcco = accoPosition.getLongitude() %}
{% set latNbSO = app.request().get("nearbySearchLat") %}
{% set longNbSO = app.request().get("nearbySearchLong") %}
{% set distanceValue = demi_calcDistance(latAcco,longAcco,latNbSO,longNbSO) %}
{% set distance = {
'value' : demi_fillTranslation({"[DISTANCE]" : distanceValue | round(1)}, "demi.list.nearby-search.text"),
'from' : 'demi.list.nearby-search.from' | trans ~ ' ' ~ nearbySearchName
} %}
{% if distanceValue %}
<div class="mb-1 distance-info small">
<span class="badge distance-info__badge">{{ distance.value }}</span>
{% if accommodationItem.getDistanceMinutesToPoi() %}
<span>{{ demi_fillTranslation({"[MIN]" : accommodationItem.getDistanceMinutesToPoi() | round(1)}, "demi.list.nearby-search.distance-in-min") }}</span>
{% endif %}
<br>
<span>{{ distance.from }}</span>
</div>
{% endif %}
{% endif %}
{% if accommodationItem %}
{{ include('@ElementsDemiFrontend/Includes/teaser/badges.html.twig', {
'accommodation' : accommodation,
'accommodationItem' : accommodationItem
}) }}
{% endif %}
{% set accoTopFacilities = demi_getTopFacilitiesForAccommodation(accommodation,demi_core_configuration("getTopFacilities", {})) %}
{% if not pimcore_device().isPhone() and accoTopFacilities | length > 0 or freeCancellationInList %}
<ul class="list-inline list-inline--dots mb-1 small">
{% if freeCancellationInList %}
<li class="list-inline-item free-cancellation">
{{ searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getFreeCancellation() ? "demi.list.free-cancellation-filtered" : "demi.list.free-cancellation" | trans }}
</li>
{% endif %}
{% if accoTopFacilities | length > 0 %}
{% for topFacility in accoTopFacilities %}
<li class="list-inline-item">
{{ topFacility.getName() }}
</li>
{% endfor %}
{% endif %}
</ul>
{% elseif freeCancellationInList %}
<ul class="list-inline list-inline--dots mb-1 small">
<li class="list-inline-item free-cancellation">
{{ searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and searchParam.getFreeCancellation() ? "demi.list.free-cancellation-filtered" : "demi.list.free-cancellation" | trans }}
</li>
</ul>
{% endif %}
{% set tvbListNoDate = searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and not searchParam.getDateFrom() %}
{% if pimcore_device().isPhone() and actualBookable and not tvbListNoDate %}
{{ include('@ElementsDemiFrontend/Accommodation/includes/acco-teaser-vacancy-info.html.twig', {
'totalVacancies':totalVacancies,
'totalOffers':totalOffers
}) }}
{% endif %}
</div>
<hr class="my-1 d-md-none">
<div class="teaser__price-body d-md-none">
<div class="mb-1 small text-muted">
<div class="media">
{% if minPriceMeal %}
<div class="demi-icon demi-icon-restaurant mr-1"
aria-label="{{ 'demi.list.meals' | trans }}"
title="{{ 'demi.list.meals' | trans }}"></div>
<div class="media-body">
{{ minPriceMeal }}
</div>
{% elseif searchParam.getIsCorridor() %}
<div class="media-body">{{ 'demi.detail.priceinfo.per-person-per-night' | trans }}</div>
{% elseif accommodationItem and accommodationItem.getPriceInfo() %}
<div
class="media-body">{{ include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type' : accommodationItem.getPriceInfo().type, 'nights' : accommodationItem.getPriceInfo().nights}) }}</div>
{% elseif accommodationItem and accommodationItem.getMinPriceProductSets() is not empty and accommodationItem.getMinPriceProductSets()[0].getPriceInfo() is iterable and accommodationItem and accommodationItem.getMinPriceProductSets() %}
{% set productToUse = accommodationItem.getMinPriceProductSets()[0] %}
{% if productToUse.getPriceInfo() is not empty %}
<div
class="media-body">{{ include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type' : productToUse.getPriceInfo().rule, 'nights' : productToUse.getPriceInfo().nights }) }}</div>
{% endif %}
{% elseif not noDate and useLtsAndFusedMapTranslation is defined and accommodationItem is not defined %}
{{ 'demi.list.map.not-available-for-filters' | trans }}
{% endif %}
</div>
</div>
{# Column right #}
<div class="row align-items-baseline">
<div class="col">
{% if priceBeforeSpecial > price %}
<span class="sr-only">{{ 'demi.instead-of' | trans }}</span>
<span class="col text-muted">
{{ demi_paymentGetPriceObject(priceBeforeSpecial, accommodation) }}
</span>
{% endif %}
</div>
{% if price > 0 %}
<strong class="col col-auto mr-auto text-success">
{{ "demi.price-from-short" | trans }} <span
class="acco-teaser__price">{{ demi_paymentGetPriceObject(price, accommodation) }}</span>
</strong>
{% endif %}
</div>
</div>
<a href="{{ detailUrl }}" class="teaser__arrow demi-icon demi-icon-chevron-right d-md-none"
title="{{ 'demi.list.detailsite' | trans }}" aria-label="{{ 'demi.list.detailsite' | trans }}"></a>
</div>
<div class="d-none d-md-block col teaser__price-body--big">
<div class="row h-100">
<div class="col">
{% if accommodation.getRatingSystem() is same as "TrustYou" %}
{% set normalizedRating = demi_ratingGetNormalized(accommodation, maxRatingValue, maxRatingNormalized) %}
{% if not pimcore_device().isPhone() and normalizedRating %}
<div class="trustyou-logo mb-1"><span class="sr-only">TrustYou Rating</span></div>
{{ include('@ElementsDemiFrontend/Includes/rating.html.twig', {
"score" : normalizedRating,
"text" : accommodation.getRatingScoreDescription(),
"styleModifier" : "mb-2 text-success",
"showReviewCount" : false,
"isTextWhite" : false
}) }}
{% endif %}
{% endif %}
<div class="mb-1 small text-muted">
<div class="media">
{% if minPriceMeal %}
<div class="demi-icon demi-icon-restaurant mr-1"
aria-label="{{ 'demi.list.meals' | trans }}"
title="{{ 'demi.list.meals' | trans }}"></div>
<div class="media-body">
{{ minPriceMeal }}
</div>
{% elseif searchParam.getIsCorridor() %}
<div class="media-body">{{ 'demi.detail.priceinfo.per-person-per-night' | trans }}</div>
{% elseif accommodationItem and accommodationItem.getPriceInfo() %}
<div
class="media-body">{{ include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type' : accommodationItem.getPriceInfo().type, 'nights' : accommodationItem.getPriceInfo().nights }) }}</div>
{% elseif accommodationItem and accommodationItem.getMinPriceProductSets() is not empty and accommodationItem.getMinPriceProductSets()[0] and accommodationItem.getMinPriceProductSets()[0].getPriceInfo() is iterable %}
{% set productToUse = accommodationItem.getMinPriceProductSets()[0] %}
{% if productToUse.getPriceInfo() is not empty %}
<div
class="media-body">{{ include('@ElementsDemiFrontend/Includes/priceInfoStr.html.twig', {'type' : productToUse.getPriceInfo().rule, 'nights' : productToUse.getPriceInfo().nights}) }}</div>
{% endif %}
{% endif %}
</div>
</div>
<div class="row align-items-baseline mb-1">
<div class="{{ priceBeforeSpecial > price ? 'col ': '' }}col-lg-12">
{% if (priceBeforeSpecial > price) %}
<span class="sr-only">{{ 'demi.instead-of' | trans }}</span>
<s class="text-muted">{{ demi_paymentGetPriceObject(priceBeforeSpecial, accommodation) }}</s>
{% endif %}
</div>
{% if price > 0 %}
<strong class="col col-auto mr-auto text-success">
{{ "demi.price-from-short" | trans }} <span
class="teaser__price">{{ demi_paymentGetPriceObject(price,accommodation) }}</span>
</strong>
{% endif %}
</div>
{% set tvbListNoDate = searchParam is instanceof("\\Elements\\Demi\\Accommodation\\Search\\Parameter") and not searchParam.getDateFrom() %}
{% if actualBookable and not tvbListNoDate %}
{{ include('@ElementsDemiFrontend/Accommodation/includes/acco-teaser-vacancy-info.html.twig', {
'totalVacancies' : totalVacancies,
'totalOffers' : totalOffers,
'styleModifier' : ''
}) }}
{% endif %}
{% if isMapAllowed and accoPosition is not null and accoPosition.getLatitude() and accoPosition.getLongitude() %}
<button type="button"
class="btn-no-styling js-accommodation-map__show-on-map teaser__show-on-map mt-2">
<span class="demi-icon demi-icon-marker icon-in-text" aria-hidden="true"></span>
<span>
{{ 'demi.list.show-on-map' | trans }}
</span>
</button>
{% endif %}
</div>
<div class="col col-auto align-self-center">
<a href="{{ detailUrl }}" class="btn btn-default teaser__detail-btn" {{ isWhiteLabel ? 'target="_blank"' : '' }}
title="{{ 'demi.list.detailsite' | trans }}" aria-label="{{ 'demi.list.detailsite' | trans }}">
<span class="demi-icon demi-icon-arrow-right" aria-hidden="true"></span>
</a>
</div>
</div>
</div>
</div>
</section>