Migrate groups price calculator

This commit is contained in:
Björn Fromme
2021-12-22 15:50:48 +01:00
parent 4894a8b869
commit 16eb99744d
5 changed files with 188 additions and 112 deletions
@@ -9,7 +9,7 @@ page {
bodyTagCObject = COA
bodyTagCObject {
10 = TEXT
10.value = <body class="antialiased text-gray-800 font-sans pt-14 lg:pt-8
10.value = <body class="antialiased text-gray-800 font-sans pt-14 lg:pt-8 bg-white
20 = TEXT
20 {
field = tx_eptheme_bodyclass
@@ -162,3 +162,9 @@ page {
if.isTrue = {$plugin.tx_eptheme.settings.cookieFirstKey}
}
}
[page["backend_layout"] == 'pagets__popup']
page.bodyTagCObject >
page.bodyTagCObject = TEXT
page.bodyTagCObject.value = <body class="antialiased text-gray-800 font-sans bg-white p-4">
[end]
@@ -1,143 +1,209 @@
<template>
<div class="container relative">
<div class="mb-4"
<div class="relative">
<div class="mb-8"
v-show="!submitted">
<label class="mb-2 font-bold">
Zeitraum
</label>
<input type="text"
class="border-gray-400 focus:border-gray-800 mt-1 w-full"
class="form-field"
placeholder="von... bis" ref="picker"/>
</div>
<div class="form-group" v-show="!submitted">
<label>Personenzahl</label>
<input type="number" class="form-control" v-model.number="selectedPax" @change="onPaxUpdated()"
<div class="mb-8"
v-show="!submitted">
<label class="mb-2 font-bold">
Personenzahl
</label>
<input type="number"
class="form-field"
v-model.number="selectedPax"
@change="onPaxUpdated()"
v-show="nightsCount > 0 && !includesBonusCard"/>
<div class="flex space-x-4" v-show="nightsCount > 0 && includesBonusCard">
<div class="w-1/3 flex flex-col space-y-1">
<span>ab 15 Jahre</span>
<input type="number" class="form-control" v-model.number="selectedPaxGroup3" @change="onPaxUpdated()"/>
<input type="number"
class="form-control"
v-model.number="selectedPaxGroup3"
@change="onPaxUpdated()"/>
</div>
<div class="w-1/3 flex flex-col space-y-1">
<span>7-14 Jahre</span>
<input type="number" class="form-control" v-model.number="selectedPaxGroup2" @change="onPaxUpdated()"/>
<input type="number"
class="form-control"
v-model.number="selectedPaxGroup2"
@change="onPaxUpdated()"/>
</div>
<div class="w-1/3 flex flex-col space-y-1">
<span>4-6 Jahre</span>
<input type="number" class="form-control" v-model.number="selectedPaxGroup1" @change="onPaxUpdated()"/>
<input type="number"
class="form-control"
v-model.number="selectedPaxGroup1"
@change="onPaxUpdated()"/>
</div>
</div>
<p class="text-sm italic" v-show="nightsCount === 0">Bitte wählen Sie einen Zeitraum</p>
<p class="text-sm italic"
v-show="nightsCount === 0">
Bitte zuerst einen Zeitraum wählen
</p>
</div>
<div class="form-group" v-show="options.length > 0 && !submitted">
<label>Optionale Zusatzleistungen</label>
<div class="checkbox" v-for="option of options" :key="option.uid">
<label>
<input type="checkbox" v-model="selectedOptions" :value="option">
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
{{ option.title }}{{ formatOptionPriceType(option) }}
</label>
<div class="mb-8"
v-show="options.length > 0 && !submitted">
<div class="mb-2 font-bold">
Optionale Zusatzleistungen
</div>
<ul class="mb-0 p-0 space-y-2">
<li v-for="option of options" :key="option.uid">
<label class="flex items-start">
<input type="checkbox"
class="w-5 h-5 border-ep-primary-light ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
v-model="selectedOptions"
:value="option">
<span class="pl-2 leading-none">{{ option.title }}{{ formatOptionPriceType(option) }}</span>
</label>
</li>
</ul>
</div>
<div class="form-group" v-show="boards.length > 0 && !submitted">
<label>Optionale Verpflegungsleistungen</label>
<select class="form-control" v-model="selectedBoard" v-if="totalPax >= 30">
<div class="mb-8"
v-show="boards.length > 0 && !submitted">
<label class="mb-2 font-bold">
Optionale Verpflegungsleistungen
</label>
<select class="form-field"
v-model="selectedBoard"
v-if="totalPax >= 30">
<option :value="null">Keine Auswahl</option>
<option v-for="board of boards" :value="board" :key="board.uid">{{ board.title }}
({{ formatCurrency(board.price) }} pro Person und Nacht)
<option v-for="board of boards"
:value="board"
:key="board.uid">
{{ board.title }} ({{ formatCurrency(board.price) }} pro Person und Nacht)
</option>
</select>
<div v-show="totalPax < 30">
<span class="label label-warning">Erst ab 30 Personen buchbar.</span>
<span class="text-red-600">Erst ab 30 Personen buchbar.</span>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Preise</div>
<div class="panel-body">
<table class="table table-striped" v-show="nightsCount > 0">
<div class="mb-8">
<div class="p-2 uppercase bg-ep-primary-dark text-white w-full">
Preise
</div>
<div class="bg-gray-100 p-2">
<table class="w-full" v-show="nightsCount > 0">
<tbody>
<tr>
<th>Zeitraum</th>
<tr class="odd:bg-gray-100">
<th class="text-left py-2">Zeitraum</th>
<td>{{ rangeFormatted }}, {{ nightsCount }} Nächte</td>
</tr>
<tr>
<th>Basispreis</th>
<tr class="odd:bg-gray-100">
<th class="text-left py-2">Basispreis</th>
<td>{{ formatCurrency(pricePax.base) }}</td>
</tr>
<tr v-if="pricePax.additional > 0">
<th>Aufpreis Personenzahl</th>
<tr class="odd:bg-gray-100"
v-if="pricePax.additional > 0">
<th class="text-left py-2">Aufpreis Personenzahl</th>
<td>{{ formatCurrency(pricePax.additional) }}</td>
</tr>
<tr v-if="priceShortTerm > 0">
<th>Aufpreis Kurzzeit</th>
<tr class="odd:bg-gray-100"
v-if="priceShortTerm > 0">
<th class="text-left py-2">Aufpreis Kurzzeit</th>
<td>{{ formatCurrency(priceShortTerm) }}</td>
</tr>
<tr v-if="includesBonusCard">
<th>Inklusivleistungen</th>
<tr class="odd:bg-gray-100"
v-if="includesBonusCard">
<th class="text-left py-2">Inklusivleistungen</th>
<td>
<a href="https://www.saalbach.com/de/sommer/joker-card" target="_blank" class="uppercase">
Joker Card
</a>
</td>
</tr>
<tr v-if="selectedOptions.length > 0">
<th>Zusatzleistungen</th>
<tr class="odd:bg-gray-100"
v-if="selectedOptions.length > 0">
<th class="text-left py-2">Zusatzleistungen</th>
<td>{{ formatCurrency(priceOptions) }}</td>
</tr>
<tr v-if="priceBoard > 0">
<th>Verpflegung</th>
<tr class="odd:bg-gray-100"
v-if="priceBoard > 0">
<th class="text-left py-2">Verpflegung</th>
<td>{{ formatCurrency(priceBoard) }}</td>
</tr>
<tr v-if="priceRunningCosts > 0">
<th>Strom- und Abfallgebühren</th>
<tr class="odd:bg-gray-100"
v-if="priceRunningCosts > 0">
<th class="text-left py-2">Strom- und Abfallgebühren</th>
<td>{{ formatCurrency(priceRunningCosts) }}</td>
</tr>
<tr>
<th>Gesamtpreis</th>
<tr class="odd:bg-gray-100">
<th class="text-left py-2">Gesamtpreis</th>
<td><strong>{{ formatCurrency(priceTotal) }}</strong><br><small>zzgl. vor Ort zu entrichtender
Ortstaxe</small></td>
</tr>
</tbody>
</table>
<div v-show="nightsCount === 0">
<span class="label label-warning">Bitte wählen Sie einen Zeitraum</span>
</div>
<p class="text-sm italic"
v-show="nightsCount === 0">
Bitte zuerst einen Zeitraum wählen
</p>
</div>
</div>
<div class="panel panel-default" v-show="nightsCount > 0 && !submitted">
<div class="panel-heading">Angebot anfordern</div>
<div class="panel-body">
<div class="form-group" :class="{ 'has-error': formErrors.name }">
<label>Name*</label>
<input type="text" class="form-control" v-model="name">
<div class="help-block"
v-show="formErrors.name" v-html="formErrors.name"></div>
</div>
<div class="form-group" :class="{ 'has-error': formErrors.email }">
<label>E-Mail*</label>
<input type="text" class="form-control" v-model="email">
<div class="help-block"
v-show="formErrors.email" v-html="formErrors.email"></div>
</div>
<div class="form-group" :class="{ 'has-error': formErrors.phone }">
<label>Telefon*</label>
<input type="text" class="form-control" v-model="phone">
<div class="help-block"
v-show="formErrors.phone" v-html="formErrors.phone"></div>
</div>
<div class="form-group">
<label>Bemerkungen/Wünsche</label>
<textarea class="form-control" cols="30" rows="3" v-model="remarks"/>
</div>
<div class="form-group">
<button class="button" type="submit" @click.prevent="submitForm()">SENDEN</button>
<div class="mb-8"
v-show="nightsCount > 0 && !submitted">
<div class="p-2 uppercase bg-ep-primary-dark text-white w-full">
Angebot anfordern
</div>
<div class="bg-gray-100 p-2">
<div class="grid md:grid-cols-2 gap-4 mb-4">
<div :class="{ 'has-error': formErrors.name }">
<label class="font-bold mb-2">
Name*
</label>
<input type="text"
class="form-field"
v-model="name">
<div class="text-sm text-red-600 mt-1"
v-show="formErrors.name"
v-html="formErrors.name"></div>
</div>
<div :class="{ 'has-error': formErrors.email }">
<label class="font-bold mb-2">
E-Mail*
</label>
<input type="text"
class="form-field"
v-model="email">
<div class="text-sm text-red-600 mt-1"
v-show="formErrors.email"
v-html="formErrors.email"></div>
</div>
<div :class="{ 'has-error': formErrors.phone }">
<label class="font-bold mb-2">
Telefon*
</label>
<input type="text"
class="form-field"
v-model="phone">
<div class="text-sm text-red-600 mt-1"
v-show="formErrors.phone"
v-html="formErrors.phone"></div>
</div>
<div>
<label class="font-bold mb-2">
Bemerkungen/Wünsche
</label>
<textarea class="form-field"
cols="30"
rows="3"
v-model="remarks"/>
</div>
</div>
<button class="button"
type="submit"
@click.prevent="submitForm()">
Senden
</button>
</div>
</div>
<div class="panel panel-default form-success" v-show="submitted">
<div class="panel-body">
<strong>Vielen Dank für Ihre Anfrage. Wir werden diese schnellstmöglich bearbeiten.</strong>
</div>
<div class="py-8 text-xl text-center font-bold" v-show="submitted">
Vielen Dank für Ihre Anfrage. Wir werden diese schnellstmöglich bearbeiten.
</div>
<div class="fixed top-0 left-0 inset-0 bg-overlay-white flex items-center justify-center" v-show="processing">
<img :src="loaderUri" alt="Loading...">
@@ -265,30 +331,37 @@ export default {
}
},
submitForm() {
let options = [];
for (let option of this.selectedOptions) {
options.push(option.uid);
let formData = new URLSearchParams({
'tx_epproducts_ajax[groupsPriceInquiry][name]': this.name ? this.name : '',
'tx_epproducts_ajax[groupsPriceInquiry][email]': this.email? this.email : '',
'tx_epproducts_ajax[groupsPriceInquiry][phone]': this.phone ? this.phone : '',
'tx_epproducts_ajax[groupsPriceInquiry][remarks]': this.remarks,
'tx_epproducts_ajax[groupsPriceInquiry][dateFrom]': this.selectedFrom.format('DD.MM.YYYY'),
'tx_epproducts_ajax[groupsPriceInquiry][dateTo]': this.selectedTo.format('DD.MM.YYYY'),
'tx_epproducts_ajax[groupsPriceInquiry][pax]': this.includesBonusCard ? '' : this.selectedPax,
'tx_epproducts_ajax[groupsPriceInquiry][paxGroup1]': this.includesBonusCard ? this.selectedPaxGroup1 : '',
'tx_epproducts_ajax[groupsPriceInquiry][paxGroup2]': this.includesBonusCard ? this.selectedPaxGroup2 : '',
'tx_epproducts_ajax[groupsPriceInquiry][paxGroup3]': this.includesBonusCard ? this.selectedPaxGroup3 : '',
'tx_epproducts_ajax[groupsPriceInquiry][summary][paxBase]': this.formatCurrency(this.pricePax.base),
'tx_epproducts_ajax[groupsPriceInquiry][summary][paxAdditional]': this.formatCurrency(this.pricePax.additional),
'tx_epproducts_ajax[groupsPriceInquiry][summary][shortTerm]': this.formatCurrency(this.priceShortTerm),
'tx_epproducts_ajax[groupsPriceInquiry][summary][options]': this.priceOptions,
'tx_epproducts_ajax[groupsPriceInquiry][summary][board]': this.formatCurrency(this.priceBoard),
'tx_epproducts_ajax[groupsPriceInquiry][summary][priceRunningCosts]': this.formatCurrency(this.priceRunningCosts),
'tx_epproducts_ajax[groupsPriceInquiry][summary][total]': this.formatCurrency(this.priceTotal),
})
if (this.selectedBoard) {
formData.append('tx_epproducts_ajax[groupsPriceInquiry][board]', this.selectedBoard.uid)
}
let formData = new FormData()
formData.set('tx_epproducts_ajax[groupsPriceInquiry][name]', this.name)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][email]', this.email)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][phone]', this.phone)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][remarks]', this.remarks)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][dateFrom]', this.selectedFrom.format('DD.MM.YYYY'))
formData.set('tx_epproducts_ajax[groupsPriceInquiry][dateTo]', this.selectedTo.format('DD.MM.YYYY'))
formData.set('tx_epproducts_ajax[groupsPriceInquiry][pax]', this.includesBonusCard ? '' : this.selectedPax)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][paxGroup1]', this.includesBonusCard ? this.selectedPaxGroup1 : '')
formData.set('tx_epproducts_ajax[groupsPriceInquiry][paxGroup2]', this.includesBonusCard ? this.selectedPaxGroup2 : '')
formData.set('tx_epproducts_ajax[groupsPriceInquiry][paxGroup3]', this.includesBonusCard ? this.selectedPaxGroup3 : '')
formData.set('tx_epproducts_ajax[groupsPriceInquiry][board]', this.selectedBoard ? this.selectedBoard.uid : null)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][options]', options)
formData.set('tx_epproducts_ajax[groupsPriceInquiry][summary]', this.priceSummary)
this.selectedOptions.map(option => (
formData.append('tx_epproducts_ajax[groupsPriceInquiry][options][]', option.uid)
))
this.processing = true;
this.submitted = false;
axios({
url: this.endpoint,
method: 'POST',
data: formData
data: formData,
}).then(response => {
if ('validation' === response.data.status) {
this.formErrors = response.data.errors;
@@ -424,7 +497,6 @@ export default {
Vue.nextTick(() => {
this.picker = flatpickr(this.$refs.picker, {
mode: 'range',
inline: true,
dateFormat: 'd.m.Y',
locale: German,
onChange: selectedDates => {
@@ -5,12 +5,15 @@ export default class extends Controller {
static targets = [ 'thumb' ]
static values = { url: String }
static values = { url: String, height: String }
connect() {
let elements = []
if (this.hasUrlValue) {
let element = { href: this.urlValue }
if (this.hasHeightValue) {
element.height = this.heightValue
}
elements.push(element)
} else if (this.element.hasAttribute('href')) {
let element = { href: this.element.href }
@@ -3,17 +3,11 @@
xmlns:encore="http://typo3.org/ns/Ssch/Typo3Encore/ViewHelpers"
data-namespace-typo3-fluid="true">
<div class="container">
<div class="page-header">
<div class="media">
<div class="media-left media-middle">
<f:image class="media-object" width="128" src="EXT:ep_theme/Resources/Public/images/logo_wide.svg" alt=""/>
</div>
<div class="media-body">
<h1 class="media-heading">Preisberechnung <small>{hotel.name}</small></h1>
</div>
</div>
</div>
<div class="max-w-screen-lg mx-auto">
<h1 class="headline--underlined headline--has-subline">
<span class="subline">{hotel.name}</span>
Preisberechnung
</h1>
<f:format.raw>
<groups-price-calculator
configs-json='{configs}'
@@ -281,6 +281,7 @@
class="button w-full"
data-controller="lightbox"
data-lightbox-url-value="{f:uri.action(action: 'index', controller: 'GroupsPrice', arguments: '{hotel: hotel}', pageUid: settings.groupsPricePopupPageUid)}"
data-lightbox-height-value="85vh"
data-action="lightbox#open">
Preisberechnung
</button>