Files
myep/src/Entity/Groups/AccommodationBooking.php
T

625 lines
15 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Entity\Groups;
use App\Entity\BlameableEntity;
use App\Entity\BlameableEntityInterface;
use App\Entity\TimestampableEntity;
use App\Entity\TimestampableEntityInterface;
use App\Entity\User;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Enum\Groups\AccommodationBookingType;
use App\Enum\Groups\AdditionalServiceType;
use App\Repository\Groups\AccommodationBookingRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: AccommodationBookingRepository::class)]
class AccommodationBooking implements BlameableEntityInterface, TimestampableEntityInterface
{
use BlameableEntity;
use TimestampableEntity;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 36, unique: true)]
private string $uuid;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Accommodation $accommodation = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
private ?\DateTimeImmutable $dateFrom = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
private ?\DateTimeImmutable $dateTo = null;
#[ORM\Column]
private int $paxCount = 0;
#[ORM\Column]
private int $minorsCount = 0;
#[ORM\Column]
private int $childrenCount = 0;
#[ORM\Column(length: 255, nullable: true)]
private ?string $boardServiceLabel = null;
#[ORM\Column(nullable: true)]
private ?int $boardServicePrice = null;
#[ORM\Column(nullable: true)]
private ?int $boardServiceOriginalId = null;
/** @var list<array{label: string, price: int, type: string, originalServiceId: int|null}> */
#[ORM\Column(type: Types::JSON)]
private array $additionalServices = [];
/** @var array<string, mixed>|null */
#[ORM\Column(type: Types::JSON, nullable: true)]
private ?array $priceBreakdown = null;
#[ORM\Column(nullable: true)]
private ?int $totalPrice = null;
#[ORM\Column(length: 3, nullable: true)]
private ?string $pricingCurrency = null;
#[ORM\Column(type: Types::SMALLINT, nullable: true)]
private ?int $pricingVersion = null;
#[ORM\Column(length: 20, enumType: AccommodationBookingStatus::class)]
private AccommodationBookingStatus $status = AccommodationBookingStatus::Draft;
/**
* What kind of record this is — an offer the customer still has to accept, or a
* directly placed, binding booking. Independent of the status: an accepted offer
* keeps its Inquiry type, which is how offer-originated bookings stay recognisable.
*/
#[ORM\Column(length: 20, enumType: AccommodationBookingType::class)]
private AccommodationBookingType $type = AccommodationBookingType::Inquiry;
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
private ?\DateTimeImmutable $accessLinkIssuedAt = null;
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
private ?\DateTimeImmutable $acceptedAt = null;
/**
* When the office validated the requested services and capacities and released the
* booking confirmation to the customer — deliberately distinct from acceptedAt, which
* only records that the customer committed.
*/
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
private ?\DateTimeImmutable $confirmedAt = null;
#[ORM\Column(length: 255, nullable: true)]
#[Assert\NotBlank(groups: ['edit'])]
private ?string $groupName = null;
#[ORM\Column(length: 10, nullable: true)]
private ?string $salutation = null;
#[ORM\Column(length: 100, nullable: true)]
#[Assert\NotBlank(groups: ['edit'])]
private ?string $firstName = null;
#[ORM\Column(length: 100, nullable: true)]
#[Assert\NotBlank(groups: ['edit'])]
private ?string $lastName = null;
/**
* The `offer` group covers the one field a customer-facing booking cannot do without:
* the access link and every notification are addressed to it. It is enforced on
* creation as soon as the booking is not a draft, while `edit` additionally demands
* the rest of the contact data.
*/
#[ORM\Column(length: 255, nullable: true)]
#[Assert\NotBlank(groups: ['edit', 'offer'])]
#[Assert\Email(groups: ['edit', 'offer'])]
private ?string $email = null;
#[ORM\Column(length: 50, nullable: true)]
private ?string $phone = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $street = null;
#[ORM\Column(length: 20, nullable: true)]
private ?string $zip = null;
#[ORM\Column(length: 100, nullable: true)]
private ?string $city = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $remarks = null;
#[ORM\Column(nullable: true)]
#[Assert\Range(min: 1, max: 100)]
private ?int $accommodationDiscount = null;
#[ORM\Column(nullable: true)]
#[Assert\Range(min: 1, max: 100)]
private ?int $boardServiceDiscount = null;
#[ORM\Column(nullable: true)]
#[Assert\Range(min: 1, max: 100)]
private ?int $additionalServicesDiscount = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(onDelete: 'SET NULL')]
private ?User $managedBy = null;
public function __construct()
{
$this->uuid = Uuid::v4()->toRfc4122();
}
public function getId(): ?int
{
return $this->id;
}
public function getUuid(): string
{
return $this->uuid;
}
public function getAccommodation(): ?Accommodation
{
return $this->accommodation;
}
public function setAccommodation(?Accommodation $accommodation): self
{
$this->accommodation = $accommodation;
return $this;
}
public function getDateFrom(): ?\DateTimeImmutable
{
return $this->dateFrom;
}
public function setDateFrom(\DateTimeImmutable $dateFrom): self
{
$this->dateFrom = $dateFrom;
return $this;
}
public function getDateTo(): ?\DateTimeImmutable
{
return $this->dateTo;
}
public function setDateTo(\DateTimeImmutable $dateTo): self
{
$this->dateTo = $dateTo;
return $this;
}
public function getNights(): int
{
if (null === $this->dateFrom || null === $this->dateTo) {
return 0;
}
return $this->dateFrom->diff($this->dateTo)->days;
}
public function getPaxCount(): int
{
return $this->paxCount;
}
public function setPaxCount(int $paxCount): self
{
$this->paxCount = $paxCount;
return $this;
}
public function getMinorsCount(): int
{
return $this->minorsCount;
}
public function setMinorsCount(int $minorsCount): self
{
$this->minorsCount = $minorsCount;
return $this;
}
public function getChildrenCount(): int
{
return $this->childrenCount;
}
public function setChildrenCount(int $childrenCount): self
{
$this->childrenCount = $childrenCount;
return $this;
}
public function getBoardServiceLabel(): ?string
{
return $this->boardServiceLabel;
}
public function setBoardServiceLabel(?string $boardServiceLabel): self
{
$this->boardServiceLabel = $boardServiceLabel;
return $this;
}
public function getBoardServicePrice(): ?int
{
return $this->boardServicePrice;
}
public function setBoardServicePrice(?int $boardServicePrice): self
{
$this->boardServicePrice = $boardServicePrice;
return $this;
}
public function getBoardServiceOriginalId(): ?int
{
return $this->boardServiceOriginalId;
}
public function setBoardServiceOriginalId(?int $boardServiceOriginalId): self
{
$this->boardServiceOriginalId = $boardServiceOriginalId;
return $this;
}
/** @return list<array{label: string, price: int, type: string, originalServiceId: int|null}> */
public function getAdditionalServices(): array
{
return $this->additionalServices;
}
/** @param list<array{label: string, price: int, type: string, originalServiceId: int|null}> $additionalServices */
public function setAdditionalServices(array $additionalServices): self
{
$this->additionalServices = $additionalServices;
return $this;
}
public function addAdditionalServiceSnapshot(string $label, int $price, AdditionalServiceType|string $type, ?int $originalServiceId): self
{
$this->additionalServices[] = [
'label' => $label,
'price' => $price,
'type' => $type instanceof AdditionalServiceType ? $type->value : $type,
'originalServiceId' => $originalServiceId,
];
return $this;
}
/** @return array<string, mixed>|null */
public function getPriceBreakdown(): ?array
{
return $this->priceBreakdown;
}
/** @param array<string, mixed> $priceBreakdown */
public function setPriceSnapshot(array $priceBreakdown, int $totalPrice, string $currency, int $version): self
{
$this->priceBreakdown = $priceBreakdown;
$this->totalPrice = $totalPrice;
$this->pricingCurrency = $currency;
$this->pricingVersion = $version;
return $this;
}
public function clearPriceSnapshot(): self
{
$this->priceBreakdown = null;
$this->totalPrice = null;
$this->pricingCurrency = null;
$this->pricingVersion = null;
return $this;
}
public function getTotalPrice(): ?int
{
return $this->totalPrice;
}
public function getPricingCurrency(): ?string
{
return $this->pricingCurrency;
}
public function getPricingVersion(): ?int
{
return $this->pricingVersion;
}
public function getStatus(): AccommodationBookingStatus
{
return $this->status;
}
public function setStatus(AccommodationBookingStatus $status): self
{
$this->status = $status;
return $this;
}
public function isDraft(): bool
{
return AccommodationBookingStatus::Draft === $this->status;
}
public function isOpen(): bool
{
return AccommodationBookingStatus::Open === $this->status;
}
public function isReceived(): bool
{
return AccommodationBookingStatus::Received === $this->status;
}
public function isConfirmed(): bool
{
return AccommodationBookingStatus::Confirmed === $this->status;
}
public function isDiscarded(): bool
{
return AccommodationBookingStatus::Discarded === $this->status;
}
public function getType(): AccommodationBookingType
{
return $this->type;
}
public function setType(AccommodationBookingType $type): self
{
$this->type = $type;
return $this;
}
public function isInquiry(): bool
{
return AccommodationBookingType::Inquiry === $this->type;
}
public function isBooking(): bool
{
return AccommodationBookingType::Booking === $this->type;
}
public function getAccessLinkIssuedAt(): ?\DateTimeImmutable
{
return $this->accessLinkIssuedAt;
}
public function setAccessLinkIssuedAt(?\DateTimeImmutable $accessLinkIssuedAt): self
{
$this->accessLinkIssuedAt = $accessLinkIssuedAt;
return $this;
}
public function getAcceptedAt(): ?\DateTimeImmutable
{
return $this->acceptedAt;
}
public function setAcceptedAt(?\DateTimeImmutable $acceptedAt): self
{
$this->acceptedAt = $acceptedAt;
return $this;
}
public function getConfirmedAt(): ?\DateTimeImmutable
{
return $this->confirmedAt;
}
public function setConfirmedAt(?\DateTimeImmutable $confirmedAt): self
{
$this->confirmedAt = $confirmedAt;
return $this;
}
public function getGroupName(): ?string
{
return $this->groupName;
}
public function setGroupName(?string $groupName): self
{
$this->groupName = $groupName;
return $this;
}
public function getSalutation(): ?string
{
return $this->salutation;
}
public function setSalutation(?string $salutation): self
{
$this->salutation = $salutation;
return $this;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(?string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(?string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(?string $phone): self
{
$this->phone = $phone;
return $this;
}
public function getStreet(): ?string
{
return $this->street;
}
public function setStreet(?string $street): self
{
$this->street = $street;
return $this;
}
public function getZip(): ?string
{
return $this->zip;
}
public function setZip(?string $zip): self
{
$this->zip = $zip;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(?string $city): self
{
$this->city = $city;
return $this;
}
public function getRemarks(): ?string
{
return $this->remarks;
}
public function setRemarks(?string $remarks): self
{
$this->remarks = $remarks;
return $this;
}
public function getAccommodationDiscount(): ?int
{
return $this->accommodationDiscount;
}
public function setAccommodationDiscount(?int $accommodationDiscount): self
{
$this->accommodationDiscount = $accommodationDiscount;
return $this;
}
public function getBoardServiceDiscount(): ?int
{
return $this->boardServiceDiscount;
}
public function setBoardServiceDiscount(?int $boardServiceDiscount): self
{
$this->boardServiceDiscount = $boardServiceDiscount;
return $this;
}
public function getAdditionalServicesDiscount(): ?int
{
return $this->additionalServicesDiscount;
}
public function setAdditionalServicesDiscount(?int $additionalServicesDiscount): self
{
$this->additionalServicesDiscount = $additionalServicesDiscount;
return $this;
}
public function getManagedBy(): ?User
{
return $this->managedBy;
}
public function setManagedBy(?User $managedBy): self
{
$this->managedBy = $managedBy;
return $this;
}
}