156 lines
4.2 KiB
PHP
156 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Entity\Groups;
|
|
|
|
use App\Entity\TimestampableEntityInterface;
|
|
use App\Entity\TimestampableParentAwareInterface;
|
|
use App\Enum\Groups\AccommodationBookingPeriodPosition;
|
|
use Doctrine\DBAL\Types\Types;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
|
|
/**
|
|
* A stretch of nights split off the start or the end of a stay, such as the day an advance team
|
|
* arrives before the group. It carries no pax, board or services of its own and is never priced
|
|
* from the catalog: the office quotes it as free-form lines, which are added to the booking's
|
|
* total and fall under its fixed total discount. The booking's own parameters price only what
|
|
* remains between the leading and the trailing periods.
|
|
*/
|
|
#[ORM\Entity]
|
|
class AccommodationBookingPeriod implements TimestampableParentAwareInterface
|
|
{
|
|
#[ORM\Id]
|
|
#[ORM\GeneratedValue]
|
|
#[ORM\Column]
|
|
private ?int $id = null;
|
|
|
|
#[ORM\ManyToOne(inversedBy: 'periods')]
|
|
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
|
private ?AccommodationBooking $booking = null;
|
|
|
|
#[ORM\Column(length: 10, enumType: AccommodationBookingPeriodPosition::class)]
|
|
private AccommodationBookingPeriodPosition $position;
|
|
|
|
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
|
private \DateTimeImmutable $dateFrom;
|
|
|
|
// Exclusive, like the booking's: the departure day, not the last night.
|
|
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
|
|
private \DateTimeImmutable $dateTo;
|
|
|
|
/** What the price breakdown calls the period, e.g. "Vorausteam"; without one it shows the dates alone. */
|
|
#[ORM\Column(length: 255, nullable: true)]
|
|
private ?string $label = null;
|
|
|
|
/**
|
|
* Amounts in minor units of the booking's pricing currency; a line has no currency of its own.
|
|
*
|
|
* The column is not called `lines`: that is a reserved word in MariaDB, and the ORM does
|
|
* not quote column names in the statements it writes.
|
|
*
|
|
* @var list<array{label: string, amount: int}>
|
|
*/
|
|
#[ORM\Column(name: 'price_lines', type: Types::JSON)]
|
|
private array $lines = [];
|
|
|
|
public function __construct(AccommodationBookingPeriodPosition $position, \DateTimeImmutable $dateFrom, \DateTimeImmutable $dateTo)
|
|
{
|
|
$this->position = $position;
|
|
$this->dateFrom = $dateFrom;
|
|
$this->dateTo = $dateTo;
|
|
}
|
|
|
|
public function __clone()
|
|
{
|
|
$this->id = null;
|
|
$this->booking = null;
|
|
}
|
|
|
|
public function getId(): ?int
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function getBooking(): ?AccommodationBooking
|
|
{
|
|
return $this->booking;
|
|
}
|
|
|
|
public function setBooking(?AccommodationBooking $booking): self
|
|
{
|
|
$this->booking = $booking;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getTimestampableParent(): ?TimestampableEntityInterface
|
|
{
|
|
return $this->booking;
|
|
}
|
|
|
|
public function getPosition(): AccommodationBookingPeriodPosition
|
|
{
|
|
return $this->position;
|
|
}
|
|
|
|
public function isLeading(): bool
|
|
{
|
|
return AccommodationBookingPeriodPosition::Leading === $this->position;
|
|
}
|
|
|
|
public function getDateFrom(): \DateTimeImmutable
|
|
{
|
|
return $this->dateFrom;
|
|
}
|
|
|
|
public function getDateTo(): \DateTimeImmutable
|
|
{
|
|
return $this->dateTo;
|
|
}
|
|
|
|
public function setDates(\DateTimeImmutable $dateFrom, \DateTimeImmutable $dateTo): self
|
|
{
|
|
$this->dateFrom = $dateFrom;
|
|
$this->dateTo = $dateTo;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getLabel(): ?string
|
|
{
|
|
return $this->label;
|
|
}
|
|
|
|
public function setLabel(?string $label): self
|
|
{
|
|
$this->label = $label;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getNights(): int
|
|
{
|
|
return $this->dateFrom < $this->dateTo ? $this->dateFrom->diff($this->dateTo)->days : 0;
|
|
}
|
|
|
|
/** @return list<array{label: string, amount: int}> */
|
|
public function getLines(): array
|
|
{
|
|
return $this->lines;
|
|
}
|
|
|
|
/** @param list<array{label: string, amount: int}> $lines */
|
|
public function setLines(array $lines): self
|
|
{
|
|
$this->lines = $lines;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getTotal(): int
|
|
{
|
|
return array_sum(array_column($this->lines, 'amount'));
|
|
}
|
|
}
|