From 24adcaebd29881abc6506b36c1660127b0ebf05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Fromme?= Date: Wed, 12 Sep 2018 18:46:36 +0200 Subject: [PATCH] Implement daily bookable dates --- composer.json | 2 + composer.lock | 63 +++++- ...ntroller.php => DateCommandController.php} | 18 +- .../Controller/AjaxCalendarController.php | 3 +- .../Controller/AjaxContingentController.php | 100 +++++++++ .../Classes/Controller/AjaxDateController.php | 2 + .../Controller/AjaxTableController.php | 8 +- .../Classes/Controller/BackendController.php | 35 ++-- .../Classes/Controller/ProductController.php | 10 +- .../Classes/Domain/Model/FilterSettings.php | 4 +- .../Classes/Domain/Model/Product.php | 6 +- .../Repository/ContingentRepository.php | 64 ++++++ .../Classes/Service/ContingentDataService.php | 76 +++++++ .../Service/ContingentImportService.php | 8 +- ...mportService.php => DateImportService.php} | 69 +++++-- .../Classes/Service/FilterService.php | 14 +- ...rtProductsTask.php => ImportDatesTask.php} | 8 +- .../Classes/Task/ImportSnowreportTask.php | 6 +- .../tx_epproducts_domain_model_contingent.php | 13 +- .../Configuration/TypoScript/setup.txt | 4 + .../ext/ep_products/ext_localconf.php | 15 +- web/typo3conf/ext/ep_products/ext_tables.sql | 48 +++++ .../Configuration/TypoScript/setup.txt | 1 + .../Assets/js/components/DateSelect.vue | 195 ++++++++++++++++++ .../Assets/js/components/DatesTable.vue | 10 +- .../Assets/js/components/PriceTable.vue | 6 +- .../Assets/js/components/ProductDetail.vue | 69 ++++++- .../Private/Templates/Product/Detail.html | 54 +++-- web/typo3conf/realurl_conf.php | 1 + 29 files changed, 808 insertions(+), 104 deletions(-) rename web/typo3conf/ext/ep_products/Classes/Command/{ProductCommandController.php => DateCommandController.php} (84%) create mode 100644 web/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php create mode 100644 web/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php rename web/typo3conf/ext/ep_products/Classes/Service/{DatesImportService.php => DateImportService.php} (90%) rename web/typo3conf/ext/ep_products/Classes/Task/{ImportProductsTask.php => ImportDatesTask.php} (89%) create mode 100644 web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue diff --git a/composer.json b/composer.json index 83074b5f..f2fb7c64 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,8 @@ "require": { "php": "^7.1", "ext-json": "*", + "ext-libxml": "*", + "ext-simplexml": "*", "typo3/cms": "^8.7", "typo3/cms-backend": "^8.7", "typo3/cms-belog": "^8.7", diff --git a/composer.lock b/composer.lock index 1e90f3fe..345df235 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bf966b3d9286731a2aa6030d0010afed", + "content-hash": "0336ff7055dae975d70aea8153e7b798", "packages": [ { "name": "christophlehmann/imageoptimizer", @@ -1265,6 +1265,63 @@ ], "time": "2018-02-06T08:27:03+00:00" }, + { + "name": "league/period", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/period.git", + "reference": "280b54d737b4d9d804d19f865a6496b82d1cee2a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/period/zipball/280b54d737b4d9d804d19f865a6496b82d1cee2a", + "reference": "280b54d737b4d9d804d19f865a6496b82d1cee2a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^1.10", + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Period\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://github.com/nyamsprod/", + "role": "Developer" + } + ], + "description": "A time range immutable value object", + "homepage": "http://period.thephpleague.com", + "keywords": [ + "date", + "dateinterval", + "dateperiod", + "datetime", + "interval", + "range", + "time" + ], + "time": "2017-11-17T11:28:33+00:00" + }, { "name": "linkorb/jsmin-php", "version": "1.0.0", @@ -3686,7 +3743,9 @@ "prefer-lowest": false, "platform": { "php": "^7.1", - "ext-json": "*" + "ext-json": "*", + "ext-libxml": "*", + "ext-simplexml": "*" }, "platform-dev": [], "platform-overrides": { diff --git a/web/typo3conf/ext/ep_products/Classes/Command/ProductCommandController.php b/web/typo3conf/ext/ep_products/Classes/Command/DateCommandController.php similarity index 84% rename from web/typo3conf/ext/ep_products/Classes/Command/ProductCommandController.php rename to web/typo3conf/ext/ep_products/Classes/Command/DateCommandController.php index fd0ba219..cb8cf565 100644 --- a/web/typo3conf/ext/ep_products/Classes/Command/ProductCommandController.php +++ b/web/typo3conf/ext/ep_products/Classes/Command/DateCommandController.php @@ -27,19 +27,19 @@ namespace EP\EpProducts\Command; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Service\DatesImportService; +use EP\EpProducts\Service\DateImportService; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Extbase\Mvc\Controller\CommandController; use TYPO3\CMS\Extbase\Service\CacheService; -class ProductCommandController extends CommandController +class DateCommandController extends CommandController { /** - * @var \EP\EpProducts\Service\DatesImportService + * @var \EP\EpProducts\Service\DateImportService */ - protected $datesImportService; + protected $dateImportService; /** * @var CacheService @@ -52,18 +52,18 @@ class ProductCommandController extends CommandController protected $configurationManager; /** - * @param DatesImportService $datesImportService + * @param DateImportService $importService * @param CacheService $cacheService * @param ConfigurationManagerInterface $configurationManager */ public function __construct ( - DatesImportService $datesImportService, + DateImportService $importService, CacheService $cacheService, ConfigurationManagerInterface $configurationManager ) { - $this->datesImportService = $datesImportService; + $this->dateImportService = $importService; $this->cacheService = $cacheService; $this->configurationManager = $configurationManager; } @@ -71,10 +71,10 @@ class ProductCommandController extends CommandController public function importCommand() { $path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport'); - if ($this->datesImportService->checkActiveUpload($path)) { + if ($this->dateImportService->checkActiveUpload($path)) { $this->outputLine('Import cancelled due to active file upload.'); } else { - $count = $this->datesImportService->import($path); + $count = $this->dateImportService->import($path); $this->outputLine('%d rows imported.', [ $count ]); $settings = $this->getSettings(); $resellerPageUid = $settings['resellerExportPageUid']; diff --git a/web/typo3conf/ext/ep_products/Classes/Controller/AjaxCalendarController.php b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxCalendarController.php index 1224e703..5e32f586 100644 --- a/web/typo3conf/ext/ep_products/Classes/Controller/AjaxCalendarController.php +++ b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxCalendarController.php @@ -58,7 +58,7 @@ class AjaxCalendarController extends ActionController */ public function rangeAction(Hotel $hotel, $year = null, $month = null, $months = 6) { - list ($begin, $end) = DateUtility::getDateRange($year, $month, $months); + [ $begin, $end ] = DateUtility::getDateRange($year, $month, $months); $factory = new Calendar(); $factory->getEventManager()->addProvider('contingent', $this->contingentRepository); @@ -88,4 +88,5 @@ class AjaxCalendarController extends ActionController 'events' => $events, ]); } + } diff --git a/web/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php new file mode 100644 index 00000000..466b2117 --- /dev/null +++ b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxContingentController.php @@ -0,0 +1,100 @@ +, 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\Domain\Model\Product; +use EP\EpProducts\Domain\Repository\ContingentRepository; +use EP\EpProducts\Service\ContingentDataService; +use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; + +class AjaxContingentController extends ActionController +{ + /** + * @var \EP\EpProducts\Domain\Repository\ContingentRepository + */ + protected $contingentRepository; + /** + * @var ContingentDataService + */ + protected $contingentDataService; + + /** + * @param ContingentRepository $contingentRepository + * @param ContingentDataService $contingentDataService + */ + public function __construct + ( + ContingentRepository $contingentRepository, + ContingentDataService $contingentDataService + ) + { + parent::__construct(); + $this->contingentRepository = $contingentRepository; + $this->contingentDataService = $contingentDataService; + } + + public function initializeAction() + { + 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 Product $product + * @return string + */ + public function listAction(Hotel $hotel, Product $product) + { + $enabled = $this->contingentRepository->getAvailableContingents($hotel, $product); + + return json_encode($enabled); + } + + /** + * @param Hotel $hotel + * @param Product $product + * @param \DateTime $dateFrom + * @param \DateTime $dateTo + * @return string + */ + public function roomsAction(Hotel $hotel, Product $product, \DateTime $dateFrom, \DateTime $dateTo) + { + $rooms = $this->contingentDataService->getAvailableRooms($dateFrom, $dateTo, $hotel, $product); + + return \json_encode($rooms); + } + +} diff --git a/web/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php index ad986399..7e99dde3 100644 --- a/web/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php +++ b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxDateController.php @@ -35,6 +35,8 @@ use EP\EpProducts\Service\DateService; use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\ResellerDataService; use EP\EpProducts\Traits\RequestArgumentTypeConversionTrait; +use EP\EpProducts\Utility\DateUtility; +use League\Period\Period; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; diff --git a/web/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php index 1efdb4e7..631960db 100644 --- a/web/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php +++ b/web/typo3conf/ext/ep_products/Classes/Controller/AjaxTableController.php @@ -90,7 +90,13 @@ class AjaxTableController extends ActionController * * @return string */ - public function pricetableAction(Product $product, Hotel $hotel, FilterSettings $filterSettings = null, Date $date = null) + public function pricetableAction + ( + Product $product, + Hotel $hotel, + FilterSettings $filterSettings = null, + Date $date = null + ) { if ($filterSettings === null) { $forcedConceptUid = (int) $this->settings['forcedConceptUid']; diff --git a/web/typo3conf/ext/ep_products/Classes/Controller/BackendController.php b/web/typo3conf/ext/ep_products/Classes/Controller/BackendController.php index 320e5c4c..e49bea12 100644 --- a/web/typo3conf/ext/ep_products/Classes/Controller/BackendController.php +++ b/web/typo3conf/ext/ep_products/Classes/Controller/BackendController.php @@ -28,7 +28,7 @@ namespace EP\EpProducts\Controller; ***************************************************************/ use EP\EpProducts\Service\ContingentImportService; -use EP\EpProducts\Service\DatesImportService; +use EP\EpProducts\Service\DateImportService; use EP\EpProducts\Service\LogService; use EP\EpProducts\Service\SnowreportImportService; use TYPO3\CMS\Backend\View\BackendTemplateView; @@ -49,14 +49,9 @@ class BackendController extends ActionController protected $view; /** - * @var \EP\EpProducts\Service\DatesImportService + * @var \EP\EpProducts\Service\DateImportService */ - protected $datesImportService; - - /** - * @var \EP\EpProducts\Service\ContingentImportService - */ - protected $contingentImportService; + protected $dateImportService; /** * @var \EP\EpProducts\Service\SnowreportImportService @@ -69,23 +64,29 @@ class BackendController extends ActionController protected $logService; /** - * @param DatesImportService $datesImportService + * @var ContingentImportService + */ + protected $contingentImportService; + + /** + * @param DateImportService $dateImportService * @param ContingentImportService $contingentImportService - * @param SnowreportImportService $snowreportImportService + * @param SnowreportImportService $snowreportService * @param LogService $logService */ public function __construct ( - DatesImportService $datesImportService, + DateImportService $dateImportService, ContingentImportService $contingentImportService, - SnowreportImportService $snowreportImportService, + SnowreportImportService $snowreportService, LogService $logService ) { parent::__construct(); - $this->datesImportService = $datesImportService; + + $this->dateImportService = $dateImportService; $this->contingentImportService = $contingentImportService; - $this->snowreportImportService = $snowreportImportService; + $this->snowreportImportService = $snowreportService; $this->logService = $logService; } @@ -95,14 +96,14 @@ class BackendController extends ActionController public function importProductsAction() { $path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport'); - if ($this->datesImportService->checkActiveUpload($path)) { + if ($this->dateImportService->checkActiveUpload($path)) { $this->addFlashMessage( 'Datenexport aus BusProNet aktiv. Import nicht möglich.', 'Import fehlgeschlagen', AbstractMessage::WARNING ); } else { - $dateCount = $this->datesImportService->import($path); + $dateCount = $this->dateImportService->import($path); $this->addFlashMessage($dateCount . ' Termine importiert', 'Import abgechlossen', AbstractMessage::OK); $resellerPageUid = $this->settings['resellerExportPageUid']; $this->cacheService->clearPageCache($resellerPageUid); @@ -153,7 +154,7 @@ class BackendController extends ActionController header('Expires: 0'); header('Pragma: public'); - $fh = @fopen( 'php://output', 'w' ); + $fh = @fopen( 'php://output', 'wb' ); foreach ($csv as $data) { fputcsv($fh, $data, ';'); diff --git a/web/typo3conf/ext/ep_products/Classes/Controller/ProductController.php b/web/typo3conf/ext/ep_products/Classes/Controller/ProductController.php index c48808a9..c7f25c34 100644 --- a/web/typo3conf/ext/ep_products/Classes/Controller/ProductController.php +++ b/web/typo3conf/ext/ep_products/Classes/Controller/ProductController.php @@ -135,7 +135,7 @@ class ProductController extends ActionController $hotel = $this->hotelRepository->findByIdentifier($hotelUid); } if ($hotel === null) { - // Forward to hotel list action in case no single hotel can be determined + // Forward to hotel list action in case multiple hotels are assigned to this product if ($product->getHotels()->count() > 1) { $arguments = [ 'product' => $product, @@ -149,11 +149,11 @@ class ProductController extends ActionController $hotel = reset($product->getHotels()->toArray()); } } - list($productDateRangeFrom, $productDateRangeTo) = $this->filterService->getProductDateRange($product, $filterSettings); + [ $productDateRangeFrom, $productDateRangeTo ] = $this->filterService->getProductDateRange($product, $filterSettings); $excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']); - $isProductWithExcludedConcept = ($product->getConcept() !== null) && in_array($product->getConcept()->getUid(), $excludedConceptUids); + $isProductWithExcludedConcept = ($product->getConcept() !== null) && \in_array($product->getConcept()->getUid(), $excludedConceptUids, false); $noInfoConceptUids = GeneralUtility::trimExplode(',', $this->settings['noInfoConceptUids']); - $isProductWithNoInfoConcept = ($product->getConcept() !== null) && in_array($product->getConcept()->getUid(), $noInfoConceptUids); + $isProductWithNoInfoConcept = ($product->getConcept() !== null) && \in_array($product->getConcept()->getUid(), $noInfoConceptUids, false); $this->view->assignMultiple([ 'filterSettings' => $filterSettings, 'hotel' => $hotel, @@ -195,7 +195,7 @@ class ProductController extends ActionController ) { $hotels = $this->hotelDataService->getList($product); - list ($productDateRangeFrom, $productDateRangeTo) = $this->filterService->getProductDateRange($product, $filterSettings); + [ $productDateRangeFrom, $productDateRangeTo ] = $this->filterService->getProductDateRange($product, $filterSettings); $this->view->assignMultiple([ 'filterSettings' => $filterSettings, 'hotels' => $hotels, diff --git a/web/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php b/web/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php index 641dfb03..0848ad7d 100644 --- a/web/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php +++ b/web/typo3conf/ext/ep_products/Classes/Domain/Model/FilterSettings.php @@ -400,7 +400,7 @@ class FilterSettings implements \JsonSerializable /** * @param \DateTime $dateFrom */ - public function setDateFrom(\DateTime $dateFrom = null) + public function setDateFrom(\DateTimeInterface $dateFrom = null) { $this->dateFrom = $dateFrom; } @@ -416,7 +416,7 @@ class FilterSettings implements \JsonSerializable /** * @param \DateTime $dateTo */ - public function setDateTo(\DateTime $dateTo = null) + public function setDateTo(\DateTimeInterface $dateTo = null) { if ($this->dateFrom !== null && $dateTo !== null && $dateTo < $this->dateFrom) { $dateTo = $this->dateFrom; diff --git a/web/typo3conf/ext/ep_products/Classes/Domain/Model/Product.php b/web/typo3conf/ext/ep_products/Classes/Domain/Model/Product.php index 676bdaff..bd42d135 100644 --- a/web/typo3conf/ext/ep_products/Classes/Domain/Model/Product.php +++ b/web/typo3conf/ext/ep_products/Classes/Domain/Model/Product.php @@ -284,7 +284,7 @@ class Product extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity implements */ public function getBookable() { - return $this->bookable; + return (bool) $this->bookable; } /** @@ -300,7 +300,7 @@ class Product extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity implements */ public function isDaytrip() { - return $this->daytrip; + return (bool) $this->daytrip; } /** @@ -308,7 +308,7 @@ class Product extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity implements */ public function setDaytrip($daytrip) { - $this->daytrip = $daytrip; + $this->daytrip = (bool) $daytrip; } /** diff --git a/web/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php b/web/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php index a531e089..4b42ed80 100644 --- a/web/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php +++ b/web/typo3conf/ext/ep_products/Classes/Domain/Repository/ContingentRepository.php @@ -30,6 +30,7 @@ namespace EP\EpProducts\Domain\Repository; use CalendR\Event\Provider\ProviderInterface; use EP\EpProducts\Domain\Model\Contingent; use EP\EpProducts\Domain\Model\Hotel; +use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Utility\DbUtility; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -90,4 +91,67 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa return $events; } + + /** + * @param Hotel $hotel + * @param Product $product + * @return array + */ + public function getAvailableContingents(Hotel $hotel, Product $product) + { + $qb = DbUtility::getDbConnection()->createQueryBuilder(); + + $qb + ->select('c.date date', 'SUM(c.available) total') + ->from('tx_epproducts_domain_model_contingent', 'c') + ->innerJoin('c', 'tx_epproducts_domain_model_daytrip', 'd', 'c.date = d.date AND c.hotel_code = d.hotel_code') + ->where('c.hotel = :hotelUid') + ->andWhere('d.product = :productUid') + ->andWhere('c.available > 0') + ->setParameters([ + 'hotelUid' => $hotel->getUid(), + 'productUid' => $product->getUid(), + ]) + ->groupBy('c.date') + ->orderBy('c.date') + ; + + return $qb->execute()->fetchAll(); + } + + /** + * @param \DateTime $dateFrom + * @param \DateTime $dateTo + * @param Hotel $hotel + * @param Product $product + * @return array + */ + public function getAvailableRooms(\DateTime $dateFrom, \DateTime $dateTo, Hotel $hotel, Product $product) + { + $qb = DbUtility::getDbConnection()->createQueryBuilder(); + + $qb + ->select('c.room_code code', 'c.room_label label', 'c.available', 'c.min_price price', + 'c.hotel_bus_pro_id hotelBusProId', 'd.bus_pro_id busProId') + ->from('tx_epproducts_domain_model_contingent', 'c') + ->innerJoin('c', 'tx_epproducts_domain_model_daytrip', 'd', 'c.date = d.date AND c.hotel_code = d.hotel_code') + ->where('c.hotel = :hotelUid') + ->andWhere('d.product = :productUid') + ->andWhere('c.date >= :dateFrom') + ->andWhere('c.date <= :dateTo') + ->andWhere('c.min_price > 0') + ->setParameters([ + 'hotelUid' => $hotel->getUid(), + 'productUid' => $product->getUid(), + 'dateFrom' => $dateFrom->format('Y-m-d'), + 'dateTo' => $dateTo->format('Y-m-d'), + ]) + ->groupBy('c.room_code') + ->orderBy('c.pax') + ->addOrderBy('c.min_price') + ; + + return $qb->execute()->fetchAll(); + } + } diff --git a/web/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php b/web/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php new file mode 100644 index 00000000..87812a7c --- /dev/null +++ b/web/typo3conf/ext/ep_products/Classes/Service/ContingentDataService.php @@ -0,0 +1,76 @@ +, 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\Domain\Model\Product; +use EP\EpProducts\Domain\Repository\ContingentRepository; +use EP\EpProducts\Utility\BookingUrlUtility; + +class ContingentDataService +{ + /** + * @var ContingentRepository + */ + protected $contingentRepository; + + /** + * @param ContingentRepository $contingentRepository + */ + public function __construct(ContingentRepository $contingentRepository) + { + $this->contingentRepository = $contingentRepository; + } + + /** + * @param \DateTime $dateFrom + * @param \DateTime $dateTo + * @param Hotel $hotel + * @param Product $product + * @return array + */ + public function getAvailableRooms(\DateTime $dateFrom, \DateTime $dateTo, Hotel $hotel, Product $product) + { + $data = $this->contingentRepository->getAvailableRooms($dateFrom, $dateTo, $hotel, $product); + + $rooms = []; + + foreach ($data as $row) + { + $row['bookingUrl'] = BookingUrlUtility::generateUrl([ + 'bookingId' => $row['busProId'], + 'hotelId' => $row['hotelBusProId'], + 'dateEnd' => $dateTo->format('Y-m-d'), + ]); + + $rooms[] = $row; + } + + return $rooms; + } +} diff --git a/web/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php b/web/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php index f782ec47..743a18c9 100644 --- a/web/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php +++ b/web/typo3conf/ext/ep_products/Classes/Service/ContingentImportService.php @@ -151,7 +151,7 @@ class ContingentImportService implements SingletonInterface protected function parseContingent(\SimpleXMLElement $xmlContingent) { $hotelCode = (string) $xmlContingent['code']; - $sql = 'SELECT uid, groupsch_id FROM tx_epproducts_domain_model_hotel WHERE deleted = 0 AND hidden = 0 AND code = :code'; + $sql = 'SELECT uid, code, groupsch_id FROM tx_epproducts_domain_model_hotel WHERE deleted = 0 AND hidden = 0 AND code = :code'; $hotelData = $this->db->fetchAssoc($sql, ['code' => $hotelCode]); // Skip import in case hotel can't be found @@ -162,6 +162,7 @@ class ContingentImportService implements SingletonInterface $this->logger->warning('hotel has no contingents', ['code' => $hotelCode]); return 0; } else { + $hotelData['busProId'] = (string) $xmlContingent['idbuspro']; $roomTypes = $this->parseRoomTypes($xmlContingent->unterbringungen); return $this->parseRooms($xmlContingent->kapazitaeten, $hotelData, $roomTypes); } @@ -179,6 +180,7 @@ class ContingentImportService implements SingletonInterface $types[(string) $xmlType['idbuspro']] = [ 'pax' => (int) $xmlType['pax_max'], 'code' => (string) $xmlType['code'], + 'label' => (string) $xmlType['zimmerbezeichnung'], 'ctrl' => (string) $xmlType['code'] === self::ROOMCODE_STATUS, ]; } @@ -231,12 +233,16 @@ class ContingentImportService implements SingletonInterface $status = Contingent::STATUS_ONREQUEST; } $minPrice = (int) $xmlRoom['abpreis']; + $roomLabel = $roomType['label']; $this->db->insert( 'tx_epproducts_domain_model_contingent_temp', [ 'pid' => $this->pid, 'hotel' => $hotelData['uid'], + 'hotel_code' => $hotelData['code'], + 'hotel_bus_pro_id' => $hotelData['busProId'], 'room_code' => $roomCode, + 'room_label' => $roomLabel, 'groupsch_id' => $hotelData['groupsch_id'], 'pax' => $pax, 'available' => $availablePax, diff --git a/web/typo3conf/ext/ep_products/Classes/Service/DatesImportService.php b/web/typo3conf/ext/ep_products/Classes/Service/DateImportService.php similarity index 90% rename from web/typo3conf/ext/ep_products/Classes/Service/DatesImportService.php rename to web/typo3conf/ext/ep_products/Classes/Service/DateImportService.php index 4daadd47..6a7e94a5 100644 --- a/web/typo3conf/ext/ep_products/Classes/Service/DatesImportService.php +++ b/web/typo3conf/ext/ep_products/Classes/Service/DateImportService.php @@ -36,7 +36,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Extbase\Service\CacheService; -class DatesImportService implements SingletonInterface +class DateImportService implements SingletonInterface { const CODE_PSEUDOPRICE = 'PDGS'; const CODE_BABYROOM = 'Baby'; @@ -174,24 +174,28 @@ class DatesImportService implements SingletonInterface public function createTempTables() { $this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_date_temp LIKE tx_epproducts_domain_model_date'); + $this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_daytrip_temp LIKE tx_epproducts_domain_model_daytrip'); $this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_room_temp LIKE tx_epproducts_domain_model_room'); } public function clearTables() { $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_date'); + $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_daytrip'); $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_room'); } public function copyTables() { $this->db->exec('INSERT INTO tx_epproducts_domain_model_date SELECT * FROM tx_epproducts_domain_model_date_temp'); + $this->db->exec('INSERT INTO tx_epproducts_domain_model_daytrip SELECT * FROM tx_epproducts_domain_model_daytrip_temp'); $this->db->exec('INSERT INTO tx_epproducts_domain_model_room SELECT * FROM tx_epproducts_domain_model_room_temp'); } public function clearTempTables() { $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_date_temp'); + $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_daytrip_temp'); $this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_room_temp'); } @@ -206,7 +210,7 @@ class DatesImportService implements SingletonInterface $dateCount = 0; $sql = ' - SELECT p.uid uid, p.name product_name, p.bus_pro_id bus_pro_id, p.searchable product_searchable, + SELECT p.uid uid, p.daytrip daytrip, p.name product_name, p.bus_pro_id bus_pro_id, p.searchable product_searchable, p.detail_page product_detail_page, p.keywords product_keywords, p.teaser product_teaser, p.feature product_feature, p.subline product_subline, p.country country, p.region region, p.city city, cnt.name country_name, cnt.code country_code, cnt.keywords country_keywords, r.name region_name, @@ -224,24 +228,31 @@ class DatesImportService implements SingletonInterface // Skip import in case product can't be found if (count($products) === 0) { - $this->logger->warning('product not found', ['code' => $code]); + $this->logger->warning('product not found or daytrip', ['code' => $code]); return 0; } - foreach ($products as $product) { - if (empty($product['bus_pro_id'])) { - $this->db->update( - 'tx_epproducts_domain_model_product', - ['bus_pro_id' => $busProId], - ['uid' => $product['uid']] - ); - } - $product['product_fact'] = $this->getTopFactForRecord('tx_epproducts_product_fact_mm', $product['uid']); - $product['region_fact'] = $this->getTopFactForRecord('tx_epproducts_region_fact_mm', $product['region']); - foreach ($xmlProduct->termin as $xmlDate) - { - $dateCount += $this->parseDates($xmlDate, $product); + // Skip import in case product is daytrip + if ($product['daytrip']) { + foreach ($xmlProduct->termin as $xmlDate) + { + $this->parseDaytripDates($xmlDate, $product); + } + } else { + if (empty($product['bus_pro_id'])) { + $this->db->update( + 'tx_epproducts_domain_model_product', + ['bus_pro_id' => $busProId], + ['uid' => $product['uid']] + ); + } + $product['product_fact'] = $this->getTopFactForRecord('tx_epproducts_product_fact_mm', $product['uid']); + $product['region_fact'] = $this->getTopFactForRecord('tx_epproducts_region_fact_mm', $product['region']); + foreach ($xmlProduct->termin as $xmlDate) + { + $dateCount += $this->parseDates($xmlDate, $product); + } } } @@ -281,6 +292,32 @@ class DatesImportService implements SingletonInterface return $dateCount; } + /** + * @param \SimpleXMLElement $xmlDate + * @param array $product + */ + protected function parseDaytripDates(\SimpleXMLElement $xmlDate, array $product) + { + foreach ($xmlDate->hotel as $xmlHotel) + { + $hotelCode = (string) $xmlHotel->attributes()['code']; + $hotel = $this->hotelMappings[$hotelCode]; + $dateStart = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['termin'])->format('Y-m-d'); + $this->db->insert( + 'tx_epproducts_domain_model_daytrip_temp', + [ + 'product' => $product['uid'], + 'date' => $dateStart, + 'bus_pro_id' => (int) $xmlDate->attributes()['idbuspro'], + 'code' => (string) $xmlDate->attributes()['code'], + 'hotel' => $hotel['uid'], + 'hotel_bus_pro_id' => (int) $xmlHotel->attributes()['idbuspro'], + 'hotel_code' => $hotelCode, + ] + ); + } + } + /** * @param array $product * @param \SimpleXMLElement $xmlDate diff --git a/web/typo3conf/ext/ep_products/Classes/Service/FilterService.php b/web/typo3conf/ext/ep_products/Classes/Service/FilterService.php index fdda4349..6883f10f 100644 --- a/web/typo3conf/ext/ep_products/Classes/Service/FilterService.php +++ b/web/typo3conf/ext/ep_products/Classes/Service/FilterService.php @@ -65,7 +65,7 @@ class FilterService implements SingletonInterface */ public function getDefaultFilterSettings($forcedConceptUid = null, $respectBookableDaterange = true) { - list($dateFrom, $dateTo) = $this->constrainDateRange($this->getDateRange()); + [ $dateFrom, $dateTo ] = $this->constrainDateRange($this->getDateRange()); if (!$respectBookableDaterange) { $dateFrom = new \DateTime('now'); } @@ -160,12 +160,12 @@ class FilterService implements SingletonInterface } // Hotel types - if (!in_array($row['hotelType'], $hotelTypes)) { + if (!\in_array($row['hotelType'], $hotelTypes, false)) { $hotelTypes[] = $row['hotelType']; } // Room types - if (!in_array($row['roomType'], $roomTypes)) { + if (!\in_array($row['roomType'], $roomTypes, false)) { $roomTypes[] = $row['roomType']; } @@ -174,7 +174,7 @@ class FilterService implements SingletonInterface 'uid' => $row['boardUid'], 'label' => $row['boardType'], ]; - if (!in_array($boardType, $boardTypes)) { + if (!\in_array($boardType, $boardTypes, false)) { $boardTypes[] = $boardType; } @@ -260,7 +260,7 @@ class FilterService implements SingletonInterface */ public function constrainDateRange(array $dateRange, FilterSettings $filterSettings = null) { - list ($dateFrom, $dateTo) = $dateRange; + [ $dateFrom, $dateTo ] = $dateRange; if ($filterSettings !== null) { $filterSettingsDateFrom = $filterSettings->getDateFrom(); if ($filterSettingsDateFrom !== null && $filterSettingsDateFrom > $dateFrom) { @@ -279,7 +279,7 @@ class FilterService implements SingletonInterface */ public function sanitizeDateRange(FilterSettings $filterSettings) { - list($validDateFrom, $validDateTo) = $this->getDateRange(); + [ $validDateFrom, $validDateTo ] = $this->getDateRange(); $dateFrom = $filterSettings->getDateFrom(); $dateTo = $filterSettings->getDateTo(); if ($dateFrom !== null && $dateTo !== null && $dateFrom >= $dateTo) { @@ -305,7 +305,7 @@ class FilterService implements SingletonInterface { if ($conceptUid) { $conceptUids = $filterSettings->getConceptUids(); - if (!in_array($conceptUid, $conceptUids)) { + if (!\in_array($conceptUid, $conceptUids, false)) { $conceptUids[] = (int) $conceptUid; $filterSettings->setConceptUids($conceptUids); } diff --git a/web/typo3conf/ext/ep_products/Classes/Task/ImportProductsTask.php b/web/typo3conf/ext/ep_products/Classes/Task/ImportDatesTask.php similarity index 89% rename from web/typo3conf/ext/ep_products/Classes/Task/ImportProductsTask.php rename to web/typo3conf/ext/ep_products/Classes/Task/ImportDatesTask.php index e0510ee1..4012193b 100644 --- a/web/typo3conf/ext/ep_products/Classes/Task/ImportProductsTask.php +++ b/web/typo3conf/ext/ep_products/Classes/Task/ImportDatesTask.php @@ -27,20 +27,20 @@ namespace EP\EpProducts\Task; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ -use EP\EpProducts\Service\DatesImportService; +use EP\EpProducts\Service\DateImportService; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Scheduler\Task\AbstractTask; -class ImportProductsTask extends AbstractTask +class ImportDatesTask extends AbstractTask { public function execute() { /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */ $objectManager = GeneralUtility::makeInstance(ObjectManager::class); - /** @var \EP\EpProducts\Service\DatesImportService $importService */ - $importService = $objectManager->get(DatesImportService::class); + /** @var \EP\EpProducts\Service\DateImportService $importService */ + $importService = $objectManager->get(DateImportService::class); $path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport'); if ($importService->checkActiveUpload($path)) { $message = GeneralUtility::makeInstance(FlashMessage::class, 'Import aborted due to active file upload', '', FlashMessage::WARNING); diff --git a/web/typo3conf/ext/ep_products/Classes/Task/ImportSnowreportTask.php b/web/typo3conf/ext/ep_products/Classes/Task/ImportSnowreportTask.php index fa81f490..ea8dcda2 100644 --- a/web/typo3conf/ext/ep_products/Classes/Task/ImportSnowreportTask.php +++ b/web/typo3conf/ext/ep_products/Classes/Task/ImportSnowreportTask.php @@ -38,9 +38,9 @@ class ImportSnowreportTask extends AbstractTask { /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */ $objectManager = GeneralUtility::makeInstance(ObjectManager::class); - $imporService = $objectManager->get(SnowreportImportService::class); - $imporService->downloadReportsXml(); - $imporService->importSnowReportData(); + $snowreportService = $objectManager->get(SnowreportImportService::class); + $snowreportService->downloadReportsXml(); + $snowreportService->importSnowReportData(); return true; } } diff --git a/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_contingent.php b/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_contingent.php index 93abbae6..39d99490 100644 --- a/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_contingent.php +++ b/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_contingent.php @@ -24,10 +24,10 @@ return [ 'iconfile' => 'EXT:ep_theme/Resources/Public/images/icon_ce.svg', ], 'interface' => [ - 'showRecordFieldList' => 'date,pax,available,status,min_price,hotel,room_code,groupsch_id', + 'showRecordFieldList' => 'date,pax,available,status,min_price,hotel,room_code,room_label,groupsch_id', ], 'types' => [ - '1' => ['showitem' => 'date, pax, available, status, min_price, hotel, room_code, groupsch_id'], + '1' => ['showitem' => 'date, pax, available, status, min_price, hotel, room_code, room_label, groupsch_id'], ], 'palettes' => [], 'columns' => [ @@ -203,5 +203,14 @@ return [ 'eval' => 'trim' ], ], + 'room_label' => [ + 'exclude' => 0, + 'label' => 'Zimmerbezeichnung', + 'config' => [ + 'type' => 'input', + 'size' => 30, + 'eval' => 'trim' + ], + ], ], ]; diff --git a/web/typo3conf/ext/ep_products/Configuration/TypoScript/setup.txt b/web/typo3conf/ext/ep_products/Configuration/TypoScript/setup.txt index 3ea48d27..5b76cacb 100644 --- a/web/typo3conf/ext/ep_products/Configuration/TypoScript/setup.txt +++ b/web/typo3conf/ext/ep_products/Configuration/TypoScript/setup.txt @@ -118,6 +118,10 @@ tx_epproducts_ajax_json { AjaxCalendar { 1 = range } + AjaxContingent { + 1 = list + 2 = rooms + } AjaxWatchlist { 1 = list } diff --git a/web/typo3conf/ext/ep_products/ext_localconf.php b/web/typo3conf/ext/ep_products/ext_localconf.php index e415be68..344f8b05 100644 --- a/web/typo3conf/ext/ep_products/ext_localconf.php +++ b/web/typo3conf/ext/ep_products/ext_localconf.php @@ -6,8 +6,8 @@ if (!defined('TYPO3_MODE')) { $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][$_EXTKEY] = \EP\EpProducts\Hook\Tcemain::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers']['ep_products_import'] = - \EP\EpProducts\Command\ProductCommandController::class; +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers']['ep_products_dates'] = + \EP\EpProducts\Command\DateCommandController::class; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers']['ep_products_snow_report'] = \EP\EpProducts\Command\SnowreportCommandController::class; @@ -15,9 +15,9 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers']['ep_p $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['extbase']['commandControllers']['ep_products_contingent'] = \EP\EpProducts\Command\ContingentCommandController::class; -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\Task\ImportProductsTask::class] = [ +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\Task\ImportDatesTask::class] = [ 'extension' => $_EXTKEY, - 'title' => 'EP Produkt Import', + 'title' => 'EP Reisedaten Import', 'description' => 'Importiert Reisedaten aus busProNet', ]; @@ -327,9 +327,9 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T 'AjaxDate' => 'dates', 'AjaxFilterpanel' => 'autocomplete', 'AjaxSearchbar' => 'options,reset', - 'AjaxContent' => 'country,region,city,hotel,product,journey,webcam', + 'AjaxContingent' => 'list,rooms', 'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable', - 'AjaxCalendar' => 'range', + 'AjaxCalendar' => 'range,contingents,availableRooms', 'AjaxWatchlist' => 'list', ], [ @@ -339,7 +339,8 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T 'AjaxSearchbar' => 'options,reset', 'AjaxContent' => 'webcam', 'AjaxTable' => 'pricetable,pricetableHtml,eventPricetable', - 'AjaxCalendar' => 'range', + 'AjaxCalendar' => 'range,contingents,availableRooms', + 'AjaxContingent' => 'list,rooms', 'AjaxWatchlist' => 'list', ] ); diff --git a/web/typo3conf/ext/ep_products/ext_tables.sql b/web/typo3conf/ext/ep_products/ext_tables.sql index 526d1e4b..cecb4b2a 100644 --- a/web/typo3conf/ext/ep_products/ext_tables.sql +++ b/web/typo3conf/ext/ep_products/ext_tables.sql @@ -947,7 +947,10 @@ CREATE TABLE tx_epproducts_domain_model_contingent ( available int(11) unsigned DEFAULT '0' NOT NULL, date date DEFAULT '0000-00-00', hotel int(11) unsigned DEFAULT '0', + hotel_code varchar(64) DEFAULT '' NOT NULL, + hotel_bus_pro_id varchar(64) DEFAULT '' NOT NULL, room_code varchar(64) DEFAULT '' NOT NULL, + room_label varchar(64) DEFAULT '' NOT NULL, status tinyint(4) unsigned DEFAULT '0' NOT NULL, min_price int(11) DEFAULT '0' NOT NULL, groupsch_id varchar(8) DEFAULT '' NOT NULL, @@ -982,6 +985,51 @@ CREATE TABLE tx_epproducts_domain_model_contingent ( ); +# +# Table structure for table 'tx_epproducts_domain_model_daytrip' +# +CREATE TABLE tx_epproducts_domain_model_daytrip ( + + uid int(11) NOT NULL auto_increment, + pid int(11) DEFAULT '0' NOT NULL, + + product int(11) unsigned DEFAULT '0', + date date DEFAULT '0000-00-00', + bus_pro_id varchar(64) DEFAULT '' NOT NULL, + code varchar(64) DEFAULT '' NOT NULL, + hotel int(11) unsigned DEFAULT '0', + hotel_bus_pro_id varchar(64) DEFAULT '' NOT NULL, + hotel_code varchar(64) DEFAULT '' 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, + + 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), + KEY t3ver_oid (t3ver_oid,t3ver_wsid), + KEY language (l10n_parent,sys_language_uid), + +); + # # Table structure for table 'tx_epproducts_domain_model_badge' # diff --git a/web/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.txt b/web/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.txt index 2b601187..3822e22d 100644 --- a/web/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.txt +++ b/web/typo3conf/ext/ep_theme/Configuration/TypoScript/setup.txt @@ -120,4 +120,5 @@ config { compressBody = 1 typolinkCheckRootline = 1 typolinkEnableLinksAcrossDomains = 1 + sendCacheHeaders = 1 } diff --git a/web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue b/web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue new file mode 100644 index 00000000..05c19ba1 --- /dev/null +++ b/web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DateSelect.vue @@ -0,0 +1,195 @@ + + + diff --git a/web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DatesTable.vue b/web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DatesTable.vue index ddedcd3d..9418deac 100644 --- a/web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DatesTable.vue +++ b/web/typo3conf/ext/ep_theme/Resources/Private/Assets/js/components/DatesTable.vue @@ -1,7 +1,9 @@