feat: additional age groups in price calculator
closes #86997e7e9, #869979zhq
This commit is contained in:
@@ -28,6 +28,7 @@ namespace EP\EpProducts\Controller;
|
||||
|
||||
use EP\EpProducts\Domain\Model\Dto\GroupsPriceInquiry;
|
||||
use EP\EpProducts\Domain\Model\GroupsPriceBoard;
|
||||
use EP\EpProducts\Domain\Model\GroupsPriceOption;
|
||||
use EP\EpProducts\Domain\Model\Hotel;
|
||||
use EP\EpProducts\Domain\Repository\GroupsPriceOptionRepository;
|
||||
use EP\EpProducts\Service\EmailService;
|
||||
@@ -69,6 +70,9 @@ class AjaxGroupsPriceController extends ActionController
|
||||
public function processFormAction(Hotel $hotel, GroupsPriceInquiry $groupsPriceInquiry)
|
||||
{
|
||||
$mode = $groupsPriceInquiry->getMode();
|
||||
$country = $hotel->getCountry()->getCode();
|
||||
$effectivePax = $groupsPriceInquiry->getEffectivePax();
|
||||
$nights = $groupsPriceInquiry->getNights();
|
||||
|
||||
if (false === in_array($mode, [GroupsPriceInquiry::MODE_BOOKING, GroupsPriceInquiry::MODE_INQUIRY])) {
|
||||
$mode = GroupsPriceInquiry::MODE_BOOKING;
|
||||
@@ -86,10 +90,25 @@ class AjaxGroupsPriceController extends ActionController
|
||||
'templateName' => 'GroupsPrice',
|
||||
];
|
||||
|
||||
$optionPrice = function (GroupsPriceOption $option) use ($country, $effectivePax, $nights) {
|
||||
$price = 'CH' === $country ? $option->getPriceChf() : $option->getPrice();
|
||||
$currency = 'CH' === $country ? 'CHF' : '€';
|
||||
|
||||
if (GroupsPriceOption::TYPE_PER_PAX === $option->getType()) {
|
||||
$price = $price * $effectivePax;
|
||||
} elseif (GroupsPriceOption::TYPE_PER_NIGHT === $option->getType()) {
|
||||
$price = $price * $nights;
|
||||
} elseif (GroupsPriceOption::TYPE_PER_PAX_AND_NIGHT === $option->getType()) {
|
||||
$price = $price * $nights * $effectivePax;
|
||||
}
|
||||
|
||||
return $price.' '.$currency;
|
||||
};
|
||||
|
||||
try {
|
||||
$options = $this->groupsPriceOptionRepository->findByUids($groupsPriceInquiry->getOptions());
|
||||
$selectedOptions = array_map(function ($option) {
|
||||
return $option->getTitle();
|
||||
$selectedOptions = array_map(function ($option) use ($optionPrice) {
|
||||
return $option->getTitle().': '.$optionPrice($option);
|
||||
}, $options);
|
||||
}
|
||||
catch (InvalidQueryException $e) {
|
||||
@@ -111,6 +130,10 @@ class AjaxGroupsPriceController extends ActionController
|
||||
'dateTo' => $groupsPriceInquiry->getDateTo(),
|
||||
'nights' => $groupsPriceInquiry->getNights(),
|
||||
'pax' => $groupsPriceInquiry->getPax(),
|
||||
'children' => $groupsPriceInquiry->getChildren(),
|
||||
'minors' => $groupsPriceInquiry->getMinors(),
|
||||
'adolescents' => $groupsPriceInquiry->getAdolescents(),
|
||||
'adolescentsAge' => $hotel->getGroupsPriceAdolescentsAge(),
|
||||
'options' => $selectedOptions,
|
||||
'board' => $groupsPriceInquiry->getBoard(),
|
||||
'summary' => $groupsPriceInquiry->getSummary(),
|
||||
|
||||
@@ -62,5 +62,6 @@ class GroupsPriceController extends ActionController
|
||||
$this->view->assign('options', json_encode($hotel->getGroupsPriceOptions()->toArray(), JSON_HEX_APOS));
|
||||
$this->view->assign('mainSeasonFrom', $mainSeasonFrom);
|
||||
$this->view->assign('mainSeasonTo', $mainSeasonTo);
|
||||
$this->view->assign('adolescentsAge', $hotel->getGroupsPriceAdolescentsAge() ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,16 @@ class GroupsPriceInquiry
|
||||
*/
|
||||
protected $children;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $minors;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $adolescents;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@@ -384,6 +394,46 @@ class GroupsPriceInquiry
|
||||
$this->children = $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMinors()
|
||||
{
|
||||
return $this->minors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $minors
|
||||
*/
|
||||
public function setMinors($minors)
|
||||
{
|
||||
$this->minors = $minors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAdolescents()
|
||||
{
|
||||
return $this->adolescents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $adolescents
|
||||
*/
|
||||
public function setAdolescents($adolescents)
|
||||
{
|
||||
$this->adolescents = $adolescents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getEffectivePax()
|
||||
{
|
||||
return max(30, $this->getPax() - $this->getChildren());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -265,6 +265,11 @@ class Hotel extends AbstractEntity implements TeaserInterface
|
||||
*/
|
||||
protected $groupsPriceBoards;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $groupsPriceAdolescentsAge;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -1059,6 +1064,16 @@ class Hotel extends AbstractEntity implements TeaserInterface
|
||||
$this->groupsPriceBoards = $groupsPriceBoards;
|
||||
}
|
||||
|
||||
public function getGroupsPriceAdolescentsAge()
|
||||
{
|
||||
return $this->groupsPriceAdolescentsAge;
|
||||
}
|
||||
|
||||
public function setGroupsPriceAdolescentsAge($groupsPriceAdolescentsAge)
|
||||
{
|
||||
$this->groupsPriceAdolescentsAge = $groupsPriceAdolescentsAge;
|
||||
}
|
||||
|
||||
public function getGroupsPriceTaxLabel()
|
||||
{
|
||||
return $this->groupsPriceTaxLabel;
|
||||
|
||||
+12
-1
@@ -30,7 +30,8 @@ return [
|
||||
--div--;Texte, teaser, description, features, room_types, additional_information,
|
||||
--div--;Verknüpfungen, facts, teamer, additional_codes,
|
||||
--div--;Bilder/Dateien, teaser_images, header_images, images, reseller_images,
|
||||
--div--;Gruppenhaus Preise, --palette--;;season,groups_price_tax_label, groups_price_configs, groups_price_boards, groups_price_options',
|
||||
--div--;Gruppenhaus Preise, --palette--;;season,--palette--;;others, groups_price_configs,
|
||||
groups_price_boards, groups_price_options',
|
||||
],
|
||||
],
|
||||
'palettes' => [
|
||||
@@ -41,6 +42,7 @@ return [
|
||||
'name' => ['showitem' => 'name,short_name,--linebreak--,header_title,header_subtitle,--linebreak--,headline'],
|
||||
'categories' => ['showitem' => 'type,category'],
|
||||
'season' => ['showitem' => 'main_season_from, main_season_to'],
|
||||
'others' => ['showitem' => 'season,groups_price_tax_label, groups_price_adolescents_age']
|
||||
],
|
||||
'columns' => [
|
||||
|
||||
@@ -702,6 +704,15 @@ return [
|
||||
'default' => 'zzgl. vor Ort zu entrichtender Ortstaxe',
|
||||
],
|
||||
],
|
||||
'groups_price_adolescents_age' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'Altersgrenze Jugendliche (6-X Jahre)',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 50,
|
||||
'eval' => 'int',
|
||||
],
|
||||
],
|
||||
'main_season_from' => [
|
||||
'exclude' => false,
|
||||
'label' => 'Hauptsaison von',
|
||||
|
||||
@@ -213,73 +213,74 @@ CREATE TABLE tx_epproducts_domain_model_date
|
||||
CREATE TABLE tx_epproducts_domain_model_hotel
|
||||
(
|
||||
|
||||
uid int(11) NOT NULL auto_increment,
|
||||
pid int(11) DEFAULT '0' NOT NULL,
|
||||
uid int(11) NOT NULL auto_increment,
|
||||
pid int(11) DEFAULT '0' NOT NULL,
|
||||
|
||||
earlybird tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
new tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
low_contingent tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
show_as_teaser tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
detail_page varchar(255) DEFAULT '' NOT NULL,
|
||||
name varchar(255) DEFAULT '' NOT NULL,
|
||||
short_name varchar(255) DEFAULT '' NOT NULL,
|
||||
headline varchar(255) DEFAULT '' NOT NULL,
|
||||
description text NOT NULL,
|
||||
keywords text NOT NULL,
|
||||
features text NOT NULL,
|
||||
room_types text NOT NULL,
|
||||
additional_information text NOT NULL,
|
||||
teaser text NOT NULL,
|
||||
header_title varchar(255) DEFAULT '' NOT NULL,
|
||||
header_subtitle varchar(255) DEFAULT '' NOT NULL,
|
||||
teaser_images int(11) unsigned NOT NULL default '0',
|
||||
header_images int(11) unsigned NOT NULL default '0',
|
||||
images int(11) unsigned NOT NULL default '0',
|
||||
reseller_images int(11) unsigned NOT NULL default '0',
|
||||
code varchar(255) DEFAULT '' NOT NULL,
|
||||
external_link varchar(255) DEFAULT '' NOT NULL,
|
||||
path_segment varchar(255) DEFAULT '' NOT NULL,
|
||||
type varchar(255) DEFAULT '' NOT NULL,
|
||||
category int(11) DEFAULT '0' NOT NULL,
|
||||
country int(11) unsigned DEFAULT '0',
|
||||
region int(11) unsigned DEFAULT '0',
|
||||
city int(11) unsigned DEFAULT '0',
|
||||
teamer int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
products int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
rooms int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
facts int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
additional_codes int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
address varchar(255) DEFAULT '' NOT NULL,
|
||||
latitude varchar(255) DEFAULT '' NOT NULL,
|
||||
longitude varchar(255) DEFAULT '' NOT NULL,
|
||||
groups_price_configs int(11) unsigned NOT NULL default '0',
|
||||
groups_price_options int(11) unsigned NOT NULL default '0',
|
||||
groups_price_boards int(11) unsigned NOT NULL default '0',
|
||||
groups_price_tax_label varchar(255) DEFAULT '' NOT NULL,
|
||||
main_season_from date DEFAULT NULL,
|
||||
main_season_to date DEFAULT NULL,
|
||||
earlybird tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
new tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
low_contingent tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
show_as_teaser tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
detail_page varchar(255) DEFAULT '' NOT NULL,
|
||||
name varchar(255) DEFAULT '' NOT NULL,
|
||||
short_name varchar(255) DEFAULT '' NOT NULL,
|
||||
headline varchar(255) DEFAULT '' NOT NULL,
|
||||
description text NOT NULL,
|
||||
keywords text NOT NULL,
|
||||
features text NOT NULL,
|
||||
room_types text NOT NULL,
|
||||
additional_information text NOT NULL,
|
||||
teaser text NOT NULL,
|
||||
header_title varchar(255) DEFAULT '' NOT NULL,
|
||||
header_subtitle varchar(255) DEFAULT '' NOT NULL,
|
||||
teaser_images int(11) unsigned NOT NULL default '0',
|
||||
header_images int(11) unsigned NOT NULL default '0',
|
||||
images int(11) unsigned NOT NULL default '0',
|
||||
reseller_images int(11) unsigned NOT NULL default '0',
|
||||
code varchar(255) DEFAULT '' NOT NULL,
|
||||
external_link varchar(255) DEFAULT '' NOT NULL,
|
||||
path_segment varchar(255) DEFAULT '' NOT NULL,
|
||||
type varchar(255) DEFAULT '' NOT NULL,
|
||||
category int(11) DEFAULT '0' NOT NULL,
|
||||
country int(11) unsigned DEFAULT '0',
|
||||
region int(11) unsigned DEFAULT '0',
|
||||
city int(11) unsigned DEFAULT '0',
|
||||
teamer int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
products int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
rooms int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
facts int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
additional_codes int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
address varchar(255) DEFAULT '' NOT NULL,
|
||||
latitude varchar(255) DEFAULT '' NOT NULL,
|
||||
longitude varchar(255) DEFAULT '' NOT NULL,
|
||||
groups_price_configs int(11) unsigned NOT NULL default '0',
|
||||
groups_price_options int(11) unsigned NOT NULL default '0',
|
||||
groups_price_boards int(11) unsigned NOT NULL default '0',
|
||||
groups_price_adolescents_age int(11) unsigned NOT NULL default '0',
|
||||
groups_price_tax_label varchar(255) DEFAULT '' NOT NULL,
|
||||
main_season_from date DEFAULT NULL,
|
||||
main_season_to date DEFAULT NULL,
|
||||
|
||||
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
crdate int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
starttime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
endtime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
crdate int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||
starttime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
endtime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
|
||||
t3ver_oid int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_id int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_label varchar(255) DEFAULT '' NOT NULL,
|
||||
t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
|
||||
t3ver_stage int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_count int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_oid int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_id int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_label varchar(255) DEFAULT '' NOT NULL,
|
||||
t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
|
||||
t3ver_stage int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_count int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
|
||||
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
|
||||
|
||||
sys_language_uid int(11) DEFAULT '0' NOT NULL,
|
||||
l10n_parent int(11) DEFAULT '0' NOT NULL,
|
||||
l10n_diffsource mediumblob,
|
||||
sys_language_uid int(11) DEFAULT '0' NOT NULL,
|
||||
l10n_parent int(11) DEFAULT '0' NOT NULL,
|
||||
l10n_diffsource mediumblob,
|
||||
|
||||
PRIMARY KEY (uid),
|
||||
KEY parent (pid),
|
||||
|
||||
+51
-4
@@ -43,9 +43,48 @@
|
||||
v-model.number="childrenCount"
|
||||
@change="onPaxUpdated()"
|
||||
v-show="nightsCount > 0"/>
|
||||
<p class="text-sm italic">
|
||||
Kinder werden nur bei Strom- und Abfallgebühren berücksichtigt
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount > 0">
|
||||
Kinder werden nur bei Strom- und Abfallgebühren berücksichtigt.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-2 font-bold">
|
||||
davon Kinder 3-5 Jahre*
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-field"
|
||||
min="0"
|
||||
v-model.number="childrenCount3to5"
|
||||
@change="onPaxUpdated()"
|
||||
v-show="nightsCount > 0"/>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="adolescentsAge > 0">
|
||||
<label class="mb-2 font-bold">
|
||||
davon Kinder 6-{{ adolescentsAge }} Jahre*
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-field"
|
||||
min="0"
|
||||
v-model.number="adolescentsCount"
|
||||
@change="onPaxUpdated()"
|
||||
v-show="nightsCount > 0"/>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
</div>
|
||||
<div class="sm:col-span-2 text-sm">
|
||||
*Die Kosten für Essen und Kurtaxe werden wir entsprechend der Altersstruktur der Gäste in der Rechnung
|
||||
anpassen.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8"
|
||||
@@ -395,6 +434,10 @@ export default {
|
||||
type: String,
|
||||
default: 'zzgl. vor Ort zu entrichtender Ortstaxe',
|
||||
},
|
||||
adolescentsAge: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -410,6 +453,8 @@ export default {
|
||||
selectedRange: [],
|
||||
selectedPax: 30,
|
||||
childrenCount: 0,
|
||||
childrenCount3to5: 0,
|
||||
adolescentsCount: 0,
|
||||
selectedOptions: [],
|
||||
selectedBoard: null,
|
||||
name: '',
|
||||
@@ -533,6 +578,8 @@ export default {
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][nights]': this.nightsCount,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][pax]': this.selectedPax,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][children]': this.childrenCount,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][minors]': this.childrenCount3to5,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][adolescents]': this.adolescentsCount,
|
||||
'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][undersubscription]': this.formatCurrency(this.pricePax.undersubscription),
|
||||
@@ -616,8 +663,8 @@ export default {
|
||||
base.EUR += config.price.EUR
|
||||
base.CHF += config.price.CHF
|
||||
let included = config.personsIncluded
|
||||
let additionalPax = this.paxCount - included
|
||||
if (this.selectedPax > included) {
|
||||
if (this.paxCount > included) {
|
||||
let additionalPax = this.paxCount - included
|
||||
additional.EUR += additionalPax * config.priceAdditionalPerson.EUR
|
||||
additional.CHF += additionalPax * config.priceAdditionalPerson.CHF
|
||||
}
|
||||
|
||||
@@ -70,6 +70,16 @@
|
||||
<th>Anzahl Kinder 0-3 Jahre</th>
|
||||
<td>{children -> v:or(alternative: '-')}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Anzahl Kinder 3-5 Jahre</th>
|
||||
<td>{minors -> v:or(alternative: '-')}</td>
|
||||
</tr>
|
||||
<f:if condition="{adolescentsAge}">
|
||||
<tr>
|
||||
<th>Anzahl Kinder 6-{adolescentsAge} Jahre</th>
|
||||
<td>{adolescents -> v:or(alternative: '-')}</td>
|
||||
</tr>
|
||||
</f:if>
|
||||
<tr>
|
||||
<th>Verpflegung</th>
|
||||
<td>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
main-season-from="{mainSeasonFrom}"
|
||||
main-season-to="{mainSeasonTo}"
|
||||
tax-label="{hotel.groupsPriceTaxLabel -> v:or(alternative: 'zzgl. vor Ort zu entrichtender Ortstaxe')}"
|
||||
adolescents-age="{adolescentsAge}"
|
||||
>
|
||||
</groups-price-calculator>
|
||||
</f:format.raw>
|
||||
|
||||
Reference in New Issue
Block a user