wiederaufbau

This commit is contained in:
Jonas 2024-03-17 21:05:03 +01:00
parent fe9820ef4b
commit 72ded82226
9 changed files with 217 additions and 34 deletions

View file

@ -3,9 +3,12 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\FoodOrder; use App\Entity\FoodOrder;
use App\Entity\ItemExtra;
use App\Entity\MenuItem; use App\Entity\MenuItem;
use App\Entity\MenuItemAlias;
use App\Entity\OrderItem; use App\Entity\OrderItem;
use App\Form\MenuItemExtraType; use App\Form\ItemExtraType;
use App\Form\MenuItemType;
use App\Form\OrderItemType; use App\Form\OrderItemType;
use App\Repository\ItemExtraRepository; use App\Repository\ItemExtraRepository;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
@ -23,15 +26,50 @@ class FoodOrderController extends AbstractController
final public const APP_FOODORDER_CLOSE = 'app_foodorder_close'; final public const APP_FOODORDER_CLOSE = 'app_foodorder_close';
#[Route('/{id}', name: self::APP_FOOD_ORDER_SHOW, methods: ['GET'])] final public const APP_FOODORDER_COPY_ITEM = 'app_foodorder_item_copy';
public function show(FoodOrder $foodOrder): Response
{ final public const APP_FOODORDER_REMOVE_ITEM = 'app_foodorder_item_remove';
#[Route(
'/{id}',
name: self::APP_FOOD_ORDER_SHOW,
methods: [Request::METHOD_GET, Request::METHOD_POST],
)]
public function show(
FoodOrder $foodOrder,
Request $request,
EntityManagerInterface $entityManager,
): Response {
$newItem = new MenuItem;
$newItem->setVendor($foodOrder->getVendor());
$newItem->setPrice(0);
$newItemForm = $this->createForm(MenuItemType::class, $newItem);
$newItemForm->handleRequest($request);
if ($newItemForm->isSubmitted() && $newItemForm->isValid()) {
$name = (string) $newItemForm->get('name')
->getData();
$alias = new MenuItemAlias;
$alias->setName($name);
$alias->setMenuItem($newItem);
$entityManager->persist($newItem);
$entityManager->persist($alias);
$entityManager->flush();
return $this->redirectToRoute(
self::APP_FOOD_ORDER_SHOW,
[
'id' => $foodOrder->getId(),
],
);
}
return $this->render( return $this->render(
'food_order/show.html.twig', 'food_order/show.html.twig',
[ [
'food_order' => $foodOrder, 'food_order' => $foodOrder,
'menu_items' => $foodOrder->getVendor() 'menu_items' => $foodOrder->getVendor()
->getMenuItems(), ->getMenuItems(),
'form' => $newItemForm,
], ],
); );
} }
@ -89,38 +127,88 @@ class FoodOrderController extends AbstractController
); );
} }
$formExtra = $this->createForm( $newExtra = new ItemExtra;
MenuItemExtraType::class, $newExtra->setMenuItem($menuItem);
$extraForm = $this->createForm(
ItemExtraType::class,
$newExtra,
[
'menuItem' => $menuItem,
],
); );
$extraForm->handleRequest($request);
if ($extraForm->isSubmitted() && $extraForm->isValid()) {
$entityManager->persist($newExtra);
$entityManager->flush();
return $this->redirectToRoute(
self::APP_FOODORDER_ADD_ITEM,
[
'foodOrder' => $foodOrder->getId(),
'menuItem' => $menuItem->getId(),
],
Response::HTTP_SEE_OTHER,
);
}
return $this->render( return $this->render(
'food_order/orderitem.html.twig', 'food_order/orderitem.html.twig',
[ [
'form' => $form, 'form' => $form,
'extraForm' => $extraForm,
'extras' => $extraRepository->getUniqueNames(), 'extras' => $extraRepository->getUniqueNames(),
], ],
); );
} }
#[Route( #[Route(
'/{foodOrder}/remove_item/{orderItem}', '/item/remove/{orderItem}',
name: 'app_foodorder_remove_item', name: self::APP_FOODORDER_REMOVE_ITEM,
methods: [Request::METHOD_GET], methods: [Request::METHOD_GET],
)] )]
public function remove( public function remove(
FoodOrder $foodOrder,
OrderItem $orderItem, OrderItem $orderItem,
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
): Response { ): Response {
$orderId = $orderItem->getFoodOrder()
->getId();
$entityManager->remove($orderItem); $entityManager->remove($orderItem);
$entityManager->flush(); $entityManager->flush();
return $this->redirectToRoute( return $this->redirectToRoute(
self::APP_FOOD_ORDER_SHOW, self::APP_FOOD_ORDER_SHOW,
[ [
'id' => $foodOrder->getId(), 'id' => $orderId,
], ],
Response::HTTP_SEE_OTHER, Response::HTTP_SEE_OTHER,
); );
} }
#[Route(
'/item/copy/{orderItem}',
name: self::APP_FOODORDER_COPY_ITEM,
methods: [Request::METHOD_GET],
)]
public function copyItem(
OrderItem $orderItem,
EntityManagerInterface $entityManager,
): Response {
$newItem = new OrderItem;
$newItem->setFoodOrder($orderItem->getFoodOrder());
$newItem->setMenuItem($orderItem->getMenuItem());
foreach ($orderItem->getExtras() as $extra) {
$newItem->getExtras()
->add($extra);
}
$entityManager->persist($newItem);
$entityManager->flush();
return $this->redirectToRoute(
self::APP_FOOD_ORDER_SHOW,
[
'id' => $orderItem->getFoodOrder()
->getId(),
],
);
}
} }

View file

@ -11,6 +11,8 @@ use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator;
use Symfony\Bridge\Doctrine\Types\UlidType; use Symfony\Bridge\Doctrine\Types\UlidType;
use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Ulid;
use function iterator_to_array;
#[ORM\Entity(repositoryClass: FoodOrderRepository::class)] #[ORM\Entity(repositoryClass: FoodOrderRepository::class)]
class FoodOrder class FoodOrder
{ {
@ -130,6 +132,12 @@ class FoodOrder
public function groupedOrderItems(): Collection public function groupedOrderItems(): Collection
{ {
return $this->getOrderItems(); $iterator = $this->orderItems->getIterator();
$orderFunction = static fn(OrderItem $a, OrderItem $b): int
=> $a->getMenuItem()
->getId()
->compare($b->getMenuItem()->getId());
$iterator->uasort($orderFunction);
return new ArrayCollection(iterator_to_array($iterator));
} }
} }

View file

@ -11,23 +11,18 @@ use Symfony\Component\Uid\Ulid;
#[ORM\Entity(repositoryClass: ItemExtraRepository::class)] #[ORM\Entity(repositoryClass: ItemExtraRepository::class)]
class ItemExtra class ItemExtra
{ {
public function __construct(
#[ORM\Column(length: 50)]
private string|null $name = null,
#[ORM\ManyToOne(inversedBy: 'itemExtras')]
#[ORM\JoinColumn(nullable: false)]
private MenuItem|null $menuItem = null,
#[ORM\Id] #[ORM\Id]
#[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\Column(type: UlidType::NAME, unique: true)] #[ORM\Column(type: UlidType::NAME, unique: true)]
#[ORM\CustomIdGenerator(class: UlidGenerator::class)] #[ORM\CustomIdGenerator(class: UlidGenerator::class)]
private Ulid $id; private Ulid $id = new Ulid,
) {}
#[ORM\Column(length: 50)]
private string|null $name = null;
#[ORM\ManyToOne(inversedBy: 'itemExtras')]
#[ORM\JoinColumn(nullable: false)]
private MenuItem|null $menuItem = null;
public function __construct()
{
$this->id = new Ulid;
}
public function getId(): Ulid public function getId(): Ulid
{ {

View file

@ -0,0 +1,31 @@
<?php declare(strict_types=1);
namespace App\Form;
use App\Entity\ItemExtra;
use App\Entity\MenuItem;
use Override;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ItemExtraType extends AbstractType
{
#[Override]
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(child: 'name', options: [
'label' => 'custom extra',
]);
}
#[Override]
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => ItemExtra::class,
]);
$resolver->setRequired('menuItem');
$resolver->setAllowedTypes('menuItem', MenuItem::class);
}
}

View file

@ -1,5 +1,4 @@
<?php <?php declare(strict_types=1);
declare(strict_types=1);
namespace App\Form; namespace App\Form;
@ -30,7 +29,7 @@ class MenuItemExtraType extends AbstractType
); );
} }
#[\Override] #[Override]
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([

43
src/Form/MenuItemType.php Normal file
View file

@ -0,0 +1,43 @@
<?php declare(strict_types=1);
namespace App\Form;
use App\Entity\MenuItem;
use Override;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
class MenuItemType extends AbstractType
{
#[Override]
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add(child: 'name', type: TextType::class, options: [
'mapped' => false,
])
->add(
child: 'price',
options: [
'label' => 'Price in cents',
'constraints' => [
new GreaterThanOrEqual([
'value' => 0,
'message' => 'The price must be a positive number or zero.',
]),
],
],
);
}
#[Override]
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => MenuItem::class,
]);
}
}

View file

@ -5,7 +5,7 @@
"repo": "github.com/symfony/recipes", "repo": "github.com/symfony/recipes",
"branch": "main", "branch": "main",
"version": "2.10", "version": "2.10",
"ref": "310a02a22033e35640468f48ff6bf31a25891537" "ref": "c170ded8fc587d6bd670550c43dafcf093762245"
}, },
"files": [ "files": [
"config/packages/doctrine.yaml", "config/packages/doctrine.yaml",

View file

@ -1,7 +1,8 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block body %} {% block body %}
{{ include('_form.html.twig') }} {% include('_form.html.twig') %}
{% include('_form.html.twig') with {'form': extraForm, 'button_label': 'add extra'} only %}
<datalist id="item-extra-list"> <datalist id="item-extra-list">
{% for item in extras %} {% for item in extras %}
<option value="{{ item.name }}"></option> <option value="{{ item.name }}"></option>

View file

@ -53,6 +53,22 @@
{{ orderItem.menuItem.price|cents_to_eur }} {{ orderItem.menuItem.price|cents_to_eur }}
</td> </td>
<td> <td>
<a
href="{{ path(
'app_foodorder_item_copy',
{
'orderItem': orderItem.id
}
) }}"
>+1</a> |
<a
href="{{ path(
'app_foodorder_item_remove',
{
'orderItem': orderItem.id
}
) }}"
>del</a> |
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -90,4 +106,6 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
{% include('_form.html.twig') %}
{% endblock %} {% endblock %}