['food_order:read', 'food_order:latest'], ] ), new GetCollection, new Get, new Post, new Put, new Delete, ] )] #[ORM\Entity(repositoryClass: FoodOrderRepository::class)] class FoodOrder { #[Groups(['food_order:read'])] #[ORM\Column(nullable: true)] private DateTimeImmutable|null $closedAt = null; #[Groups(['food_order:read'])] #[ORM\Column(length: 255, options: [ 'default' => 'nobody', ])] private string|null $createdBy = 'nobody'; #[Groups(['food_order:read', 'food_order:latest'])] #[ORM\JoinColumn(nullable: false)] #[ORM\ManyToOne(inversedBy: 'foodOrders')] private FoodVendor|null $foodVendor = null; /** * @var Collection */ #[Groups(['food_order:read', 'food_order:latest'])] #[ORM\OneToMany(targetEntity: OrderItem::class, mappedBy: 'foodOrder', orphanRemoval: true)] private Collection $orderItems; public function __construct( #[Groups(['food_order:read'])] #[ORM\Column(type: UlidType::NAME, unique: true)] #[ORM\Id] private Ulid|null $id = new Ulid ) { $this->id ??= new Ulid; $this->orderItems = new ArrayCollection; $this->open(); } public function addOrderItem(OrderItem $orderItem): static { if (! $this->orderItems->contains($orderItem)) { $this->orderItems->add($orderItem); $orderItem->setFoodOrder($this); } return $this; } public function close(): static { return $this->setClosedAt(new DateTimeImmutable); } public function getClosedAt(): DateTimeImmutable|null { return $this->closedAt; } #[Groups(['food_order:read'])] public function getCreatedAt(): DateTimeImmutable { return $this->id->getDateTime(); } public function getCreatedBy(): string|null { return $this->createdBy; } public function getFoodVendor(): FoodVendor|null { return $this->foodVendor; } public function getId(): Ulid|null { return $this->id; } /** * @return Collection */ public function getOrderItems(): Collection { return $this->orderItems; } /** * @return Collection */ public function getOrderItemsSortedByName(): Collection { $iterator = $this->getOrderItems() ->getIterator(); $iterator->uasort( static fn(OrderItem $a, OrderItem $b): int => $a->getName() <=> $b->getName() ); return new ArrayCollection( iterator_to_array( $iterator ) ); } public function isClosed(): bool { if (! $this->closedAt instanceof DateTimeImmutable) { return false; } return $this->closedAt < new DateTimeImmutable; } public function open(): static { $this->closedAt = (new DateTimeImmutable)->add(new DateInterval('PT1H')); return $this; } public function removeOrderItem(OrderItem $orderItem): static { // set the owning side to null (unless already changed) if ($this->orderItems->removeElement($orderItem)) { $orderItem->setFoodOrder(null); } return $this; } public function setClosedAt(DateTimeImmutable|null $closedAt = null): static { $this->closedAt = $closedAt; return $this; } public function setCreatedBy(string $createdBy): static { $this->createdBy = $createdBy; return $this; } public function setFoodVendor(FoodVendor|null $foodVendor): static { $this->foodVendor = $foodVendor; return $this; } }