git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3283 f459cee4-fb09-11de-96c3-f9c5f16c3c76

This commit is contained in:
uli 2016-12-17 10:11:28 +00:00
parent 75a065758f
commit 7422f06e90
261 changed files with 83347 additions and 0 deletions

View file

@ -0,0 +1,266 @@
<?php
/**
* @author Ulrich Hecht <ulrich.hecht@hecht-software.de>
* @date 11/03/2016
*/
namespace AppBundle\Entity;
use AppBundle\Util\DepartureUtil;
/**
* 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->flightPeriod = $flightPeriod;
}
else
{
$this->start = $travelPeriod->getStartDate();
}
$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 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 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($defaultDepartures, $departures, true);
}
return $this->departures;
}
/**
* @return TravelPeriodPrice[]|\Doctrine\Common\Collections\Collection
*/
public function getPrices()
{
if (!$this->calculatedEffectivePrices)
{
$this->calculatedEffectivePrices = true;
if ($this->travelProgram->getIsMediated())
{
$profitMargin = 1;
$flightPrice = 0;
}
else
{
$profitMargin = $this->travelProgram->getProfitMargin() / 100 + 1;
$flightPrice = null;
if ($this->flightPeriod !== null)
{
$flightPrice = $this->flightPeriod->getPrice();
}
if ($flightPrice === null)
{
$flightPrice = $this->travelProgram->getDefaultFlightPrice();
}
}
$currencyFactor = $this->travelProgram->getNettoPricesInEuro() ? 1 : $this->currencyFactor;
foreach ($this->travelPeriod->getPrices() as $price)
{
$price->setEffectivePrice(round(($flightPrice + $price->getPrice() * $currencyFactor) * $profitMargin));
$price->setEffectiveDiscountPrice(
round(($flightPrice + $price->getDiscountPrice() * $currencyFactor) * $profitMargin));
//$price->setEffectiveDiscountPrice($pr)
}
}
return $this->travelPeriod->getPrices();
}
public function getLowestPrice()
{
$lowest = -1;
foreach ($this->getPrices() as $price)
{
if ($price->getPriceType() == 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 TravelPeriod
* @internal
*/
public function __getTravelPeriod()
{
return $this->travelPeriod;
}
}