Implement group bookings price calculator
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
rootPageId: 9
|
|
||||||
base: /
|
base: /
|
||||||
baseVariants:
|
baseVariants:
|
||||||
-
|
-
|
||||||
@@ -7,6 +6,12 @@ baseVariants:
|
|||||||
-
|
-
|
||||||
base: 'https://schnee-event.burn.dpn'
|
base: 'https://schnee-event.burn.dpn'
|
||||||
condition: 'applicationContext == "Development/Skimax"'
|
condition: 'applicationContext == "Development/Skimax"'
|
||||||
|
disableStaticFileCache: true
|
||||||
|
errorHandling:
|
||||||
|
-
|
||||||
|
errorCode: '404'
|
||||||
|
errorHandler: Page
|
||||||
|
errorContentSource: 't3://page?uid=608'
|
||||||
languages:
|
languages:
|
||||||
-
|
-
|
||||||
title: Deutsch
|
title: Deutsch
|
||||||
@@ -34,16 +39,7 @@ languages:
|
|||||||
fallbackType: strict
|
fallbackType: strict
|
||||||
fallbacks: ''
|
fallbacks: ''
|
||||||
flag: gb
|
flag: gb
|
||||||
errorHandling:
|
rootPageId: 9
|
||||||
-
|
|
||||||
errorCode: '404'
|
|
||||||
errorHandler: Page
|
|
||||||
errorContentSource: 't3://page?uid=608'
|
|
||||||
routes:
|
|
||||||
-
|
|
||||||
route: robots.txt
|
|
||||||
type: staticText
|
|
||||||
content: "User-agent: *\r\nDisallow: /typo3/\r\nDisallow: /typo3_src/\r\nAllow: /typo3/sysext/frontend/Resources/Public/*\r\n"
|
|
||||||
routeEnhancers:
|
routeEnhancers:
|
||||||
NewsDetailPlugin:
|
NewsDetailPlugin:
|
||||||
type: Extbase
|
type: Extbase
|
||||||
@@ -232,11 +228,16 @@ routeEnhancers:
|
|||||||
default: /
|
default: /
|
||||||
index: ''
|
index: ''
|
||||||
map:
|
map:
|
||||||
'/': 0
|
/: 0
|
||||||
'/json': 1701
|
/json: 1701
|
||||||
'/html': 1702
|
/html: 1702
|
||||||
'.json': 1803
|
.json: 1803
|
||||||
'.ical': 1710
|
.ical: 1710
|
||||||
'sitemap.xml': 1533906435
|
sitemap.xml: 1533906435
|
||||||
'yoast-snippetpreview.json': 1480321830
|
yoast-snippetpreview.json: 1480321830
|
||||||
'/pxa': 7378121
|
/pxa: 7378121
|
||||||
|
routes:
|
||||||
|
-
|
||||||
|
route: robots.txt
|
||||||
|
type: staticText
|
||||||
|
content: "User-agent: *\r\nDisallow: /typo3/\r\nDisallow: /typo3_src/\r\nAllow: /typo3/sysext/frontend/Resources/Public/*\r\n"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace EP\EpProducts\Controller;
|
namespace EP\EpProducts\Controller;
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
@@ -27,69 +26,106 @@ namespace EP\EpProducts\Controller;
|
|||||||
* This copyright notice MUST APPEAR in all copies of the script!
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
***************************************************************/
|
***************************************************************/
|
||||||
|
|
||||||
|
use EP\EpProducts\Domain\Model\GroupsPriceBoard;
|
||||||
use EP\EpProducts\Domain\Model\Hotel;
|
use EP\EpProducts\Domain\Model\Hotel;
|
||||||
use EP\EpProducts\Service\GroupsPriceService;
|
use EP\EpProducts\Domain\Repository\GroupsPriceOptionRepository;
|
||||||
use League\Period\Period;
|
use EP\EpProducts\Service\EmailService;
|
||||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||||
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
|
use TYPO3\CMS\Extbase\Annotation as Extbase;
|
||||||
|
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||||
|
|
||||||
class AjaxGroupsPriceController extends ActionController
|
class AjaxGroupsPriceController extends ActionController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var GroupsPriceService
|
* @var GroupsPriceOptionRepository
|
||||||
*/
|
*/
|
||||||
protected $groupsPriceService;
|
protected $groupsPriceOptionRepository;
|
||||||
|
|
||||||
public function __construct(GroupsPriceService $groupsPriceService)
|
/**
|
||||||
|
* @var EmailService
|
||||||
|
*/
|
||||||
|
protected $emailService;
|
||||||
|
|
||||||
|
public function __construct(GroupsPriceOptionRepository $groupsPriceOptionRepository, EmailService $emailService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->groupsPriceService = $groupsPriceService;
|
$this->groupsPriceOptionRepository = $groupsPriceOptionRepository;
|
||||||
|
$this->emailService = $emailService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function initializeAction()
|
public function initializeProcessFormAction()
|
||||||
{
|
{
|
||||||
if ($this->request->hasArgument('dateFrom')) {
|
if ($this->request->hasArgument('options')) {
|
||||||
try {
|
$optionUids = $this->request->getArgument('options');
|
||||||
$dateFrom = new \DateTime($this->request->getArgument('dateFrom'));
|
$options = $this->groupsPriceOptionRepository->findByUids($optionUids)->toArray();
|
||||||
}
|
$this->request->setArgument('options', $options);
|
||||||
catch (\Throwable $e) {
|
|
||||||
$dateFrom = null;
|
|
||||||
}
|
|
||||||
$this->request->setArgument('dateFrom', $dateFrom);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->request->hasArgument('dateTo')) {
|
|
||||||
try {
|
|
||||||
$dateTo = new \DateTime($this->request->getArgument('dateTo'));
|
|
||||||
}
|
|
||||||
catch (\Throwable $e) {
|
|
||||||
$dateTo = null;
|
|
||||||
}
|
|
||||||
$this->request->setArgument('dateTo', $dateTo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Hotel $hotel
|
* @param Hotel $hotel
|
||||||
* @param \DateTime $dateFrom
|
* @param string $name
|
||||||
* @param \DateTime $dateTo
|
* @param string $email
|
||||||
|
* @param string $dateFrom
|
||||||
|
* @param string $dateTo
|
||||||
* @param int $pax
|
* @param int $pax
|
||||||
* @return string
|
* @param array $options
|
||||||
* @throws \League\Period\Exception
|
* @param GroupsPriceBoard $board
|
||||||
|
*
|
||||||
|
* @Extbase\Validate("NotEmpty", param="name")
|
||||||
|
* @Extbase\Validate("NotEmpty", param="email")
|
||||||
|
* @Extbase\Validate("EmailAddress", param="email")
|
||||||
*/
|
*/
|
||||||
public function indexAction(Hotel $hotel, \DateTime $dateFrom = null, \DateTime $dateTo = null, $pax = 0)
|
public function processFormAction(Hotel $hotel, $name, $email, $dateFrom, $dateTo, $pax = 30, array $options = [], GroupsPriceBoard $board = null)
|
||||||
{
|
{
|
||||||
if (null !== $dateFrom && null !== $dateTo) {
|
$emailOptions = [
|
||||||
$period = new Period($dateFrom, $dateTo);
|
'toEmail' => $this->settings['groupsPriceToEmail'],
|
||||||
$price = $this->groupsPriceService->calculateHotelPrice($hotel, $period, $pax);
|
'toName' => $this->settings['groupsPriceToName'],
|
||||||
|
'fromEmail' => $this->settings['groupsPriceToEmail'],
|
||||||
|
'fromName' => $this->settings['groupsPriceToName'],
|
||||||
|
'subject' => 'Gruppenhaus Preiskalkulator/Anfrage',
|
||||||
|
'templateName' => 'GroupsPrice',
|
||||||
|
];
|
||||||
|
|
||||||
|
$variables = [
|
||||||
|
'hotel' => $hotel,
|
||||||
|
'name' => $name,
|
||||||
|
'email' => $email,
|
||||||
|
'dateFrom' => $dateFrom,
|
||||||
|
'dateTo' => $dateTo,
|
||||||
|
'pax' => $pax,
|
||||||
|
'options' => $this->groupsPriceOptionRepository->findByUids($options)->toArray(),
|
||||||
|
'board' => $board,
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->emailService->send($emailOptions, $variables);
|
||||||
|
|
||||||
|
return json_encode(['status' => 'ok'], JSON_THROW_ON_ERROR, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function errorAction() {
|
||||||
|
$formErrors = [];
|
||||||
|
if ($this->arguments->validate()->hasErrors()) {
|
||||||
|
foreach ($this->arguments->validate()->getFlattenedErrors() as $key => $errors)
|
||||||
|
{
|
||||||
|
$parts = explode('.', $key);
|
||||||
|
$fieldName = array_pop($parts);
|
||||||
|
$errorsRaw = [];
|
||||||
|
foreach ($errors as $error) {
|
||||||
|
$translationKey = sprintf('tx_eptheme.message.%s.%s', $fieldName, $error->getCode());
|
||||||
|
$errorsRaw[] = LocalizationUtility::translate($translationKey, 'ep_theme');
|
||||||
|
}
|
||||||
|
$formErrors[$fieldName] = implode(', ', $errorsRaw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return json_encode([
|
$response['status'] = 'validation';
|
||||||
'price' => $price ?? [],
|
$response['errors'] = $formErrors;
|
||||||
'configs' => $hotel->getGroupsPriceConfigs()->toArray(),
|
|
||||||
'boards' => $hotel->getGroupsPriceBoards()->toArray(),
|
return json_encode($response);
|
||||||
'options' => $hotel->getGroupsPriceOptions()->toArray(),
|
|
||||||
], JSON_THROW_ON_ERROR, 512);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpProducts\Controller;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2020 Björn Fromme <[email protected]>, dreipunktnull
|
||||||
|
*
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||||
|
* free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The GNU General Public License can be found at
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
*
|
||||||
|
* This script is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
use EP\EpProducts\Domain\Model\Hotel;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||||
|
|
||||||
|
class GroupsPriceController extends ActionController
|
||||||
|
{
|
||||||
|
public function indexAction(Hotel $hotel)
|
||||||
|
{
|
||||||
|
$this->view->assign('hotel', $hotel);
|
||||||
|
$this->view->assign('configs', json_encode($hotel->getGroupsPriceConfigs()->toArray()));
|
||||||
|
$this->view->assign('boards', json_encode($hotel->getGroupsPriceBoards()->toArray()));
|
||||||
|
$this->view->assign('options', json_encode($hotel->getGroupsPriceOptions()->toArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -79,6 +79,7 @@ class GroupsPriceBoard extends AbstractEntity implements \JsonSerializable
|
|||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'uid' => $this->getUid(),
|
||||||
'title' => $this->getTitle(),
|
'title' => $this->getTitle(),
|
||||||
'price' => $this->getPrice(),
|
'price' => $this->getPrice(),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -142,11 +142,12 @@ class GroupsPriceConfig extends AbstractEntity implements \JsonSerializable
|
|||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'dateFrom' => $this->getDateFrom()->format('d.m.Y'),
|
'uid' => $this->getUid(),
|
||||||
'dateTo' => $this->getDateTo()->format('d.m.Y'),
|
'dateFrom' => $this->getDateFrom()->format('Y-m-d'),
|
||||||
|
'dateTo' => $this->getDateTo()->format('Y-m-d'),
|
||||||
'personsIncluded' => $this->getPersonsIncluded(),
|
'personsIncluded' => $this->getPersonsIncluded(),
|
||||||
'price' => $this->getPrice(),
|
'price' => $this->getPrice(),
|
||||||
'priceAdditionalPerson' => $this->getPriceAdditionalPerson(),
|
'priceAdditionalPerson' => $this->getPriceAdditionalPerson(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
|
|||||||
|
|
||||||
class GroupsPriceOption extends AbstractEntity implements \JsonSerializable
|
class GroupsPriceOption extends AbstractEntity implements \JsonSerializable
|
||||||
{
|
{
|
||||||
|
const TYPE_GLOBAL = 1;
|
||||||
|
const TYPE_PER_PAX = 2;
|
||||||
|
const TYPE_PER_NIGHT = 3;
|
||||||
|
const TYPE_PER_PAX_AND_NIGHT = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
@@ -41,6 +46,16 @@ class GroupsPriceOption extends AbstractEntity implements \JsonSerializable
|
|||||||
*/
|
*/
|
||||||
protected $price;
|
protected $price;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $ignoreWithBoard = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -73,14 +88,49 @@ class GroupsPriceOption extends AbstractEntity implements \JsonSerializable
|
|||||||
$this->price = $price;
|
$this->price = $price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getType(): int
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $type
|
||||||
|
*/
|
||||||
|
public function setType(int $type): void
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isIgnoreWithBoard(): bool
|
||||||
|
{
|
||||||
|
return $this->ignoreWithBoard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $ignoreWithBoard
|
||||||
|
*/
|
||||||
|
public function setIgnoreWithBoard(bool $ignoreWithBoard): void
|
||||||
|
{
|
||||||
|
$this->ignoreWithBoard = $ignoreWithBoard;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'uid' => $this->getUid(),
|
||||||
'title' => $this->getTitle(),
|
'title' => $this->getTitle(),
|
||||||
'price' => $this->getPrice(),
|
'price' => $this->getPrice(),
|
||||||
|
'type' => $this->getType(),
|
||||||
|
'ignoreWithBoard' => $this->isIgnoreWithBoard(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace EP\EpProducts\Domain\Repository;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2020 Björn Fromme <[email protected]>, dreipunktnull
|
||||||
|
*
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||||
|
* free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The GNU General Public License can be found at
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
*
|
||||||
|
* This script is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
|
||||||
|
use TYPO3\CMS\Extbase\Persistence\Repository;
|
||||||
|
|
||||||
|
class GroupsPriceOptionRepository extends Repository
|
||||||
|
{
|
||||||
|
public function findByUids(array $uids)
|
||||||
|
{
|
||||||
|
/** @var Typo3QuerySettings $querySettings */
|
||||||
|
$querySettings = $this->objectManager->get(Typo3QuerySettings::class);
|
||||||
|
$querySettings->setRespectStoragePage(false);
|
||||||
|
$this->setDefaultQuerySettings($querySettings);
|
||||||
|
|
||||||
|
$query = $this->createQuery();
|
||||||
|
$query->matching($query->in('uid', $uids));
|
||||||
|
|
||||||
|
return $query->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
namespace EP\EpProducts\Service;
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
*
|
||||||
|
* Copyright notice
|
||||||
|
*
|
||||||
|
* (c) 2020 Björn Fromme <[email protected]>, dreipunktnull
|
||||||
|
*
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||||
|
* free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The GNU General Public License can be found at
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
*
|
||||||
|
* This script is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* This copyright notice MUST APPEAR in all copies of the script!
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use TYPO3\CMS\Core\Mail\MailMessage;
|
||||||
|
use TYPO3\CMS\Core\SingletonInterface;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||||
|
use TYPO3\CMS\Fluid\View\StandaloneView;
|
||||||
|
|
||||||
|
class EmailService implements SingletonInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ConfigurationManagerInterface
|
||||||
|
*/
|
||||||
|
protected $configurationManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ConfigurationManagerInterface $manager
|
||||||
|
*/
|
||||||
|
public function injectConfigurationManager(ConfigurationManagerInterface $manager)
|
||||||
|
{
|
||||||
|
$this->configurationManager = $manager;
|
||||||
|
$settings = GeneralUtility::removeDotsFromTS(
|
||||||
|
$this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT)
|
||||||
|
);
|
||||||
|
$this->settings = $settings['plugin']['tx_eptheme'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $options
|
||||||
|
* @param array $variables
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function send(array $options, array $variables)
|
||||||
|
{
|
||||||
|
$resolvedOptions = $this->resolveOptions($options);
|
||||||
|
|
||||||
|
/** @var MailMessage $message */
|
||||||
|
$message = GeneralUtility::makeInstance(MailMessage::class);
|
||||||
|
$message
|
||||||
|
->setTo([$resolvedOptions['toEmail'] => $resolvedOptions['toName']])
|
||||||
|
->setFrom([$resolvedOptions['fromEmail'] => $resolvedOptions['fromName']])
|
||||||
|
->setSubject($resolvedOptions['subject'])
|
||||||
|
;
|
||||||
|
|
||||||
|
$view = $this->getView($resolvedOptions['templateName']);
|
||||||
|
$view->assignMultiple($variables);
|
||||||
|
$message->setBody($view->render(), 'text/html');
|
||||||
|
|
||||||
|
return $message->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $templateName
|
||||||
|
* @param string $format
|
||||||
|
* @return StandaloneView
|
||||||
|
*/
|
||||||
|
protected function getView($templateName, $format = 'html')
|
||||||
|
{
|
||||||
|
/** @var StandaloneView $view */
|
||||||
|
$view = GeneralUtility::makeInstance(StandaloneView::class);
|
||||||
|
$view->setFormat($format);
|
||||||
|
|
||||||
|
$view->setTemplateRootPaths($this->settings['view']['templateRootPaths']);
|
||||||
|
$view->setLayoutRootPaths($this->settings['view']['layoutRootPaths']);
|
||||||
|
$view->setPartialRootPaths($this->settings['view']['partialRootPaths']);
|
||||||
|
|
||||||
|
$template = GeneralUtility::getFileAbsFileName('EXT:ep_theme/Resources/Private/Templates/Email/'.$templateName.'.'.$format);
|
||||||
|
$view->setTemplatePathAndFilename($template);
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $options
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function resolveOptions(array $options)
|
||||||
|
{
|
||||||
|
$optionsResolver = new OptionsResolver();
|
||||||
|
$optionsResolver->setDefined(['toEmail', 'toName', 'subject', 'templateName', 'fromEmail', 'fromName']);
|
||||||
|
$optionsResolver->setRequired(['toEmail', 'toName', 'subject', 'templateName']);
|
||||||
|
$optionsResolver->setDefaults([
|
||||||
|
'fromEmail' => $this->settings['settings']['contactFormToEmail'],
|
||||||
|
'fromName' => $this->settings['settings']['contactFormToName'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $optionsResolver->resolve($options);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace EP\EpProducts\Service;
|
|
||||||
|
|
||||||
use EP\EpProducts\Domain\Model\Hotel;
|
|
||||||
use League\Period\Period;
|
|
||||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
||||||
|
|
||||||
class GroupsPriceService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param Hotel $hotel
|
|
||||||
* @param Period $period
|
|
||||||
* @param int $pax
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function calculateHotelPrice(Hotel $hotel, Period $period, $pax)
|
|
||||||
{
|
|
||||||
// Get all price configs for provided hotel
|
|
||||||
$configs = $this->getConfigs($hotel);
|
|
||||||
|
|
||||||
// Create periods in configs to simplify following steps
|
|
||||||
$this->patchConfigPeriods($configs);
|
|
||||||
|
|
||||||
$nights = 0;
|
|
||||||
$price = 0;
|
|
||||||
|
|
||||||
// Iterate over provided period
|
|
||||||
foreach ($period->getDatePeriod('1 DAY') as $day) {
|
|
||||||
|
|
||||||
// Iterate over all configs
|
|
||||||
foreach ($configs as $config) {
|
|
||||||
|
|
||||||
// Skip config if current day is not contained
|
|
||||||
if (false === $config['period']->contains($day)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate base price
|
|
||||||
$price += $config['price'];
|
|
||||||
|
|
||||||
// Add costs for not-included number of persons
|
|
||||||
if ($pax > $config['persons_included']) {
|
|
||||||
$price += $config['price_additional_person'] * ($pax - $config['persons_included']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$nights++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($nights === 2) {
|
|
||||||
$shortTermCosts = $price * .2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($nights === 3) {
|
|
||||||
$shortTermCosts = $price * .1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$electricityCosts = ($nights - 1) * $pax * 1.7;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'pax' => $pax,
|
|
||||||
'basePrice' => $price,
|
|
||||||
'shortTermCosts' => $shortTermCosts ?? 0.0,
|
|
||||||
'electricityCosts' => $electricityCosts,
|
|
||||||
'nights' => $nights,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function patchConfigPeriods(array &$configs)
|
|
||||||
{
|
|
||||||
foreach ($configs as $idx => $config) {
|
|
||||||
$configDateFrom = (new \DateTimeImmutable())->setTimestamp($config['date_from']);
|
|
||||||
$configDateTo = (new \DateTimeImmutable())->setTimestamp($config['date_to']);
|
|
||||||
$configs[$idx]['period'] = new Period($configDateFrom, $configDateTo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Hotel $hotel
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getConfigs(Hotel $hotel)
|
|
||||||
{
|
|
||||||
$qb = $this->getQueryBuilder();
|
|
||||||
|
|
||||||
return $qb
|
|
||||||
->select('*')
|
|
||||||
->from('tx_epproducts_domain_model_groupspriceconfig')
|
|
||||||
->where($qb->expr()->eq('hotel', $qb->createNamedParameter($hotel->getUid())))
|
|
||||||
->orderBy('date_from')
|
|
||||||
->execute()
|
|
||||||
->fetchAll()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getQueryBuilder()
|
|
||||||
{
|
|
||||||
/** @var ConnectionPool $connectionPool */
|
|
||||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
|
||||||
|
|
||||||
return $connectionPool->getQueryBuilderForTable('tx_epproducts_domain_model_groupspriceconfig');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,7 +26,7 @@ call_user_func(function () {
|
|||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'product_detail',
|
'product_detail',
|
||||||
'Produktdetails'
|
'Produkt: Details'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
@@ -38,7 +38,7 @@ call_user_func(function () {
|
|||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'product_teasergroup',
|
'product_teasergroup',
|
||||||
'Produktteaser'
|
'Produkt: Teaser'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
@@ -56,61 +56,67 @@ call_user_func(function () {
|
|||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'region_teasergroup',
|
'region_teasergroup',
|
||||||
'Gebietsteaser'
|
'Gebiet: Teaser'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'region_detail',
|
'region_detail',
|
||||||
'Gebietsdetails'
|
'Gebiet: Details'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'city_teasergroup',
|
'city_teasergroup',
|
||||||
'Ortsteaser'
|
'Ort: Teaser'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'city_detail',
|
'city_detail',
|
||||||
'Ortsdetails'
|
'Ort: Details'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'hotel_teasergroup',
|
'hotel_teasergroup',
|
||||||
'Hotelteaser'
|
'Hotel: Teaser'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'hotel_teasergroup_nodate',
|
'hotel_teasergroup_nodate',
|
||||||
'Hotelteaser (terminunabhängig)'
|
'Hotel: Teaser (terminunabhängig)'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'hotel_detail',
|
'hotel_detail',
|
||||||
'Hoteldetails'
|
'Hotel: Details'
|
||||||
|
);
|
||||||
|
|
||||||
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
|
'EP.EpProducts',
|
||||||
|
'hotel_groups_price',
|
||||||
|
'Hotel: Preiskalulator Gruppen'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'hotel_detail_event',
|
'hotel_detail_event',
|
||||||
'Hoteldetails (Event)'
|
'Hotel: Details (Event)'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'concept_teasergroup',
|
'concept_teasergroup',
|
||||||
'Konzeptteaser'
|
'Konzept: Teaser'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
'EP.EpProducts',
|
'EP.EpProducts',
|
||||||
'concept_detail',
|
'concept_detail',
|
||||||
'Konzeptdetails'
|
'Konzept: Details'
|
||||||
);
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
|
|||||||
+27
-2
@@ -24,14 +24,16 @@ return [
|
|||||||
'hideTable' => true,
|
'hideTable' => true,
|
||||||
],
|
],
|
||||||
'interface' => [
|
'interface' => [
|
||||||
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, title, price',
|
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, title, price, type,
|
||||||
|
ignore_with_board',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
'1' => [
|
'1' => [
|
||||||
'showitem' => 'title, price',
|
'showitem' => 'title, --palette--;;priceconfig',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'palettes' => [
|
'palettes' => [
|
||||||
|
'priceconfig' => ['showitem' => 'price, type, ignore_with_board'],
|
||||||
],
|
],
|
||||||
'columns' => [
|
'columns' => [
|
||||||
|
|
||||||
@@ -140,6 +142,29 @@ return [
|
|||||||
'eval' => 'double2,required',
|
'eval' => 'double2,required',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
'type' => [
|
||||||
|
'exclude' => false,
|
||||||
|
'label' => 'Typ',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'select',
|
||||||
|
'renderType' => 'selectSingle',
|
||||||
|
'items' => [
|
||||||
|
['pauschal', \EP\EpProducts\Domain\Model\GroupsPriceOption::TYPE_GLOBAL],
|
||||||
|
['pro Person', \EP\EpProducts\Domain\Model\GroupsPriceOption::TYPE_PER_PAX],
|
||||||
|
['pro Nacht', \EP\EpProducts\Domain\Model\GroupsPriceOption::TYPE_PER_NIGHT],
|
||||||
|
['pro Person und Nacht', \EP\EpProducts\Domain\Model\GroupsPriceOption::TYPE_PER_PAX_AND_NIGHT],
|
||||||
|
],
|
||||||
|
'default' => \EP\EpProducts\Domain\Model\GroupsPriceOption::TYPE_GLOBAL,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'ignore_with_board' => [
|
||||||
|
'exclude' => false,
|
||||||
|
'label' => 'Entfällt bei Verpflegung',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'check',
|
||||||
|
'default' => 0,
|
||||||
|
]
|
||||||
|
],
|
||||||
'sorting' => [
|
'sorting' => [
|
||||||
'config' => [
|
'config' => [
|
||||||
'type' => 'passthrough'
|
'type' => 'passthrough'
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ plugin.tx_epproducts {
|
|||||||
searchLogIgnoreIps =
|
searchLogIgnoreIps =
|
||||||
# cat=plugin.tx_epproducts//a; type=string; label=Page UID with reseller export plugin
|
# cat=plugin.tx_epproducts//a; type=string; label=Page UID with reseller export plugin
|
||||||
resellerExportPageUid =
|
resellerExportPageUid =
|
||||||
|
# cat=plugin.tx_epproducts//a; type=string; label=Email recipient for groups price inquiries
|
||||||
|
groupsPriceToEmail = [email protected]
|
||||||
|
# cat=plugin.tx_epproducts//a; type=string; label=Email recipient for groups price inquiries
|
||||||
|
groupsPriceToName = EP Reisen
|
||||||
}
|
}
|
||||||
persistence {
|
persistence {
|
||||||
# cat=plugin.tx_epproducts//a; type=string; label=Default storage PID
|
# cat=plugin.tx_epproducts//a; type=string; label=Default storage PID
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ plugin.tx_epproducts {
|
|||||||
ratingPageUid = {$plugin.tx_eptheme.settings.ratingPageUid}
|
ratingPageUid = {$plugin.tx_eptheme.settings.ratingPageUid}
|
||||||
searchPageHeaderImage = {$plugin.tx_eptheme.settings.searchPageHeaderImage}
|
searchPageHeaderImage = {$plugin.tx_eptheme.settings.searchPageHeaderImage}
|
||||||
bpnBookingUrlTemplateCode = {$plugin.tx_eptheme.settings.bpnBookingUrlTemplateCode}
|
bpnBookingUrlTemplateCode = {$plugin.tx_eptheme.settings.bpnBookingUrlTemplateCode}
|
||||||
|
groupsPricePopupPageUid = {$plugin.tx_eptheme.settings.groupsPricePopupPageUid}
|
||||||
|
groupsPriceToEmail = {$plugin.tx_epproducts.settings.groupsPriceToEmail}
|
||||||
|
groupsPriceToName = {$plugin.tx_epproducts.settings.groupsPriceToName}
|
||||||
datePickerPresets {
|
datePickerPresets {
|
||||||
1 {
|
1 {
|
||||||
label = Silvester
|
label = Silvester
|
||||||
@@ -134,7 +137,7 @@ tx_epproducts_ajax_json {
|
|||||||
1 = list
|
1 = list
|
||||||
}
|
}
|
||||||
AjaxGroupsPrice {
|
AjaxGroupsPrice {
|
||||||
1 = index
|
1 = processForm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
features.requireCHashArgumentForActionArguments = 0
|
features.requireCHashArgumentForActionArguments = 0
|
||||||
|
|||||||
@@ -201,6 +201,17 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
||||||
|
'EP.' . $_EXTKEY,
|
||||||
|
'hotel_groups_price',
|
||||||
|
[
|
||||||
|
'GroupsPrice' => 'index',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'GroupsPrice' => 'index',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
||||||
'EP.' . $_EXTKEY,
|
'EP.' . $_EXTKEY,
|
||||||
'hotel_detail_event',
|
'hotel_detail_event',
|
||||||
@@ -345,7 +356,7 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T
|
|||||||
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
||||||
'AjaxCalendar' => 'range,contingents,availableRooms',
|
'AjaxCalendar' => 'range,contingents,availableRooms',
|
||||||
'AjaxWatchlist' => 'list',
|
'AjaxWatchlist' => 'list',
|
||||||
'AjaxGroupsPrice' => 'index',
|
'AjaxGroupsPrice' => 'processForm',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'AjaxSearch' => 'searchresult',
|
'AjaxSearch' => 'searchresult',
|
||||||
@@ -356,7 +367,7 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T
|
|||||||
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable',
|
||||||
'AjaxCalendar' => 'range,contingents,availableRooms',
|
'AjaxCalendar' => 'range,contingents,availableRooms',
|
||||||
'AjaxWatchlist' => 'list',
|
'AjaxWatchlist' => 'list',
|
||||||
'AjaxGroupsPrice' => 'index',
|
'AjaxGroupsPrice' => 'processForm',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -322,35 +322,37 @@ CREATE TABLE tx_epproducts_domain_model_groupspriceconfig
|
|||||||
CREATE TABLE tx_epproducts_domain_model_groupspriceoption
|
CREATE TABLE tx_epproducts_domain_model_groupspriceoption
|
||||||
(
|
(
|
||||||
|
|
||||||
uid int(11) NOT NULL auto_increment,
|
uid int(11) NOT NULL auto_increment,
|
||||||
pid int(11) DEFAULT '0' NOT NULL,
|
pid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
title varchar(255) DEFAULT '' NOT NULL,
|
title varchar(255) DEFAULT '' NOT NULL,
|
||||||
price float(8) unsigned DEFAULT '0' NOT NULL,
|
price float(8) unsigned DEFAULT '0' NOT NULL,
|
||||||
hotel int(11) unsigned DEFAULT '0',
|
type tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||||
sorting int(11) DEFAULT '0' NOT NULL,
|
ignore_with_board tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
hotel int(11) unsigned DEFAULT '0',
|
||||||
|
sorting int(11) DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
|
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
crdate int(11) unsigned DEFAULT '0' NOT NULL,
|
crdate int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
|
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
deleted tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||||
hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
|
||||||
starttime int(11) unsigned DEFAULT '0' NOT NULL,
|
starttime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
endtime int(11) unsigned DEFAULT '0' NOT NULL,
|
endtime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
t3ver_oid int(11) DEFAULT '0' NOT NULL,
|
t3ver_oid int(11) DEFAULT '0' NOT NULL,
|
||||||
t3ver_id int(11) DEFAULT '0' NOT NULL,
|
t3ver_id int(11) DEFAULT '0' NOT NULL,
|
||||||
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
|
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
|
||||||
t3ver_label varchar(255) DEFAULT '' NOT NULL,
|
t3ver_label varchar(255) DEFAULT '' NOT NULL,
|
||||||
t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
|
t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
|
||||||
t3ver_stage int(11) DEFAULT '0' NOT NULL,
|
t3ver_stage int(11) DEFAULT '0' NOT NULL,
|
||||||
t3ver_count int(11) DEFAULT '0' NOT NULL,
|
t3ver_count int(11) DEFAULT '0' NOT NULL,
|
||||||
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
|
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
|
||||||
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
|
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
sys_language_uid int(11) DEFAULT '0' NOT NULL,
|
sys_language_uid int(11) DEFAULT '0' NOT NULL,
|
||||||
l10n_parent int(11) DEFAULT '0' NOT NULL,
|
l10n_parent int(11) DEFAULT '0' NOT NULL,
|
||||||
l10n_diffsource mediumblob,
|
l10n_diffsource mediumblob,
|
||||||
|
|
||||||
PRIMARY KEY (uid),
|
PRIMARY KEY (uid),
|
||||||
KEY parent (pid),
|
KEY parent (pid),
|
||||||
|
|||||||
+2
@@ -21,6 +21,8 @@ mod {
|
|||||||
}
|
}
|
||||||
frontpageEvent < .frontpage
|
frontpageEvent < .frontpage
|
||||||
frontpageEvent.title = Startseite Events
|
frontpageEvent.title = Startseite Events
|
||||||
|
popup < .frontpage
|
||||||
|
popup.title = Popup
|
||||||
detail {
|
detail {
|
||||||
title = Detailseite
|
title = Detailseite
|
||||||
config {
|
config {
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ plugin.tx_eptheme {
|
|||||||
myEpPageUid =
|
myEpPageUid =
|
||||||
# cat=eptheme/200/310; type=string; label=Booking links PID
|
# cat=eptheme/200/310; type=string; label=Booking links PID
|
||||||
bookingLinksPid =
|
bookingLinksPid =
|
||||||
|
# cat=eptheme/200/330; type=string; label=Groups price popup page UID
|
||||||
|
groupsPricePopupPageUid =
|
||||||
|
|
||||||
# cat=eptheme/400/100; type=string; label=Phone number general
|
# cat=eptheme/400/100; type=string; label=Phone number general
|
||||||
phoneNumber = 0221 - 272 276 0
|
phoneNumber = 0221 - 272 276 0
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ plugin.tx_eptheme {
|
|||||||
eventDisturberButtonLink = {$plugin.tx_eptheme.settings.eventDisturberButtonLink}
|
eventDisturberButtonLink = {$plugin.tx_eptheme.settings.eventDisturberButtonLink}
|
||||||
googleTagManagerId = {$plugin.tx_eptheme.settings.googleTagManagerId}
|
googleTagManagerId = {$plugin.tx_eptheme.settings.googleTagManagerId}
|
||||||
bpnBookingUrlTemplateCode = {$plugin.tx_eptheme.settings.bpnBookingUrlTemplateCode}
|
bpnBookingUrlTemplateCode = {$plugin.tx_eptheme.settings.bpnBookingUrlTemplateCode}
|
||||||
|
groupsPricePopupPageUid = {$plugin.tx_eptheme.settings.groupsPricePopupPageUid}
|
||||||
googleStaticMapsBaseUrl = {$plugin.tx_eptheme.settings.googleStaticMapsBaseUrl}
|
googleStaticMapsBaseUrl = {$plugin.tx_eptheme.settings.googleStaticMapsBaseUrl}
|
||||||
googleMapsJsApiUrl = {$plugin.tx_eptheme.settings.googleMapsJsApiUrl}
|
googleMapsJsApiUrl = {$plugin.tx_eptheme.settings.googleMapsJsApiUrl}
|
||||||
googleMapsApiKey = {$plugin.tx_eptheme.settings.googleMapsApiKey}
|
googleMapsApiKey = {$plugin.tx_eptheme.settings.googleMapsApiKey}
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ const sliderPrevArrow = '<button class="slider-pagination__arrow slider-paginati
|
|||||||
const sliderNextArrow = '<button class="slider-pagination__arrow slider-pagination__arrow--next"><i class="fa fa-2x fa-chevron-right"></i></button>';
|
const sliderNextArrow = '<button class="slider-pagination__arrow slider-pagination__arrow--next"><i class="fa fa-2x fa-chevron-right"></i></button>';
|
||||||
const sliderDot = '<button class="slider-pagination__dot" data-role="none" role="button" tabindex="0" />';
|
const sliderDot = '<button class="slider-pagination__dot" data-role="none" role="button" tabindex="0" />';
|
||||||
|
|
||||||
|
// Configure fancybox
|
||||||
|
$.fancybox.defaults.iframe.css.width = '800px';
|
||||||
|
|
||||||
// Define date filter for vue templates
|
// Define date filter for vue templates
|
||||||
Vue.filter('date', (value) => {
|
Vue.filter('date', (value) => {
|
||||||
return dayjs(value).format('DD.MM.YYYY');
|
return dayjs(value).format('DD.MM.YYYY');
|
||||||
@@ -67,6 +70,7 @@ new Vue({
|
|||||||
HotelList,
|
HotelList,
|
||||||
BackLink,
|
BackLink,
|
||||||
MyEp: () => import('./myep/App.vue'),
|
MyEp: () => import('./myep/App.vue'),
|
||||||
|
GroupsPriceCalculator: () => import('./components/GroupsPriceCalculator.vue'),
|
||||||
FacebookPixel
|
FacebookPixel
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
|
|||||||
+277
-18
@@ -1,53 +1,312 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="form-wrapper form--border">
|
||||||
Foo!
|
<div class="form-group" v-show="!submitted">
|
||||||
|
<label>Zeitraum</label>
|
||||||
|
<input type="text" class="form-control datepicker--visible" placeholder="von... bis" ref="picker"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" v-show="!submitted">
|
||||||
|
<label>Personenzahl</label>
|
||||||
|
<input type="number" class="form-control" v-model="selectedPax" @change="onPaxUpdated()"/>
|
||||||
|
</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 }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" v-show="boards.length > 0 && !submitted">
|
||||||
|
<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 }}</option>
|
||||||
|
</select>
|
||||||
|
<div v-show="selectedPax < 30">
|
||||||
|
<span class="label label-warning">Erst ab 30 Personen buchbar.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Preise</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div v-show="nightsCount > 0">
|
||||||
|
Zeitraum: {{ rangeFormatted }}, {{ nightsCount }} Nächte<br>
|
||||||
|
Basispreis: {{ pricePax.base | money }} €<br>
|
||||||
|
<span v-if="pricePax.additional > 0">Aufpreis Personenzahl: {{ pricePax.additional | money }} €<br></span>
|
||||||
|
<span v-if="priceShortTerm > 0">Aufpreis Kurzzeit: {{ priceShortTerm | money }} €<br></span>
|
||||||
|
<span v-if="selectedOptions.length > 0">Zusatzleistungen: {{ priceOptions | money }} €<br></span>
|
||||||
|
<span v-if="priceBoard > 0">Verpflegung: {{ priceBoard | money }} €<br></span>
|
||||||
|
<span v-if="priceRunningCosts > 0">Strom- und Abfallgebühren: {{ priceRunningCosts | money }} €<br></span>
|
||||||
|
<span><strong>Gesamtpreis: {{ totalPrice | money }} €</strong></span>
|
||||||
|
</div>
|
||||||
|
<div v-show="nightsCount === 0">
|
||||||
|
<span class="label label-warning">Bitte wählen Sie einen Zeitraum</span>
|
||||||
|
</div>
|
||||||
|
</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">
|
||||||
|
<button class="button" type="submit" @click.prevent="submitForm()">Abschicken</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default" v-show="submitted">
|
||||||
|
<div class="panel-body">
|
||||||
|
Vielen Dank für Ihre Anfrage. Wir werden Sie schnellstmöglich bearbeiten.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-overlay" v-show="processing">
|
||||||
|
<img :src="loaderUri" alt="Loading...">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
|
||||||
import $ from 'jquery';
|
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';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
|
loaderUri: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
endpoint: {
|
endpoint: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
configs: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
boards: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
processing: false,
|
processing: false,
|
||||||
price: {},
|
submitted: false,
|
||||||
configs: [],
|
picker: null,
|
||||||
boards: [],
|
formErrors: {},
|
||||||
options: []
|
selectedFrom: null,
|
||||||
|
selectedTo: null,
|
||||||
|
selectedRange: [],
|
||||||
|
selectedPax: 30,
|
||||||
|
selectedOptions: [],
|
||||||
|
selectedBoard: null,
|
||||||
|
name: null,
|
||||||
|
email: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
money (value) {
|
||||||
|
if (0 === value) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
return parseFloat(value).toFixed(2).replace(/\./, ',');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
load () {
|
initSelectableRanges () {
|
||||||
|
let enabledDates = [];
|
||||||
|
for (let config of this.configs) {
|
||||||
|
const dateFrom = dayjs(config.dateFrom);
|
||||||
|
const dateTo = dayjs(config.dateTo);
|
||||||
|
enabledDates.push({
|
||||||
|
from: dateFrom.format('DD.MM.YYYY'),
|
||||||
|
to: dateTo.format('DD.MM.YYYY')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.picker.set('enable', enabledDates);
|
||||||
|
if (enabledDates.length > 0) {
|
||||||
|
const firstDate = enabledDates[0].from;
|
||||||
|
this.picker.set('minDate', firstDate);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateSelectedRange () {
|
||||||
|
let range = [];
|
||||||
|
let currentDate = this.selectedFrom;
|
||||||
|
while (currentDate < this.selectedTo) {
|
||||||
|
range.push(currentDate);
|
||||||
|
currentDate = currentDate.add(1, 'day');
|
||||||
|
}
|
||||||
|
this.selectedRange = range;
|
||||||
|
},
|
||||||
|
onPaxUpdated () {
|
||||||
|
if (this.selectedPax < 30) {
|
||||||
|
this.selectedBoard = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submitForm () {
|
||||||
|
let options = [];
|
||||||
|
for (let option of this.selectedOptions) {
|
||||||
|
options.push(option.uid);
|
||||||
|
}
|
||||||
|
let formData = {
|
||||||
|
'tx_epproducts_ajax[name]': this.name,
|
||||||
|
'tx_epproducts_ajax[email]': this.email,
|
||||||
|
'tx_epproducts_ajax[dateFrom]': this.selectedFrom.format('DD.MM.YYYY'),
|
||||||
|
'tx_epproducts_ajax[dateTo]': this.selectedTo.format('DD.MM.YYYY'),
|
||||||
|
'tx_epproducts_ajax[pax]': this.selectedPax,
|
||||||
|
'tx_epproducts_ajax[board]': this.selectedBoard ? this.selectedBoard.uid : null,
|
||||||
|
'tx_epproducts_ajax[options]': options
|
||||||
|
};
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
this.submitted = false;
|
||||||
axios({
|
axios({
|
||||||
url: this.endpoint,
|
url: this.endpoint,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: $.param({
|
data: $.param(formData)
|
||||||
'tx_epproducts_ajax[pax]': 60,
|
|
||||||
'tx_epproducts_ajax[dateFrom]': '2020-04-28',
|
|
||||||
'tx_epproducts_ajax[dateTo]': '2020-04-31'
|
|
||||||
})
|
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
this.configs = response.data.configs;
|
if ('validation' === response.data.status) {
|
||||||
this.boards = response.data.boards;
|
this.formErrors = response.data.errors;
|
||||||
this.options = response.data.options;
|
} else {
|
||||||
this.price = response.data.price;
|
this.submitted = true;
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.processing = false;
|
this.processing = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
nightsCount () {
|
||||||
|
return this.selectedRange.length;
|
||||||
|
},
|
||||||
|
rangeFormatted () {
|
||||||
|
if (null === this.selectedFrom || null === this.selectedTo) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.selectedFrom.format('DD.MM.YYYY') + ' - ' + this.selectedTo.format('DD.MM.YYYY');
|
||||||
|
},
|
||||||
|
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.selectedPax > config.personsIncluded) {
|
||||||
|
additional += (this.selectedPax - config.personsIncluded) * config.priceAdditionalPerson;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { base, additional };
|
||||||
|
},
|
||||||
|
priceOptions () {
|
||||||
|
let price = 0;
|
||||||
|
for (let option of this.selectedOptions) {
|
||||||
|
if (true === option.ignoreWithBoard && this.selectedBoard) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (1 === option.type) {
|
||||||
|
price += option.price;
|
||||||
|
} else if (2 === option.type) {
|
||||||
|
price += option.price * this.selectedPax;
|
||||||
|
} else if (3 === option.type) {
|
||||||
|
price += option.price * this.nightsCount;
|
||||||
|
} else if (4 === option.type) {
|
||||||
|
price += option.price * this.nightsCount * this.selectedPax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return price;
|
||||||
|
},
|
||||||
|
priceBoard () {
|
||||||
|
let price = 0;
|
||||||
|
if (this.selectedBoard) {
|
||||||
|
price = this.selectedBoard.price * this.nightsCount * this.selectedPax;
|
||||||
|
}
|
||||||
|
return price;
|
||||||
|
},
|
||||||
|
priceShortTerm () {
|
||||||
|
let price = 0;
|
||||||
|
const totalPricePax = this.pricePax.base + this.pricePax.additional;
|
||||||
|
if (2 === this.nightsCount) {
|
||||||
|
price = totalPricePax * 0.2;
|
||||||
|
}
|
||||||
|
if (3 === this.nightsCount) {
|
||||||
|
price = totalPricePax * 0.1;
|
||||||
|
}
|
||||||
|
return price;
|
||||||
|
},
|
||||||
|
priceRunningCosts () {
|
||||||
|
if (this.selectedBoard) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return this.nightsCount * this.selectedPax * 1.7;
|
||||||
|
},
|
||||||
|
totalPrice () {
|
||||||
|
return this.pricePax.base + this.pricePax.additional + this.priceOptions
|
||||||
|
+ this.priceBoard + this.priceShortTerm + this.priceRunningCosts;
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.load();
|
Vue.nextTick(() => {
|
||||||
|
this.picker = $(this.$refs.picker).flatpickr({
|
||||||
|
mode: 'range',
|
||||||
|
dateFormat: 'd.m.Y',
|
||||||
|
locale: German,
|
||||||
|
onChange: selectedDates => {
|
||||||
|
if (2 === selectedDates.length) {
|
||||||
|
this.selectedFrom = dayjs(selectedDates[0]);
|
||||||
|
this.selectedTo = dayjs(selectedDates[1]);
|
||||||
|
this.updateSelectedRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.initSelectableRanges();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.form-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.form-control[readonly] {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.form-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: rgba(white, 0.85);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
DaterangeSelect,
|
DaterangeSelect,
|
||||||
AjaxContent,
|
AjaxContent,
|
||||||
Calendar,
|
Calendar,
|
||||||
GroupsPriceCalculator: () => import('./GroupsPriceCalculator.vue'),
|
|
||||||
FacebookPixel,
|
FacebookPixel,
|
||||||
WatchlistToggle,
|
WatchlistToggle,
|
||||||
OsmMap,
|
OsmMap,
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ $output-bourbon-deprecation-warnings: false;
|
|||||||
@import "remix/faq";
|
@import "remix/faq";
|
||||||
@import "remix/destination-pulldown";
|
@import "remix/destination-pulldown";
|
||||||
@import "remix/watchlist";
|
@import "remix/watchlist";
|
||||||
|
@import "remix/calculator";
|
||||||
|
|
||||||
// core config
|
// core config
|
||||||
@import "fonts";
|
@import "fonts";
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
.calculator {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calculator__loading {
|
||||||
|
position: absolute;
|
||||||
|
@include size(100%);
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: rgba(white, 0.5);
|
||||||
|
|
||||||
|
img {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.flatpickr-calendar {
|
.flatpickr-calendar {
|
||||||
box-shadow: none;
|
//box-shadow: none;
|
||||||
|
|
||||||
&.inline {
|
&.inline {
|
||||||
border: 1px solid $color-grey-light;
|
border: 1px solid $color-grey-light;
|
||||||
|
|||||||
@@ -75,18 +75,27 @@
|
|||||||
<trans-unit id="tx_eptheme.message.contactForm.name.1221560718">
|
<trans-unit id="tx_eptheme.message.contactForm.name.1221560718">
|
||||||
<source>Bitte angeben</source>
|
<source>Bitte angeben</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_eptheme.message.name.1221560718">
|
||||||
|
<source>Bitte angeben</source>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="tx_eptheme.message.contactForm.firstName.1221560718">
|
<trans-unit id="tx_eptheme.message.contactForm.firstName.1221560718">
|
||||||
<source>Bitte angeben</source>
|
<source>Bitte angeben</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="tx_eptheme.message.contactForm.email.1221560718">
|
<trans-unit id="tx_eptheme.message.contactForm.email.1221560718">
|
||||||
<source>Bitte angeben</source>
|
<source>Bitte angeben</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_eptheme.message.email.1221560718">
|
||||||
|
<source>Bitte angeben</source>
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="tx_eptheme.message.contactForm.phone.1221560718">
|
<trans-unit id="tx_eptheme.message.contactForm.phone.1221560718">
|
||||||
<source>Bitte angeben</source>
|
<source>Bitte angeben</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="tx_eptheme.message.contactForm.email.1221559976">
|
<trans-unit id="tx_eptheme.message.contactForm.email.1221559976">
|
||||||
<source>Ungültige E-Mail Adresse</source>
|
<source>Ungültige E-Mail Adresse</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_eptheme.message.email.1221559976">
|
||||||
|
<source>Ungültige E-Mail Adresse</source>
|
||||||
|
</trans-unit>
|
||||||
|
|
||||||
<trans-unit id="label.whatsapp_instructions">
|
<trans-unit id="label.whatsapp_instructions">
|
||||||
<source>Nummer einfach als neuen Kontakt abspeichern und los geht es! Wir beraten Dich über WhatsApp!</source>
|
<source>Nummer einfach als neuen Kontakt abspeichern und los geht es! Wir beraten Dich über WhatsApp!</source>
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
|
<div id="app">
|
||||||
|
<f:render section="Content"/>
|
||||||
|
</div>
|
||||||
|
<f:render partial="Config" arguments="{_all}" />
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
|
<f:layout name="Email/Default"/>
|
||||||
|
|
||||||
|
<f:section name="Main">
|
||||||
|
<h1>Anfrage Gruppenhaus vom <f:format.date date="now" format="d.m.y" /></h1>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Haus</th>
|
||||||
|
<td>{hotel.name}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<td>{name}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>E-Mail</th>
|
||||||
|
<td>{email}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Zeitraum</th>
|
||||||
|
<td>{dateFrom} - {dateTo}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Anzahl der Personen</th>
|
||||||
|
<td>{pax}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Verpflegung</th>
|
||||||
|
<td>
|
||||||
|
<f:if condition="{board}">
|
||||||
|
<f:then>
|
||||||
|
{board.title}
|
||||||
|
</f:then>
|
||||||
|
<f:else>
|
||||||
|
-
|
||||||
|
</f:else>
|
||||||
|
</f:if>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Optionale Zusatzleistungen</th>
|
||||||
|
<td>
|
||||||
|
<f:if condition="{options}">
|
||||||
|
<f:then>
|
||||||
|
<ul>
|
||||||
|
<f:for each="{options}" as="option">
|
||||||
|
<li>{option.title}</li>
|
||||||
|
</f:for>
|
||||||
|
</ul>
|
||||||
|
</f:then>
|
||||||
|
</f:if>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</f:section>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h1>Preiskalkulator {hotel.name}</h1>
|
||||||
|
<groups-price-calculator
|
||||||
|
:configs='{configs -> f:format.raw()}'
|
||||||
|
:boards='{boards -> f:format.raw()}'
|
||||||
|
:options='{options -> f:format.raw()}'
|
||||||
|
endpoint="{ep:uri.ajax(action: 'processForm', controller: 'AjaxGroupsPrice', pageUid: settings.defaultAjaxUid, arguments: '{hotel: hotel}')}"
|
||||||
|
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
||||||
|
>
|
||||||
|
</groups-price-calculator>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<html data-namespace-typo3-fluid="true" lang="en"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||||
|
|
||||||
|
<f:layout name="Page/Popup"/>
|
||||||
|
|
||||||
|
<f:section name="Content">
|
||||||
|
<f:cObject typoscriptObjectPath="lib.dynamicContent" data="{pageUid: '{data.uid}', colPos: '0'}" />
|
||||||
|
</f:section>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -87,13 +87,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden-xs">
|
<div class="hidden-xs">
|
||||||
<f:comment>
|
|
||||||
<f:if condition="{product.calendarHotel}">
|
|
||||||
<groups-price-calculator
|
|
||||||
endpoint="{ep:uri.ajax(action: 'index', controller: 'AjaxGroupsPrice', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: hotel}')}"
|
|
||||||
></groups-price-calculator>
|
|
||||||
</f:if>
|
|
||||||
</f:comment>
|
|
||||||
<f:render section="Calendar" arguments="{_all}"/>
|
<f:render section="Calendar" arguments="{_all}"/>
|
||||||
<f:render partial="Facts" arguments="{facts: product.facts}"/>
|
<f:render partial="Facts" arguments="{facts: product.facts}"/>
|
||||||
<f:if condition="{product.video}">
|
<f:if condition="{product.video}">
|
||||||
@@ -255,6 +248,9 @@
|
|||||||
|
|
||||||
<f:section name="Calendar">
|
<f:section name="Calendar">
|
||||||
<f:if condition="{product.calendarHotel}">
|
<f:if condition="{product.calendarHotel}">
|
||||||
|
<a class="button button--full" data-fancybox data-type="iframe" href="{f:uri.action(action: 'index', controller: 'GroupsPrice', arguments: '{hotel: hotel}', pageUid: settings.groupsPricePopupPageUid)}">
|
||||||
|
Preiskalkulator
|
||||||
|
</a>
|
||||||
<div class="ep-sidebar ep-facts">
|
<div class="ep-sidebar ep-facts">
|
||||||
<p><strong>Belegungskalender</strong></p>
|
<p><strong>Belegungskalender</strong></p>
|
||||||
<calendar
|
<calendar
|
||||||
|
|||||||
Reference in New Issue
Block a user