feat: groups price calculator admin crud, booking/offer flow and api

This commit is contained in:
Björn Fromme
2026-08-03 15:25:10 +02:00
parent eabed8295a
commit 9d2aa11fdb
258 changed files with 16231 additions and 582 deletions
+231
View File
@@ -0,0 +1,231 @@
<?php
namespace App\Entity\Groups;
use App\Entity\BlameableEntity;
use App\Entity\BlameableEntityInterface;
use App\Entity\TimestampableEntity;
use App\Entity\TimestampableEntityInterface;
use App\Repository\Groups\AccommodationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: AccommodationRepository::class)]
class Accommodation implements BlameableEntityInterface, TimestampableEntityInterface
{
use BlameableEntity;
use TimestampableEntity;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Assert\NotBlank(message: 'required')]
private ?string $name = null;
#[ORM\Column(length: 16, unique: true)]
#[Assert\NotBlank(message: 'required')]
private ?string $calendarCode = null;
#[ORM\Column(length: 16, nullable: true)]
private ?string $cmsCode = null;
/**
* @var Collection<int, AccommodationPrice>
*/
#[ORM\OneToMany(targetEntity: AccommodationPrice::class, mappedBy: 'accommodation', cascade: ['all'])]
#[ORM\OrderBy(['dateFrom' => 'ASC'])]
private Collection $accommodationPrices;
/**
* @var Collection<int, BoardService>
*/
#[ORM\OneToMany(targetEntity: BoardService::class, mappedBy: 'accommodation', cascade: ['all'])]
#[ORM\OrderBy(['dateFrom' => 'ASC', 'label' => 'ASC'])]
private Collection $boardServices;
/**
* @var Collection<int, AdditionalService>
*/
#[ORM\OneToMany(targetEntity: AdditionalService::class, mappedBy: 'accommodation', cascade: ['all'])]
#[ORM\OrderBy(['dateFrom' => 'ASC', 'label' => 'ASC'])]
private Collection $additionalServices;
#[ORM\Column]
#[Assert\NotNull(message: 'required')]
private ?int $maxAdolescentAge = null;
#[ORM\Column(length: 3)]
#[Assert\NotBlank(message: 'required')]
#[Assert\Choice(choices: ['EUR', 'CHF'], message: 'invalid')]
private ?string $currency = 'EUR';
public function __construct()
{
$this->accommodationPrices = new ArrayCollection();
$this->boardServices = new ArrayCollection();
$this->additionalServices = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getCalendarCode(): ?string
{
return $this->calendarCode;
}
public function setCalendarCode(string $calendarCode): self
{
$this->calendarCode = $calendarCode;
return $this;
}
public function getCmsCode(): ?string
{
return $this->cmsCode;
}
public function setCmsCode(?string $cmsCode): self
{
$this->cmsCode = $cmsCode;
return $this;
}
public function getEffectiveCmsCode(): string
{
return $this->cmsCode ?? $this->calendarCode;
}
/**
* @return Collection<int, AccommodationPrice>
*/
public function getAccommodationPrices(): Collection
{
return $this->accommodationPrices;
}
public function addAccommodationPrice(AccommodationPrice $accommodationPrice): self
{
if (!$this->accommodationPrices->contains($accommodationPrice)) {
$this->accommodationPrices->add($accommodationPrice);
$accommodationPrice->setAccommodation($this);
}
return $this;
}
public function removeAccommodationPrice(AccommodationPrice $accommodationPrice): self
{
if ($this->accommodationPrices->removeElement($accommodationPrice)) {
// set the owning side to null (unless already changed)
if ($accommodationPrice->getAccommodation() === $this) {
$accommodationPrice->setAccommodation(null);
}
}
return $this;
}
public function getMaxAdolescentAge(): ?int
{
return $this->maxAdolescentAge;
}
public function setMaxAdolescentAge(int $maxAdolescentAge): self
{
$this->maxAdolescentAge = $maxAdolescentAge;
return $this;
}
public function getCurrency(): ?string
{
return $this->currency;
}
public function setCurrency(string $currency): self
{
$this->currency = $currency;
return $this;
}
/**
* @return Collection<int, BoardService>
*/
public function getBoardServices(): Collection
{
return $this->boardServices;
}
public function addBoardService(BoardService $boardService): self
{
if (!$this->boardServices->contains($boardService)) {
$this->boardServices->add($boardService);
$boardService->setAccommodation($this);
}
return $this;
}
public function removeBoardService(BoardService $boardService): self
{
if ($this->boardServices->removeElement($boardService)) {
if ($boardService->getAccommodation() === $this) {
$boardService->setAccommodation(null);
}
}
return $this;
}
/**
* @return Collection<int, AdditionalService>
*/
public function getAdditionalServices(): Collection
{
return $this->additionalServices;
}
public function addAdditionalService(AdditionalService $additionalService): self
{
if (!$this->additionalServices->contains($additionalService)) {
$this->additionalServices->add($additionalService);
$additionalService->setAccommodation($this);
}
return $this;
}
public function removeAdditionalService(AdditionalService $additionalService): self
{
if ($this->additionalServices->removeElement($additionalService)) {
if ($additionalService->getAccommodation() === $this) {
$additionalService->setAccommodation(null);
}
}
return $this;
}
}
+536
View File
@@ -0,0 +1,536 @@
<?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\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]
private bool $isInquiry = false;
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
private ?\DateTimeImmutable $accessLinkIssuedAt = null;
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
private ?\DateTimeImmutable $acceptedAt = null;
#[ORM\Column(length: 255)]
private ?string $groupName = null;
#[ORM\Column(length: 10, nullable: true)]
private ?string $salutation = null;
#[ORM\Column(length: 100)]
private ?string $firstName = null;
#[ORM\Column(length: 100)]
private ?string $lastName = null;
#[ORM\Column(length: 255)]
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 isInquiry(): bool
{
return $this->isInquiry;
}
public function setIsInquiry(bool $isInquiry): self
{
$this->isInquiry = $isInquiry;
return $this;
}
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 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;
}
}
+211
View File
@@ -0,0 +1,211 @@
<?php
namespace App\Entity\Groups;
use App\Entity\BlameableEntity;
use App\Entity\BlameableEntityInterface;
use App\Entity\TimestampableEntity;
use App\Entity\TimestampableEntityInterface;
use App\Enum\Groups\PriceType;
use App\Enum\Groups\Season;
use App\Repository\Groups\AccommodationPriceRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: AccommodationPriceRepository::class)]
class AccommodationPrice implements BlameableEntityInterface, TimestampableEntityInterface
{
use BlameableEntity;
use TimestampableEntity;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(inversedBy: 'accommodationPrices')]
#[ORM\JoinColumn(nullable: false)]
private ?Accommodation $accommodation = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
#[Assert\NotNull(message: 'required')]
private ?\DateTimeImmutable $dateFrom = null;
// Inclusive: the last night this price applies.
// A booking 01.01.10.01. covers 9 nights (01.01.09.01.), 10.01. is checkout.
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
#[Assert\NotNull(message: 'required')]
#[Assert\GreaterThan(propertyPath: 'dateFrom', message: 'Das Bis-Datum muss nach dem Von-Datum liegen')]
private ?\DateTimeImmutable $dateTo = null;
#[ORM\Column(length: 20, enumType: Season::class)]
private ?Season $season = null;
#[ORM\Column]
#[Assert\NotNull(message: 'required')]
private ?int $includedPax = null;
#[ORM\Column]
#[Assert\NotNull(message: 'required')]
private ?int $pricePerNight = null;
#[ORM\Column]
#[Assert\NotNull(message: 'required')]
private ?int $priceAdditionalPerson = null;
#[ORM\Column]
#[Assert\NotNull(message: 'required')]
private ?int $minNights = null;
#[ORM\Column(length: 20, nullable: true, enumType: PriceType::class)]
private ?PriceType $type = null;
#[ORM\Column]
private bool $acceptUndersubscription = false;
#[ORM\Column]
private bool $acceptShortTerm = false;
public function __clone()
{
$this->id = null;
}
public function getId(): ?int
{
return $this->id;
}
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 getSeason(): ?Season
{
return $this->season;
}
public function setSeason(?Season $season): self
{
$this->season = $season;
return $this;
}
public function getIncludedPax(): ?int
{
return $this->includedPax;
}
public function setIncludedPax(int $includedPax): self
{
$this->includedPax = $includedPax;
return $this;
}
public function getPricePerNight(): ?int
{
return $this->pricePerNight;
}
public function setPricePerNight(int $pricePerNight): self
{
$this->pricePerNight = $pricePerNight;
return $this;
}
public function getPriceAdditionalPerson(): ?int
{
return $this->priceAdditionalPerson;
}
public function setPriceAdditionalPerson(int $priceAdditionalPerson): self
{
$this->priceAdditionalPerson = $priceAdditionalPerson;
return $this;
}
public function getMinNights(): ?int
{
return $this->minNights;
}
public function setMinNights(int $minNights): self
{
$this->minNights = $minNights;
return $this;
}
public function getType(): ?PriceType
{
return $this->type;
}
public function setType(?PriceType $type): self
{
$this->type = $type;
return $this;
}
public function isAcceptUndersubscription(): bool
{
return $this->acceptUndersubscription;
}
public function setAcceptUndersubscription(bool $acceptUndersubscription): self
{
$this->acceptUndersubscription = $acceptUndersubscription;
return $this;
}
public function isAcceptShortTerm(): bool
{
return $this->acceptShortTerm;
}
public function setAcceptShortTerm(bool $acceptShortTerm): self
{
$this->acceptShortTerm = $acceptShortTerm;
return $this;
}
}
+161
View File
@@ -0,0 +1,161 @@
<?php
namespace App\Entity\Groups;
use App\Entity\BlameableEntity;
use App\Entity\BlameableEntityInterface;
use App\Entity\TimestampableEntity;
use App\Entity\TimestampableEntityInterface;
use App\Enum\Groups\AdditionalServiceType;
use App\Repository\Groups\AdditionalServiceRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: AdditionalServiceRepository::class)]
class AdditionalService implements BlameableEntityInterface, TimestampableEntityInterface
{
use BlameableEntity;
use TimestampableEntity;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(inversedBy: 'additionalServices')]
#[ORM\JoinColumn(nullable: false)]
private ?Accommodation $accommodation = null;
#[ORM\Column(length: 255)]
#[Assert\NotBlank(message: 'required')]
private ?string $label = null;
#[ORM\Column(type: 'text', nullable: true)]
private ?string $description = null;
#[ORM\Column]
#[Assert\NotNull(message: 'required')]
private ?int $price = null;
#[ORM\Column(length: 20, enumType: AdditionalServiceType::class)]
#[Assert\NotNull(message: 'required')]
private ?AdditionalServiceType $type = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
#[Assert\NotNull(message: 'required')]
private ?\DateTimeImmutable $dateFrom = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
#[Assert\NotNull(message: 'required')]
private ?\DateTimeImmutable $dateTo = null;
#[ORM\Column(length: 128, nullable: true)]
private ?string $selectionGroup = null;
public function __clone()
{
$this->id = null;
}
public function getId(): ?int
{
return $this->id;
}
public function getAccommodation(): ?Accommodation
{
return $this->accommodation;
}
public function setAccommodation(?Accommodation $accommodation): self
{
$this->accommodation = $accommodation;
return $this;
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): self
{
$this->label = $label;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getPrice(): ?int
{
return $this->price;
}
public function setPrice(int $price): self
{
$this->price = $price;
return $this;
}
public function getType(): ?AdditionalServiceType
{
return $this->type;
}
public function setType(AdditionalServiceType $type): self
{
$this->type = $type;
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 getSelectionGroup(): ?string
{
return $this->selectionGroup;
}
public function setSelectionGroup(?string $selectionGroup): self
{
$this->selectionGroup = $selectionGroup;
return $this;
}
}
+129
View File
@@ -0,0 +1,129 @@
<?php
namespace App\Entity\Groups;
use App\Entity\BlameableEntity;
use App\Entity\BlameableEntityInterface;
use App\Entity\TimestampableEntity;
use App\Entity\TimestampableEntityInterface;
use App\Repository\Groups\BoardServiceRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity(repositoryClass: BoardServiceRepository::class)]
class BoardService implements BlameableEntityInterface, TimestampableEntityInterface
{
use BlameableEntity;
use TimestampableEntity;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(inversedBy: 'boardServices')]
#[ORM\JoinColumn(nullable: false)]
private ?Accommodation $accommodation = null;
#[ORM\Column(length: 255)]
#[Assert\NotBlank(message: 'required')]
private ?string $label = null;
#[ORM\Column(type: 'text', nullable: true)]
private ?string $description = null;
#[ORM\Column]
#[Assert\NotNull(message: 'required')]
private ?int $price = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
#[Assert\NotNull(message: 'required')]
private ?\DateTimeImmutable $dateFrom = null;
#[ORM\Column(type: Types::DATE_IMMUTABLE)]
#[Assert\NotNull(message: 'required')]
private ?\DateTimeImmutable $dateTo = null;
public function __clone()
{
$this->id = null;
}
public function getId(): ?int
{
return $this->id;
}
public function getAccommodation(): ?Accommodation
{
return $this->accommodation;
}
public function setAccommodation(?Accommodation $accommodation): self
{
$this->accommodation = $accommodation;
return $this;
}
public function getLabel(): ?string
{
return $this->label;
}
public function setLabel(string $label): self
{
$this->label = $label;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getPrice(): ?int
{
return $this->price;
}
public function setPrice(int $price): self
{
$this->price = $price;
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;
}
}