Import prices for additional nights, calculate prices correctly for selected period

This commit is contained in:
Björn Fromme
2018-10-03 13:21:09 +02:00
parent a5ff3e67fc
commit 8a68bba3e5
6 changed files with 182 additions and 25 deletions
@@ -47,6 +47,16 @@ class Contingent extends AbstractEntity implements EventInterface
*/ */
protected $hotel; protected $hotel;
/**
* @var string
*/
protected $roomCode;
/**
* @var string
*/
protected $roomLabel;
/** /**
* @var int * @var int
*/ */
@@ -62,6 +72,26 @@ class Contingent extends AbstractEntity implements EventInterface
*/ */
protected $status; protected $status;
/**
* @var int
*/
protected $minPrice;
/**
* @var int
*/
protected $minNights;
/**
* @var int
*/
protected $additionalNightMinPrice;
/**
* @var int
*/
protected $additionalNightMinNights;
/** /**
* @param array $data * @param array $data
* @return Contingent * @return Contingent
@@ -114,6 +144,38 @@ class Contingent extends AbstractEntity implements EventInterface
$this->hotel = $hotel; $this->hotel = $hotel;
} }
/**
* @return string
*/
public function getRoomCode()
{
return $this->roomCode;
}
/**
* @param string $roomCode
*/
public function setRoomCode($roomCode)
{
$this->roomCode = $roomCode;
}
/**
* @return string
*/
public function getRoomLabel()
{
return $this->roomLabel;
}
/**
* @param string $roomLabel
*/
public function setRoomLabel($roomLabel)
{
$this->roomLabel = $roomLabel;
}
/** /**
* @return int * @return int
*/ */
@@ -174,6 +236,70 @@ class Contingent extends AbstractEntity implements EventInterface
$this->status = $status; $this->status = $status;
} }
/**
* @return int
*/
public function getMinPrice()
{
return $this->minPrice;
}
/**
* @param int $minPrice
*/
public function setMinPrice($minPrice)
{
$this->minPrice = $minPrice;
}
/**
* @return int
*/
public function getMinNights()
{
return $this->minNights;
}
/**
* @param int $minNights
*/
public function setMinNights($minNights)
{
$this->minNights = $minNights;
}
/**
* @return int
*/
public function getAdditionalNightMinPrice()
{
return $this->additionalNightMinPrice;
}
/**
* @param int $additionalNightMinPrice
*/
public function setAdditionalNightMinPrice($additionalNightMinPrice)
{
$this->additionalNightMinPrice = $additionalNightMinPrice;
}
/**
* @return int
*/
public function getAdditionalNightMinNights()
{
return $this->additionalNightMinNights;
}
/**
* @param int $additionalNightMinNights
*/
public function setAdditionalNightMinNights($additionalNightMinNights)
{
$this->additionalNightMinNights = $additionalNightMinNights;
}
/** /**
* @return \DateTime * @return \DateTime
*/ */
@@ -137,8 +137,10 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$qb $qb
->select('c.room_code as code', 'c.room_label as label', 'c.available as available', 'c.min_price as price', ->select('c.date as date', 'c.room_code as code', 'c.room_label as label', 'c.available as available',
'c.hotel_bus_pro_id as hotelBusProId', 'd.bus_pro_id as busProId', 'c.min_price as price', 'c.hotel_bus_pro_id as hotelBusProId', 'c.min_nights as minNights',
'c.additional_night_min_price as additionalNightPrice',
'c.additional_night_min_nights as additionalNightMinNights', 'd.bus_pro_id as busProId',
'd.services_included as servicesIncluded', 'd.services_general as servicesOptional', 'd.services_included as servicesIncluded', 'd.services_general as servicesOptional',
'd.skipass_included as skipassIncluded') 'd.skipass_included as skipassIncluded')
->from('tx_epproducts_domain_model_contingent', 'c') ->from('tx_epproducts_domain_model_contingent', 'c')
@@ -83,6 +83,7 @@ class ContingentImportService implements SingletonInterface
/** /**
* @param string $path * @param string $path
* @return int * @return int
* @throws \Doctrine\DBAL\DBALException
*/ */
public function import($path) public function import($path)
{ {
@@ -248,6 +249,9 @@ class ContingentImportService implements SingletonInterface
$status = Contingent::STATUS_ONREQUEST; $status = Contingent::STATUS_ONREQUEST;
} }
$minPrice = (int) $xmlRoom['abpreis']; $minPrice = (int) $xmlRoom['abpreis'];
$minNights = (int) $xmlRoom['abpreis_naechte'];
$additionalNightMinPrice = (int) $xmlRoom['abpreis_verlaengerung'];
$additionalNightMinNights = (int) $xmlRoom['abpreis_verlaengerung_naechte'];
$roomLabel = $roomType['label']; $roomLabel = $roomType['label'];
$this->db->insert( $this->db->insert(
'tx_epproducts_domain_model_contingent_temp', 'tx_epproducts_domain_model_contingent_temp',
@@ -264,6 +268,9 @@ class ContingentImportService implements SingletonInterface
'status' => $status, 'status' => $status,
'date' => $date->format('Y-m-d'), 'date' => $date->format('Y-m-d'),
'min_price' => $minPrice, 'min_price' => $minPrice,
'min_nights' => $minNights,
'additional_night_min_price' => $additionalNightMinPrice,
'additional_night_min_nights' => $additionalNightMinNights,
] ]
); );
} }
@@ -185,6 +185,33 @@ return [
'eval' => 'trim', 'eval' => 'trim',
], ],
], ],
'min_nights' => [
'exclude' => 0,
'label' => 'ab Preis Nächte',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
],
],
'additional_night_min_price' => [
'exclude' => 0,
'label' => 'ab Preis Verlängerungsnacht',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
],
],
'additional_night_min_nights' => [
'exclude' => 0,
'label' => 'Verlängerungsnacht min. Nächte',
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
],
],
'groupsch_id' => [ 'groupsch_id' => [
'exclude' => 0, 'exclude' => 0,
'label' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_contingent.groupsch_id', 'label' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_contingent.groupsch_id',
@@ -959,6 +959,9 @@ CREATE TABLE tx_epproducts_domain_model_contingent (
room_label varchar(64) DEFAULT '' NOT NULL, room_label varchar(64) DEFAULT '' NOT NULL,
status tinyint(4) unsigned DEFAULT '0' NOT NULL, status tinyint(4) unsigned DEFAULT '0' NOT NULL,
min_price int(11) DEFAULT '0' NOT NULL, min_price int(11) DEFAULT '0' NOT NULL,
min_nights int(11) DEFAULT '0' NOT NULL,
additional_night_min_price int(11) DEFAULT '0' NOT NULL,
additional_night_min_nights int(11) DEFAULT '0' NOT NULL,
groupsch_id varchar(8) DEFAULT '' NOT NULL, groupsch_id varchar(8) DEFAULT '' NOT NULL,
tstamp int(11) unsigned DEFAULT '0' NOT NULL, tstamp int(11) unsigned DEFAULT '0' NOT NULL,
@@ -24,7 +24,7 @@
<tbody> <tbody>
<tr v-for="(row, index) of availableRooms"> <tr v-for="(row, index) of availableRooms">
<td>{{ row.label }}</td> <td>{{ row.label }}</td>
<td style="white-space: nowrap">ab {{ row.price * selectedNumberOfDays }} &euro;</td> <td style="white-space: nowrap">ab {{ calculatePrice(row.code, selectedNumberOfDays) }} &euro;</td>
<td> <td>
<i v-if="row.skipassIncluded" data-placement="top" title="Skipass inklusive" class="fa fa-tag tooltiptoggle"></i> <i v-if="row.skipassIncluded" data-placement="top" title="Skipass inklusive" class="fa fa-tag tooltiptoggle"></i>
<a href="#" data-toggle="modal" <a href="#" data-toggle="modal"
@@ -64,7 +64,7 @@
</tbody> </tbody>
</table> </table>
<div v-show="loading" class="loader"><p>Loading...</p></div> <div v-show="loading" class="loader"><p>Loading...</p></div>
<div v-show="message">{{message}}</div> <div v-show="message">{{ message }}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -105,18 +105,6 @@
type: Number, type: Number,
required: true required: true
}, },
minDate: {
type: Date,
default () {
return new Date()
}
},
maxDate: {
type: Date,
default () {
return new Date(dayjs().add(1, 'year'))
}
},
contingentEndpointUri: { contingentEndpointUri: {
type: String, type: String,
required: true required: true
@@ -155,13 +143,9 @@
if (this.selectedFrom === null || this.selectedTo === null) { if (this.selectedFrom === null || this.selectedTo === null) {
return 'Bitte einen Zeitraum auswählen.'; return 'Bitte einen Zeitraum auswählen.';
} }
if (this.selectedTo.diff(this.selectedFrom, 'days') < 2) {
return 'Bitte mindestens zwei Nächte auswählen';
}
if (this.availableRooms.length === 0) { if (this.availableRooms.length === 0) {
return 'Im gewählten Zeitraum sind leider keine Zimmer verfügbar.'; return 'Im gewählten Zeitraum sind leider keine Zimmer verfügbar.';
} }
return ''; return '';
} }
}, },
@@ -179,10 +163,12 @@
this.availableDates = json; this.availableDates = json;
const enabledDates = []; const enabledDates = [];
if (json.length) { if (json.length) {
for (let entry of this.availableDates) { for (const entry of this.availableDates) {
enabledDates.push(entry.date); enabledDates.push(entry.date);
} }
this.picker.set('enable', enabledDates); this.picker.set('enable', enabledDates);
this.picker.set('minDate', enabledDates[0]);
this.picker.set('maxDate', enabledDates[enabledDates.length - 1]);
this.picker.jumpToDate(enabledDates[0]); this.picker.jumpToDate(enabledDates[0]);
} }
}, 'json'); }, 'json');
@@ -199,6 +185,14 @@
this.availableRooms = json; this.availableRooms = json;
EventBus.$emit('tableLoaded'); EventBus.$emit('tableLoaded');
}, 'json'); }, 'json');
},
calculatePrice (roomCode, nights) {
for (const room of this.availableRooms) {
if (room.code === roomCode) {
return room.price + (nights - room.minNights) * room.additionalNightPrice;
}
}
return null;
} }
}, },
mounted () { mounted () {
@@ -207,14 +201,12 @@
dateFormat: 'Y-m-d', dateFormat: 'Y-m-d',
locale: German, locale: German,
inline: true, inline: true,
minDate: new Date(this.minDate),
maxDate: new Date(this.maxDate),
onChange: (selectedDates) => { onChange: (selectedDates) => {
this.availableRooms = []; this.availableRooms = [];
if (selectedDates.length === 2) { if (selectedDates.length === 2) {
this.selectedFrom = dayjs(selectedDates[0]); this.selectedFrom = dayjs(selectedDates[0]);
this.selectedTo = dayjs(selectedDates[1]); this.selectedTo = dayjs(selectedDates[1]);
if (this.selectedTo.diff(this.selectedFrom, 'days') > 1) { if (this.selectedNumberOfDays > 1) {
this.fetchAvailableRooms(); this.fetchAvailableRooms();
} }
} }
@@ -224,7 +216,7 @@
for (const entry of this.availableDates) { for (const entry of this.availableDates) {
if (entry.date === day) { if (entry.date === day) {
dayElem.classList.add('available'); dayElem.classList.add('available');
return false; return;
} }
} }