configstuff

This commit is contained in:
lubiana 2025-06-14 20:21:36 +02:00
parent ca0e7d300d
commit c3411e5754
Signed by: lubiana
SSH key fingerprint: SHA256:vW1EA0fRR3Fw+dD/sM0K+x3Il2gSry6YRYHqOeQwrfk
12 changed files with 243 additions and 121 deletions

View file

@ -1,121 +0,0 @@
<?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;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[Route('/inventory-record')]
final class InventoryRecordController extends AbstractController
{
#[Route(name: 'app_inventory_record_index', methods: ['GET'])]
public function index(InventoryRecordRepository $inventoryRecordRepository): Response
{
return $this->render('inventory_record/index.html.twig', [
'inventory_records' => $inventoryRecordRepository->findAll(),
]);
}
#[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);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($inventoryRecord);
$entityManager->flush();
// 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', [
'inventory_record' => $inventoryRecord,
'form' => $form,
]);
}
#[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
{
return $this->render('inventory_record/show.html.twig', [
'inventory_record' => $inventoryRecord,
]);
}
#[Route('/{id}/edit', name: 'app_inventory_record_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, InventoryRecord $inventoryRecord, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(InventoryRecordForm::class, $inventoryRecord);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
return $this->redirectToRoute('app_inventory_record_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('inventory_record/edit.html.twig', [
'inventory_record' => $inventoryRecord,
'form' => $form,
]);
}
#[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'))) {
$entityManager->remove($inventoryRecord);
$entityManager->flush();
}
return $this->redirectToRoute('app_inventory_record_index', [], Response::HTTP_SEE_OTHER);
}
}

View file

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\SystemConfig;
use App\Enum\SystemSettingKey;
use App\Form\SystemConfigForm;
use App\Repository\SystemConfigRepository;
use App\Service\ConfigurationService;
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('/system-config')]
final class SystemConfigController extends AbstractController
{
#[Route(name: 'app_system_config_index', methods: ['GET'])]
public function index(SystemConfigRepository $systemConfigRepository): Response
{
$configs = [];
foreach (SystemSettingKey::cases() as $key) {
$configs[] = $systemConfigRepository->findByKey($key);
}
return $this->render('system_config/index.html.twig', [
'system_configs' => $configs,
]);
}
#[Route(path: '/{id}/edit', name: 'app_system_config_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, SystemConfig $systemConfig, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(SystemConfigForm::class, $systemConfig);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
return $this->redirectToRoute('app_system_config_index', [], Response::HTTP_SEE_OTHER);
}
return $this->render('system_config/edit.html.twig', [
'system_config' => $systemConfig,
'form' => $form,
]);
}
#[Route(path: '/{id}/reset', name: 'app_system_config_reset', methods: ['POST'])]
public function reset(Request $request, SystemConfig $systemConfig, ConfigurationService $configurationService): Response
{
if ($this->isCsrfTokenValid('reset' . $systemConfig->getId(), $request->getPayload()->getString('_token'))) {
$configurationService->reset($systemConfig->getKey());
}
return $this->redirectToRoute('app_system_config_index', [], Response::HTTP_SEE_OTHER);
}
}

View file

@ -14,11 +14,17 @@ use Doctrine\ORM\Mapping as ORM;
class SystemConfig
{
public const string DEFAULT_STOCK_ADJUSTMENT_LOOKBACK_ORDERS = '3';
public const string STOCK_ADJUSTMENT_LOOKBACK_ORDERS_DESCRIPTION = 'Number of orders to look back for stock adjustment';
public const string DEFAULT_DEFAULT_WANTED_STOCK = '2';
public const string DEFAULT_DEFAULT_WANTED_STOCK_DESCRIPTION = 'Default wanted stock for new drink types';
public const string DEFAULT_SYSTEM_NAME = 'Zaufen';
public const string DEFAULT_SYSTEM_NAME_DESCRIPTION = 'System name';
public const string DEFAULT_STOCK_INCREASE_AMOUNT = '1';
public const string DEFAULT_STOCK_INCREASE_AMOUNT_DESCRIPTION = 'Amount to increase stock by for stock adjustment suggested by the system';
public const string DEFAULT_STOCK_DECREASE_AMOUNT = '1';
public const string DEFAULT_STOCK_DECREASE_AMOUNT_DESCRIPTION = 'Amount to decrease stock by for stock adjustment suggested by the system';
public const string DEFAULT_STOCK_LOW_MULTIPLIER = '0.3';
public const string DEFAULT_STOCK_LOW_MULTIPLIER_DESCRIPTION = 'Multiplier to to check if stock is low.';
#[ORM\Id]
#[ORM\GeneratedValue]
@ -37,6 +43,12 @@ class SystemConfig
#[ORM\Column(type: 'text')]
private string $value;
#[ORM\Column(type: 'text', options: [
'default' => '',
])]
private string $description;
public function __construct(
) {
$this->createdAt = new DateTimeImmutable();
@ -85,4 +97,14 @@ class SystemConfig
{
$this->updatedAt = new DateTimeImmutable();
}
public function getDescription(): string
{
return $this->description;
}
public function setDescription(string $description): void
{
$this->description = $description;
}
}

View file

@ -29,4 +29,16 @@ enum SystemSettingKey: string
self::STOCK_LOW_MULTIPLIER => SystemConfig::DEFAULT_STOCK_LOW_MULTIPLIER,
};
}
public function defaultDescription(): string
{
return match ($this) {
self::STOCK_ADJUSTMENT_LOOKBACK_ORDERS => SystemConfig::STOCK_ADJUSTMENT_LOOKBACK_ORDERS_DESCRIPTION,
self::DEFAULT_WANTED_STOCK => SystemConfig::DEFAULT_DEFAULT_WANTED_STOCK_DESCRIPTION,
self::SYSTEM_NAME => SystemConfig::DEFAULT_SYSTEM_NAME_DESCRIPTION,
self::STOCK_INCREASE_AMOUNT => SystemConfig::DEFAULT_STOCK_INCREASE_AMOUNT_DESCRIPTION,
self::STOCK_DECREASE_AMOUNT => SystemConfig::DEFAULT_STOCK_DECREASE_AMOUNT_DESCRIPTION,
self::STOCK_LOW_MULTIPLIER => SystemConfig::DEFAULT_STOCK_LOW_MULTIPLIER_DESCRIPTION,
};
}
}

View file

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace App\Form;
use App\Entity\SystemConfig;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SystemConfigForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('value', TextType::class, [
'label' => 'Value',
'help' => 'The value of the system setting',
])
->add('description', TextType::class, [
'label' => 'Description',
'help' => 'Description of the system setting',
'disabled' => true,
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => SystemConfig::class,
]);
}
}

View file

@ -27,6 +27,11 @@ class SystemConfigRepository extends AbstractRepository
$config = new SystemConfig();
$config->setKey($key);
$config->setValue($key->defaultValue());
$config->setDescription($key->defaultDescription());
$this->save($config);
}
if ($config->getDescription() === '') {
$config->setDescription($key->defaultDescription());
$this->save($config);
}
return $config;