git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3447 f459cee4-fb09-11de-96c3-f9c5f16c3c76
861 lines
No EOL
33 KiB
PHP
861 lines
No EOL
33 KiB
PHP
<?php
|
|
|
|
namespace AppBundle\Service;
|
|
|
|
use AppBundle\Entity\FewoLodging;
|
|
use AppBundle\Entity\FewoPrice;
|
|
use AppBundle\Entity\FewoReservation;
|
|
use AppBundle\Entity\FewoSeason;
|
|
use Doctrine\Common\Collections\Collection;
|
|
use Doctrine\ORM\EntityManager;
|
|
use AppBundle\Util\CalendarDayState;
|
|
|
|
class LodgingCalendarService
|
|
{
|
|
private $em;
|
|
|
|
public function __construct(EntityManager $entityManager)
|
|
{
|
|
$this->em = $entityManager;
|
|
}
|
|
|
|
|
|
|
|
private function daysInMonth($month, $year)
|
|
{
|
|
return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
|
|
}
|
|
//$months = number of Month to the last season
|
|
public function getCalendarWithPadding($months)
|
|
{
|
|
$calendar = null;
|
|
$currentMonth = date('n');
|
|
$currentYear = date('Y');
|
|
$weekDays = ['So','Mo','Di','Mi','Do','Fr','Sa'];
|
|
|
|
setlocale(LC_TIME, "german");
|
|
|
|
$yearTurned = false;
|
|
$yearsTurned = 0;
|
|
$now = new \DateTime();
|
|
|
|
for($m = $currentMonth; $m < ($currentMonth + $months); $m++)
|
|
{
|
|
$actualMonth = $m % 12;
|
|
|
|
if($actualMonth == 0)
|
|
{
|
|
$actualMonth = 12;
|
|
$yearTurned = true;
|
|
}
|
|
$actualYear = $currentYear + $yearsTurned;
|
|
if($yearTurned)
|
|
{
|
|
$yearsTurned = $yearsTurned + 1;
|
|
$yearTurned = false;
|
|
}
|
|
|
|
$date = getdate(mktime(0,0,0, $actualMonth, 1, $actualYear));
|
|
$weekDay = $weekDays[$date['wday']];
|
|
|
|
$numberDays = $this->daysInMonth($actualMonth, $actualYear);
|
|
$data = null;
|
|
|
|
$actualStartingWeekDay = $date['wday'];
|
|
|
|
if($actualStartingWeekDay == 0)
|
|
{
|
|
$actualStartingWeekDay = 7;
|
|
}
|
|
//first empty days from the last month
|
|
for($fwd = 0; $fwd < $actualStartingWeekDay - 1; $fwd++)
|
|
{
|
|
$day = new CalendarDayState();
|
|
$day->setDay(0);
|
|
$day->setIsBookable(false);
|
|
$day->setIsInSeason(false);
|
|
$day->setIsReserved(false);
|
|
$day->setIsReservationBegin(false);
|
|
$day->setIsReservationEnd(false);
|
|
$day->setIsEmpty(true);
|
|
$day->setIsPastDate(false);
|
|
|
|
$data[] = $day;
|
|
}
|
|
//days of month
|
|
for($d = 1; $d <= $numberDays; $d++)
|
|
{
|
|
$day = new CalendarDayState();
|
|
$day->setDay($d);
|
|
$datetime = new \DateTime();
|
|
$datetime->setTimestamp(mktime(0,0,0, $actualMonth, $d, $actualYear));
|
|
$day->setDate($datetime);
|
|
$day->setIsBookable(false);
|
|
$day->setIsInSeason(false);
|
|
$day->setIsReserved(false);
|
|
$day->setIsReservationBegin(false);
|
|
$day->setIsReservationEnd(false);
|
|
$day->setIsEmpty(false);
|
|
if($datetime < $now){
|
|
$day->setIsPastDate(true);
|
|
}else{
|
|
$day->setIsPastDate(false);
|
|
}
|
|
$data[] = $day;
|
|
}
|
|
|
|
$startIndex = count($data);
|
|
//last empty days from the next month
|
|
for($lwd = $startIndex; $lwd < 42; $lwd++)
|
|
{
|
|
$day = new CalendarDayState();
|
|
$day->setDay(0);
|
|
$day->setIsBookable(false);
|
|
$day->setIsInSeason(false);
|
|
$day->setIsReserved(false);
|
|
$day->setIsReservationBegin(false);
|
|
$day->setIsReservationEnd(false);
|
|
$day->setIsEmpty(true);
|
|
$day->setIsPastDate(false);
|
|
|
|
$data[] = $day;
|
|
}
|
|
$calendar[$actualYear."-".$actualMonth] = [
|
|
'numberDays' => $numberDays,
|
|
'monthNumber' => $actualMonth,
|
|
'monthName' => utf8_encode(strftime("%B", mktime(0, 0, 0, $actualMonth, 1, $actualYear))),
|
|
'year' => $actualYear,
|
|
'startWeekDay' => $weekDay,
|
|
'data' => $data,
|
|
'marked' => 0
|
|
];
|
|
}
|
|
|
|
return $calendar;
|
|
}
|
|
|
|
|
|
public function getCalendar($lodging)
|
|
{
|
|
$months = $this->getMinCalendarEntriesByLodging($lodging);
|
|
$calendar = null;
|
|
$currentMonth = date('n');
|
|
$currentYear = date('Y');
|
|
$weekDays = ['So','Mo','Di','Mi','Do','Fr','Sa'];
|
|
|
|
setlocale(LC_TIME, "german");
|
|
|
|
$yearTurned = false;
|
|
$yearsTurned = 0;
|
|
|
|
for($m = $currentMonth; $m < ($currentMonth + $months); $m++)
|
|
{
|
|
$actualMonth = $m % 12;
|
|
|
|
if($actualMonth == 0)
|
|
{
|
|
$actualMonth = 12;
|
|
$yearTurned = true;
|
|
}
|
|
|
|
$actualYear = $currentYear + $yearsTurned;
|
|
|
|
if($yearTurned)
|
|
{
|
|
$yearsTurned = $yearsTurned + 1;
|
|
$yearTurned = false;
|
|
}
|
|
|
|
$date = getdate(mktime(0,0,0, $actualMonth, 1, $actualYear));
|
|
$weekDay = $weekDays[$date['wday']];
|
|
|
|
$numberDays = $this->daysInMonth($actualMonth, $actualYear);
|
|
|
|
$data = null;
|
|
|
|
// alle Wochentage
|
|
for($d = 1; $d <= $numberDays; $d++)
|
|
{
|
|
// standard-vorbelegung
|
|
$day = new CalendarDayState();
|
|
$day->setDay($d);
|
|
$day->setIsBookable(false);
|
|
$day->setIsInSeason(false);
|
|
$day->setIsReserved(false);
|
|
$day->setIsReservationBegin(false);
|
|
$day->setIsReservationEnd(false);
|
|
$datetime = new \DateTime();
|
|
$datetime->setTimestamp(mktime(0,0,0, $actualMonth, $d, $actualYear));
|
|
$day->setDate($datetime);
|
|
|
|
$data[] = $day;
|
|
}
|
|
|
|
$calendar[] = [
|
|
'numberDays' => $numberDays,
|
|
'monthNumber' => $actualMonth,
|
|
'monthName' => utf8_encode(strftime("%B", mktime(0, 0, 0, $actualMonth, 1, $actualYear))),
|
|
'year' => $actualYear,
|
|
'startWeekDay' => $weekDay,
|
|
'data' => $data,
|
|
'marked' => 0
|
|
];
|
|
}
|
|
|
|
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);
|
|
$dateInterval = $seasonMonthDate->diff($curMonthDate);
|
|
$month = intval($dateInterval->format('%m')) + (intval($dateInterval->format('%y')) * 12);
|
|
return 2 + $month;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param FewoLodging $lodging
|
|
* @return array|null
|
|
*/
|
|
public function getReservations(FewoLodging $lodging)
|
|
{
|
|
$reservations = $lodging->getReservations();
|
|
$ret = null;
|
|
|
|
for($i = 0; $i < count($reservations); $i++)
|
|
{
|
|
$fromDate = $reservations[$i]->getFromDate();
|
|
$toDate = $reservations[$i]->getToDate();
|
|
|
|
$ret[] = [
|
|
'startDay' => $fromDate->format('j'),
|
|
'startMonth' => $fromDate->format('n'),
|
|
'startYear' => $fromDate->format('Y'),
|
|
'endDay' => $toDate->format('j'),
|
|
'endMonth' => $toDate->format('n'),
|
|
'endYear' => $toDate->format('Y')
|
|
];
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
private function getMonthIndex($calendar, $month, $year)
|
|
{
|
|
$result = 0;
|
|
for($i = 0; $i < count($calendar); $i++)
|
|
{
|
|
if($calendar[$i]['monthNumber'] == $month && $calendar[$i]['year'] == $year)
|
|
{
|
|
$result = $i;
|
|
break;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @param $calendar
|
|
* @param \DateTime $fromDate
|
|
* @param \DateTime $toDate
|
|
* @param $appendix
|
|
* @return mixed
|
|
*/
|
|
private function markCalendarDays($calendar, \DateTime $fromDate, \DateTime $toDate,
|
|
$reservationMode = false,
|
|
FewoPrice $price = null, FewoReservation $reservation = null)
|
|
{
|
|
$startDay = $fromDate->format('j');
|
|
$startMonth = $fromDate->format('n');
|
|
$startYear = $fromDate->format('Y');
|
|
$endDay = $toDate->format('j');
|
|
$endMonth = $toDate->format('n');
|
|
$endYear = $toDate->format('Y');
|
|
$today = new \DateTime();
|
|
$todayDay = $today->format('j');
|
|
$todayMonth = $today->format('n');
|
|
$todayYear = $today->format('Y');
|
|
|
|
|
|
if ($endMonth >= $todayMonth || ($todayMonth == 12 && $endMonth >= 1 && ($todayYear < $endYear))) //($toDate > $today)
|
|
{
|
|
if($fromDate < $today)
|
|
{
|
|
$startDay = 1;
|
|
$startMonth = $today->format('n');
|
|
$startYear = $today->format('Y');
|
|
}
|
|
|
|
// wenn sich der Kalender über mehrere Jahre zieht, könnte es hier zu Problemen kommen
|
|
$startCalendarIndex = $this->getMonthIndex($calendar, $startMonth, $startYear);
|
|
$endCalendarIndex = $this->getMonthIndex($calendar, $endMonth, $endYear);
|
|
|
|
// anfang und ende innerhalb eines monats
|
|
if($startCalendarIndex == $endCalendarIndex)
|
|
{
|
|
$data = $calendar[$startCalendarIndex]['data'];
|
|
|
|
$calendar[$startCalendarIndex]['marked'] = 1;
|
|
|
|
// hier geht man von ungepaddeten Kalendermonaten aus
|
|
$startIndex = $startDay - 1;
|
|
$endIndex = $endDay - 1;
|
|
|
|
for ($i = $startIndex; $i <= $endIndex; $i++)
|
|
{
|
|
if ($reservationMode)
|
|
{
|
|
if ($i == $startIndex)
|
|
{
|
|
$data[$i]->setIsReserved(true);
|
|
$data[$i]->setIsReservationBegin(true);
|
|
$data[$i]->setReservation($reservation);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
elseif ($i == $endIndex)
|
|
{
|
|
$data[$i]->setIsReserved(true);
|
|
$data[$i]->setIsReservationEnd(true);
|
|
$data[$i]->setReservation($reservation);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
//$data[$i]->setIsBookable(true);
|
|
}
|
|
else
|
|
{
|
|
$data[$i]->setIsReserved(true);
|
|
$data[$i]->setReservation($reservation);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$data[$i]->setIsReserved(false);
|
|
$data[$i]->setPrice($price);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
}
|
|
$calendar[$startCalendarIndex]['data'] = $data;
|
|
}
|
|
else
|
|
{
|
|
// erster monat
|
|
|
|
$data = $calendar[$startCalendarIndex]['data'];
|
|
|
|
$calendar[$startCalendarIndex]['marked'] = 1;
|
|
|
|
$startIndex = $startDay - 1;
|
|
|
|
$endIndex = count($data) - 1;
|
|
for($i = $startIndex; $i <= $endIndex; $i++)
|
|
{
|
|
if ($reservationMode)
|
|
{
|
|
if ($i == $startIndex)
|
|
{
|
|
$data[$i]->setIsReserved(true);
|
|
$data[$i]->setIsReservationBegin(true);
|
|
$data[$i]->setReservation($reservation);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
else
|
|
{
|
|
$data[$i]->setIsReserved(true);
|
|
$data[$i]->setReservation($reservation);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$data[$i]->setIsReserved(false);
|
|
$data[$i]->setPrice($price);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
}
|
|
$calendar[$startCalendarIndex]['data'] = $data;
|
|
|
|
// letzter monat
|
|
|
|
$data = $calendar[$endCalendarIndex]['data'];
|
|
|
|
$calendar[$endCalendarIndex]['marked'] = 1;
|
|
|
|
$startIndex = 0;
|
|
$endIndex = $endDay - 1;
|
|
for($i = $startIndex; $i <= $endIndex; $i++)
|
|
{
|
|
|
|
if ($reservationMode)
|
|
{
|
|
if ($i == $endIndex)
|
|
{
|
|
$data[$i]->setIsReserved(true);
|
|
$data[$i]->setIsReservationEnd(true);
|
|
$data[$i]->setReservation($reservation);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
//$data[$i]->setIsBookable(true);
|
|
}
|
|
else
|
|
{
|
|
$data[$i]->setIsReserved(true);
|
|
$data[$i]->setReservation($reservation);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$data[$i]->setIsReserved(false);
|
|
$data[$i]->setPrice($price);
|
|
$data[$i]->setIsInSeason(true);
|
|
$data[$i]->setIsBookable(false);
|
|
}
|
|
}
|
|
$calendar[$endCalendarIndex]['data'] = $data;
|
|
|
|
|
|
// alle monate dazwischen
|
|
for($i = $startCalendarIndex + 1; $i < $endCalendarIndex; $i++)
|
|
{
|
|
$data = $calendar[$i]['data'];
|
|
|
|
$calendar[$i]['marked'] = 1;
|
|
|
|
$startIndex = 0;
|
|
$endIndex = count($data) - 1;
|
|
for($j = $startIndex; $j <= $endIndex; $j++)
|
|
{
|
|
if ($reservationMode)
|
|
{
|
|
$data[$j]->setIsReserved(true);
|
|
$data[$j]->setReservation($reservation);
|
|
$data[$j]->setIsInSeason(true);
|
|
$data[$j]->setIsBookable(false);
|
|
}
|
|
else
|
|
{
|
|
$data[$j]->setIsReserved(false);
|
|
$data[$j]->setPrice($price);
|
|
$data[$j]->setIsInSeason(true);
|
|
$data[$j]->setIsBookable(false);
|
|
}
|
|
}
|
|
$calendar[$i]['data'] = $data;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $calendar;
|
|
}
|
|
|
|
|
|
// in der Regel: calendar = pricesCalendar; extensionCalendar = reservationsCalendar
|
|
private function mergeCalendars($calendar, $extensionCalendar)
|
|
{
|
|
for($i = 0; $i < count($calendar); $i++)
|
|
{
|
|
$calendarData = $calendar[$i]['data'];
|
|
|
|
$extensionCalendarData = $extensionCalendar[$i]['data'];
|
|
|
|
$endIndex = count($calendarData);
|
|
|
|
for($j = 0; $j < $endIndex; $j++)
|
|
{
|
|
if ($extensionCalendarData[$j]->getIsReserved())
|
|
{
|
|
$price = $calendarData[$j]->getPrice();
|
|
//$isInSeason = $calendarData[$j]->getIsInSeason();
|
|
$reservation = $calendarData[$j]->getReservation();
|
|
$calendarData[$j] = $extensionCalendarData[$j];
|
|
|
|
if ($calendarData[$j]->getIsReservationEnd() && $extensionCalendarData[$j]->getIsReservationBegin())
|
|
{
|
|
$calendarData[$j]->setReservation($reservation);
|
|
$calendarData[$j]->setIsReservationBegin(false);
|
|
$calendarData[$j]->setIsReservationEnd(false);
|
|
}
|
|
|
|
$calendarData[$j]->setIsInSeason(true);
|
|
$calendarData[$j]->setPrice($price);
|
|
}
|
|
}
|
|
|
|
$calendar[$i]['data'] = $calendarData;
|
|
}
|
|
return $calendar;
|
|
}
|
|
|
|
|
|
/** @var CalendarDayState[] $calendarMonth */
|
|
private function findCalendarDayIndexInMonth($dayNumber, $calendarMonth)
|
|
{
|
|
$result = 0;
|
|
for ($i = 0; $i < count($calendarMonth); $i++)
|
|
{
|
|
if ($calendarMonth[$i]->getDay() == $dayNumber)
|
|
{
|
|
$result = $i;
|
|
break;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
public function mergeWithPaddedCalendar($calendar, $paddedCalendar)
|
|
{
|
|
$i = 0;
|
|
foreach ($paddedCalendar as $key => $data){
|
|
|
|
$calendarDataCurrMonth = $calendar[$i]['data'];
|
|
$paddedCalendarDataCurrMonth = $paddedCalendar[$key]['data'];
|
|
|
|
$startIndex = $this->findCalendarDayIndexInMonth(1, $paddedCalendarDataCurrMonth);
|
|
//$startIndex = array_search(1, $paddedCalendarDataCurrMonth);
|
|
|
|
for($j = 0; $j < count($calendarDataCurrMonth); $j++, $startIndex++)
|
|
{
|
|
$paddedCalendarDataCurrMonth[$startIndex] = $calendarDataCurrMonth[$j];
|
|
}
|
|
$paddedCalendar[$key]['data'] = $paddedCalendarDataCurrMonth;
|
|
$i++;
|
|
}
|
|
/*for($i = 0; $i < count($paddedCalendar); $i++)
|
|
{
|
|
$calendarDataCurrMonth = $calendar[$i]['data'];
|
|
$paddedCalendarDataCurrMonth = $paddedCalendar[$i]['data'];
|
|
|
|
$startIndex = $this->findCalendarDayIndexInMonth(1, $paddedCalendarDataCurrMonth);
|
|
//$startIndex = array_search(1, $paddedCalendarDataCurrMonth);
|
|
|
|
for($j = 0; $j < count($calendarDataCurrMonth); $j++, $startIndex++)
|
|
{
|
|
$paddedCalendarDataCurrMonth[$startIndex] = $calendarDataCurrMonth[$j];
|
|
}
|
|
$paddedCalendar[$i]['data'] = $paddedCalendarDataCurrMonth;
|
|
}*/
|
|
return $paddedCalendar;
|
|
}
|
|
|
|
|
|
private function isNextDay($current, $next)
|
|
{
|
|
$result = false;
|
|
|
|
$calculatedNextDate = date('d.m.Y', strtotime($current." + 1 day"));
|
|
|
|
|
|
if($calculatedNextDate == $next)
|
|
{
|
|
$result = true;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
private function getMonthFromCalendar($calendar, $monthNumber)
|
|
{
|
|
$result = [];
|
|
|
|
for($i = 0; $i < count($calendar); $i++)
|
|
{
|
|
if($calendar[$i]['monthNumber'] == $monthNumber)
|
|
{
|
|
$result = $calendar[$i];
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* @param FewoLodging $lodging
|
|
* @param $calendar
|
|
* @return array|null calendars
|
|
*/
|
|
private function filterReservableDays(FewoLodging $lodging, $calendar)
|
|
{
|
|
$potentiallyReservableDays = [];
|
|
|
|
for ($currMonthIndex = 0; $currMonthIndex < count($calendar); $currMonthIndex++)
|
|
{
|
|
$currMonth = $calendar[$currMonthIndex];
|
|
$data = $currMonth['data'];
|
|
|
|
for ($currDayIndex = 0; $currDayIndex < count($data); $currDayIndex++)
|
|
{
|
|
$currDay = $data[$currDayIndex];
|
|
|
|
// 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())
|
|
{
|
|
while (!empty($potentiallyReservableDays))
|
|
{
|
|
$potentiallyReservableDay = array_pop($potentiallyReservableDays);
|
|
$potentiallyReservableDay->setIsBookable(false);
|
|
}
|
|
$currDay->setIsBookable(false);
|
|
continue;
|
|
}
|
|
|
|
$currSeason = $currDay->getPrice()->getSeason();
|
|
|
|
// 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())
|
|
{
|
|
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]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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')))
|
|
{
|
|
$potentiallyReservableDays[] = $currDay;
|
|
}
|
|
else
|
|
{
|
|
$currDay->setIsBookable(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remaining entries in the stack are definitely not reservable. Otherwise they would have been processed before.
|
|
foreach ($potentiallyReservableDays as $potentiallyReservableDay)
|
|
{
|
|
$potentiallyReservableDay->setIsBookable(false);
|
|
}
|
|
|
|
return $calendar;
|
|
}
|
|
|
|
private function findCalendarDayKey($calendarMonth, $dayNumber){
|
|
|
|
foreach ($calendarMonth['data'] as $key => $data) {
|
|
if($data->getDay() == $dayNumber){
|
|
return $key;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
public function calendarAndFillDayStates($paddedCalendar, FewoLodging $lodging){
|
|
|
|
$startMonth = array_values($paddedCalendar)[0]['monthNumber'];
|
|
$startYear = array_values($paddedCalendar)[0]['year'];
|
|
$endMonth = array_values($paddedCalendar)[count($paddedCalendar)-1]['monthNumber'];
|
|
$endYear = array_values($paddedCalendar)[count($paddedCalendar)-1]['year'];
|
|
$endDay = array_values($paddedCalendar)[count($paddedCalendar)-1]['numberDays'];
|
|
|
|
$startDate = new \DateTime(date( "Y-m-d", mktime(0,0,0, $startMonth, 1, $startYear)));
|
|
$endDate = new \DateTime(date( "Y-m-d", mktime(0,0,0, $endMonth, $endDay, $endYear)));
|
|
|
|
|
|
//reservations in the Calender Time
|
|
$reservations = $lodging->getReservationsFilter($startDate, $endDate);
|
|
|
|
|
|
foreach($reservations as $reservation)
|
|
{
|
|
$setFromIntervall = clone $reservation->getFromDate();
|
|
$fromDate = $reservation->getFromDate();
|
|
$toDate = $reservation->getToDate();
|
|
|
|
// $diff = $fromDate->diff($toDate);
|
|
$interval = \DateInterval::createFromDateString('1 day');
|
|
$period = new \DatePeriod($setFromIntervall->modify('+1 day'), $interval, $toDate);
|
|
|
|
//first
|
|
if(isset($paddedCalendar[$fromDate->format("Y-n")])){
|
|
$key = $this->findCalendarDayKey($paddedCalendar[$fromDate->format("Y-n")], $fromDate->format("d"));
|
|
$paddedCalendar[$fromDate->format("Y-n")]['data'][$key]->setIsReservationBegin(true);
|
|
$paddedCalendar[$fromDate->format("Y-n")]['data'][$key]->setReservation($reservation);
|
|
|
|
}
|
|
//last
|
|
if(isset($paddedCalendar[$toDate->format("Y-n")])) {
|
|
$key = $this->findCalendarDayKey($paddedCalendar[$toDate->format("Y-n")], $toDate->format("d"));
|
|
$paddedCalendar[$toDate->format("Y-n")]['data'][$key]->setIsReservationEnd(true);
|
|
}
|
|
//days
|
|
foreach ($period as $dt) {
|
|
if(isset($paddedCalendar[$dt->format("Y-n")])) {
|
|
$key = $this->findCalendarDayKey($paddedCalendar[$dt->format("Y-n")], $dt->format("d"));
|
|
$paddedCalendar[$dt->format("Y-n")]['data'][$key]->setIsReserved(true);
|
|
$paddedCalendar[$dt->format("Y-n")]['data'][$key]->setReservation($reservation);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
$prices = $lodging->getPricesFilter($startDate, $endDate);
|
|
|
|
foreach ($prices as $price)
|
|
{
|
|
|
|
/** @var FewoSeason $season */
|
|
$season = $price->getSeason();
|
|
$setFromIntervall = clone $season->getFromDate();
|
|
//$fromDate = $season->getFromDate();
|
|
$setToIntervall = clone $season->getToDate();
|
|
//$toDate = $season->getToDate();
|
|
|
|
$interval = \DateInterval::createFromDateString('1 day');
|
|
$period = new \DatePeriod($setFromIntervall, $interval, $setToIntervall->modify('+1 day'));
|
|
|
|
//days
|
|
foreach ($period as $dt) {
|
|
if(isset($paddedCalendar[$dt->format("Y-n")])) {
|
|
$key = $this->findCalendarDayKey($paddedCalendar[$dt->format("Y-n")], $dt->format("d"));
|
|
$currDay = $paddedCalendar[$dt->format("Y-n")]['data'][$key];
|
|
$currDay->setPrice($price);
|
|
|
|
|
|
if(!$currDay->getIsReserved() && $season->getOnlyWeekday() != null && $season->getOnlyWeekday() == $currDay->getDate()->format('w')){
|
|
$currDay->setIsBookable(true);
|
|
}
|
|
|
|
if(!$currDay->getIsReserved() && $season->getOnlyWeekday() == null){
|
|
$currDay->setIsBookable(true);
|
|
}
|
|
if($currDay->getIsReservationBegin() == true && $currDay->getIsReservationEnd() == true){
|
|
$currDay->setIsBookable(false);
|
|
}
|
|
//check for the min sty days.
|
|
if ($currDay->getIsReservationBegin() == true)
|
|
{
|
|
//days
|
|
$minDays = $season->getMinimumStay();
|
|
$setMinStayFrom = clone $currDay->getDate();
|
|
$setMinStayTo = clone $currDay->getDate();
|
|
|
|
//$minStayInterval = \DateInterval::createFromDateString('-1 day');
|
|
// $minStayPeriod = new \DatePeriod($setMinStayTo->modify('+1 day'), $minStayInterval, $setMinStayFrom->modify('-'.($minDays-1).' days'));
|
|
$setMinStayTo->modify('-'.($minDays).' days');
|
|
$counter = 0;
|
|
$last = $minDays;
|
|
|
|
for($mSdt = $setMinStayFrom; $mSdt >= $setMinStayTo; $mSdt->modify('-1 day')){
|
|
|
|
if(isset($paddedCalendar[$mSdt->format("Y-n")])) {
|
|
$key = $this->findCalendarDayKey($paddedCalendar[$mSdt->format("Y-n")], $mSdt->format("d"));
|
|
$checkDay = $paddedCalendar[$mSdt->format("Y-n")]['data'][$key];
|
|
|
|
|
|
|
|
if(!empty($checkDay->getPrice())){
|
|
if(!empty($checkDay->getPrice()->getSeason()) && $minDays != $checkDay->getPrice()->getSeason()->getMinimumStay()){
|
|
|
|
if($minDays > $checkDay->getPrice()->getSeason()->getMinimumStay()){
|
|
$last = $counter+$checkDay->getPrice()->getSeason()->getMinimumStay();
|
|
$setMinStayTo->modify('-'.($last).' days');
|
|
}
|
|
if($minDays < $checkDay->getPrice()->getSeason()->getMinimumStay()){
|
|
$last = $counter+$checkDay->getPrice()->getSeason()->getMinimumStay();
|
|
$setMinStayTo->modify('-'.($last).' days');
|
|
|
|
}
|
|
$minDays = $checkDay->getPrice()->getSeason()->getMinimumStay();
|
|
}
|
|
}
|
|
$counter++;
|
|
if($counter <= $last) {
|
|
$checkDay->setIsBookable(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
//$season is end
|
|
}
|
|
return $paddedCalendar;
|
|
|
|
|
|
}
|
|
/**
|
|
* @param FewoLodging $lodging
|
|
* @param $calendar
|
|
* @return mixed
|
|
*
|
|
* createCalendarAndFillDayStates
|
|
*/
|
|
public function createCalendarAndFillDayStates(FewoLodging $lodging)
|
|
{
|
|
$pricesCalendar = $this->getCalendar($lodging);
|
|
$reservationsCalendar = $this->getCalendar($lodging);
|
|
|
|
$reservations = $lodging->getReservations();
|
|
|
|
$prices = $lodging->getPrices();
|
|
|
|
foreach ($prices as $price) {
|
|
if (!empty($price->getSeason())){
|
|
$season = $price->getSeason();
|
|
$pricesCalendar = $this->markCalendarDays($pricesCalendar, $season->getFromDate(), $season->getToDate(),
|
|
false, $price);
|
|
}
|
|
}
|
|
foreach($reservations as $reservation)
|
|
{
|
|
$fromDate = $reservation->getFromDate();
|
|
$toDate = $reservation->getToDate();
|
|
$reservationsCalendar = $this->markCalendarDays($reservationsCalendar, $fromDate, $toDate,
|
|
true, null, $reservation); //TODO fast fertig
|
|
}
|
|
$mergedPricesAndReservationsCalendar = $this->mergeCalendars($pricesCalendar, $reservationsCalendar);
|
|
$actuallyReservableDaysCalendar = $this->filterReservableDays($lodging, $mergedPricesAndReservationsCalendar);
|
|
//$resultCalendar = $this->mergeCalendars($actuallyReservableDaysCalendar, $reservationsCalendar, true);
|
|
|
|
return $actuallyReservableDaysCalendar;
|
|
//return $resultCalendar;
|
|
}
|
|
|
|
|
|
public function convertDate($date)
|
|
{
|
|
$result = substr($date, 0, 2).'.'.substr($date, 2, 2).'.'.substr($date, 4, 4);
|
|
return $result;
|
|
}
|
|
|
|
} |