diff --git a/public/typo3conf/ext/ep_products/Classes/Controller/AjaxGroupsPriceController.php b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxGroupsPriceController.php new file mode 100644 index 00000000..4f8c54ea --- /dev/null +++ b/public/typo3conf/ext/ep_products/Classes/Controller/AjaxGroupsPriceController.php @@ -0,0 +1,91 @@ +, 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 EP\EpProducts\Service\GroupsPriceService; +use League\Period\Period; +use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; + +class AjaxGroupsPriceController extends ActionController +{ + /** + * @var GroupsPriceService + */ + protected $groupsPriceService; + + public function __construct(GroupsPriceService $groupsPriceService) + { + parent::__construct(); + + $this->groupsPriceService = $groupsPriceService; + } + + /** + * @param Hotel $hotel + * @return string + */ + public function configsAction(Hotel $hotel) + { + return json_encode([ + 'configs' => $hotel->getGroupsPriceConfigs()->toArray(), + 'boards' => $hotel->getGroupsPriceBoards()->toArray(), + 'options' => $hotel->getGroupsPriceOptions()->toArray(), + ], JSON_THROW_ON_ERROR, 512); + } + + public function initializePriceAction() + { + if ($this->request->hasArgument('dateFrom')) { + $dateFrom = new \DateTime($this->request->getArgument('dateFrom')); + $this->request->setArgument('dateFrom', $dateFrom); + } + if ($this->request->hasArgument('dateTo')) { + $dateTo = new \DateTime($this->request->getArgument('dateTo')); + $this->request->setArgument('dateTo', $dateTo); + } + } + + /** + * @param Hotel $hotel + * @param \DateTime $dateFrom + * @param \DateTime $dateTo + * @param int $pax + * @return string + * @throws \League\Period\Exception + */ + public function priceAction(Hotel $hotel, \DateTime $dateFrom, \DateTime $dateTo, $pax) + { + $period = new Period($dateFrom, $dateTo); + $price = $this->groupsPriceService->calculateHotelPrice($hotel, $period, $pax); + + return json_encode([ + 'price' => $price, + ], JSON_THROW_ON_ERROR, 512); + } +} diff --git a/public/typo3conf/ext/ep_products/Classes/Service/GroupsPriceService.php b/public/typo3conf/ext/ep_products/Classes/Service/GroupsPriceService.php new file mode 100644 index 00000000..f44deadf --- /dev/null +++ b/public/typo3conf/ext/ep_products/Classes/Service/GroupsPriceService.php @@ -0,0 +1,80 @@ +getConfigs($hotel); + + // Create periods in configs to simplify following steps + $this->patchConfigPeriods($configs); + + $price = 0; + + // Iterate over all days in 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']); + } + } + } + + return $price; + } + + 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/TypoScript/setup.typoscript b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript index 7f1e426c..5be9ade7 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript +++ b/public/typo3conf/ext/ep_products/Configuration/TypoScript/setup.typoscript @@ -133,6 +133,10 @@ tx_epproducts_ajax_json { AjaxWatchlist { 1 = list } + AjaxGroupsPrice { + 1 = configs + 2 = price + } } features.requireCHashArgumentForActionArguments = 0 settings =< plugin.tx_epproducts.settings diff --git a/public/typo3conf/ext/ep_products/ext_localconf.php b/public/typo3conf/ext/ep_products/ext_localconf.php index b32051ff..83c46f2d 100644 --- a/public/typo3conf/ext/ep_products/ext_localconf.php +++ b/public/typo3conf/ext/ep_products/ext_localconf.php @@ -345,6 +345,7 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T 'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable', 'AjaxCalendar' => 'range,contingents,availableRooms', 'AjaxWatchlist' => 'list', + 'AjaxGroupsPrice' => 'configs,price', ], [ 'AjaxSearch' => 'searchresult', @@ -355,6 +356,7 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T 'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable', 'AjaxCalendar' => 'range,contingents,availableRooms', 'AjaxWatchlist' => 'list', + 'AjaxGroupsPrice' => 'configs,price', ] ); @@ -382,6 +384,7 @@ $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epp $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_ajax[months]'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_ajax[month]'; $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_ajax[year]'; +$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'tx_epproducts_ajax[hotel]'; $GLOBALS['TYPO3_CONF_VARS']['LOG']['EP']['EpProducts']['Controller']['writerConfiguration'] = [ \TYPO3\CMS\Core\Log\LogLevel::INFO => [ diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/GroupsPriceCalculator.vue b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/GroupsPriceCalculator.vue new file mode 100644 index 00000000..ee647cad --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/GroupsPriceCalculator.vue @@ -0,0 +1,27 @@ + + + diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue index cbc22ec8..dbd0234b 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/ProductDetail.vue @@ -11,6 +11,7 @@ import DaterangeSelect from './DaterangeSelect.vue' import AjaxContent from './AjaxContent.vue' import Calendar from './Calendar.vue' + import GroupsPriceCalculator from './GroupsPriceCalculator.vue'; import FacebookPixel from './FacebookPixel.vue' import WatchlistToggle from './WatchlistToggle.vue' import OsmMap from './OsmMap.vue' @@ -28,6 +29,7 @@ DaterangeSelect, AjaxContent, Calendar, + GroupsPriceCalculator, FacebookPixel, WatchlistToggle, OsmMap, diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html index 52e4e8ed..c2b101a1 100644 --- a/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Templates/Product/Detail.html @@ -248,6 +248,9 @@ +

Belegungskalender