This commit is contained in:
lubiana 2025-06-09 19:56:08 +02:00
parent 66c4c1fe4f
commit 2c2e34b71e
Signed by: lubiana
SSH key fingerprint: SHA256:vW1EA0fRR3Fw+dD/sM0K+x3Il2gSry6YRYHqOeQwrfk
42 changed files with 910 additions and 939 deletions

View file

@ -6,7 +6,7 @@ namespace App\Controller;
use App\Entity\DrinkType;
use App\Form\DrinkTypeForm;
use App\Repository\DrinkTypeRepository;
use App\Repository\PropertyChangeLogRepository;
use App\Service\InventoryService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -21,7 +21,7 @@ final class DrinkTypeController extends AbstractController
public function index(InventoryService $inventoryService): Response
{
return $this->render('drink_type/index.html.twig', [
'drink_stocks' => $inventoryService->getAllDrinkTypesWithStockLevels(true)
'drink_stocks' => $inventoryService->getAllDrinkTypesWithStockLevels(true),
]);
}
@ -46,10 +46,26 @@ final class DrinkTypeController extends AbstractController
}
#[Route(path: '/{id}', name: 'app_drink_type_show', methods: ['GET'])]
public function show(DrinkType $drinkType): Response
public function show(DrinkType $drinkType, PropertyChangeLogRepository $propertyChangeLogRepository): Response
{
// Get orders that contain this drink type
$orderItems = $drinkType->getOrderItems();
// Get inventory history for this drink type
$inventoryRecords = $drinkType->getInventoryRecords();
// Get desired stock history from PropertyChangeLog
$desiredStockHistory = $propertyChangeLogRepository->findBy([
'entityClass' => DrinkType::class,
'propertyName' => 'desiredStock',
'entityId' => $drinkType->getId()
], ['changeDate' => 'DESC']);
return $this->render('drink_type/show.html.twig', [
'drink_type' => $drinkType,
'order_items' => $orderItems,
'inventory_records' => $inventoryRecords,
'desired_stock_history' => $desiredStockHistory,
]);
}

View file

@ -24,12 +24,12 @@ final class Index extends AbstractController
$low = array_filter(
$drinkStocks,
fn (DrinkStock $stock): bool => $stock->stock === StockState::LOW || $stock->stock === StockState::CRITICAL,
fn(DrinkStock $stock): bool => $stock->stock === StockState::LOW || $stock->stock === StockState::CRITICAL,
);
return $this->render('index.html.twig', [
'drinkStocks' => $drinkStocks,
'low' => $low
'low' => $low,
]);
}
}

View file

@ -1,10 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\DrinkType;
use App\Entity\InventoryRecord;
use App\Form\InventoryRecordForm;
use App\Repository\InventoryRecordRepository;
use App\Service\InventoryService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
@ -22,10 +26,11 @@ final class InventoryRecordController extends AbstractController
]);
}
#[Route('/new', name: 'app_inventory_record_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response
#[Route('/new/{drinkType}', name: 'app_inventory_record_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager, DrinkType $drinkType): Response
{
$inventoryRecord = new InventoryRecord();
$inventoryRecord->setDrinkType($drinkType);
$form = $this->createForm(InventoryRecordForm::class, $inventoryRecord);
$form->handleRequest($request);
@ -33,7 +38,22 @@ final class InventoryRecordController extends AbstractController
$entityManager->persist($inventoryRecord);
$entityManager->flush();
return $this->redirectToRoute('app_inventory_record_index', [], Response::HTTP_SEE_OTHER);
// If it's an HTMX request, return a redirect that HTMX will follow
if ($request->headers->has('HX-Request')) {
$response = new Response('', Response::HTTP_SEE_OTHER);
$response->headers->set('HX-Redirect', $this->generateUrl('app_index'));
return $response;
}
return $this->redirectToRoute('app_index', [], Response::HTTP_SEE_OTHER);
}
// Check if it's an HTMX request
if ($request->headers->has('HX-Request')) {
return $this->render('inventory_record/_modal_form.html.twig', [
'inventory_record' => $inventoryRecord,
'form' => $form,
]);
}
return $this->render('inventory_record/new.html.twig', [
@ -42,6 +62,26 @@ final class InventoryRecordController extends AbstractController
]);
}
#[Route('/modal/{drinkType}', name: 'app_inventory_record_modal', methods: ['GET'])]
public function modal(DrinkType $drinkType, InventoryService $inventoryService): Response
{
$inventoryRecord = new InventoryRecord();
$inventoryRecord->setDrinkType($drinkType);
$inventoryRecord->setQuantity(
$inventoryService->getLatestInventoryRecord($drinkType)->getQuantity() ?? 0
);
$form = $this->createForm(InventoryRecordForm::class, $inventoryRecord, [
'action' => $this->generateUrl('app_inventory_record_new', [
'drinkType' => $drinkType->getId(),
]),
]);
return $this->render('inventory_record/_modal_form.html.twig', [
'inventory_record' => $inventoryRecord,
'form' => $form,
]);
}
#[Route('/{id}', name: 'app_inventory_record_show', methods: ['GET'])]
public function show(InventoryRecord $inventoryRecord): Response
{
@ -71,7 +111,7 @@ final class InventoryRecordController extends AbstractController
#[Route('/{id}', name: 'app_inventory_record_delete', methods: ['POST'])]
public function delete(Request $request, InventoryRecord $inventoryRecord, EntityManagerInterface $entityManager): Response
{
if ($this->isCsrfTokenValid('delete'.$inventoryRecord->getId(), $request->getPayload()->getString('_token'))) {
if ($this->isCsrfTokenValid('delete' . $inventoryRecord->getId(), $request->getPayload()->getString('_token'))) {
$entityManager->remove($inventoryRecord);
$entityManager->flush();
}

View file

@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\Order;
use App\Form\OrderForm;
use App\Repository\OrderRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[Route('/order')]
final class OrderController extends AbstractController
{
#[Route(name: 'app_order_index', methods: ['GET'])]
public function index(OrderRepository $orderRepository): Response
{
return $this->render('order/index.html.twig', [
'orders' => $orderRepository->findAll(),
]);
}
#[Route('/new', name: 'app_order_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager): Response
{
$order = new Order();
$form = $this->createForm(OrderForm::class, $order);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($order);
$entityManager->flush();
return $this->redirectToRoute('app_order_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('order/new.html.twig', [
'order' => $order,
'form' => $form,
]);
}
#[Route('/{id}', name: 'app_order_show', methods: ['GET'])]
public function show(Order $order): Response
{
return $this->render('order/show.html.twig', [
'order' => $order,
]);
}
#[Route('/{id}/edit', name: 'app_order_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Order $order, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(OrderForm::class, $order);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
return $this->redirectToRoute('app_order_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('order/edit.html.twig', [
'order' => $order,
'form' => $form,
]);
}
#[Route('/{id}', name: 'app_order_delete', methods: ['POST'])]
public function delete(Request $request, Order $order, EntityManagerInterface $entityManager): Response
{
if ($this->isCsrfTokenValid('delete' . $order->getId(), $request->getPayload()->getString('_token'))) {
$entityManager->remove($order);
$entityManager->flush();
}
return $this->redirectToRoute('app_order_index', [], Response::HTTP_SEE_OTHER);
}
}