* Fertigstellung Buchungsformular (#1321) (SternTours-CRM-API-Anbindung, Mailversand, Validierung, Dynamische Preisberechnung, Persistierung von Buchungsinformationen)

* Fehler bei der Preisberechnung behoben
* Farbschema geändert (Kevin Adametz)

git-svn-id: http://78.47.251.156/svn/dev/sterntours-3@3289 f459cee4-fb09-11de-96c3-f9c5f16c3c76
This commit is contained in:
uli 2017-02-14 11:26:49 +00:00
parent dde3b91724
commit 3a28866cd2
36 changed files with 2200 additions and 268 deletions

View file

@ -7,10 +7,20 @@
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
use AppBundle\Validator\Constraints as AppBundleAssert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Class BookingRequest
* @package AppBundle\Entity
* @AppBundleAssert\BookingRequest
*/
class BookingRequest
{
// Used in SternToursCrmBookingExports, expected to be equivalent to sex (as defined in Traveler)
const MR = 1;
const MRS = 2;
/**
* @var TravelDeparturePoint $departure
*/
@ -23,14 +33,78 @@ class BookingRequest
*/
private $insurance;
private $comfort;
private $comfort = false;
private $travelOptions;
private $travelOptions = [];
private $salutation;
/**
* @Assert\NotBlank()
*/
private $firstName;
/**
* @Assert\NotBlank()
*/
private $lastName;
/**
* @Assert\NotBlank()
*/
private $streetAddress;
/**
* @Assert\NotBlank()
*/
private $zipCode;
/**
* @Assert\NotBlank()
*/
private $city;
private $nation;
/**
* @Assert\NotBlank()
*/
private $phone;
private $fax;
/**
* @Assert\NotBlank()
*/
private $email;
/*
* @ Assert\Valid()
*/
private $travelers = [];
private $notes;
/**
* @Assert\IsTrue()
*/
private $acceptTerms = false;
/**
* BookingRequest constructor.
*/
public function __construct()
{
for ($i = 0; $i < 4; ++$i)
{
$this->travelers[] = new Traveler();
}
}
/**
* @return TravelDeparturePoint
*/
public function getDeparture(): TravelDeparturePoint
public function getDeparture()
{
return $this->departure;
}
@ -62,7 +136,7 @@ class BookingRequest
/**
* @return TravelInsurance
*/
public function getInsurance(): TravelInsurance
public function getInsurance()
{
return $this->insurance;
}
@ -92,7 +166,7 @@ class BookingRequest
}
/**
* @return mixed
* @return TravelOption[]
*/
public function getTravelOptions()
{
@ -107,6 +181,221 @@ class BookingRequest
$this->travelOptions = $travelOptions;
}
/**
* @return int
*/
public function getSalutation()
{
return $this->salutation;
}
/**
* @param int $salutation
*/
public function setSalutation($salutation)
{
$this->salutation = $salutation;
}
/**
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* @param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* @param string $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* @return string
*/
public function getStreetAddress()
{
return $this->streetAddress;
}
/**
* @param string $streetAddress
*/
public function setStreetAddress($streetAddress)
{
$this->streetAddress = $streetAddress;
}
/**
* @return string
*/
public function getZipCode()
{
return $this->zipCode;
}
/**
* @param string $zipCode
*/
public function setZipCode($zipCode)
{
$this->zipCode = $zipCode;
}
/**
* @return string
*/
public function getCity()
{
return $this->city;
}
/**
* @param string $city
*/
public function setCity($city)
{
$this->city = $city;
}
/**
* @return int
*/
public function getNation()
{
return $this->nation;
}
/**
* @param int $nation
*/
public function setNation($nation)
{
$this->nation = $nation;
}
/**
* @return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* @param string $phone
*/
public function setPhone($phone)
{
$this->phone = $phone;
}
/**
* @return string
*/
public function getFax()
{
return $this->fax;
}
/**
* @param string $fax
*/
public function setFax($fax)
{
$this->fax = $fax;
}
/**
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return Traveler[]
*/
public function getTravelers()
{
return $this->travelers;
}
/**
* @param Traveler[] $travelers
*/
public function setTravelers($travelers)
{
$this->travelers = $travelers;
}
/*
public function addTraveler(Traveler $traveler)
{
$this->travelers[] = $traveler;
}
*/
/**
* @return string
*/
public function getNotes()
{
return $this->notes;
}
/**
* @param string $notes
*/
public function setNotes($notes)
{
$this->notes = $notes;
}
/**
* @return bool
*/
public function isAcceptTerms()
{
return $this->acceptTerms;
}
/**
* @param bool $acceptTerms
*/
public function setAcceptTerms($acceptTerms)
{
$this->acceptTerms = $acceptTerms;
}
/**
* @Assert\Callback
*/

View file

@ -10,4 +10,50 @@ namespace AppBundle\Entity;
*/
class FlightPeriodRepository extends \Doctrine\ORM\EntityRepository
{
public function getIndexedFlightPeriodsForTimePeriod($startDate, $endDate, $arrivalPointIds = null)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->from('AppBundle:FlightPeriod', 'fp')
->addSelect('fp')
->leftJoin('fp.departures', 'fp_dep')
->addSelect('fp_dep')
;
if ($startDate !== null)
{
$qb->where('fp.startDate >= :startDate');
$qb->setParameter('startDate', $startDate);
}
if ($endDate !== null)
{
$qb->andWhere('fp.endDate <= :endDate');
$qb->setParameter('endDate', $endDate);
}
if (!empty($arrivalPointIds))
{
if (is_array($arrivalPointIds))
{
$qb->andWhere($qb->expr()->in('IDENTITY(fp.travelArrivalPoint)', $arrivalPointIds));
}
else
{
$qb->andWhere($qb->expr()->eq('IDENTITY(fp.travelArrivalPoint)', $arrivalPointIds));
}
}
$unindexedFlightPeriods = $qb->getQuery()->getResult();
$ret = [];
// Index by CONCAT(start date, end date, arrival point id):
/** @var FlightPeriod $flightPeriod */
foreach ($unindexedFlightPeriods as $flightPeriod)
{
$ret[$flightPeriod->getStartDate()->format('Y-m-d') .
$flightPeriod->getEndDate()->format('Y-m-d') .
$flightPeriod->getTravelArrivalPoint()->getId()] = $flightPeriod;
}
return $ret;
}
}

View file

@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
* TravelBooking
*
* @ORM\Table(name="travel_booking", indexes={@ORM\Index(name="FK_travel_booking_travel_period", columns={"period_id"}), @ORM\Index(name="FK_travel_booking_travel_program", columns={"program_id"})})
* @ORM\Entity
* @ORM\Entity(repositoryClass="AppBundle\Entity\TravelBookingRepository")
*/
class TravelBooking
{
@ -678,7 +678,7 @@ class TravelBooking
*/
public function setSelectedDeparture($selectedDeparture)
{
$this->selectedDeparture = $selectedDeparture;
$this->selectedDeparture = is_array($selectedDeparture) ? json_encode($selectedDeparture) : $selectedDeparture;
return $this;
}
@ -690,7 +690,12 @@ class TravelBooking
*/
public function getSelectedDeparture()
{
return $this->selectedDeparture;
$ret = json_decode($this->selectedDeparture, true);
if (empty($ret) || !is_array($ret))
{
return $this->selectedDeparture;
}
return $ret;
}
/**
@ -846,7 +851,7 @@ class TravelBooking
*/
public function setRooms($rooms)
{
$this->rooms = $rooms;
$this->options = is_array($rooms) ? json_encode($rooms) : $rooms;
return $this;
}
@ -858,19 +863,43 @@ class TravelBooking
*/
public function getRooms()
{
return $this->rooms;
$ret = json_decode($this->rooms, true);
if (empty($ret) || !is_array($ret))
{
return $this->rooms;
}
return $ret;
}
/**
* Set participants
*
* @param string $participants
* @param Traveler[] $travelers
*
* @return TravelBooking
*/
public function setParticipants($participants)
public function setParticipants($travelers)
{
$this->participants = $participants;
if (!is_array($travelers))
{
$this->participants = $travelers;
return $this;
}
$participants = [];
for ($i = 0; $i < count($travelers); ++$i)
{
$traveler = $travelers[$i];
$participants[''. ($i+1)] = [
'gender' => $traveler->getSex(),
'first_name' => $traveler->getFirstName(),
'last_name' => $traveler->getLastName(),
'birthday' => $traveler->getBirthDate()->format('d.m.Y')
];
}
$this->participants = json_encode($participants);
return $this;
}
@ -882,7 +911,22 @@ class TravelBooking
*/
public function getParticipants()
{
return $this->participants;
$participants = json_decode($this->participants, true);
if (empty($participants) || !is_array($participants))
{
return $this->participants;
}
$ret = [];
foreach ($participants as $participant)
{
$traveler = new Traveler();
$traveler->setSex(intval($participant['gender']));
$traveler->setFirstName($participant['first_name']);
$traveler->setLastName($participant['last_name']);
$traveler->setBirthDate(\DateTime::createFromFormat('d.m.Y', $participant['birthday']));
$ret[] = $traveler;
}
return $ret;
}
/**
@ -990,7 +1034,7 @@ class TravelBooking
*/
public function setInsurances($insurances)
{
$this->insurances = $insurances;
$this->insurances = is_array($insurances) ? json_encode($insurances) : $insurances;
return $this;
}
@ -1002,7 +1046,12 @@ class TravelBooking
*/
public function getInsurances()
{
return $this->insurances;
$ret = json_decode($this->insurances, true);
if (empty($ret) || !is_array($ret))
{
return $this->insurances;
}
return $ret;
}
/**
@ -1014,7 +1063,7 @@ class TravelBooking
*/
public function setOptions($options)
{
$this->options = $options;
$this->options = is_array($options) ? json_encode($options) : $options;
return $this;
}
@ -1026,7 +1075,12 @@ class TravelBooking
*/
public function getOptions()
{
return $this->options;
$ret = json_decode($this->options, true);
if (empty($ret) || !is_array($ret))
{
return $this->options;
}
return $ret;
}
/**
@ -1038,7 +1092,7 @@ class TravelBooking
*/
public function setClassOptions($classOptions)
{
$this->classOptions = $classOptions;
$this->classOptions = is_array($classOptions) ? json_encode($classOptions) : $classOptions;
return $this;
}
@ -1050,7 +1104,12 @@ class TravelBooking
*/
public function getClassOptions()
{
return $this->classOptions;
$ret = json_decode($this->classOptions, true);
if (empty($ret) || !is_array($ret))
{
return $this->classOptions;
}
return $ret;
}
/**
@ -1062,7 +1121,7 @@ class TravelBooking
*/
public function setExtraCategory($extraCategory)
{
$this->extraCategory = $extraCategory;
$this->extraCategory = is_array($extraCategory) ? json_encode($extraCategory) : $extraCategory;
return $this;
}
@ -1074,7 +1133,12 @@ class TravelBooking
*/
public function getExtraCategory()
{
return $this->extraCategory;
$ret = json_decode($this->extraCategory, true);
if (empty($ret) || !is_array($ret))
{
return $this->extraCategory;
}
return $ret;
}
/**

View file

@ -0,0 +1,88 @@
<?php
namespace AppBundle\Entity;
/**
* TravelBookingRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class TravelBookingRepository extends \Doctrine\ORM\EntityRepository
{
public function createFromBookingRequest(BookingRequest $bookingRequest, TravelDate $travelDate, $bookingPriceInfo)
{
$tp = $travelDate->getTravelProgram();
$ret = new TravelBooking();
$ret->setIp($_SERVER['REMOTE_ADDR']);
$ret->setCreated(new \DateTime());
$ret->setProgramName($tp->getTitle() . ' ('. $travelDate->getName() .')');
//$ret->setClass()
$ret->setSalutation($bookingRequest->getSalutation());
$ret->setFirstName($bookingRequest->getFirstName());
$ret->setLastName($bookingRequest->getLastName());
$ret->setStreet($bookingRequest->getStreetAddress());
//$ret->setHouseNr()
$ret->setZipcode($bookingRequest->getZipCode());
$ret->setCity($bookingRequest->getCity());
$ret->setCountry($bookingRequest->getNation());
$ret->setMail($bookingRequest->getEmail());
$ret->setPhone($bookingRequest->getPhone());
$ret->setFax($bookingRequest->getFax());
$ret->setSelectedDeparture([
'name' => $bookingRequest->getDeparture()->getName(),
'extra_charge' => $bookingRequest->getDeparture()->getExtraCharge(),
'extra_charge_total' => $bookingRequest->getTravelerCount()
]);
$ret->setSelectedStartDate($travelDate->getStart());
$ret->setSelectedEndDate($travelDate->getEnd());
$ret->setSelectedAdults($bookingRequest->getTravelerCount());
$ret->setSelectedChild1(0);
$ret->setSelectedChild2(0);
$ret->setSelectedChild3(0);
$insurance = $bookingRequest->getInsurance();
$ret->setInsuranceName($insurance ? $insurance->getName() : '0'); // #TODO Adapted from v2
if (empty($bookingPriceInfo['insurances']))
{
$ret->setInsurances(false);
}
else
{
$insurances = [];
foreach ($bookingPriceInfo['insurances'] as $insuranceInfo)
{
$insurances[] = [
'count' => $insuranceInfo['count'],
'price' => $insuranceInfo['insurancePriceValue'],
'code' => $insuranceInfo['insurancePrice']->getCode()
];
}
$ret->setInsurances($insurances);
}
$ret->setParticipants(array_slice($bookingRequest->getTravelers(), 0, $bookingRequest->getTravelerCount()));
$ret->setParticipantsTotal($bookingRequest->getTravelerCount());
$ret->setRooms($bookingPriceInfo['rooms']);
$ret->setPriceTotal($bookingPriceInfo['total']);
$ret->setComments($bookingRequest->getNotes());
if (empty($bookingPriceInfo['options']))
{
$ret->setOptions(false);
}
else
{
$options = [];
foreach ($bookingPriceInfo['options'] as $option)
{
$options[] = [
'name' => $option->getName(),
'price' => $option->getPrice()
];
}
$ret->setOptions($options);
}
$ret->setClassOptions(false);
$ret->setExtraCategory(empty($bookingPriceInfo['classOptions']) ? false : $bookingPriceInfo['classOptions']);
return $ret;
}
}

View file

@ -89,12 +89,12 @@ final class TravelDate
}
$this->start = $start;
$this->index = $index;
$this->flightPeriod = $flightPeriod;
}
else
{
$this->start = $travelPeriod->getStartDate();
}
$this->flightPeriod = $flightPeriod;
$this->travelProgram = $travelPeriod->getProgram();
$this->key = $key;
$this->travelPeriod = $travelPeriod;
@ -187,6 +187,24 @@ final class TravelDate
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;
}
/**
* @return TravelPeriodPrice[]|\Doctrine\Common\Collections\Collection
*/
@ -195,31 +213,21 @@ final class TravelDate
if (!$this->calculatedEffectivePrices)
{
$this->calculatedEffectivePrices = true;
$flightPrice = $this->getFlightPrice();
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)
$price->setEffectiveComfortPrice(round($price->getPriceComfort() * $currencyFactor * $profitMargin));
$price->setEffectiveChildPrice(round($price->getPriceChildren() * $currencyFactor * $profitMargin));
}
}
return $this->travelPeriod->getPrices();
@ -255,6 +263,14 @@ final class TravelDate
return false;
}
/**
* @return TravelProgram
*/
public function getTravelProgram(): TravelProgram
{
return $this->travelProgram;
}
/**
* @return TravelPeriod
* @internal

View file

@ -139,11 +139,11 @@ class TravelDeparturePoint
/**
* Get extraCharge
*
* @return string
* @return float
*/
public function getExtraCharge()
{
return $this->extraCharge;
return ($this->extraCharge === null || $this->extraCharge === '') ? null : floatval($this->extraCharge);
}
/**

View file

@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM;
* TravelInsurancePrice
*
* @ORM\Table(name="travel_insurance_price", indexes={@ORM\Index(name="FK_travel_insurance_price_travel_insurance", columns={"insurance_id"})})
* @ORM\Entity
* @ORM\Entity(repositoryClass="AppBundle\Entity\TravelInsurancePriceRepository")
*/
class TravelInsurancePrice
{

View file

@ -0,0 +1,32 @@
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\Collection;
/**
* TravelInsurancePriceRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class TravelInsurancePriceRepository extends \Doctrine\ORM\EntityRepository
{
/**
* @param $insuranceId
* @param $assessmentBasis
*
* @return TravelInsurancePrice|null
*/
public function findOneByInsuranceIdAndAssessmentBasis($insuranceId, $assessmentBasis)
{
$qb = $this->createQueryBuilder('i');
return $qb
->where($qb->expr()->eq('IDENTITY(i.insurance)', $insuranceId))
//->where('IDENTITY(i.insurance) = '. $insuranceId)
->andWhere($qb->expr()->gte('i.border', $assessmentBasis))
->orderBy('i.border')
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
}

View file

@ -67,7 +67,8 @@ class TravelPeriodPrice
private $priceTypeId;
private $effectivePrice = null;
private $effectiveDiscountPrice = null;
private $effectiveChildPrice = null;
private $effectiveComfortPrice = null;
/**
* Set priceType
@ -199,29 +200,28 @@ class TravelPeriodPrice
return $this->period;
}
public function getDiscountPrice()
/**
* Set priceTypeId
*
* @param integer $priceTypeId
*
* @return TravelPeriodPrice
*/
public function setPriceTypeId($priceTypeId)
{
if ($this->getPeriod() == null)
{
return null;
}
// #TODO FIX! Discount calculation differs for period and program
$price = $this->price; // #TODO Is the discount calculated for the effective price or for the original price?
$newPrice = $price;
foreach ($this->getPeriod()->getDiscounts() as $discount)
{
$newPrice -= $discount->getPercent()
? round($newPrice * $discount->getValue() / 100, 2) // FIXME
: $discount->getValue();
}
$program = $this->getPeriod()->getProgram();
if ($program != null && $program->getDiscount() != null)
{
$newPrice -= $program->getDiscountIsPercentValue()
? round($price * $program->getDiscount() / 100, 2) // FIXME
: $program->getDiscount();
}
return $price == $newPrice ? null : $newPrice;
$this->priceTypeId = $priceTypeId;
return $this;
}
/**
* Get priceTypeId
*
* @return integer
*/
public function getPriceTypeId()
{
return $this->priceTypeId;
}
/**
@ -245,48 +245,92 @@ class TravelPeriodPrice
$this->effectivePrice = $effectivePrice;
}
/**
* Probably getEffectiveDiscountPrice() is the method you are actually looking for.
* @return float|null
*/
public function getDiscountPrice()
{
return $this->calculateDiscountPrice($this->price);
}
/**
* @return float
* @throws \Exception
*/
public function getEffectiveDiscountPrice()
{
if ($this->effectiveDiscountPrice === null)
if ($this->effectivePrice === null)
{
throw new \Exception('Effective discount price must be set from outside before reading it.');
throw new \Exception('Effective price must be set from outside before reading effective discount price.');
}
return $this->effectiveDiscountPrice;
return $this->calculateDiscountPrice($this->effectivePrice);
}
/**
* @param float $effectiveDiscountPrice
* @return float
* @throws \Exception
*
* @todo The child price will not be set yet. This is just a preparation for later
*/
public function setEffectiveDiscountPrice($effectiveDiscountPrice)
public function getEffectiveChildPrice()
{
$this->effectiveDiscountPrice = $effectiveDiscountPrice;
if ($this->effectiveChildPrice === null)
{
throw new \Exception('Effective child price must be set from outside before reading it.');
}
return $this->effectiveChildPrice;
}
/**
* Set priceTypeId
*
* @param integer $priceTypeId
*
* @return TravelPeriodPrice
* @param null $effectiveChildPrice
*/
public function setPriceTypeId($priceTypeId)
public function setEffectiveChildPrice($effectiveChildPrice)
{
$this->priceTypeId = $priceTypeId;
return $this;
$this->effectiveChildPrice = $effectiveChildPrice;
}
/**
* Get priceTypeId
*
* @return integer
* @return float|null
* @throws \Exception
*/
public function getPriceTypeId()
public function getEffectiveComfortPrice()
{
return $this->priceTypeId;
if ($this->effectiveComfortPrice === null)
{
throw new \Exception('Effective comfort price must be set from outside before reading it.');
}
return $this->effectiveComfortPrice;
}
/**
* @param float|null $effectiveComfortPrice
*/
public function setEffectiveComfortPrice($effectiveComfortPrice)
{
$this->effectiveComfortPrice = $effectiveComfortPrice;
}
private function calculateDiscountPrice($price)
{
if ($this->getPeriod() == null)
{
return null;
}
$newPrice = $price;
foreach ($this->getPeriod()->getDiscounts() as $discount)
{
$newPrice -= $discount->getPercent()
? round($newPrice * $discount->getValue() / 100, 2) // #TODO FIXME
: $discount->getValue();
}
$program = $this->getPeriod()->getProgram();
if ($program != null && $program->getDiscount() != null)
{
$newPrice -= $program->getDiscountIsPercentValue()
? round($price * $program->getDiscount() / 100, 2) // #TODO FIXME
: $program->getDiscount();
}
return $price == $newPrice ? null : $newPrice;
}
}

View file

@ -129,32 +129,9 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
$usedArrivalPointIds = array_keys($isUsedArrivalPointById);
// Find flight periods and related departures
$flightPeriods = [];
if (!empty($isUsedArrivalPointById))
{
$qb = $this->getEntityManager()->createQueryBuilder();
$unindexedFlightPeriods = $qb
->from('AppBundle:FlightPeriod', 'fp')
->addSelect('fp')
->leftJoin('fp.departures', 'fp_dep')
->addSelect('fp_dep')
->where('fp.startDate >= :startDate')
->andWhere('fp.endDate <= :endDate')
->andWhere($qb->expr()->in('IDENTITY(fp.travelArrivalPoint)', $usedArrivalPointIds))
->setParameter('startDate', $startDate)
->setParameter('endDate', $endDate)
->getQuery()->getResult();
// Index by CONCAT(start date, end date, arrival point id):
/** @var FlightPeriod $flightPeriod */
foreach ($unindexedFlightPeriods as $flightPeriod)
{
$flightPeriods[$flightPeriod->getStartDate()->format('Y-m-d') .
$flightPeriod->getEndDate()->format('Y-m-d') .
$flightPeriod->getTravelArrivalPoint()->getId()] = $flightPeriod;
}
}
$flightPeriods = empty($isUsedArrivalPointById) ? []
: $this->getEntityManager()->getRepository('AppBundle:FlightPeriod')
->getIndexedFlightPeriodsForTimePeriod($startDate, $endDate, $usedArrivalPointIds);
// Find default departures and classify by-program or by-arrival-point
// We could've simply left joined them to get an equal result. But we're reducing the number of rows returned
@ -253,8 +230,9 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
// Only mediated travel programs define departures in travelPeriods
$qb->leftJoin('p.departures', 'p_dep')->addSelect('p_dep');
}
else
elseif (!($flags & self::TD_QUERY_VIRTUAL))
{
// Retrieving all flight periods by join is only possible, if virtual entries are excluded
$qb->leftJoin('AppBundle:FlightPeriod', 'fp', Expr\Join::WITH, 'IDENTITY(fp.travelArrivalPoint) = '.
':travelArrivalPointId AND d.startDate = fp.startDate AND d.endDate = fp.endDate');
$qb->setParameter('travelArrivalPointId', $program->getTravelArrivalPoint()->getId());
@ -299,11 +277,19 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
->addOrderBy('p.name', 'ASC')
;
// #TODO Try to optimize this later
$entities = $qb->getQuery()->execute();
$flightPeriodByKey = [];
$flightPeriodByKey = null;
if (!$program->getIsMediated())
{
if ($flags & self::TD_QUERY_VIRTUAL)
{
// If virtual entries are included, we have to fetch all flight periods, because we don't know
// the actual dates yet
$flightPeriodByKey = $this->getEntityManager()->getRepository('AppBundle:FlightPeriod')
->getIndexedFlightPeriodsForTimePeriod($startDate, null, $program->getTravelArrivalPoint()->getId());
}
foreach ($entities as $key => $entity)
{
if ($entity == null)
@ -334,6 +320,8 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
}
}
}
//$x = array_keys($flightPeriodByKey);
//var_dump($x); die();
$this->addTravelDatesToProgram($program, $entities, $flightPeriodByKey, $startDate, null);
return $program->getTravelDates();
@ -415,6 +403,15 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
{
$flightPeriodKey = $travelDateKey .
$travelProgram->getTravelArrivalPoint()->getId();
// #DEBUG
/*
if ($travelPeriodDate->getId() . $travelPeriod->getName() . $i == '18888D8')
{
$x = array_keys($flightPeriods);
var_dump($x);
die (isset($flightPeriods[$flightPeriodKey]) ? 'ok' : 'nok');
}
*/
$flightPeriod = $flightPeriods[$flightPeriodKey] ?? null;
}
$travelProgram->addTravelDateFromSeasonTravelPeriod(
@ -443,8 +440,13 @@ class TravelPeriodRepository extends \Doctrine\ORM\EntityRepository
$flightPeriod = null;
if (!$travelProgram->getIsMediated())
{
//$x = array_keys($flightPeriods);
//var_dump($x);
//die($travelDateKey . $travelProgram->getTravelArrivalPoint()->getId());
$flightPeriod = $flightPeriods[$travelDateKey . $travelProgram->getTravelArrivalPoint()->getId()]
?? null;
//if ($travelPeriod->getName() == 'ISRA-HOE18888D8');
//die($travelPeriod->getName() .';'. $flightPeriod->getPrice());
}
// #TODO There is an error in the old backend which causes duplicates

View file

@ -0,0 +1,104 @@
<?php
/**
* @author Ulrich Hecht <ulrich.hecht@hecht-software.de>
* @date 02/10/2017
*/
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Traveler
{
// Used in SternToursCrmBookingExports, expected to be equivalent to salutation (as defined in BookingRequest)
const MALE = 1;
const FEMALE = 2;
/**
* @Assert\NotNull
* @ Assert\Choice(choices={1,2})
*/
private $sex;
/**
* @Assert\NotBlank()
*/
private $firstName;
/**
* @Assert\NotBlank()
*/
private $lastName;
/**
* @var \DateTime $birthDate
* @Assert\NotBlank()
*/
private $birthDate;
/**
* @return int
*/
public function getSex()
{
return $this->sex;
}
/**
* @param int $sex
*/
public function setSex($sex)
{
$this->sex = $sex;
}
/**
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* @param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* @param string $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* @return \DateTime
*/
public function getBirthDate()
{
return $this->birthDate;
}
/**
* @param \DateTime $birthDate
*/
public function setBirthDate($birthDate)
{
$this->birthDate = $birthDate;
}
}