sterntours/trunk/src/AppBundle/Entity/TravelDate.php
adametz 002f60e735 dublicate Booking Perido Names
sort out where Status = 0

git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3461 f459cee4-fb09-11de-96c3-f9c5f16c3c76
2018-09-05 11:25:01 +00:00

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;
}
}