From 69f9b427570ab50fba5d3fbdc7b3515e99151cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Thu, 8 Oct 2026 16:09:11 +0200 Subject: [PATCH] feat: flag group travel dates from the BusPro customer selection --- .../ep_products/Classes/Domain/Model/Date.php | 21 ++++++++++ .../Domain/Repository/ProductRepository.php | 2 + .../Classes/Service/DateImportService.php | 38 +++++++++++++++++++ .../Classes/Service/DateService.php | 2 + .../TCA/tx_epproducts_domain_model_date.php | 12 +++++- .../typo3conf/ext/ep_products/ext_tables.sql | 1 + 6 files changed, 74 insertions(+), 2 deletions(-) diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Model/Date.php b/public/typo3conf/ext/ep_products/Classes/Domain/Model/Date.php index a6060a2d..c7b38ebe 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Model/Date.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Model/Date.php @@ -114,6 +114,11 @@ class Date extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity */ protected $skipassIncluded = false; + /** + * @var bool + */ + protected $groupTravel = false; + /** * @var bool */ @@ -421,6 +426,22 @@ class Date extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity $this->skipassIncluded = $skipassIncluded; } + /** + * @return bool + */ + public function getGroupTravel() + { + return $this->groupTravel; + } + + /** + * @param bool $groupTravel + */ + public function setGroupTravel($groupTravel) + { + $this->groupTravel = $groupTravel; + } + /** * @return bool */ diff --git a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php index 637f19ed..9a1007a2 100644 --- a/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php +++ b/public/typo3conf/ext/ep_products/Classes/Domain/Repository/ProductRepository.php @@ -210,6 +210,7 @@ class ProductRepository extends AbstractRepository 'date.uid as dateUid', 'date.date_start as dateStart', 'date.date_end as dateEnd', 'date.bus_pro_id as dateBusProId', 'date.hotel as hotelUid', 'date.hotel_bus_pro_id as hotelBusProId', 'date.bus_included as dateBusIncluded', 'date.skipass_included as dateSkiPassIncluded', + 'date.group_travel as dateGroupTravel', 'date.season as season', 'date.product_detail_page as productDetailPage', 'room.uid as roomUid', 'room.bus_pro_id as roomBusProId', 'room.name as roomName', 'room.price as roomPrice', 'date.discount as roomDiscount', 'date.bus_price as busPrice', @@ -273,6 +274,7 @@ class ProductRepository extends AbstractRepository 'date.discount as dateDiscount', 'date.bus_price as busPrice', 'date.nights as dateNights', 'date.bus_included as dateBusIncluded', 'date.services_included as dateServicesIncluded', 'date.services_general as dateServicesGeneral', 'date.skipass_included as dateSkiPassIncluded', + 'date.group_travel as dateGroupTravel', 'date.bus_pro_id as dateBusProId', 'date.hotel_bus_pro_id as hotelBusProId', 'date.available as available', 'date.product_detail_page as productDetailPage', ) diff --git a/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php b/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php index 418f83ae..24ab510f 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php @@ -64,6 +64,15 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface const SELECTION_GROUP_EVENTS = 89; const SELECTION_GROUP_TRANSPORTATION = 90; + /** + * Group 'Kunde' also carries trip types (Wochenreise, Midweekreise, ...), so + * group travel keys on the selection, not on the group's presence. Every + * date should carry either 'Gruppenkunde' or 'Endkunde'. + */ + const SELECTION_GROUP_CUSTOMER = 96; + const SELECTION_CUSTOMER_GROUP = 1418; + const SELECTION_CUSTOMER_END = 1419; + /** * 'Leistungen Personal' occurs in no export so far, so its id is unknown and * it is still matched by label. Register its id once the warning fires. @@ -286,6 +295,9 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface { $dateCount = 0; + // Selection groups are date-level, so any hotel row tells. + $this->checkCustomerSelection(reset($rows)); + foreach ($rows as $row) { $date = $this->createDateRecord($product, $row); @@ -410,6 +422,9 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface $skiPassIncluded = (int) (count($includedSkiPass) > 0); $date['skipass_included'] = $skiPassIncluded; + $customer = $this->parseSelectionGroup($row['selectionGroups'], static::SELECTION_GROUP_CUSTOMER); + $date['group_travel'] = (int) isset($customer[static::SELECTION_CUSTOMER_GROUP]); + $servicesTransportation = $this->parseService($row['transportServices']); $discount = $this->determineDiscount($servicesTransportation); $date['discount'] = $discount; @@ -771,6 +786,29 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface return $data; } + /** + * A date without 'Gruppenkunde' imports as end-customer travel, which is + * only right when BusPro says 'Endkunde'. + * + * @param array $row + */ + protected function checkCustomerSelection(array $row): void + { + $customer = $this->parseSelectionGroup($row['selectionGroups'], static::SELECTION_GROUP_CUSTOMER); + $isGroup = isset($customer[static::SELECTION_CUSTOMER_GROUP]); + $isEnd = isset($customer[static::SELECTION_CUSTOMER_END]); + if ($isGroup !== $isEnd) { + return; + } + + $this->logger->warning( + $isGroup + ? 'date has both Gruppenkunde and Endkunde selected, importing as group travel' + : 'date has neither Gruppenkunde nor Endkunde selected, importing as end-customer travel', + ['product' => $row['product']['code'], 'date' => $row['date']['code']] + ); + } + /** * @param array[] $selections * @param array $data diff --git a/public/typo3conf/ext/ep_products/Classes/Service/DateService.php b/public/typo3conf/ext/ep_products/Classes/Service/DateService.php index a13ce9ce..95e54eba 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/DateService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/DateService.php @@ -230,6 +230,7 @@ class DateService implements SingletonInterface 'summer' => $row['season'] === 's', 'busIncluded' => (bool) $row['dateBusIncluded'], 'skiPassIncluded' => (bool) $row['dateSkiPassIncluded'], + 'groupTravel' => (bool) $row['dateGroupTravel'], 'roomUid' => $row['roomUid'], 'roomName' => $row['roomName'], 'available' => $row['roomAvailable'] && $row['roomPrice'], @@ -320,6 +321,7 @@ class DateService implements SingletonInterface 'nights' => $row['dateNights'], 'busIncluded' => (bool) $row['dateBusIncluded'], 'skiPassIncluded' => (bool) $row['dateSkiPassIncluded'], + 'groupTravel' => (bool) $row['dateGroupTravel'], 'servicesIncluded' => unserialize($row['dateServicesIncluded'], ['allowed_classes' => false]), 'servicesGeneral' => unserialize($row['dateServicesGeneral'], ['allowed_classes' => false]), 'season' => $row['season'], diff --git a/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_date.php b/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_date.php index e0cf9c35..473e6026 100644 --- a/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_date.php +++ b/public/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_date.php @@ -24,8 +24,8 @@ return [ ], 'types' => [ '1' => ['showitem' => 'hidden, bus_pro_id, hotel_bus_pro_id, code, daytrip, date_start, date_end, nights, board, - board_code, board_bus_pro_id, bus_included, bus_available, skipass_included, services_included, - services_general, courses_included, guide, pickups, discount, min_price, pseudo_price, available, min_pax, + board_code, board_bus_pro_id, bus_included, bus_available, skipass_included, group_travel, + services_included, services_general, courses_included, guide, pickups, discount, min_price, pseudo_price, available, min_pax, new' ], ], @@ -322,6 +322,14 @@ return [ 'default' => 0 ] ], + 'group_travel' => [ + 'exclude' => false, + 'label' => 'Gruppenreise', + 'config' => [ + 'type' => 'check', + 'default' => 0 + ] + ], 'bus_price' => [ 'exclude' => false, 'label' => 'Bus Preis', diff --git a/public/typo3conf/ext/ep_products/ext_tables.sql b/public/typo3conf/ext/ep_products/ext_tables.sql index 675354db..2a54011d 100644 --- a/public/typo3conf/ext/ep_products/ext_tables.sql +++ b/public/typo3conf/ext/ep_products/ext_tables.sql @@ -117,6 +117,7 @@ CREATE TABLE tx_epproducts_domain_model_date bus_included tinyint(1) unsigned DEFAULT '0' NOT NULL, bus_available tinyint(1) unsigned DEFAULT '0' NOT NULL, skipass_included tinyint(1) unsigned DEFAULT '0' NOT NULL, + group_travel tinyint(1) unsigned DEFAULT '0' NOT NULL, bus_price decimal(10,2) DEFAULT '0.00' NOT NULL, services_included text NOT NULL, services_general text NOT NULL,