sort out where Status = 0 git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3461 f459cee4-fb09-11de-96c3-f9c5f16c3c76
343 lines
No EOL
10 KiB
PHP
343 lines
No EOL
10 KiB
PHP
<?php
|
|
/**
|
|
* @author Ulrich Hecht <ulrich.hecht@hecht-software.de>
|
|
* @date 11/03/2016
|
|
*/
|
|
|
|
namespace AppBundle\Entity;
|
|
use AppBundle\Util\DepartureUtil;
|
|
use Doctrine\Common\Collections\ArrayCollection;
|
|
|
|
/**
|
|
* TravelDate is a wrapper for TravelPeriod + start date and end date. This entity doesn't represent a database
|
|
* table. It was introduced because of requirement to keep the bad original database design in which a TravelPeriod
|
|
* serves two purposes:
|
|
* - Representing a season
|
|
* - Representing a single travel date (by being linked to a TravelPeriodDate-instance)
|
|
* Also TravelPeriodDate has two purposes:
|
|
* - Representing a time period of a season. From this time period, multiple travel dates are derived by taking
|
|
* the possible weekdays into account
|
|
* - Holding the start and end date for a TravelPeriod that is not a season (see above)
|
|
*
|
|
* To avoid further confusion and to slowly move away from this design, "TravelDate" has been invented, which has single
|
|
* clearly defined purpose:
|
|
* Representing a single travel date, i.e.
|
|
* - time period a traveller starts and ends his/her journey
|
|
* - prices
|
|
* - availability
|
|
* - departure locations and their prices
|
|
*
|
|
* "TravelPeriod" would be a more fitting name, but this name is already in use.
|
|
*
|
|
* @package AppBundle\Entity
|
|
*/
|
|
final class TravelDate
|
|
{
|
|
/** @var String $key */
|
|
private $key;
|
|
|
|
/** @var TravelPeriod $travelPeriod */
|
|
private $travelPeriod;
|
|
|
|
/** @var \DateTime $start */
|
|
private $start;
|
|
|
|
/** @var \DateTime $end */
|
|
private $end;
|
|
|
|
private $index;
|
|
|
|
/** @var FlightPeriod $flightPeriod */
|
|
private $flightPeriod;
|
|
|
|
private $currencyFactor;
|
|
|
|
private $travelProgram;
|
|
|
|
/** @var TravelDeparturePoint[]|null $departures Departures cache */
|
|
private $departures = null;
|
|
|
|
/** @var TravelPeriodPrice[]|null $prices Prices cache */
|
|
private $prices = null;
|
|
|
|
private $calculatedEffectivePrices = false;
|
|
|
|
/**
|
|
* TravelDate constructor.
|
|
*
|
|
* @param String $key
|
|
* @param TravelPeriod $travelPeriod
|
|
* @param FlightPeriod|null $flightPeriod
|
|
* @param float $currencyFactor
|
|
* @param \DateTime $start
|
|
* @param \DateTime $end Optional. Computed from travel duration, if not specified.
|
|
* @param null $index
|
|
*
|
|
* @todo Make this object immutable
|
|
*/
|
|
public function __construct($key, TravelPeriod $travelPeriod, FlightPeriod $flightPeriod = null, $currencyFactor,
|
|
\DateTime $start = null, \DateTime $end = null, $index = null)
|
|
{
|
|
if ($travelPeriod->getIsSeason())
|
|
{
|
|
if ($index === null)
|
|
{
|
|
throw new \InvalidArgumentException('Expected numeric value for argument $index due to virtual travel date. Got null.');
|
|
}
|
|
if ($start === null)
|
|
{
|
|
throw new \InvalidArgumentException('Expected DateTime value for argument $start due to virtual travel date. Got null.');
|
|
}
|
|
$this->start = $start;
|
|
$this->index = $index;
|
|
$this->prices = [];
|
|
foreach ($travelPeriod->getPrices() as $price)
|
|
{
|
|
$this->prices[$price->getPriceTypeId()] = clone $price;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->start = $travelPeriod->getStartDate();
|
|
$this->prices = $travelPeriod->getPrices();
|
|
}
|
|
$this->flightPeriod = $flightPeriod;
|
|
$this->travelProgram = $travelPeriod->getProgram();
|
|
$this->key = $key;
|
|
$this->travelPeriod = $travelPeriod;
|
|
|
|
if ($end === null)
|
|
{
|
|
$this->end = clone $this->start;
|
|
$this->end->modify('+'. $this->travelProgram->getProgramDuration() .' day');
|
|
}
|
|
else
|
|
{
|
|
$this->end = $end;
|
|
}
|
|
$this->currencyFactor = $currencyFactor;
|
|
}
|
|
|
|
public static function createForNonSeasonTravelPeriod($key, TravelPeriod $travelPeriod,
|
|
FlightPeriod $flightPeriod = null, $currencyFactor)
|
|
{
|
|
if ($travelPeriod->getIsSeason())
|
|
{
|
|
throw new \Exception('Expected non-season TravelPeriod instance');
|
|
}
|
|
return new TravelDate($key, $travelPeriod, $flightPeriod, $currencyFactor);
|
|
}
|
|
|
|
public static function createForSeasonTravelPeriod($key, TravelPeriod $travelPeriod, $index, \DateTime $start,
|
|
\DateTime $end = null, FlightPeriod $flightPeriod = null, $currencyFactor)
|
|
{
|
|
if (!$travelPeriod->getIsSeason())
|
|
{
|
|
throw new \Exception('Expected season TravelPeriod instance');
|
|
}
|
|
return new TravelDate($key, $travelPeriod, $flightPeriod, $currencyFactor, $start, $end, $index);
|
|
}
|
|
|
|
/**
|
|
* @return String
|
|
*/
|
|
public function getKey()
|
|
{
|
|
return $this->key;
|
|
}
|
|
|
|
/**
|
|
* @return \DateTime
|
|
*/
|
|
public function getStart()
|
|
{
|
|
return $this->start;
|
|
}
|
|
|
|
/**
|
|
* @return \DateTime
|
|
*/
|
|
public function getStartWeekday()
|
|
{
|
|
return $this->start->format('w');
|
|
}
|
|
|
|
public function getFinalPaymentDate()
|
|
{
|
|
$pDate = strtotime('-4 week', $this->getStart()->getTimestamp());
|
|
if($pDate <= time()){
|
|
$pDate = time();
|
|
}
|
|
return date('d.m.Y',$pDate);
|
|
}
|
|
|
|
public function getFinalPaymentDateStr()
|
|
{
|
|
$pDate = strtotime('-4 week', $this->getStart()->getTimestamp());
|
|
if($pDate <= time()){
|
|
return "ist sofort fällig";
|
|
}
|
|
return "bis zum ".date('d.m.Y',$pDate);
|
|
}
|
|
|
|
|
|
/**
|
|
* @return \DateTime
|
|
*/
|
|
public function getEnd()
|
|
{
|
|
return $this->end;
|
|
}
|
|
|
|
public function getName()
|
|
{
|
|
return $this->travelPeriod->getIsSeason()
|
|
? (trim($this->travelProgram->getProgramCode()) . $this->index)
|
|
: $this->travelPeriod->getName()
|
|
;
|
|
}
|
|
|
|
public function getStatus()
|
|
{
|
|
return $this->travelPeriod->getStatus();
|
|
}
|
|
|
|
public function getEffectiveStatus()
|
|
{
|
|
if ($this->getStatus() == 2 && $this->getStart()->getTimestamp() < time() + 2419200)
|
|
{
|
|
return 1;
|
|
}
|
|
return $this->getStatus();
|
|
}
|
|
|
|
public function getDepartures()
|
|
{
|
|
if ($this->departures === null)
|
|
{
|
|
if ($this->travelProgram->getIsMediated())
|
|
{
|
|
$defaultDepartures = $this->travelProgram->getDepartures();
|
|
$departures = $this->travelPeriod->getDepartures();
|
|
}
|
|
else
|
|
{
|
|
$defaultDepartures = $this->travelProgram->getTravelArrivalPoint()->getDepartures();
|
|
$departures = $this->flightPeriod === null ? [] : $this->flightPeriod->getDepartures();
|
|
}
|
|
$defaultDepartures = DepartureUtil::filterDeparturesByPeriod($defaultDepartures, $this->start, $this->end, true);
|
|
$this->departures = DepartureUtil::mergeDeparturesWithDefaults($departures, $defaultDepartures, true);
|
|
}
|
|
return $this->departures;
|
|
}
|
|
|
|
public function getFlightPrice()
|
|
{
|
|
if ($this->travelProgram->getIsMediated())
|
|
{
|
|
return 0;
|
|
}
|
|
$flightPrice = null;
|
|
if ($this->flightPeriod !== null)
|
|
{
|
|
$flightPrice = $this->flightPeriod->getPrice();
|
|
}
|
|
if ($flightPrice === null)
|
|
{
|
|
$flightPrice = $this->travelProgram->getDefaultFlightPrice();
|
|
}
|
|
return $flightPrice;
|
|
}
|
|
|
|
|
|
public function getFlightCalcPrice()
|
|
{
|
|
$flightPrice = $this->getFlightPrice();
|
|
if ($this->travelProgram->getIsMediated())
|
|
{
|
|
$profitMargin = 1;
|
|
}
|
|
else
|
|
{
|
|
$profitMargin = $this->travelProgram->getProfitMargin() / 100 + 1;
|
|
}
|
|
$currencyFactor = $this->travelProgram->getNettoPricesInEuro() ? 1 : $this->currencyFactor;
|
|
return round(($flightPrice * $currencyFactor) * $profitMargin);
|
|
|
|
}
|
|
|
|
/**
|
|
* @return TravelPeriodPrice[]|\Doctrine\Common\Collections\Collection
|
|
*/
|
|
public function getPrices()
|
|
{
|
|
if (!$this->calculatedEffectivePrices)
|
|
{
|
|
$this->calculatedEffectivePrices = true;
|
|
$flightPrice = $this->getFlightPrice();
|
|
if ($this->travelProgram->getIsMediated())
|
|
{
|
|
$profitMargin = 1;
|
|
}
|
|
else
|
|
{
|
|
$profitMargin = $this->travelProgram->getProfitMargin() / 100 + 1;
|
|
}
|
|
$currencyFactor = $this->travelProgram->getNettoPricesInEuro() ? 1 : $this->currencyFactor;
|
|
foreach ($this->prices as &$price)
|
|
{
|
|
$price->setEffectivePrice(round(($flightPrice + $price->getPrice() * $currencyFactor) * $profitMargin));
|
|
$price->setEffectiveComfortPrice(round($price->getPriceComfort() * $currencyFactor * $profitMargin));
|
|
$price->setEffectiveChildPrice(round(($flightPrice + $price->getPriceChildren() * $currencyFactor) * $profitMargin));
|
|
}
|
|
}
|
|
return $this->prices;
|
|
}
|
|
|
|
public function getLowestPrice()
|
|
{
|
|
$lowest = -1;
|
|
foreach ($this->getPrices() as $price)
|
|
{
|
|
if ($price->getPriceTypeId() == 3)
|
|
{
|
|
// Use double room if available (#1076)
|
|
return $price->getEffectiveDiscountPrice() ?? $price->getEffectivePrice();
|
|
}
|
|
if ($lowest < 0 || $price->getEffectivePrice() < 0)
|
|
{
|
|
$lowest = $price->getEffectivePrice();
|
|
}
|
|
}
|
|
return $lowest == -1 ? null : $lowest;
|
|
}
|
|
|
|
public function hasComfortCategory()
|
|
{
|
|
foreach ($this->getPrices() as $price)
|
|
{
|
|
if ($price->getPriceComfort() > 0)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return TravelProgram
|
|
*/
|
|
public function getTravelProgram(): TravelProgram
|
|
{
|
|
return $this->travelProgram;
|
|
}
|
|
|
|
/**
|
|
* @return TravelPeriod
|
|
* @internal
|
|
*/
|
|
public function __getTravelPeriod()
|
|
{
|
|
return $this->travelPeriod;
|
|
}
|
|
} |