Merge branch 'release/2021.08-03'

This commit is contained in:
Björn Fromme
2021-08-18 19:02:58 +02:00
7 changed files with 331 additions and 342 deletions
+11 -8
View File
@@ -1,8 +1,8 @@
name: ep-reisen name: ep-reisen
type: typo3 type: typo3
docroot: public docroot: public
php_version: "7.3" php_version: "7.4"
webserver_type: apache-fpm webserver_type: nginx-fpm
router_http_port: "80" router_http_port: "80"
router_https_port: "443" router_https_port: "443"
xdebug_enabled: false xdebug_enabled: false
@@ -27,12 +27,12 @@ use_dns_when_possible: true
timezone: Europe/Berlin timezone: Europe/Berlin
composer_version: "2" composer_version: "2"
web_environment: web_environment:
- TYPO3_CONTEXT=Development - TYPO3_CONTEXT=Development
# This config.yaml was created with ddev version v1.17.1 # This config.yaml was created with ddev version v1.17.7
# webimage: drud/ddev-webserver:v1.17.1 # webimage: drud/ddev-webserver:v1.17.7
# dbimage: drud/ddev-dbserver-mariadb-10.3:v1.17.0 # dbimage: drud/ddev-dbserver-mariadb-10.3:v1.17.7
# dbaimage: phpmyadmin:5 # dbaimage: phpmyadmin:5
# However we do not recommend explicitly wiring these images into the # However we do not recommend explicitly wiring these images into the
# config.yaml as they may break future versions of ddev. # config.yaml as they may break future versions of ddev.
@@ -71,6 +71,11 @@ web_environment:
# "ddev xdebug" to enable xdebug and "ddev xdebug off" to disable it work better, # "ddev xdebug" to enable xdebug and "ddev xdebug off" to disable it work better,
# as leaving xdebug enabled all the time is a big performance hit. # as leaving xdebug enabled all the time is a big performance hit.
# xhprof_enabled: false # Set to true to enable xhprof and "ddev start" or "ddev restart"
# Note that for most people the commands
# "ddev xhprof" to enable xhprof and "ddev xhprof off" to disable it work better,
# as leaving xhprof enabled all the time is a big performance hit.
# webserver_type: nginx-fpm # or apache-fpm # webserver_type: nginx-fpm # or apache-fpm
# timezone: Europe/Berlin # timezone: Europe/Berlin
@@ -183,8 +188,6 @@ web_environment:
# This is to enable experimentation with alternate file mounting strategies. # This is to enable experimentation with alternate file mounting strategies.
# For advanced users only! # For advanced users only!
# provider: default # Currently "default", "pantheon", "ddev-live"
#
# Many ddev commands can be extended to run tasks before or after the # Many ddev commands can be extended to run tasks before or after the
# ddev command is executed, for example "post-start", "post-import-db", # ddev command is executed, for example "post-start", "post-import-db",
# "pre-composer", "post-composer" # "pre-composer", "post-composer"
Generated
+221 -222
View File
File diff suppressed because it is too large Load Diff
@@ -32,8 +32,9 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
class ContingentCommandController extends Command class ContingentCommand extends Command
{ {
/** /**
@@ -49,9 +50,11 @@ class ContingentCommandController extends Command
/** /**
* @param ContingentImportService $contingentImportService * @param ContingentImportService $contingentImportService
*/ */
public function __construct(ContingentImportService $contingentImportService) public function __construct()
{ {
$this->contingentImportService = $contingentImportService; /** @var ObjectManager $objectManager */
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->contingentImportService = $objectManager->get(ContingentImportService::class);
parent::__construct(); parent::__construct();
} }
@@ -212,8 +212,11 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac
$types = []; $types = [];
foreach ($xmlTypes->unterbringung as $xmlType) foreach ($xmlTypes->unterbringung as $xmlType)
{ {
$idBusPro = (string) $xmlType['idbuspro'];
$code = (string) $xmlType['code']; $code = (string) $xmlType['code'];
$types[(string) $xmlType['idbuspro']] = [ $types[] = [
'idBusPro' => $idBusPro,
'link' => isset($xmlType['idbuspro_kontingent_aus']) ? (string) $xmlType['idbuspro_kontingent_aus'] : null,
'pax' => (int) $xmlType['pax_max'], 'pax' => (int) $xmlType['pax_max'],
'code' => $code, 'code' => $code,
'label' => (string) $xmlType['zimmerbezeichnung'], 'label' => (string) $xmlType['zimmerbezeichnung'],
@@ -233,63 +236,62 @@ class ContingentImportService implements SingletonInterface, LoggerAwareInterfac
protected function parseRooms(\SimpleXMLElement $xmlDates, array $hotelData, array $roomTypes) protected function parseRooms(\SimpleXMLElement $xmlDates, array $hotelData, array $roomTypes)
{ {
$dateCount = 0; $dateCount = 0;
foreach ($xmlDates->kapazitaet as $xmlDate) foreach ($xmlDates->kapazitaet as $xmlDate) {
{
$date = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate['termin']); $date = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate['termin']);
$status = Contingent::STATUS_OK; foreach ($roomTypes as $roomType) {
foreach ($xmlDate->zimmerliste->children() as $xmlRoom)
{
$roomTypeBusProId = (string) $xmlRoom['idbuspro'];
if (!array_key_exists($roomTypeBusProId, $roomTypes)) {
continue;
}
$roomType = $roomTypes[$roomTypeBusProId];
$roomCode = $roomType['code']; $roomCode = $roomType['code'];
if (in_array($roomCode, $this->ignoredRoomTypes, true)) { if (in_array($roomCode, $this->ignoredRoomTypes, true)) {
continue; continue;
} }
$availablePax = 0; $roomTypeBusProId = $roomType['link'] ?? $roomType['idBusPro'];
$capacity = 0; $xpath = sprintf('zimmerliste/zimmer[@idbuspro="%d"]', $roomTypeBusProId);
if ($roomType['ctrl'] === true) { $xmlRoom = $xmlDate->xpath($xpath)[0];
if ((string) $xmlRoom['status'] === 'A') { $this->calculateContingent($xmlRoom, $roomType, $date, $hotelData);
$status = Contingent::STATUS_ONREQUEST;
}
if ((string) $xmlRoom['status'] === 'S') {
$status = Contingent::STATUS_BLOCKED;
}
} else {
$capacity = (int) $xmlRoom['kontingent'] * (int) $roomType['pax'];
$availableRooms = (int) $xmlRoom['frei'] > 0 ? (int) $xmlRoom['frei'] : 0;
$availablePax = $availableRooms * $roomType['pax'];
}
$minPrice = (int) $xmlRoom['abpreis'];
$minNights = (int) $xmlRoom['abpreis_naechte'];
$additionalNightMinPrice = (int) $xmlRoom['abpreis_verlaengerung'];
$additionalNightMinNights = (int) $xmlRoom['abpreis_verlaengerung_naechte'];
$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,
'pax' => $capacity,
'available' => $availablePax,
'status' => $status,
'date' => $date->format('Y-m-d'),
'min_price' => $minPrice,
'min_nights' => $minNights,
'additional_night_min_price' => $additionalNightMinPrice,
'additional_night_min_nights' => $additionalNightMinNights,
]
);
} }
$dateCount++; $dateCount++;
} }
return $dateCount; return $dateCount;
} }
protected function calculateContingent(\SimpleXMLElement $xmlRoom, array $roomType, \DateTime $date, array $hotelData): void
{
$availablePax = 0;
$capacity = 0;
$status = Contingent::STATUS_OK;
$isControlRoom = $roomType['ctrl'] === true;
if ($isControlRoom && (string) $xmlRoom['status'] === 'A') {
$status = Contingent::STATUS_ONREQUEST;
} elseif ($isControlRoom && (string) $xmlRoom['status'] === 'S') {
$status = Contingent::STATUS_BLOCKED;
} else {
$capacity = (int) $xmlRoom['kontingent'] * (int) $roomType['pax'];
$availableRooms = (int) $xmlRoom['frei'] > 0 ? (int) $xmlRoom['frei'] : 0;
$availablePax = $availableRooms * $roomType['pax'];
}
$minPrice = (int) $xmlRoom['abpreis'];
$minNights = (int) $xmlRoom['abpreis_naechte'];
$additionalNightMinPrice = (int) $xmlRoom['abpreis_verlaengerung'];
$additionalNightMinNights = (int) $xmlRoom['abpreis_verlaengerung_naechte'];
$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' => $roomType['code'],
'room_label' => $roomLabel,
'pax' => $capacity,
'available' => $availablePax,
'status' => $status,
'date' => $date->format('Y-m-d'),
'min_price' => $minPrice,
'min_nights' => $minNights,
'additional_night_min_price' => $additionalNightMinPrice,
'additional_night_min_nights' => $additionalNightMinNights,
]
);
}
} }
@@ -8,4 +8,8 @@ return [
'ep:groups-swiss' => [ 'ep:groups-swiss' => [
'class' => \EP\EpProducts\Command\GroupsSwissCommand::class, 'class' => \EP\EpProducts\Command\GroupsSwissCommand::class,
], ],
'ep:contingent-import' => [
'class' => \EP\EpProducts\Command\ContingentCommand::class,
'scheduleable' => false,
],
]; ];
@@ -1,40 +1,30 @@
<html data-namespace-typo3-fluid="true" lang="en" <html data-namespace-typo3-fluid="true" lang="en"
xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers" xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"> xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:section name="Teaser"> <f:section name="Teaser">
<f:if condition="{data.header_link}"> <f:link.typolink parameter="{data.header_link}"
<v:condition.string.isNumeric value="{data.header_link}"> class="teaserbox teaserbox--default">
<f:then> <div class="teaserbox__image">
<f:link.typolink parameter="{data.header_link}" title="{data.header}" class="teaserbox teaserbox--default"> <f:if condition="{context.country}">
<f:render section="Content" arguments="{_all}"/> <f:image class="teaserbox__flag"
</f:link.typolink> src="{ep:flagiconSource(country: context.country)}"
</f:then> alt="{context.country.name}"/>
<f:else> </f:if>
<a href="{data.header_link}" target="_blank" title="{data.header}" class="teaserbox teaserbox--default"> <f:render partial="TeaserImage" arguments="{image: teaserImage}"/>
<f:render section="Content" arguments="{_all}"/> </div>
</a> <div class="teaserbox__main" data-rte-content>
</f:else> <span class="headline headline--3 headline--teaser">
</v:condition.string.isNumeric> {data.header -> f:format.nl2br()}{f:if(condition: data.subheader, then: '<br>{data.subheader}')}
</f:if> </span>
</f:section> <hr>
{data.bodytext -> f:format.html()}
<f:section name="Content"> </div>
<div class="teaserbox__image"> <button class="button w-full">
<f:if condition="{context.country}"> {data.button -> v:or(alternative: 'Details')}
<f:image class="teaserbox__flag" </button>
src="{ep:flagiconSource(country: context.country)}" alt="{context.country.name}"/> </f:link.typolink>
</f:if>
<f:render partial="TeaserImage" arguments="{image: teaserImage}"/>
</div>
<div class="teaserbox__main" data-rte-content>
<span class="headline headline--3 headline--teaser">{data.header -> f:format.nl2br()}{f:if(condition: data.subheader, then: '<br>{data.subheader}')}</span>
<hr>
{data.bodytext -> f:format.html()}
</div>
<button class="button button--full">{data.button -> v:or(alternative: 'Details')}</button>
</f:section> </f:section>
</html> </html>
@@ -3,35 +3,23 @@
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers" xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"> xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:layout name="Default"/>
<f:section name="Teaser"> <f:section name="Teaser">
<f:if condition="{data.header_link}"> <f:link.typolink parameter="{data.header_link}"
<v:condition.string.isNumeric value="{data.header_link}"> class="teaserbox teaserbox--default">
<f:then> <div class="teasebox__image">
<f:link.typolink parameter="{data.header_link}" title="{data.header}" class="teaserbox teaserbox--default"> <f:render partial="TeaserImage" arguments="{image: teaserImage}"/>
<f:render section="Content" arguments="{_all}"/> </div>
</f:link.typolink> <div class="teaserbox__main" data-rte-content>
</f:then> <span class="headline headline--3 headline--teaser">
<f:else> {data.header -> f:format.nl2br()}{f:if(condition: data.subheader, then: '<br>{data.subheader}')}
<a href="{data.header_link}" target="_blank" title="{data.header}" class="teaserbox teaserbox--default"> </span>
<f:render section="Content" arguments="{_all}"/> <hr>
</a> {data.bodytext -> f:format.html()}
</f:else> </div>
</v:condition.string.isNumeric> <button class="button button--full">
</f:if> {data.button -> v:or(alternative: 'Details')}
</f:section> </button>
</f:link.typolink>
<f:section name="Content">
<div class="teasebox__image">
<f:render partial="TeaserImage" arguments="{image: teaserImage}"/>
</div>
<div class="teaserbox__main" data-rte-content>
<span class="headline headline--3 headline--teaser">{data.header -> f:format.nl2br()}{f:if(condition: data.subheader, then: '<br>{data.subheader}')}</span>
<hr>
{data.bodytext -> f:format.html()}
</div>
<button class="button button--full">{data.button -> v:or(alternative: 'Details')}</button>
</f:section> </f:section>
</html> </html>