* Anreise-Wochentag nun per Saison statt Objekt definierbar
* Anreise-Wochentag wird für buchbare Tage im Kalender berücksichtigt
* Kalenderblätter bis zum Ende des spätesten bekannten Saisonende
* Datepicker erlaubt nur noch mögliche Reiseenddaten anzuklicken im Fewo-Buchungsformular
* Algogrithmus zur Bestimmung buchbarer Kalendereinträge komplett umgeschrieben, da bisher Reservierungen von nur einer Nacht nicht berücksichtigt werden konnten
* Upload mehrerer Bilder gleichzeitig nun möglich
* Beim Upload von Bildern werden diese gleich in JPEG umgewandelt, komprimiert und für den Slider zugeschnitten
* Behoben: CRM-Export funktioniert teilweise nicht
* Für CMS-Template "overview" können nun twig-Variablen per JSON in Spalte cms_settings gesetzt werden (=> Kulturreisensuche ausblendbar für Fewo-Übersichtsseite)
* 

Sonstiges:
* Falls CRM-Export nicht funktioniert, wird dies in der Buchungs-Mail für den Service deutlich gemacht

SQL:

ALTER TABLE fewo_lodging DROP only_weekday;
ALTER TABLE fewo_season ADD only_weekday INT DEFAULT NULL;


git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3359 f459cee4-fb09-11de-96c3-f9c5f16c3c76
This commit is contained in:
uli 2017-11-28 06:16:21 +00:00
parent 45977fd4de
commit 1a0388311e
26 changed files with 485 additions and 254 deletions

View file

@ -26,7 +26,7 @@ class LodgingCalendarService
return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
}
public function getCalendarWithPadding()
public function getCalendarWithPadding($months)
{
$calendar = null;
$currentMonth = date('n');
@ -35,7 +35,7 @@ class LodgingCalendarService
setlocale(LC_TIME, "german");
for($m = $currentMonth; $m < ($currentMonth + 12); $m++)
for($m = $currentMonth; $m < ($currentMonth + $months); $m++)
{
if($m < 13)
{
@ -117,9 +117,9 @@ class LodgingCalendarService
}
public function getCalendar()
public function getCalendar($lodging)
{
$months = $this->getMinCalendarEntriesByLodging($lodging);
$calendar = null;
$currentMonth = date('n');
$currentYear = date('Y');
@ -127,7 +127,7 @@ class LodgingCalendarService
setlocale(LC_TIME, "german");
for($m = $currentMonth; $m < ($currentMonth + 12); $m++)
for($m = $currentMonth; $m < ($currentMonth + $months); $m++)
{
if($m < 13)
{
@ -180,6 +180,22 @@ class LodgingCalendarService
return $calendar;
}
/**
* Retrieve needed number of months to generate a calendar which includes all available seasons
*
* @param FewoLodging $lodging
* @return int
*/
public function getMinCalendarEntriesByLodging($lodging)
{
$latestSeason = $this->em->getRepository('AppBundle:FewoLodging')->findLatestSeasonEndForLodging($lodging);
$curMonthDate = new \DateTime();
$curMonthDate->setDate($curMonthDate->format('Y'), $curMonthDate->format('n'), 1);
$seasonMonthDate = new \DateTime($latestSeason->getToDate()->format('Y-m-d'));
$seasonMonthDate->setDate($seasonMonthDate->format('Y'), $seasonMonthDate->format('n'), 1);
return 2 + intval($seasonMonthDate->diff($curMonthDate)->format('%m'));
}
/**
* @param FewoLodging $lodging
@ -426,7 +442,7 @@ class LodgingCalendarService
private function mergeCalendars($calendar, $extensionCalendar, $withFromTo = false)
{
for($i = 0; $i < 12; $i++)
for($i = 0; $i < count($calendar); $i++)
{
/** @var CalendarDayState[] $calendarData */
$calendarData = $calendar[$i]['data'];
@ -584,10 +600,8 @@ class LodgingCalendarService
*/
private function filterReservableDays(FewoLodging $lodging, $calendar)
{
/** @var CalendarDayState[] $potentiallyReservableDays */
$potentiallyReservableDays = [];
$priceId = 0;
/** @var FewoPrice $lastReservablePrice */
$lastReservablePrice = null;
for ($currMonthIndex = 0; $currMonthIndex < count($calendar); $currMonthIndex++)
{
@ -599,140 +613,81 @@ class LodgingCalendarService
{
$currDay = $data[$currDayIndex];
if ($currDay->getPrice() !== $lastReservablePrice && !$currDay->getIsInSeason())
// We passed the season end? => All days in the stack are not reservable, as their minimum stay
// requirement would mean their reservation end is outside a season
if (!$currDay->getIsInSeason())
{
$actuallyReservableDays = $this->processPotentiallyReservableDays($potentiallyReservableDays,
$lastReservablePrice->getSeason()->getMinimumStay());
$this->processRest($actuallyReservableDays, $lastReservablePrice, $calendar);
$potentiallyReservableDays = [];
}
if ($currDay->getIsInSeason() && (!$currDay->getIsReserved() || $currDay->getIsReservationBegin() ||
$currDay->getIsReservationEnd()))
{
$currentDayDate = date("d.m.Y", strtotime($currMonth['year']."-".
$currMonth['monthNumber']."-".$currDay->getDay()));
$potentiallyReservableDays[] = $currentDayDate;
while (!empty($potentiallyReservableDays))
{
$potentiallyReservableDay = array_pop($potentiallyReservableDays);
$potentiallyReservableDay->setIsBookable(false);
}
$currDay->setIsBookable(false);
continue;
}
$lastReservablePrice = $currDay->getIsInSeason() ? $currDay->getPrice() : null;
}
}
if ($lastReservablePrice !== null)
{
$actuallyReservableDays = $this->processPotentiallyReservableDays($potentiallyReservableDays,
$lastReservablePrice->getSeason()->getMinimumStay());
$this->processRest($actuallyReservableDays, $lastReservablePrice, $calendar);
}
return $calendar;
}
$currSeason = $currDay->getPrice()->getSeason();
private function processPotentiallyReservableDays($potentiallyReservableDays, $minimumStay)
{
$coherentDays = [];
$actuallyReservableDays = [];
//$coherentDays[] = $potentiallyReservableDays[0];
for($i = 1; $i < count($potentiallyReservableDays); $i++)
{
if($this->isNextDay($potentiallyReservableDays[$i - 1], $potentiallyReservableDays[$i]))
{
if(count($coherentDays) == 0)
// Process the stack of reservable days and set reservable=true, if their minimum stay requirement could
// be fulfilled. Set reservable=false if there is no chance for the stack entry to be reservable.
// Remove potentially reservable days from the stack for which a final decision has been made.
if (!$currDay->getIsReserved() || $currDay->getIsReservationBegin())
{
$coherentDays[] = $potentiallyReservableDays[$i - 1];
foreach ($potentiallyReservableDays as $k => $potentiallyReservableDay)
{
$nights = intval($potentiallyReservableDay->getDate()->diff($currDay->getDate())->format('%a'));
if ($nights >= $currSeason->getMinimumStay())
{
$potentiallyReservableDay->setIsBookable(true);
unset($potentiallyReservableDays[$k]);
}
elseif ($currDay->getIsReservationBegin())
{
// Reservation begin => We are absolutely sure that this day is not reservable
$potentiallyReservableDay->setIsBookable(false);
unset($potentiallyReservableDays[$k]);
}
}
}
$coherentDays[] = $potentiallyReservableDays[$i];
}
else
{
if(count($coherentDays) < $minimumStay)
// Add the current calendar day to stack, as we need to analyse the following days in order to be able
// to decide if the day is reservable or not.
if ((!$currDay->getIsReserved() || $currDay->getIsReservationEnd()) &&
($currSeason->getOnlyWeekday() == null || $currSeason->getOnlyWeekday() == $currDay->getDate()->format('w')))
{
$coherentDays = [];
$coherentDays[] = $potentiallyReservableDays[$i];
$potentiallyReservableDays[] = $currDay;
}
else
{
$coherentDaysCount = count($coherentDays);
$offset = $coherentDaysCount - ($minimumStay - 1);
$coherentDays = array_splice($coherentDays, 0, $offset);
for($j = 0; $j < count($coherentDays); $j++)
{
$actuallyReservableDays[] = $coherentDays[$j];
}
$coherentDays = [];
$currDay->setIsBookable(false);
}
}
}
if(count($coherentDays) > 0)
// Remaining entries in the stack are definitely not reservable. Otherwise they would have been processed before.
foreach ($potentiallyReservableDays as $potentiallyReservableDay)
{
$coherentDaysCount = count($coherentDays);
$offset = $coherentDaysCount - ($minimumStay - 1);
$coherentDays = array_splice($coherentDays, 0, $offset);
for($j = 0; $j < count($coherentDays); $j++)
{
$actuallyReservableDays[] = $coherentDays[$j];
}
$potentiallyReservableDay->setIsBookable(false);
}
return $actuallyReservableDays;
return $calendar;
}
private function processRest($actuallyReservableDays, FewoPrice $price, &$cleanCalendar)
{
for($currMonthIndex = 0; $currMonthIndex < count($cleanCalendar); $currMonthIndex++)
{
$currMonth = $cleanCalendar[$currMonthIndex];
/** @var CalendarDayState[] $data */
$data = $currMonth['data'];
for($currDayIndex = 0; $currDayIndex < count($data); $currDayIndex++)
{
$currDay = $data[$currDayIndex];
$currentDate = date("d.m.Y", strtotime($currMonth['year']."-".$currMonth['monthNumber']."-".$currDay->getDay()));
if (in_array($currentDate, $actuallyReservableDays))
{
//$data[$currDayIndex]->setIsInSeason(true);
//$data[$currDayIndex]->setIsReserved(false); // todo ?
$data[$currDayIndex]->setIsBookable(true);
//$data[$currDayIndex]->setIsReservationBegin(false);
//$data[$currDayIndex]->setIsReservationEnd(false); // todo ?
//$data[$currDayIndex]->setPrice($price);
$currMonth['marked'] = 1;
}
}
$currMonth['data'] = $data;
$cleanCalendar[$currMonthIndex] = $currMonth;
}
}
/**
* @param FewoLodging $lodging
* @param $calendar
* @return mixed
*
* createCalendarAndFillDayStates
*/
public function getCalendarWithReservations(FewoLodging $lodging)
public function createCalendarAndFillDayStates(FewoLodging $lodging)
{
$today = new \DateTime();
$pricesCalendar = $this->getCalendar();
$reservationsCalendar = $this->getCalendar();
$pricesCalendar = $this->getCalendar($lodging);
$reservationsCalendar = $this->getCalendar($lodging);
$reservations = $lodging->getReservations();
$prices = $lodging->getPrices();
$lodgingId = $lodging->getId();
foreach ($prices as $price)
{
/** @var FewoSeason $season */