Merge branch 'develop' into feature/js-rework

This commit is contained in:
Björn Fromme
2021-08-10 11:03:36 +02:00
11 changed files with 14107 additions and 8888 deletions
Generated
+560 -416
View File
File diff suppressed because it is too large Load Diff
+12920 -8150
View File
File diff suppressed because it is too large Load Diff
@@ -95,6 +95,9 @@ class AjaxGroupsPriceController extends ActionController
'dateFrom' => $groupsPriceInquiry->getDateFrom(),
'dateTo' => $groupsPriceInquiry->getDateTo(),
'pax' => $groupsPriceInquiry->getPax(),
'paxGroup1' => $groupsPriceInquiry->getPaxGroup1(),
'paxGroup2' => $groupsPriceInquiry->getPaxGroup2(),
'paxGroup3' => $groupsPriceInquiry->getPaxGroup3(),
'options' => $selectedOptions,
'board' => $groupsPriceInquiry->getBoard(),
'summary' => $groupsPriceInquiry->getSummary(),
@@ -67,8 +67,10 @@ class ConceptController extends ActionController
$conceptUid = $this->settings['conceptUid'];
$concept = $this->conceptRepository->findByIdentifier($conceptUid);
}
$teaserConceptUids = GeneralUtility::trimExplode(',', $this->settings['additionalConceptUids']);
array_unshift($teaserConceptUids, $concept->getUid());
$filterSettings = new FilterSettings();
$filterSettings->setConceptUids([$concept->getUid()]);
$filterSettings->setConceptUids($teaserConceptUids);
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids'], true);
$limit = $this->settings['showMoreLink'] ? 4 : 0;
$teasers = $this->productDataService->getTeasergroup($filterSettings, $excludedConceptUids, $limit);
@@ -66,10 +66,24 @@ class GroupsPriceInquiry
/**
* @var string
* @TYPO3\CMS\Extbase\Annotation\Validate("NotEmpty")
*/
protected $pax;
/**
* @var string
*/
protected $paxGroup1;
/**
* @var string
*/
protected $paxGroup2;
/**
* @var string
*/
protected $paxGroup3;
/**
* @var array
*/
@@ -197,6 +211,54 @@ class GroupsPriceInquiry
$this->pax = $pax;
}
/**
* @return string
*/
public function getPaxGroup1()
{
return $this->paxGroup1;
}
/**
* @param string $paxGroup1
*/
public function setPaxGroup1($paxGroup1)
{
$this->paxGroup1 = $paxGroup1;
}
/**
* @return string
*/
public function getPaxGroup2()
{
return $this->paxGroup2;
}
/**
* @param string $paxGroup2
*/
public function setPaxGroup2($paxGroup2)
{
$this->paxGroup2 = $paxGroup2;
}
/**
* @return string
*/
public function getPaxGroup3()
{
return $this->paxGroup3;
}
/**
* @param string $paxGroup3
*/
public function setPaxGroup3($paxGroup3)
{
$this->paxGroup3 = $paxGroup3;
}
/**
* @return array
*/
@@ -56,6 +56,26 @@ class GroupsPriceConfig extends AbstractEntity implements \JsonSerializable
*/
protected $priceAdditionalPerson;
/**
* @var float
*/
protected $priceAdditionalPersonGroup1;
/**
* @var float
*/
protected $priceAdditionalPersonGroup2;
/**
* @var float
*/
protected $priceAdditionalPersonGroup3;
/**
* @var bool
*/
protected $bonusCardIncluded = false;
/**
* @return \DateTime
*/
@@ -136,6 +156,70 @@ class GroupsPriceConfig extends AbstractEntity implements \JsonSerializable
$this->priceAdditionalPerson = $priceAdditionalPerson;
}
/**
* @return float
*/
public function getPriceAdditionalPersonGroup1(): float
{
return $this->priceAdditionalPersonGroup1;
}
/**
* @param float $priceAdditionalPersonGroup1
*/
public function setPriceAdditionalPersonGroup1(float $priceAdditionalPersonGroup1): void
{
$this->priceAdditionalPersonGroup1 = $priceAdditionalPersonGroup1;
}
/**
* @return float
*/
public function getPriceAdditionalPersonGroup2(): float
{
return $this->priceAdditionalPersonGroup2;
}
/**
* @param float $priceAdditionalPersonGroup2
*/
public function setPriceAdditionalPersonGroup2(float $priceAdditionalPersonGroup2): void
{
$this->priceAdditionalPersonGroup2 = $priceAdditionalPersonGroup2;
}
/**
* @return float
*/
public function getPriceAdditionalPersonGroup3(): float
{
return $this->priceAdditionalPersonGroup3;
}
/**
* @param float $priceAdditionalPersonGroup3
*/
public function setPriceAdditionalPersonGroup3(float $priceAdditionalPersonGroup3): void
{
$this->priceAdditionalPersonGroup3 = $priceAdditionalPersonGroup3;
}
/**
* @return bool
*/
public function isBonusCardIncluded(): bool
{
return $this->bonusCardIncluded;
}
/**
* @param bool $bonusCardIncluded
*/
public function setBonusCardIncluded(bool $bonusCardIncluded): void
{
$this->bonusCardIncluded = $bonusCardIncluded;
}
/**
* @return array
*/
@@ -148,6 +232,12 @@ class GroupsPriceConfig extends AbstractEntity implements \JsonSerializable
'personsIncluded' => $this->getPersonsIncluded(),
'price' => $this->getPrice(),
'priceAdditionalPerson' => $this->getPriceAdditionalPerson(),
'priceAdditionalPersonByGroup' => [
1 => $this->getPriceAdditionalPersonGroup1(),
2 => $this->getPriceAdditionalPersonGroup2(),
3 => $this->getPriceAdditionalPersonGroup3(),
],
'bonusCardIncluded' => $this->isBonusCardIncluded(),
];
}
}
@@ -25,11 +25,25 @@
<numIndex index="1">0</numIndex>
</numIndex>
</items>
<minitems>0</minitems>
<minitems>1</minitems>
<maxitems>1</maxitems>
</config>
</TCEforms>
</settings.conceptUid>
<settings.additionalConceptUids>
<TCEforms>
<label>Weitere Konzepte für Teaser:</label>
<config>
<type>select</type>
<renderType>selectSingleBox</renderType>
<foreign_table>tx_epproducts_domain_model_concept</foreign_table>
<foreign_table_where>AND tx_epproducts_domain_model_concept.hidden = 0 AND tx_epproducts_domain_model_concept.deleted = 0 ORDER BY tx_epproducts_domain_model_concept.name</foreign_table_where>
<size>5</size>
<minitems>0</minitems>
<maxitems>10</maxitems>
</config>
</TCEforms>
</settings.additionalConceptUids>
<settings.showMoreLink>
<TCEforms>
<exclude>0</exclude>
@@ -25,16 +25,20 @@ return [
],
'interface' => [
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, date_from, date_to,
persons_included, price, price_additional_person',
persons_included, bonus_card_included, price, price_additional_person,
price_additional_person_group_1, price_additional_person_group_2, price_additional_person_group_3',
],
'types' => [
'1' => [
'showitem' => '--palette--;;dates, --palette--;;prices, persons_included',
'showitem' => '--palette--;;dates, --palette--;;included, --palette--;;prices, --palette--;;prices_groups',
],
],
'palettes' => [
'dates' => ['showitem' => 'date_from, date_to'],
'included' => ['showitem' => 'bonus_card_included, persons_included'],
'prices' => ['showitem' => 'price, price_additional_person'],
'prices_groups' => ['showitem' => 'price_additional_person_group_1, price_additional_person_group_2,
--linebreak--, price_additional_person_group_3'],
],
'columns' => [
@@ -50,6 +54,7 @@ return [
['LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages', -1],
['LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.default_value', 0]
],
'default' => -1,
],
],
'l10n_parent' => [
@@ -166,11 +171,49 @@ return [
'price_additional_person' => [
'exclude' => false,
'label' => 'Preis weitere Person',
'description' => 'ohne Jokercard, alle Altersgruppen',
'config' => [
'type' => 'input',
'size' => 8,
'eval' => 'double2,required',
'eval' => 'double2',
]
],
'price_additional_person_group_1' => [
'exclude' => false,
'label' => 'Preis weitere Person',
'description' => 'mit Jokercard, 4-6 Jahre',
'config' => [
'type' => 'input',
'size' => 8,
'eval' => 'double2',
]
],
'price_additional_person_group_2' => [
'exclude' => false,
'label' => 'Preis weitere Person',
'description' => 'mit Jokercard, 7-14 Jahre',
'config' => [
'type' => 'input',
'size' => 8,
'eval' => 'double2',
]
],
'price_additional_person_group_3' => [
'exclude' => false,
'label' => 'Preis weitere Person',
'description' => 'mit Jokercard, ab 15 Jahre',
'config' => [
'type' => 'input',
'size' => 8,
'eval' => 'double2',
]
],
'bonus_card_included' => [
'exclude' => 0,
'label' => 'Jokercard inklusive',
'config' => [
'type' => 'check',
],
],
],
];
@@ -288,6 +288,10 @@ CREATE TABLE tx_epproducts_domain_model_groupspriceconfig
persons_included int(11) unsigned DEFAULT '0' NOT NULL,
price float(8) unsigned DEFAULT '0' NOT NULL,
price_additional_person float(8) unsigned DEFAULT '0' NOT NULL,
price_additional_person_group_1 float(8) unsigned DEFAULT '0' NOT NULL,
price_additional_person_group_2 float(8) unsigned DEFAULT '0' NOT NULL,
price_additional_person_group_3 float(8) unsigned DEFAULT '0' NOT NULL,
bonus_card_included tinyint(4) unsigned DEFAULT '0' NOT NULL,
hotel int(11) unsigned DEFAULT '0',
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
@@ -6,7 +6,23 @@
</div>
<div class="form-group" v-show="!submitted">
<label>Personenzahl</label>
<input type="number" class="form-control" v-model="selectedPax" @change="onPaxUpdated()"/>
<input type="number" class="form-control" 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()"/>
</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()"/>
</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()"/>
</div>
</div>
<p class="text-sm italic" v-show="nightsCount === 0">Bitte wählen Sie einen Zeitraum</p>
</div>
<div class="form-group" v-show="options.length > 0 && !submitted">
<label>Optionale Zusatzleistungen</label>
@@ -22,7 +38,9 @@
<label>Optionale Verpflegungsleistungen</label>
<select class="form-control" v-model="selectedBoard" v-if="selectedPax >= 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>
<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="selectedPax < 30">
<span class="label label-warning">Erst ab 30 Personen buchbar.</span>
@@ -49,6 +67,14 @@
<th>Aufpreis Kurzzeit</th>
<td>{{ formatCurrency(priceShortTerm) }}</td>
</tr>
<tr v-if="includesBonusCard">
<th>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>
<td>{{ formatCurrency(priceOptions) }}</td>
@@ -63,7 +89,8 @@
</tr>
<tr>
<th>Gesamtpreis</th>
<td><strong>{{ formatCurrency(priceTotal) }}</strong><br><small>zzgl. vor Ort zu entrichtender Ortstaxe</small></td>
<td><strong>{{ formatCurrency(priceTotal) }}</strong><br><small>zzgl. vor Ort zu entrichtender
Ortstaxe</small></td>
</tr>
</tbody>
</table>
@@ -114,12 +141,13 @@
</template>
<script>
import $ from 'jquery';
import dayjs from 'dayjs'
import 'dayjs/locale/de'
import 'flatpickr'
import { German } from 'flatpickr/dist/l10n/de'
import Vue from 'vue'
import axios from 'axios'
import 'flatpickr';
import {German} from 'flatpickr/dist/l10n/de';
import Vue from 'vue';
import axios from 'axios';
export default {
props: {
@@ -154,6 +182,9 @@
selectedTo: null,
selectedRange: [],
selectedPax: 30,
selectedPaxGroup1: 0,
selectedPaxGroup2: 0,
selectedPaxGroup3: 30,
selectedOptions: [],
selectedBoard: null,
name: null,
@@ -171,16 +202,16 @@
},
formatOptionPriceType(option) {
if (2 === option.type) {
return ` (${this.formatCurrency(option.price)} pro Person)`
return ' (' + this.formatCurrency(option.price) + ' pro Person)';
}
if (3 === option.type) {
return ` (${this.formatCurrency(option.price)} pro Nacht)`
return ' (' + this.formatCurrency(option.price) + ' pro Nacht)';
}
if (4 === option.type) {
return ` (${this.formatCurrency(option.price)} pro Person und Nacht)`
return ' (' + this.formatCurrency(option.price) + ' pro Person und Nacht)';
}
return ` (${this.formatCurrency(option.price)})`
return ' (' + this.formatCurrency(option.price) + ')';
},
initSelectableRanges() {
let enabledDates = [];
@@ -217,29 +248,35 @@
for (let option of this.selectedOptions) {
options.push(option.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.selectedPax)
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)
let formData = {
'tx_epproducts_ajax[groupsPriceInquiry][name]': this.name,
'tx_epproducts_ajax[groupsPriceInquiry][email]': this.email,
'tx_epproducts_ajax[groupsPriceInquiry][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][board]': this.selectedBoard ? this.selectedBoard.uid : null,
'tx_epproducts_ajax[groupsPriceInquiry][options]': options,
'tx_epproducts_ajax[groupsPriceInquiry][summary]': this.priceSummary
};
this.processing = true;
this.submitted = false;
axios.post(this.endpoint, formData)
.then(response => {
axios({
url: this.endpoint,
method: 'POST',
data: $.param(formData)
}).then(response => {
if ('validation' === response.data.status) {
this.formErrors = response.data.errors;
} else {
this.submitted = true;
}
})
.catch(error => {})
.finally(() => {
}).catch(error => {
}).finally(() => {
this.processing = false;
});
}
@@ -255,21 +292,57 @@
return this.selectedFrom.format('DD.MM.YYYY') + ' - ' + this.selectedTo.format('DD.MM.YYYY');
},
pricePax () {
let base = 0;
let additional = 0;
includesBonusCard() {
let included = false
for (let date of this.selectedRange) {
for (let config of this.configs) {
if (date >= dayjs(config.dateFrom) && date < dayjs(config.dateTo)) {
base += config.price;
if (this.selectedPax > config.personsIncluded) {
if (config.bonusCardIncluded) {
included = true
}
}
}
}
return included
},
pricePax() {
let base = 0
let additional = 0
for (let date of this.selectedRange) {
for (let config of this.configs) {
if (date >= dayjs(config.dateFrom) && date < dayjs(config.dateTo)) {
base += config.price
if (this.totalPax > config.personsIncluded) {
if (false === config.bonusCardIncluded) {
additional += (this.selectedPax - config.personsIncluded) * config.priceAdditionalPerson;
} else {
// Distribute additional persons costs by group
let included = config.personsIncluded
if (this.selectedPaxGroup3 <= included) {
included -= this.selectedPaxGroup3
} else {
additional += (this.selectedPaxGroup3 - included) * config.priceAdditionalPersonByGroup[3]
included = 0
}
if (this.selectedPaxGroup2 <= included) {
included -= this.selectedPaxGroup2
} else {
additional += (this.selectedPaxGroup2 - included) * config.priceAdditionalPersonByGroup[2]
included = 0
}
if (this.selectedPaxGroup1 > included) {
additional += (this.selectedPaxGroup1 - included) * config.priceAdditionalPersonByGroup[1]
}
}
}
}
}
}
return {base, additional};
},
totalPax() {
return this.includesBonusCard ? this.selectedPaxGroup1 + this.selectedPaxGroup2 + this.selectedPaxGroup3 : this.selectedPax
},
priceOptions() {
let price = 0;
for (let option of this.selectedOptions) {
@@ -279,11 +352,11 @@
if (1 === option.type) {
price += option.price;
} else if (2 === option.type) {
price += option.price * this.selectedPax;
price += option.price * this.totalPax;
} else if (3 === option.type) {
price += option.price * this.nightsCount;
} else if (4 === option.type) {
price += option.price * this.nightsCount * this.selectedPax;
price += option.price * this.nightsCount * this.totalPax;
}
}
return price;
@@ -291,13 +364,13 @@
priceBoard() {
let price = 0;
if (this.selectedBoard) {
price = this.selectedBoard.price * this.nightsCount * this.selectedPax;
price = this.selectedBoard.price * this.nightsCount * this.totalPax;
}
return price;
},
priceShortTerm() {
let price = 0;
const totalPricePax = this.pricePax.base + this.pricePax.additional;
const totalPricePax = (this.pricePax.base + this.pricePax.additional);
if (2 === this.nightsCount) {
price = totalPricePax * 0.2;
}
@@ -330,7 +403,7 @@
},
mounted() {
Vue.nextTick(() => {
this.picker = flatpickr(this.$refs.picker, {
this.picker = $(this.$refs.picker).flatpickr({
mode: 'range',
dateFormat: 'd.m.Y',
locale: German,
@@ -352,9 +425,11 @@
.form-wrapper {
position: relative;
}
.form-control[readonly] {
background-color: white;
}
.form-overlay {
position: fixed;
top: 0;
@@ -29,7 +29,19 @@
</tr>
<tr>
<th>Anzahl der Personen</th>
<td>{pax}</td>
<td>{pax -> v:or(alternative: '-')}</td>
</tr>
<tr>
<th>Anzahl der Personen (ab 15 Jahre)</th>
<td>{paxGroup3 -> v:or(alternative: '-')}</td>
</tr>
<tr>
<th>Anzahl der Personen (7-14 Jahre)</th>
<td>{paxGroup2 -> v:or(alternative: '-')}</td>
</tr>
<tr>
<th>Anzahl der Personen (4-6 Jahre)</th>
<td>{paxGroup1 -> v:or(alternative: '-')}</td>
</tr>
<tr>
<th>Verpflegung</th>