ratzen
This commit is contained in:
parent
203233d2ed
commit
93fa2da696
45 changed files with 2633 additions and 550 deletions
|
@ -5,13 +5,12 @@ namespace App\Controller;
|
|||
use App\Entity\FoodOrder;
|
||||
use App\Entity\MenuItem;
|
||||
use App\Entity\OrderItem;
|
||||
use App\Form\FoodOrderType;
|
||||
use App\Repository\FoodOrderRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use DateTimeImmutable;
|
||||
|
||||
#[Route('/order')]
|
||||
class FoodOrderController extends AbstractController
|
||||
|
@ -20,82 +19,48 @@ class FoodOrderController extends AbstractController
|
|||
|
||||
final public const APP_FOODORDER_ADD_ITEM = 'app_foodorder_add_item';
|
||||
|
||||
#[Route('/', name: 'app_food_order_index', methods: ['GET'])]
|
||||
public function index(FoodOrderRepository $foodOrderRepository): Response
|
||||
{
|
||||
return $this->render(
|
||||
'food_order/index.html.twig',
|
||||
[
|
||||
'food_orders' => $foodOrderRepository->findAll(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[Route(
|
||||
'/new',
|
||||
name: 'app_food_order_new',
|
||||
methods: [Request::METHOD_GET, Request::METHOD_POST],
|
||||
)]
|
||||
public function new(
|
||||
Request $request,
|
||||
EntityManagerInterface $entityManager,
|
||||
): Response {
|
||||
$foodOrder = new FoodOrder;
|
||||
$form = $this->createForm(FoodOrderType::class, $foodOrder);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->persist($foodOrder);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute(
|
||||
'app_food_order_index',
|
||||
[],
|
||||
Response::HTTP_SEE_OTHER,
|
||||
);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'food_order/new.html.twig',
|
||||
[
|
||||
'food_order' => $foodOrder,
|
||||
'form' => $form,
|
||||
],
|
||||
);
|
||||
}
|
||||
final public const APP_FOODORDER_CLOSE = 'app_foodorder_close';
|
||||
|
||||
#[Route('/{id}', name: self::APP_FOOD_ORDER_SHOW, methods: ['GET'])]
|
||||
public function show(FoodOrder $foodOrder): Response
|
||||
{
|
||||
$menuItems = $foodOrder->vendor->menuItems;
|
||||
return $this->render(
|
||||
'food_order/show.html.twig',
|
||||
[
|
||||
'food_order' => $foodOrder,
|
||||
'menu_items' => $menuItems,
|
||||
'menu_items' => $foodOrder->getVendor()->getMenuItems(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/close/{id}', name: self::APP_FOODORDER_CLOSE, methods: ['GET'])]
|
||||
public function close(
|
||||
FoodOrder $foodOrder,
|
||||
EntityManagerInterface $entityManager,
|
||||
): Response {
|
||||
$foodOrder->setClosedAt();
|
||||
$entityManager->persist($foodOrder);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute(
|
||||
self::APP_FOOD_ORDER_SHOW,
|
||||
[
|
||||
'id' => $foodOrder->getId(),
|
||||
],
|
||||
Response::HTTP_SEE_OTHER,
|
||||
);
|
||||
}
|
||||
|
||||
#[Route(
|
||||
'/{foodOrder}/add/{menuItem}',
|
||||
'/{foodOrder}/add',
|
||||
name: self::APP_FOODORDER_ADD_ITEM,
|
||||
methods: [Request::METHOD_GET],
|
||||
methods: [Request::METHOD_GET, Request::METHOD_POST],
|
||||
)]
|
||||
public function add(
|
||||
FoodOrder $foodOrder,
|
||||
MenuItem $menuItem,
|
||||
EntityManagerInterface $entityManager,
|
||||
): Response {
|
||||
$orderItem = new OrderItem(foodOrder: $foodOrder, menuItem: $menuItem);
|
||||
$entityManager->persist($orderItem);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute(
|
||||
self::APP_FOOD_ORDER_SHOW,
|
||||
[
|
||||
'id' => $foodOrder->id,
|
||||
],
|
||||
Response::HTTP_SEE_OTHER,
|
||||
);
|
||||
return new Response('lol');
|
||||
}
|
||||
|
||||
#[Route(
|
||||
|
@ -118,50 +83,4 @@ class FoodOrderController extends AbstractController
|
|||
Response::HTTP_SEE_OTHER,
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/{id}/edit', name: 'app_food_order_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(
|
||||
Request $request,
|
||||
FoodOrder $foodOrder,
|
||||
EntityManagerInterface $entityManager,
|
||||
): Response {
|
||||
$form = $this->createForm(FoodOrderType::class, $foodOrder);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute(''[], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'food_order/edit.html.twig',
|
||||
[
|
||||
'food_order' => $foodOrder,
|
||||
'form' => $form,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/{id}', name: 'app_food_order_delete', methods: ['POST'])]
|
||||
public function delete(
|
||||
Request $request,
|
||||
FoodOrder $foodOrder,
|
||||
EntityManagerInterface $entityManager,
|
||||
): Response {
|
||||
if (
|
||||
$this->isCsrfTokenValid(
|
||||
'delete' . $foodOrder->id ?? '',
|
||||
$request->request->get('_token'),
|
||||
)
|
||||
) {
|
||||
$entityManager->remove($foodOrder);
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute(
|
||||
'app_food_order_index',
|
||||
[],
|
||||
Response::HTTP_SEE_OTHER,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,25 +2,28 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\FoodOrder;
|
||||
use App\Form\FoodOrderType;
|
||||
use App\Repository\FoodOrderRepository;
|
||||
use App\Service\WhoAreYou;
|
||||
use App\Entity\FoodOrder;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\HttpFoundation\Cookie;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
final class Start extends AbstractController
|
||||
{
|
||||
#[Route('/')]
|
||||
#[Route('/', name: 'app_index')]
|
||||
public function index(
|
||||
FoodOrderRepository $foodOrderRepository,
|
||||
EntityManagerInterface $em,
|
||||
Request $request,
|
||||
): Response {
|
||||
$openOrders = $foodOrderRepository->findOpen();
|
||||
$order = new FoodOrder('');
|
||||
$openOrders = $foodOrderRepository->findOpenOrders();
|
||||
$order = new FoodOrder();
|
||||
$form = $this->createForm(FoodOrderType::class, $order);
|
||||
$form->handleRequest($request);
|
||||
|
||||
|
@ -28,8 +31,10 @@ final class Start extends AbstractController
|
|||
$em->persist($order);
|
||||
$em->flush();
|
||||
return $this->redirectToRoute(
|
||||
'app_food_order_index',
|
||||
[],
|
||||
FoodOrderController::APP_FOOD_ORDER_SHOW,
|
||||
[
|
||||
'id' => $order->getId(),
|
||||
],
|
||||
Response::HTTP_SEE_OTHER,
|
||||
);
|
||||
}
|
||||
|
@ -42,4 +47,31 @@ final class Start extends AbstractController
|
|||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[Route(
|
||||
'/name',
|
||||
name: 'app_name',
|
||||
methods: [Request::METHOD_GET, Request::METHOD_POST],
|
||||
)]
|
||||
public function name(Request $request, WhoAreYou $who): Response
|
||||
{
|
||||
$form = $this
|
||||
->createFormBuilder()
|
||||
->add('name', TextType::class, [
|
||||
'data' => $who->username,
|
||||
])
|
||||
->getForm();
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$name = $form->getData()['name'];
|
||||
$response = $this->redirectToRoute('app_index');
|
||||
$response->headers->setCookie(new Cookie('username', $name));
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $this->render('start/name.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Vendor;
|
||||
use App\Form\VendorType;
|
||||
use App\Repository\VendorRepository;
|
||||
use App\Entity\Vendor;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
|
42
src/DataFixtures/AppFixture.php
Normal file
42
src/DataFixtures/AppFixture.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\DataFixtures;
|
||||
|
||||
use App\Entity\MenuItem;
|
||||
use App\Entity\MenuItemAlias;
|
||||
use App\Entity\Vendor;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Generator;
|
||||
|
||||
final class AppFixture extends Fixture
|
||||
{
|
||||
private Generator $faker;
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
$this->faker = \Faker\Factory::create();
|
||||
foreach (range(0, 20) as $vendorCount) {
|
||||
$vendor = new Vendor();
|
||||
$vendor->setName($this->faker->name);
|
||||
$manager->persist($vendor);
|
||||
|
||||
foreach (range(0, 10) as $itemCount) {
|
||||
$menuItem = new MenuItem();
|
||||
$menuItem->setVendor($vendor);
|
||||
$menuItem->setPrice(random_int(500, 2000));
|
||||
$manager->persist($menuItem);
|
||||
$menuItemAliasOne = new MenuItemAlias();
|
||||
$menuItemAliasOne->setName($this->faker->word);
|
||||
$menuItem->addMenuItemAlias($menuItemAliasOne);
|
||||
$manager->persist($menuItemAliasOne);
|
||||
$menuItemAliasTwo = new MenuItemAlias();
|
||||
$menuItemAliasTwo->setName($this->faker->word);
|
||||
$menuItem->addMenuItemAlias($menuItemAliasTwo);
|
||||
$manager->persist($menuItemAliasTwo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\DataFixtures;
|
||||
|
||||
use App\Entity\MenuItem;
|
||||
use App\Entity\MenuItemAlias;
|
||||
use App\Entity\Vendor;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Factory;
|
||||
use Faker\Generator;
|
||||
use Override;
|
||||
|
||||
use function random_int;
|
||||
use function range;
|
||||
|
||||
class AppFixtures extends Fixture
|
||||
{
|
||||
private readonly Generator $faker;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->faker = Factory::create();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
foreach (range(0, 10) as $counter) {
|
||||
$vendor = new Vendor(name: $this->faker->company());
|
||||
$this->addMenuItemsToVendor($vendor, $manager);
|
||||
$manager->persist($vendor);
|
||||
}
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
private function addMenuItemsToVendor(Vendor $vendor, ObjectManager $manager): void
|
||||
{
|
||||
foreach (range(0, 100) as $counter) {
|
||||
$aliasOne = MenuItemAlias::new($this->faker->lastName());
|
||||
$aliasTwo = MenuItemAlias::new($this->faker->lastName());
|
||||
$manager->persist($aliasOne);
|
||||
$manager->persist($aliasTwo);
|
||||
$item = MenuItem::new([$aliasOne, $aliasTwo]);
|
||||
$item->price = random_int(500, 2000);
|
||||
$manager->persist($item);
|
||||
$vendor->addMenuItem($item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +1,105 @@
|
|||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\FoodOrderRepository;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UlidType;
|
||||
use Symfony\Component\Uid\Ulid;
|
||||
use DateTimeImmutable;
|
||||
|
||||
#[ORM\Entity(repositoryClass: FoodOrderRepository::class)]
|
||||
class FoodOrder
|
||||
{
|
||||
public function __construct(
|
||||
#[ORM\Column]
|
||||
public string $startedByName,
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
public Ulid $id = new Ulid,
|
||||
#[ORM\Column(nullable: true)]
|
||||
public DateTimeImmutable|null $closedAt = null,
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
private Ulid $id;
|
||||
|
||||
/** @var Collection<int, OrderItem> $orderItems */
|
||||
#[ORM\OneToMany(
|
||||
mappedBy: 'foodOrder',
|
||||
targetEntity: OrderItem::class,
|
||||
orphanRemoval: true,
|
||||
)]
|
||||
public Collection $orderItems = new ArrayCollection,
|
||||
#[ORM\ManyToOne(inversedBy: 'foodOrders')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
public Vendor|null $vendor = null,
|
||||
#[ORM\Column]
|
||||
public DateTimeImmutable $startedAt = new DateTimeImmutable,
|
||||
)
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?DateTimeImmutable $closedAt = null;
|
||||
|
||||
#[ORM\Column(length: 30)]
|
||||
private string|null $startedBy = null;
|
||||
|
||||
#[ORM\Column]
|
||||
private DateTimeImmutable $startedAt;
|
||||
|
||||
#[ORM\OneToMany(
|
||||
mappedBy: 'foodOrder',
|
||||
targetEntity: OrderItem::class,
|
||||
orphanRemoval: true,
|
||||
)]
|
||||
private Collection $orderItems;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Vendor $vendor = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->id = new Ulid;
|
||||
$this->orderItems = new ArrayCollection;
|
||||
$this->startedAt = new DateTimeImmutable;
|
||||
}
|
||||
|
||||
public function getId(): Ulid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getClosedAt(): \DateTimeImmutable|null
|
||||
{
|
||||
return $this->closedAt;
|
||||
}
|
||||
|
||||
public function setClosedAt(\DateTimeImmutable $closedAt = new DateTimeImmutable()): static
|
||||
{
|
||||
$this->closedAt = $closedAt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStartedBy(): string|null
|
||||
{
|
||||
return $this->startedBy;
|
||||
}
|
||||
|
||||
public function setStartedBy(string $startedBy): static
|
||||
{
|
||||
$this->startedBy = $startedBy;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getStartedAt(): \DateTimeImmutable
|
||||
{
|
||||
return $this->startedAt;
|
||||
}
|
||||
|
||||
public function setStartedAt(\DateTimeImmutable $startedAt): static
|
||||
{
|
||||
$this->startedAt = $startedAt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, OrderItem>
|
||||
*/
|
||||
public function getOrderItems(): Collection
|
||||
{
|
||||
return $this->orderItems;
|
||||
}
|
||||
|
||||
public function addOrderItem(OrderItem $orderItem): static
|
||||
{
|
||||
if (!$this->orderItems->contains($orderItem)) {
|
||||
if (! $this->orderItems->contains($orderItem)) {
|
||||
$this->orderItems->add($orderItem);
|
||||
$orderItem->foodOrder = $this;
|
||||
$orderItem->setFoodOrder($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -56,19 +110,31 @@ class FoodOrder
|
|||
// set the owning side to null (unless already changed)
|
||||
if (
|
||||
$this->orderItems->removeElement($orderItem)
|
||||
&& $orderItem->foodOrder === $this
|
||||
&& $orderItem->getFoodOrder() === $this
|
||||
) {
|
||||
$orderItem->foodOrder = null;
|
||||
$orderItem->setFoodOrder(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVendor(): ?Vendor
|
||||
{
|
||||
return $this->vendor;
|
||||
}
|
||||
|
||||
public function setVendor(?Vendor $vendor): static
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function groupedOrderItems(): array
|
||||
{
|
||||
return $this->orderItems->reduce(
|
||||
function (array $carry, OrderItem $item): array {
|
||||
$menuItemStringId = (string)$item->menuItem->id;
|
||||
$menuItemStringId = (string)$item->getMenuItem()->getId();
|
||||
if (isset($carry[$menuItemStringId])) {
|
||||
$carry[$menuItemStringId]['amount']++;
|
||||
} else {
|
||||
|
@ -82,4 +148,6 @@ class FoodOrder
|
|||
[]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,55 +13,87 @@ use Symfony\Component\Uid\Ulid;
|
|||
#[ORM\Entity(repositoryClass: MenuItemRepository::class)]
|
||||
class MenuItem
|
||||
{
|
||||
public function __construct(
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
public Ulid $id = new Ulid,
|
||||
#[ORM\ManyToOne(inversedBy: 'menuItems')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
public Vendor|null $vendor = null,
|
||||
#[ORM\Column(nullable: true)]
|
||||
public int|null $price = null,
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
private Ulid $id;
|
||||
|
||||
/** @var Collection<int, MenuItemAlias> $aliases */
|
||||
#[ORM\OneToMany(
|
||||
mappedBy: 'menuItem',
|
||||
targetEntity: MenuItemAlias::class,
|
||||
orphanRemoval: true,
|
||||
)]
|
||||
public Collection $aliases = new ArrayCollection,
|
||||
) {}
|
||||
#[ORM\ManyToOne(inversedBy: 'menuItems')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Vendor $vendor;
|
||||
|
||||
public function addAlias(MenuItemAlias $alias): static
|
||||
#[ORM\Column]
|
||||
private int $price;
|
||||
|
||||
#[ORM\OneToMany(
|
||||
mappedBy: 'menuItem',
|
||||
targetEntity: MenuItemAlias::class,
|
||||
orphanRemoval: true,
|
||||
)]
|
||||
private Collection $menuItemAliases;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->aliases->contains($alias)) {
|
||||
$this->aliases->add($alias);
|
||||
$alias->menuItem = $this;
|
||||
}
|
||||
|
||||
return false;
|
||||
$this->id = new Ulid;
|
||||
$this->menuItemAliases = new ArrayCollection;
|
||||
}
|
||||
|
||||
public function removeAlias(MenuItemAlias $alias): static
|
||||
public function getId(): Ulid
|
||||
{
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($this->aliases->removeElement($alias) && $alias->menuItem === $this) {
|
||||
$alias->menuItem = null;
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getVendor(): Vendor
|
||||
{
|
||||
return $this->vendor;
|
||||
}
|
||||
|
||||
public function setVendor(Vendor$vendor): static
|
||||
{
|
||||
$this->vendor = $vendor;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPrice(): int|null
|
||||
{
|
||||
return $this->price;
|
||||
}
|
||||
|
||||
public function setPrice(int $price): static
|
||||
{
|
||||
$this->price = $price;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, MenuItemAlias>
|
||||
*/
|
||||
public function getMenuItemAliases(): Collection
|
||||
{
|
||||
return $this->menuItemAliases;
|
||||
}
|
||||
|
||||
public function addMenuItemAlias(MenuItemAlias $menuItemAlias): static
|
||||
{
|
||||
if (! $this->menuItemAliases->contains($menuItemAlias)) {
|
||||
$this->menuItemAliases->add($menuItemAlias);
|
||||
$menuItemAlias->setMenuItem($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function new(array $aliases): self
|
||||
public function removeMenuItemAlias(MenuItemAlias $menuItemAlias): static
|
||||
{
|
||||
$menuItem = new self;
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
$menuItem->addAlias($alias);
|
||||
// set the owning side to null (unless already changed)
|
||||
if (
|
||||
$this->menuItemAliases->removeElement($menuItemAlias)
|
||||
&& $menuItemAlias->getMenuItem() === $this
|
||||
) {
|
||||
$menuItemAlias->setMenuItem(null);
|
||||
}
|
||||
|
||||
return $menuItem;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
|
@ -11,23 +12,48 @@ use Symfony\Component\Uid\Ulid;
|
|||
#[ORM\Entity(repositoryClass: MenuItemAliasRepository::class)]
|
||||
class MenuItemAlias
|
||||
{
|
||||
public function __construct(
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
public Ulid $id = new Ulid,
|
||||
#[ORM\ManyToOne(inversedBy: 'aliases')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
public MenuItem|null $menuItem = null,
|
||||
#[ORM\Column(length: 255)]
|
||||
public string|null $name = null,
|
||||
) {}
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
private Ulid $id;
|
||||
|
||||
public static function new(string $name): self
|
||||
#[ORM\Column(length: 50)]
|
||||
private string|null $name = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'menuItemAliases')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private MenuItem|null $menuItem = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$new = new self;
|
||||
$new->name = $name;
|
||||
return $new;
|
||||
$this->id = new Ulid;
|
||||
}
|
||||
|
||||
public function getId(): Ulid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string|null
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMenuItem(): MenuItem|null
|
||||
{
|
||||
return $this->menuItem;
|
||||
}
|
||||
|
||||
public function setMenuItem(MenuItem|null $menuItem): static
|
||||
{
|
||||
$this->menuItem = $menuItem;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,17 +11,49 @@ use Symfony\Component\Uid\Ulid;
|
|||
#[ORM\Entity(repositoryClass: OrderItemRepository::class)]
|
||||
class OrderItem
|
||||
{
|
||||
public function __construct(
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
public Ulid $id = new Ulid,
|
||||
#[ORM\ManyToOne(inversedBy: 'orderItems')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
public FoodOrder|null $foodOrder = null,
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
public MenuItem|null $menuItem = null,
|
||||
) {}
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
private Ulid $id;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'orderItems')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private FoodOrder|null $foodOrder = null;
|
||||
|
||||
#[ORM\OneToOne(cascade: ['persist', 'remove'])]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private MenuItem|null $menuItem = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->id = new Ulid;
|
||||
}
|
||||
|
||||
public function getId(): Ulid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getFoodOrder(): FoodOrder|null
|
||||
{
|
||||
return $this->foodOrder;
|
||||
}
|
||||
|
||||
public function setFoodOrder(FoodOrder|null $foodOrder): static
|
||||
{
|
||||
$this->foodOrder = $foodOrder;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMenuItem(): MenuItem|null
|
||||
{
|
||||
return $this->menuItem;
|
||||
}
|
||||
|
||||
public function setMenuItem(MenuItem $menuItem): static
|
||||
{
|
||||
$this->menuItem = $menuItem;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
|
@ -13,33 +14,58 @@ use Symfony\Component\Uid\Ulid;
|
|||
#[ORM\Entity(repositoryClass: VendorRepository::class)]
|
||||
class Vendor
|
||||
{
|
||||
public function __construct(
|
||||
#[ORM\Column]
|
||||
public string $name,
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
public Ulid $id = new Ulid,
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\Column(type: UlidType::NAME, unique: true)]
|
||||
#[ORM\CustomIdGenerator(class: UlidGenerator::class)]
|
||||
private Ulid $id;
|
||||
|
||||
/** @var Collection<int, MenuItem> $menuItems */
|
||||
#[ORM\OneToMany(mappedBy: 'vendor', targetEntity: MenuItem::class)]
|
||||
public Collection $menuItems = new ArrayCollection,
|
||||
#[ORM\Column(length: 50)]
|
||||
private string|null $name = null;
|
||||
|
||||
/** @var Collection<int, FoodOrder> $foodOrders */
|
||||
#[ORM\OneToMany(
|
||||
mappedBy: 'vendor',
|
||||
targetEntity: FoodOrder::class,
|
||||
orphanRemoval: true,
|
||||
)]
|
||||
private Collection $foodOrders = new ArrayCollection,
|
||||
) {}
|
||||
#[ORM\OneToMany(
|
||||
mappedBy: 'vendor',
|
||||
targetEntity: MenuItem::class,
|
||||
orphanRemoval: true,
|
||||
)]
|
||||
private Collection $menuItems;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->id = new Ulid;
|
||||
$this->menuItems = new ArrayCollection;
|
||||
}
|
||||
|
||||
public function getId(): Ulid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string|null
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, MenuItem>
|
||||
*/
|
||||
public function getMenuItems(): Collection
|
||||
{
|
||||
return $this->menuItems;
|
||||
}
|
||||
|
||||
public function addMenuItem(MenuItem $menuItem): static
|
||||
{
|
||||
if (! $this->menuItems->contains($menuItem)) {
|
||||
$this->menuItems->add($menuItem);
|
||||
$menuItem->vendor = $this;
|
||||
$menuItem->setVendor($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -48,29 +74,11 @@ class Vendor
|
|||
public function removeMenuItem(MenuItem $menuItem): static
|
||||
{
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($this->menuItems->removeElement($menuItem) && $menuItem->vendor === $this) {
|
||||
$menuItem->vendor = null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addFoodOrder(FoodOrder $foodOrder): static
|
||||
{
|
||||
if (! $this->foodOrders->contains($foodOrder)) {
|
||||
$this->foodOrders->add($foodOrder);
|
||||
$foodOrder->vendor = $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeFoodOrder(FoodOrder $foodOrder): static
|
||||
{
|
||||
if (
|
||||
$this->foodOrders->removeElement($foodOrder) && $foodOrder->vendor === $this
|
||||
$this->menuItems->removeElement($menuItem)
|
||||
&& $menuItem->getVendor() === $this
|
||||
) {
|
||||
$foodOrder->vendor = null;
|
||||
$menuItem->setVendor(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
|
|
@ -2,21 +2,29 @@
|
|||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Service\WhoAreYou;
|
||||
use App\Entity\FoodOrder;
|
||||
use App\Entity\Vendor;
|
||||
use Override;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class FoodOrderType extends AbstractType
|
||||
{
|
||||
public function __construct(
|
||||
private readonly WhoAreYou $who
|
||||
) {}
|
||||
|
||||
#[Override]
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('startedByName')
|
||||
->add('startedBy', TextType::class, [
|
||||
'data' => $this->who->username,
|
||||
])
|
||||
->add(
|
||||
'vendor',
|
||||
EntityType::class,
|
||||
|
|
35
src/Form/OrderItemType.php
Normal file
35
src/Form/OrderItemType.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\FoodOrder;
|
||||
use App\Entity\MenuItem;
|
||||
use App\Entity\OrderItem;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class OrderItemType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('foodOrder', EntityType::class, [
|
||||
'class' => FoodOrder::class,
|
||||
'choice_label' => 'id',
|
||||
])
|
||||
->add('menuItem', EntityType::class, [
|
||||
'class' => MenuItem::class,
|
||||
'choice_label' => 'id',
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => OrderItem::class,
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -1,12 +1,10 @@
|
|||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\FoodOrder;
|
||||
use DateTime;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
|
@ -25,17 +23,13 @@ class FoodOrderRepository extends ServiceEntityRepository
|
|||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, FoodOrder>
|
||||
* @return FoodOrder[] Returns an array of FoodOrder objects
|
||||
*/
|
||||
public function findOpen(int $limit = 10): Collection
|
||||
public function findOpenOrders(): array
|
||||
{
|
||||
$yesterday = new DateTime;
|
||||
$yesterday->modify('-1 day');
|
||||
$queryBuilder = $this->createQueryBuilder('e');
|
||||
$queryBuilder
|
||||
->where('e.closedAt IS NULL')
|
||||
->andWhere($queryBuilder->expr()->gte('e.startedAt', ':yesterday'))
|
||||
->setParameter('yesterday', $yesterday);
|
||||
return new ArrayCollection($queryBuilder->getQuery()->getResult());
|
||||
return $this->createQueryBuilder('f')
|
||||
->andWhere('f.closedAt IS NULL')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
|
|
29
src/Service/WhoAreYou.php
Normal file
29
src/Service/WhoAreYou.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Override;
|
||||
use Stringable;
|
||||
use Symfony\Bridge\Twig\AppVariable;
|
||||
|
||||
final class WhoAreYou implements Stringable
|
||||
{
|
||||
public string $username = '';
|
||||
|
||||
public function __construct(AppVariable $appVariable)
|
||||
{
|
||||
$this->username = $appVariable->getRequest()?->cookies?->get('username', '')
|
||||
?? '';
|
||||
}
|
||||
|
||||
public function isKnown(): bool
|
||||
{
|
||||
return $this->username !== '';
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
}
|
26
src/Twig/AppExtension.php
Normal file
26
src/Twig/AppExtension.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Twig;
|
||||
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
use function number_format;
|
||||
|
||||
use Override;
|
||||
|
||||
final class AppExtension extends AbstractExtension
|
||||
{
|
||||
#[Override]
|
||||
public function getFilters(): array
|
||||
{
|
||||
return [new TwigFilter('cents_to_eur', $this->formatCentsToEur(...))];
|
||||
}
|
||||
|
||||
public function formatCentsToEur(int $cents): string
|
||||
{
|
||||
$euros = $cents / 100;
|
||||
return number_format($euros, 2, ',', '') . ' EUR';
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue