Correctly validate selected date range

This commit is contained in:
Björn Fromme
2018-10-05 08:54:51 +02:00
parent 2cb8e95933
commit 46c3e82ffc
4 changed files with 52 additions and 15 deletions
@@ -79,9 +79,9 @@ class AjaxContingentController extends ActionController
*/ */
public function listAction(Hotel $hotel, Product $product) public function listAction(Hotel $hotel, Product $product)
{ {
$enabled = $this->contingentRepository->getAvailableContingents($hotel, $product); $enabled = $this->contingentDataService->getAvailableContingents($hotel, $product);
return json_encode($enabled); return \json_encode($enabled);
} }
/** /**
@@ -106,13 +106,14 @@ class ContingentRepository extends AbstractRepository implements ProviderInterfa
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$qb $qb
->select('c.date as date') ->select('c.date as date', 'c.min_nights as minNights')
->addSelectLiteral('SUM(c.available) as total') ->addSelectLiteral('SUM(c.available) as total')
->from('tx_epproducts_domain_model_contingent', 'c') ->from('tx_epproducts_domain_model_contingent', 'c')
->innerJoin('c', 'tx_epproducts_domain_model_date', 'd', 'c.date = d.date_start 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') ->where('c.hotel = :hotelUid')
->andWhere('d.product = :productUid') ->andWhere('d.product = :productUid')
->andWhere('c.available > 0') ->andWhere('c.available > 0')
->andWhere('c.min_price > 0')
->setParameters([ ->setParameters([
'hotelUid' => $hotel->getUid(), 'hotelUid' => $hotel->getUid(),
'productUid' => $product->getUid(), 'productUid' => $product->getUid(),
@@ -47,6 +47,30 @@ class ContingentDataService
$this->contingentRepository = $contingentRepository; $this->contingentRepository = $contingentRepository;
} }
/**
* @param Hotel $hotel
* @param Product $product
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getAvailableContingents(Hotel $hotel, Product $product)
{
$data = $this->contingentRepository->getAvailableContingents($hotel, $product);
$contingents = [];
foreach ($data as $row)
{
$contingents[$row['date']] = [
'date' => $row['date'],
'minNights' => $row['minNights'],
'total' => $row['total'],
];
}
return $contingents;
}
/** /**
* @param \DateTime $dateFrom * @param \DateTime $dateFrom
* @param \DateTime $dateTo * @param \DateTime $dateTo
@@ -142,6 +142,16 @@
} }
return this.selectedTo.diff(this.selectedFrom, 'days'); return this.selectedTo.diff(this.selectedFrom, 'days');
}, },
minNightsForSelectedDate () {
if (this.selectedFrom === null) {
return 0;
}
const key = this.selectedFrom.format('YYYY-MM-DD');
if (!key in this.availableDates) {
return 0;
}
return this.availableDates[key].minNights;
},
message () { message () {
if (this.loading) { if (this.loading) {
return ''; return '';
@@ -149,6 +159,10 @@
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.';
} }
const minNights = this.minNightsForSelectedDate;
if (this.selectedNumberOfDays < minNights) {
return 'Bitte mindestens ' + minNights + ' 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.';
} }
@@ -166,11 +180,13 @@
this.loading = true; this.loading = true;
$.post(this.contingentEndpointUri, query, (json) => { $.post(this.contingentEndpointUri, query, (json) => {
this.loading = false; this.loading = false;
if (json) {
this.availableDates = json; this.availableDates = json;
const enabledDates = []; const enabledDates = [];
if (json.length) { for (const date in this.availableDates) {
for (const entry of this.availableDates) { if (this.availableDates.hasOwnProperty(date)) {
enabledDates.push(entry.date); enabledDates.push(this.availableDates[date].date);
}
} }
this.picker.set('enable', enabledDates); this.picker.set('enable', enabledDates);
this.picker.set('minDate', enabledDates[0]); this.picker.set('minDate', enabledDates[0]);
@@ -212,21 +228,17 @@
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.selectedNumberOfDays > 1) { if (this.selectedNumberOfDays >= this.minNightsForSelectedDate) {
this.fetchAvailableRooms(); this.fetchAvailableRooms();
} }
} }
}, },
onDayCreate: (dObj, dStr, fp, dayElem) => { onDayCreate: (dObj, dStr, fp, dayElem) => {
const day = dayjs(dayElem.dateObj).format('YYYY-MM-DD'); const day = dayjs(dayElem.dateObj).format('YYYY-MM-DD');
for (const entry of this.availableDates) { if (day in this.availableDates) {
if (entry.date === day) {
dayElem.classList.add('available'); dayElem.classList.add('available');
return;
} }
} }
}
}); });
Vue.nextTick(() => { Vue.nextTick(() => {
this.fetchEnabledDates(); this.fetchEnabledDates();