From 0477589a7a8c65b666f4162ab5f67e07838f5585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Tue, 13 Oct 2026 14:24:49 +0200 Subject: [PATCH] feat: fall back to the travel code for dates without a customer selection --- .../Classes/Service/DateImportService.php | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php b/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php index 24ab510f..520a73c5 100644 --- a/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php +++ b/public/typo3conf/ext/ep_products/Classes/Service/DateImportService.php @@ -73,6 +73,13 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface const SELECTION_CUSTOMER_GROUP = 1418; const SELECTION_CUSTOMER_END = 1419; + /** + * Fallback for dates the office has not tagged with either selection: these + * trip type markers in front of the travel code's trailing date mean + * end-customer travel. + */ + const END_CUSTOMER_CODE_PATTERN = '/(?:MP|WE|KT|PM|MW)\d{6}$/'; + /** * '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. @@ -422,8 +429,7 @@ 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]); + $date['group_travel'] = (int) $this->isGroupTravel($row); $servicesTransportation = $this->parseService($row['transportServices']); $discount = $this->determineDiscount($servicesTransportation); @@ -787,8 +793,27 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface } /** - * A date without 'Gruppenkunde' imports as end-customer travel, which is - * only right when BusPro says 'Endkunde'. + * 'Gruppenkunde' and 'Endkunde' decide. A date carrying neither is judged by + * its travel code. + * + * @param array $row + * @return bool + */ + protected function isGroupTravel(array $row): bool + { + $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 $isGroup; + } + + return !preg_match(static::END_CUSTOMER_CODE_PATTERN, (string) $row['date']['code']); + } + + /** + * Reports dates whose customer selection is missing or contradictory, along + * with what they import as. * * @param array $row */ @@ -804,7 +829,8 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface $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', + : 'date has neither Gruppenkunde nor Endkunde selected, falling back to travel code, importing as ' + . ($this->isGroupTravel($row) ? 'group travel' : 'end-customer travel'), ['product' => $row['product']['code'], 'date' => $row['date']['code']] ); }