Merge branch 'tablemerge'

This commit is contained in:
Björn Fromme
2018-10-02 12:07:46 +02:00
12 changed files with 77 additions and 136 deletions
@@ -48,6 +48,11 @@ class Date extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
*/
protected $code = '';
/**
* @var bool
*/
protected $daytrip = false;
/**
* @var \DateTime
*/
@@ -181,6 +186,22 @@ class Date extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
$this->code = $code;
}
/**
* @return bool
*/
public function isDaytrip()
{
return $this->daytrip;
}
/**
* @param bool $daytrip
*/
public function setDaytrip($daytrip)
{
$this->daytrip = $daytrip;
}
/**
* @return \DateTime $dateStart
*/
@@ -109,7 +109,7 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa
->select('c.date as date')
->addSelectLiteral('SUM(c.available) as 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')
->innerJoin('c', 'tx_epproducts_domain_model_date', 'd', 'c.date = d.date_start AND c.hotel_code = d.hotel_code')
->where('c.hotel = :hotelUid')
->andWhere('d.product = :productUid')
->andWhere('c.available > 0')
@@ -141,7 +141,7 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa
'c.hotel_bus_pro_id as hotelBusProId', 'd.bus_pro_id as busProId',
'd.services_included as servicesIncluded', 'd.skipass_included as skipassIncluded')
->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')
->innerJoin('c', 'tx_epproducts_domain_model_date', 'd', 'c.date = d.date_start AND c.hotel_code = d.hotel_code')
->where('c.hotel = :hotelUid')
->andWhere('d.product = :productUid')
->andWhere('c.date >= :dateFrom')
@@ -90,7 +90,7 @@ class ProductRepository extends AbstractRepository
->select(
'date.concept as conceptUid', 'date.concept_name as conceptName', 'date.concept_code as conceptCode',
'date.product as productUid', 'date.product_name as productName', 'date.product_detail_page as productDetailPage',
'date.product_feature as productFeature',
'date.product_feature as productFeature', 'date.daytrip as daytrip',
'date.country as countryUid','date.country_name as countryName', 'date.country_code as countryCode',
'date.region as regionUid', 'date.region_name as regionName', 'date.region_feature as regionFeature',
'date.date_start as dateStart', 'date.date_end as dateEnd',
@@ -101,7 +101,7 @@ class ProductRepository extends AbstractRepository
'date.available as available', 'date.pseudo_price as pseudoPrice'
)
->from('tx_epproducts_domain_model_date', 'date')
->innerJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid')
->leftJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid')
->leftJoin('date', 'tx_epproducts_product_region_mm', 'mm', 'mm.uid_local = date.product')
->where('date.product_searchable = 1')
->andWhere('date.date_start >= NOW()')
@@ -149,7 +149,7 @@ class ProductRepository extends AbstractRepository
'date_start as dateStart', 'date_end as dateEnd', 'uid as dateUid', 'min_price as minPrice',
'pseudo_price as pseudoPrice', 'nights as nights', 'available as available',
'skipass_included as skipassIncluded', 'bus_included as busIncluded',
'earlybird', 'low_contingent as lowContingent',
'earlybird', 'daytrip', 'low_contingent as lowContingent',
'concept_code as conceptCode', 'concept_name as conceptName',
'board'
)
@@ -180,7 +180,6 @@ class DateImportService 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');
}
@@ -190,7 +189,6 @@ class DateImportService implements SingletonInterface
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');
}
@@ -200,7 +198,6 @@ class DateImportService implements SingletonInterface
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');
}
@@ -210,7 +207,6 @@ class DateImportService implements SingletonInterface
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');
}
@@ -248,26 +244,18 @@ class DateImportService implements SingletonInterface
}
foreach ($products as $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);
}
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);
}
}
@@ -307,48 +295,6 @@ class DateImportService implements SingletonInterface
return $dateCount;
}
/**
* @param \SimpleXMLElement $xmlDate
* @param array $product
*/
protected function parseDaytripDates(\SimpleXMLElement $xmlDate, array $product)
{
static $datesAdded = [];
$skiPass = $this->parseSelectionGroup($xmlDate, 'Leistungen Skipass');
$skiPassIncluded = (int) (count($skiPass) > 0);
$servicesBoard = $this->parseSelectionGroup($xmlDate, 'Leistungen Verpflegung');
$servicesIncluded = $this->parseSelectionGroup($xmlDate, 'Leistungen Sonstige');
$servicesCombined = serialize($this->combineServices($skiPass, $servicesBoard, $servicesIncluded));
foreach ($xmlDate->hotel as $xmlHotel)
{
$hotelCode = (string) $xmlHotel->attributes()['code'];
$dateStart = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['termin'])->format('Y-m-d');
$key = $hotelCode . $dateStart;
if (\in_array($key, $datesAdded, true)) {
continue;
}
$datesAdded[] = $key;
$hotel = $this->hotelMappings[$hotelCode];
$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,
'services_included' => $servicesCombined,
'skipass_included' => $skiPassIncluded,
]
);
}
}
/**
* @param array $product
* @param \SimpleXMLElement $xmlDate
@@ -395,6 +341,7 @@ class DateImportService implements SingletonInterface
'nights' => $nights,
'bus_pro_id' => $busProId,
'code' => $code,
'daytrip' => $product['daytrip'],
];
$skiPass = $this->parseSelectionGroup($xmlDate, 'Leistungen Skipass');
@@ -532,7 +479,9 @@ class DateImportService implements SingletonInterface
}
$this->parseRooms($xmlHotel, $hotel['uid'], $date, $services);
$date['hotel'] = $hotel['uid'];
$date['hotel_code'] = $hotel['code'];
$date['hotel_bus_pro_id'] = $busProId;
$date['hotel_fact'] = $hotel['fact'];
$date['hotel_name'] = $hotel['name'];
@@ -783,6 +732,7 @@ class DateImportService implements SingletonInterface
{
$this->hotelMappings[$row['code']] = [
'uid' => $row['uid'],
'code' => $row['code'],
'type' => $row['type'],
'name' => $row['name'],
'earlybird' => $row['earlybird'],
@@ -195,6 +195,7 @@ class ProductDataService implements SingletonInterface
'pseudoPrice' => $teaserData['pseudoPrice'],
'board' => $teaserData['board'],
'earlybird' => $teaserData['earlybird'],
'daytrip' => $teaserData['daytrip'],
'lowContingent' => $teaserData['lowContingent'],
'servicesIncluded' => unserialize($teaserData['servicesIncluded']),
'product' => [
@@ -118,6 +118,7 @@ class SearchResultService implements SingletonInterface
'minPrice' => null,
'detailPageUri' => null,
'earlybird' => $row['earlybird'],
'daytrip' => $row['daytrip'],
'lowContingent' => $row['lowContingent'],
'servicesIncluded' => unserialize($row['servicesIncluded']),
'hotel' => [
@@ -29,7 +29,7 @@ return [
available',
],
'types' => [
'1' => ['showitem' => 'hidden, bus_pro_id, hotel_bus_pro_id, code, date_start, date_end, nights, board,
'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, pickups, discount, min_price, pseudo_price, available'],
],
@@ -150,6 +150,14 @@ return [
'eval' => 'trim'
],
],
'daytrip' => [
'exclude' => 0,
'label' => 'tageweise buchbar',
'config' => [
'type' => 'check',
'default' => 0
]
],
'date_start' => [
'exclude' => 0,
'label' => 'Datum von',
+3 -47
View File
@@ -113,6 +113,7 @@ CREATE TABLE tx_epproducts_domain_model_date (
pseudo_price int(11) DEFAULT '0' NOT NULL,
available int(11) DEFAULT '0' NOT NULL,
product int(11) unsigned DEFAULT '0',
daytrip tinyint(1) unsigned DEFAULT '0' NOT NULL,
product_name varchar(255) DEFAULT '' NOT NULL,
product_subline varchar(255) DEFAULT '' NOT NULL,
product_fact varchar(255) DEFAULT '' NOT NULL,
@@ -138,6 +139,7 @@ CREATE TABLE tx_epproducts_domain_model_date (
city_name varchar(255) DEFAULT '' NOT NULL,
city_keywords text NOT NULL,
hotel int(11) unsigned DEFAULT '0',
hotel_code varchar(32) DEFAULT '' NOT NULL,
hotel_category int(11) DEFAULT '0' NOT NULL,
hotel_name varchar(255) DEFAULT '' NOT NULL,
hotel_header_title varchar(255) DEFAULT '' NOT NULL,
@@ -178,6 +180,7 @@ CREATE TABLE tx_epproducts_domain_model_date (
KEY language (l10n_parent,sys_language_uid),
KEY aggregates (date_start,date_end,min_price),
KEY relations (product,date_start),
KEY contingents (hotel_code,date_start),
KEY groups (product,hotel)
);
@@ -986,53 +989,6 @@ 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,
services_included TEXT NOT NULL,
skipass_included tinyint(4) unsigned DEFAULT '0' 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'
#
@@ -40,6 +40,7 @@ class NightsOptionsViewHelper extends AbstractViewHelper
parent::initializeArguments();
$this->registerArgument('options', 'array', 'The options');
$this->registerArgument('daytrip', 'bool', 'Is daytrip or not', false, false);
}
/**
@@ -54,6 +55,9 @@ class NightsOptionsViewHelper extends AbstractViewHelper
RenderingContextInterface $renderingContext
)
{
if ($arguments['daytrip']) {
return 'Tageweise buchbar';
}
$options = $arguments['options'];
if ($options === null) {
return '';
@@ -1,19 +1,19 @@
<template>
<div class="teaserbox teaserbox--landscape teaserbox--searchresult searchresult-item">
<div class="teaserbox__image">
<img class="teaserbox__flag" v-bind:src="item.country.flag" v-bind:alt="item.country.name"/>
<a v-bind:href="item.detailPageUri" rel="nofollow">
<img class="teaserbox__flag" :src="item.country.flag" :alt="item.country.name"/>
<a :href="item.detailPageUri" rel="nofollow">
<picture class="searchresult-item__image">
<source media="(max-width: 768px)" v-bind:srcset="item.hotel.images.resized.s[0].url + ' 220w'"/>
<source media="(max-width: 1200px)" v-bind:srcset="item.hotel.images.resized.l[0].url + ' 280w'"/>
<source media="(min-width: 1201px)" v-bind:srcset="item.hotel.images.resized.m[0].url + ' 260w'"/>
<img class="scale" v-bind:src="item.hotel.images.resized.s[0].url"
v-bind:title="item.hotel.images.resized.s[0].title"
v-bind:alt="item.hotel.images.resized.s[0].alt">
<source media="(max-width: 768px)" :srcset="item.hotel.images.resized.s[0].url + ' 220w'"/>
<source media="(max-width: 1200px)" :srcset="item.hotel.images.resized.l[0].url + ' 280w'"/>
<source media="(min-width: 1201px)" :srcset="item.hotel.images.resized.m[0].url + ' 260w'"/>
<img class="scale" :src="item.hotel.images.resized.s[0].url"
:title="item.hotel.images.resized.s[0].title"
:alt="item.hotel.images.resized.s[0].alt">
</picture>
</a>
<div class="concept-badge" v-bind:id="section.concept.code"
v-bind:class=" 'concept-badge--' + section.concept.code">{{ section.concept.name }}</div>
<div class="concept-badge" :id="section.concept.code"
:class=" 'concept-badge--' + section.concept.code">{{ section.concept.name }}</div>
</div>
<div class="teaserbox__main">
<div class="teaserbox__header">
@@ -44,17 +44,17 @@
<div class="teaserbox__aside__top">
<span class="searchresult-item__label">{{ item.dates.length > 1 ? 'Zeitraum' : 'Termin' }}</span>
<span class="searchresult-item__daterange">{{ dateRange }}</span>
<a v-bind:href="item.detailPageUri" rel="nofollow" v-if="item.dates.length">
<a :href="item.detailPageUri" rel="nofollow" v-if="item.dates.length && !item.daytrip">
<span class="searchresult-item__daterange">
<i class="fa fa-arrow-circle-right"></i> {{ item.dates.length }} Termin{{ item.dates.length > 1 ? 'e' : '' }}
</span>
</a>
<hr>
<span class="searchresult-item__label">{{ nightsOptions }}</span>
<span class="searchresult-item__label">{{ item.daytrip ? 'Tageweise buchbar' : nightsOptions }}</span>
</div>
<div class="teaserbox__aside__bottom">
<span class="searchresult-item__price">ab {{ item.minPrice }} </span>
<a v-bind:href="item.detailPageUri" class="button button--full searchresult-item__button" rel="nofollow">
<a :href="item.detailPageUri" class="button button--full searchresult-item__button" rel="nofollow">
Details &amp; Buchen
</a>
</div>
@@ -59,8 +59,8 @@
</div>
<hr>
<span class="product-teaser__description">
{ep:dateRange(dateFrom: teaser.minDateStart, dateTo: teaser.maxDateEnd, includeLabel: 0, format: 'd.m.y')} <f:if condition="{teaser.dates -> f:count()} > 1">({teaser.dates -> f:count()} Termine)</f:if><br>
{ep:nightsOptions(options: teaser.nights)}<f:if condition="{teaser.skipassIncluded}">, <strong>inkl. Skipass</strong></f:if>
{ep:dateRange(dateFrom: teaser.minDateStart, dateTo: teaser.maxDateEnd, includeLabel: 0, format: 'd.m.y')} <f:if condition="{teaser.dates -> f:count()} > 1 && !{teaser.daytrip}">({teaser.dates -> f:count()} Termine)</f:if><br>
{ep:nightsOptions(options: teaser.nights, daytrip: teaser.daytrip)}<f:if condition="{teaser.skipassIncluded}">, <strong>inkl. Skipass</strong></f:if>
</span>
<hr>
<div class="product-teaser__footer">
@@ -79,7 +79,7 @@
<div class="teaserbox__aside__top">
<span class="searchresult-item__label">{f:if(condition: '{teaser.dates -> f:count()} > 1', then: 'Zeitraum', else: 'Termin')}</span>
<span class="searchresult-item__daterange">{ep:dateRange(dateFrom: teaser.minDateStart, dateTo: teaser.maxDateEnd, includeLabel: 0)}</span>
<f:if condition="{teaser.dates -> f:count()} > 1">
<f:if condition="{teaser.dates -> f:count()} > 1 && !{teaser.daytrip}">
<a href="{uriLink}" title="Alle Termine {teaser.product.name}">
<span class="searchresult-item__daterange">
<i class="fa fa-arrow-circle-right"></i> {teaser.dates -> f:count()} Termin{f:if(condition: '{teaser.dates -> f:count()} > 1', then: 'e')}
@@ -87,7 +87,7 @@
</a>
</f:if>
<hr>
<span class="searchresult-item__label">{ep:nightsOptions(options: teaser.nights)}</span>
<span class="searchresult-item__label">{ep:nightsOptions(options: teaser.nights, daytrip: teaser.daytrip)}</span>
</div>
<div class="teaserbox__aside__bottom">
<span class="searchresult-item__price">ab {teaser.minPrice} €{f:if(condition: teaser.pseudoPrice, then: ' <s class="searchresult-item__pseudo-price">{teaser.pseudoPrice} €</s>')}</span>