From b85ec4d5f3f8fdeaa032951facbebddff9dce326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Fromme?= Date: Mon, 13 Jan 2020 18:12:13 +0100 Subject: [PATCH 1/4] Implement group bookings price calculator --- config/sites/ep-reisen/config.yaml | 39 +-- .../Controller/AjaxGroupsPriceController.php | 118 ++++--- .../Controller/GroupsPriceController.php | 42 +++ .../Classes/Domain/Model/GroupsPriceBoard.php | 1 + .../Domain/Model/GroupsPriceConfig.php | 7 +- .../Domain/Model/GroupsPriceOption.php | 52 ++- .../GroupsPriceOptionRepository.php | 47 +++ .../Classes/Service/EmailService.php | 122 ++++++++ .../Classes/Service/GroupsPriceService.php | 105 ------- .../TCA/Overrides/tt_content.php | 30 +- ...roducts_domain_model_groupspriceoption.php | 29 +- .../TypoScript/constants.typoscript | 4 + .../Configuration/TypoScript/setup.typoscript | 5 +- .../ext/ep_products/ext_localconf.php | 15 +- .../typo3conf/ext/ep_products/ext_tables.sql | 52 +-- .../Mod/WebLayout/BackendLayouts.tsconfig | 2 + .../TypoScript/constants.typoscript | 2 + .../Configuration/TypoScript/setup.typoscript | 1 + .../Resources/Private/Assets/js/_app.js | 4 + .../js/components/GroupsPriceCalculator.vue | 295 ++++++++++++++++-- .../Assets/js/components/ProductDetail.vue | 1 - .../Resources/Private/Assets/scss/main.scss | 1 + .../Assets/scss/remix/_calculator.scss | 19 ++ .../Assets/scss/remix/_datepicker.scss | 2 +- .../Resources/Private/Language/locallang.xlf | 9 + .../Resources/Private/Layouts/Page/Popup.html | 9 + .../Private/Templates/Email/GroupsPrice.html | 59 ++++ .../Private/Templates/GroupsPrice/Index.html | 22 ++ .../Private/Templates/Page/Popup.html | 11 + .../Private/Templates/Product/Detail.html | 10 +- 30 files changed, 877 insertions(+), 238 deletions(-) create mode 100644 public/typo3conf/ext/ep_products/Classes/Controller/GroupsPriceController.php create mode 100644 public/typo3conf/ext/ep_products/Classes/Domain/Repository/GroupsPriceOptionRepository.php create mode 100644 public/typo3conf/ext/ep_products/Classes/Service/EmailService.php delete mode 100644 public/typo3conf/ext/ep_products/Classes/Service/GroupsPriceService.php create mode 100644 public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/remix/_calculator.scss create mode 100644 public/typo3conf/ext/ep_theme/Resources/Private/Layouts/Page/Popup.html create mode 100644 public/typo3conf/ext/ep_theme/Resources/Private/Templates/Email/GroupsPrice.html create mode 100644 public/typo3conf/ext/ep_theme/Resources/Private/Templates/GroupsPrice/Index.html create mode 100644 public/typo3conf/ext/ep_theme/Resources/Private/Templates/Page/Popup.html diff --git a/config/sites/ep-reisen/config.yaml b/config/sites/ep-reisen/config.yaml index 8444105a..1c876d72 100644 --- a/config/sites/ep-reisen/config.yaml +++ b/config/sites/ep-reisen/config.yaml @@ -1,4 +1,3 @@ -rootPageId: 9 base: / baseVariants: - @@ -7,6 +6,12 @@ baseVariants: - base: 'https://schnee-event.burn.dpn' condition: 'applicationContext == "Development/Skimax"' +disableStaticFileCache: true +errorHandling: + - + errorCode: '404' + errorHandler: Page + errorContentSource: 't3://page?uid=608' languages: - title: Deutsch @@ -34,16 +39,7 @@ languages: fallbackType: strict fallbacks: '' flag: gb -errorHandling: - - - 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" +rootPageId: 9 routeEnhancers: NewsDetailPlugin: type: Extbase @@ -232,11 +228,16 @@ routeEnhancers: default: / index: '' map: - '/': 0 - '/json': 1701 - '/html': 1702 - '.json': 1803 - '.ical': 1710 - 'sitemap.xml': 1533906435 - 'yoast-snippetpreview.json': 1480321830 - '/pxa': 7378121 + /: 0 + /json: 1701 + /html: 1702 + .json: 1803 + .ical: 1710 + sitemap.xml: 1533906435 + yoast-snippetpreview.json: 1480321830 + /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" diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxGroupsPriceController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxGroupsPriceController.php index 70b2e9f9..82ae706c 100644 --- a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxGroupsPriceController.php +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxGroupsPriceController.php @@ -1,5 +1,4 @@ groupsPriceService = $groupsPriceService; + $this->groupsPriceOptionRepository = $groupsPriceOptionRepository; + $this->emailService = $emailService; } - public function initializeAction() + public function initializeProcessFormAction() { - if ($this->request->hasArgument('dateFrom')) { - try { - $dateFrom = new \DateTime($this->request->getArgument('dateFrom')); - } - 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); + if ($this->request->hasArgument('options')) { + $optionUids = $this->request->getArgument('options'); + $options = $this->groupsPriceOptionRepository->findByUids($optionUids)->toArray(); + $this->request->setArgument('options', $options); } } /** * @param Hotel $hotel - * @param \DateTime $dateFrom - * @param \DateTime $dateTo + * @param string $name + * @param string $email + * @param string $dateFrom + * @param string $dateTo * @param int $pax - * @return string - * @throws \League\Period\Exception + * @param array $options + * @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) { - $period = new Period($dateFrom, $dateTo); - $price = $this->groupsPriceService->calculateHotelPrice($hotel, $period, $pax); + $emailOptions = [ + 'toEmail' => $this->settings['groupsPriceToEmail'], + '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([ - 'price' => $price ?? [], - 'configs' => $hotel->getGroupsPriceConfigs()->toArray(), - 'boards' => $hotel->getGroupsPriceBoards()->toArray(), - 'options' => $hotel->getGroupsPriceOptions()->toArray(), - ], JSON_THROW_ON_ERROR, 512); + $response['status'] = 'validation'; + $response['errors'] = $formErrors; + + return json_encode($response); } } diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/GroupsPriceController.php b/public/typo3conf/ext/ep_products/Classes/Controller/GroupsPriceController.php new file mode 100644 index 00000000..796fb7aa --- /dev/null +++ b/public/typo3conf/ext/ep_products/Classes/Controller/GroupsPriceController.php @@ -0,0 +1,42 @@ +, 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())); + } +} diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceBoard.php b/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceBoard.php index 71c6fd21..97e67129 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceBoard.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceBoard.php @@ -79,6 +79,7 @@ class GroupsPriceBoard extends AbstractEntity implements \JsonSerializable public function jsonSerialize() { return [ + 'uid' => $this->getUid(), 'title' => $this->getTitle(), 'price' => $this->getPrice(), ]; diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceConfig.php b/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceConfig.php index a1b7d8ab..e5ef594b 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceConfig.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceConfig.php @@ -142,11 +142,12 @@ class GroupsPriceConfig extends AbstractEntity implements \JsonSerializable public function jsonSerialize() { return [ - 'dateFrom' => $this->getDateFrom()->format('d.m.Y'), - 'dateTo' => $this->getDateTo()->format('d.m.Y'), + 'uid' => $this->getUid(), + 'dateFrom' => $this->getDateFrom()->format('Y-m-d'), + 'dateTo' => $this->getDateTo()->format('Y-m-d'), 'personsIncluded' => $this->getPersonsIncluded(), 'price' => $this->getPrice(), 'priceAdditionalPerson' => $this->getPriceAdditionalPerson(), ]; } -} \ No newline at end of file +} diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceOption.php b/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceOption.php index 63f4d534..36cc4e4e 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceOption.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Model/GroupsPriceOption.php @@ -31,6 +31,11 @@ use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; 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 */ @@ -41,6 +46,16 @@ class GroupsPriceOption extends AbstractEntity implements \JsonSerializable */ protected $price; + /** + * @var int + */ + protected $type; + + /** + * @var bool + */ + protected $ignoreWithBoard = false; + /** * @return string */ @@ -73,14 +88,49 @@ class GroupsPriceOption extends AbstractEntity implements \JsonSerializable $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 */ public function jsonSerialize() { return [ + 'uid' => $this->getUid(), 'title' => $this->getTitle(), 'price' => $this->getPrice(), + 'type' => $this->getType(), + 'ignoreWithBoard' => $this->isIgnoreWithBoard(), ]; } -} \ No newline at end of file +} diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/GroupsPriceOptionRepository.php b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/GroupsPriceOptionRepository.php new file mode 100644 index 00000000..c2572427 --- /dev/null +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/GroupsPriceOptionRepository.php @@ -0,0 +1,47 @@ +, 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(); + } +} diff --git a/public/typo3conf/ext/ep_products/Classes/Service/EmailService.php b/public/typo3conf/ext/ep_products/Classes/Service/EmailService.php new file mode 100644 index 00000000..c05afe99 --- /dev/null +++ b/public/typo3conf/ext/ep_products/Classes/Service/EmailService.php @@ -0,0 +1,122 @@ +, 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); + } +} diff --git a/public/typo3conf/ext/ep_products/Classes/Service/GroupsPriceService.php b/public/typo3conf/ext/ep_products/Classes/Service/GroupsPriceService.php deleted file mode 100644 index cc174e83..00000000 --- a/public/typo3conf/ext/ep_products/Classes/Service/GroupsPriceService.php +++ /dev/null @@ -1,105 +0,0 @@ -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'); - } -} \ No newline at end of file diff --git a/public/typo3conf/ext/ep_products/Configuration/TCA/Overrides/tt_content.php b/public/typo3conf/ext/ep_products/Configuration/TCA/Overrides/tt_content.php index 0b9c6340..3b9e2372 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TCA/Overrides/tt_content.php +++ b/public/typo3conf/ext/ep_products/Configuration/TCA/Overrides/tt_content.php @@ -26,7 +26,7 @@ call_user_func(function () { \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'product_detail', - 'Produktdetails' + 'Produkt: Details' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( @@ -38,7 +38,7 @@ call_user_func(function () { \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'product_teasergroup', - 'Produktteaser' + 'Produkt: Teaser' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( @@ -56,61 +56,67 @@ call_user_func(function () { \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'region_teasergroup', - 'Gebietsteaser' + 'Gebiet: Teaser' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'region_detail', - 'Gebietsdetails' + 'Gebiet: Details' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'city_teasergroup', - 'Ortsteaser' + 'Ort: Teaser' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'city_detail', - 'Ortsdetails' + 'Ort: Details' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'hotel_teasergroup', - 'Hotelteaser' + 'Hotel: Teaser' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'hotel_teasergroup_nodate', - 'Hotelteaser (terminunabhängig)' + 'Hotel: Teaser (terminunabhängig)' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', '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( 'EP.EpProducts', 'hotel_detail_event', - 'Hoteldetails (Event)' + 'Hotel: Details (Event)' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'concept_teasergroup', - 'Konzeptteaser' + 'Konzept: Teaser' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( 'EP.EpProducts', 'concept_detail', - 'Konzeptdetails' + 'Konzept: Details' ); \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin( diff --git a/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_groupspriceoption.php b/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_groupspriceoption.php index 7808a59b..996d4232 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_groupspriceoption.php +++ b/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_groupspriceoption.php @@ -24,14 +24,16 @@ return [ 'hideTable' => true, ], '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' => [ '1' => [ - 'showitem' => 'title, price', + 'showitem' => 'title, --palette--;;priceconfig', ], ], 'palettes' => [ + 'priceconfig' => ['showitem' => 'price, type, ignore_with_board'], ], 'columns' => [ @@ -140,6 +142,29 @@ return [ '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' => [ 'config' => [ 'type' => 'passthrough' diff --git a/public/typo3conf/ext/ep_products/Configuration/TypoScript/constants.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/constants.typoscript index a3160370..bb375bb2 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/constants.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/constants.typoscript @@ -38,6 +38,10 @@ plugin.tx_epproducts { searchLogIgnoreIps = # cat=plugin.tx_epproducts//a; type=string; label=Page UID with reseller export plugin resellerExportPageUid = + # cat=plugin.tx_epproducts//a; type=string; label=Email recipient for groups price inquiries + groupsPriceToEmail = gruppen@ep-reisen.de + # cat=plugin.tx_epproducts//a; type=string; label=Email recipient for groups price inquiries + groupsPriceToName = EP Reisen } persistence { # cat=plugin.tx_epproducts//a; type=string; label=Default storage PID diff --git a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript index a770a066..2e5a6c96 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript @@ -42,6 +42,9 @@ plugin.tx_epproducts { ratingPageUid = {$plugin.tx_eptheme.settings.ratingPageUid} searchPageHeaderImage = {$plugin.tx_eptheme.settings.searchPageHeaderImage} 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 { 1 { label = Silvester @@ -134,7 +137,7 @@ tx_epproducts_ajax_json { 1 = list } AjaxGroupsPrice { - 1 = index + 1 = processForm } } features.requireCHashArgumentForActionArguments = 0 diff --git a/public/typo3conf/ext/ep_products/ext_localconf.php b/public/typo3conf/ext/ep_products/ext_localconf.php index 255c1ddf..6f7de83a 100644 --- a/public/typo3conf/ext/ep_products/ext_localconf.php +++ b/public/typo3conf/ext/ep_products/ext_localconf.php @@ -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( 'EP.' . $_EXTKEY, 'hotel_detail_event', @@ -345,7 +356,7 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T 'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable', 'AjaxCalendar' => 'range,contingents,availableRooms', 'AjaxWatchlist' => 'list', - 'AjaxGroupsPrice' => 'index', + 'AjaxGroupsPrice' => 'processForm', ], [ 'AjaxSearch' => 'searchresult', @@ -356,7 +367,7 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T 'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable', 'AjaxCalendar' => 'range,contingents,availableRooms', 'AjaxWatchlist' => 'list', - 'AjaxGroupsPrice' => 'index', + 'AjaxGroupsPrice' => 'processForm', ] ); diff --git a/public/typo3conf/ext/ep_products/ext_tables.sql b/public/typo3conf/ext/ep_products/ext_tables.sql index 7bccd587..3b927f41 100644 --- a/public/typo3conf/ext/ep_products/ext_tables.sql +++ b/public/typo3conf/ext/ep_products/ext_tables.sql @@ -322,35 +322,37 @@ CREATE TABLE tx_epproducts_domain_model_groupspriceconfig CREATE TABLE tx_epproducts_domain_model_groupspriceoption ( - 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, - title varchar(255) DEFAULT '' NOT NULL, - price float(8) unsigned DEFAULT '0' NOT NULL, - hotel int(11) unsigned DEFAULT '0', - sorting int(11) DEFAULT '0' NOT NULL, + title varchar(255) DEFAULT '' NOT NULL, + price float(8) unsigned DEFAULT '0' NOT NULL, + type tinyint(4) unsigned 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, - 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), diff --git a/public/typo3conf/ext/ep_theme/Configuration/PageTS/Mod/WebLayout/BackendLayouts.tsconfig b/public/typo3conf/ext/ep_theme/Configuration/PageTS/Mod/WebLayout/BackendLayouts.tsconfig index 5e9f9e54..202eda51 100644 --- a/public/typo3conf/ext/ep_theme/Configuration/PageTS/Mod/WebLayout/BackendLayouts.tsconfig +++ b/public/typo3conf/ext/ep_theme/Configuration/PageTS/Mod/WebLayout/BackendLayouts.tsconfig @@ -21,6 +21,8 @@ mod { } frontpageEvent < .frontpage frontpageEvent.title = Startseite Events + popup < .frontpage + popup.title = Popup detail { title = Detailseite config { diff --git a/public/typo3conf/ext/ep_theme/Configuration/TypoScript/constants.typoscript b/public/typo3conf/ext/ep_theme/Configuration/TypoScript/constants.typoscript index 114b9ba5..9038288f 100644 --- a/public/typo3conf/ext/ep_theme/Configuration/TypoScript/constants.typoscript +++ b/public/typo3conf/ext/ep_theme/Configuration/TypoScript/constants.typoscript @@ -58,6 +58,8 @@ plugin.tx_eptheme { myEpPageUid = # cat=eptheme/200/310; type=string; label=Booking links PID bookingLinksPid = + # cat=eptheme/200/330; type=string; label=Groups price popup page UID + groupsPricePopupPageUid = # cat=eptheme/400/100; type=string; label=Phone number general phoneNumber = 0221 - 272 276 0 diff --git a/public/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.typoscript index 5d7df14c..042f5f69 100644 --- a/public/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.typoscript @@ -66,6 +66,7 @@ plugin.tx_eptheme { eventDisturberButtonLink = {$plugin.tx_eptheme.settings.eventDisturberButtonLink} googleTagManagerId = {$plugin.tx_eptheme.settings.googleTagManagerId} bpnBookingUrlTemplateCode = {$plugin.tx_eptheme.settings.bpnBookingUrlTemplateCode} + groupsPricePopupPageUid = {$plugin.tx_eptheme.settings.groupsPricePopupPageUid} googleStaticMapsBaseUrl = {$plugin.tx_eptheme.settings.googleStaticMapsBaseUrl} googleMapsJsApiUrl = {$plugin.tx_eptheme.settings.googleMapsJsApiUrl} googleMapsApiKey = {$plugin.tx_eptheme.settings.googleMapsApiKey} diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js index 9e6fe920..2e565cd5 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/_app.js @@ -40,6 +40,9 @@ const sliderPrevArrow = ''; const sliderDot = '