ldc-ovoteam/app/Http/Controllers/Back/ProductController.php
Jérémy Munsch 481d80c8ea
refactor(requests): simplify nutritional values handling in product requests
Updated the handling of nutritional values in StoreProductRequest and UpdateProductRequest
to improve clarity and maintainability. The logic for processing nutritional values has been
centralized into a dedicated method, enhancing code readability.
2026-11-05 13:25:39 +01:00

223 lines
8.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Http\Controllers\Back;
use App\Contracts\Executor;
use App\Cqs\Actions\Products\Create\CreateProduct;
use App\Cqs\Actions\Products\Delete\DeleteProduct;
use App\Cqs\Actions\Products\Delete\DeleteProductInput;
use App\Cqs\Actions\Products\ForceDelete\ForceDeleteProduct;
use App\Cqs\Actions\Products\ForceDelete\ForceDeleteProductInput;
use App\Cqs\Actions\Products\Restore\RestoreProduct;
use App\Cqs\Actions\Products\Restore\RestoreProductInput;
use App\Cqs\Actions\Products\Update\UpdateProduct;
use App\Cqs\Queries\Products\GetBoPaginatedProductsQuery;
use App\Dto\ProductDto;
use App\Http\Requests\Back\Products\IndexProductRequest;
use App\Http\Requests\Back\Products\StoreProductRequest;
use App\Http\Requests\Back\Products\UpdateProductRequest;
use App\Http\Resources\CommonResource;
use App\Models\Product;
use Domain\Models\ValueObjects\Entities\ProductId;
use Domain\Models\ValueObjects\Products\BreedingMethod;
use Domain\Models\ValueObjects\Products\Business;
use Domain\Models\ValueObjects\Products\NutritionnalUnit;
use Domain\Models\ValueObjects\Products\ProductCategory;
use Domain\Models\ValueObjects\Products\ProductFormat;
use Domain\Models\ValueObjects\Products\Technology;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Inertia\Response;
class ProductController extends BackendController
{
public function __construct(
Request $request,
Session $session,
private readonly Executor $executor
) {
parent::__construct(
$request,
$session
);
$this->modelName = Product::modelName();
$this->modelPage = Product::modelPage();
}
public function index(IndexProductRequest $request, GetBoPaginatedProductsQuery $query): Response
{
$this->authorize('viewAny', Product::class);
$output = $this->executor->execute($query, $request->toGetBoPaginatedProductsQueryInput());
return $this->inertiaRender('back/Pages/Products/Index', [
'paginatedModels' => CommonResource::collection($output->paginatedProducts),
'search' => $output->search,
'searchFields' => $output->searchFields,
'enumProductCategory' => $output->categories,
'enumTechnology' => $output->technologies,
]);
}
public function show(Product $product): RedirectResponse
{
$this->authorize('viewAny', Product::class);
return redirect()->route('back.products.edit', $product);
}
public function create(Product $product): Response
{
$this->authorize('create', Product::class);
return $this->inertiaRender('back/Pages/Products/Create', [
'data' => CommonResource::make($product),
'enumProductCategory' => ProductCategory::toArray(),
'enumTechnology' => Technology::toArray(),
'enumBreedingMethod' => BreedingMethod::toArray(),
'enumBusiness' => Business::toArray(),
'enumProductFormat' => ProductFormat::toArray(),
'enumNutritionnalUnit' => NutritionnalUnit::toArray(),
]);
}
public function store(StoreProductRequest $request, CreateProduct $createProduct): RedirectResponse
{
$this->authorize('create', Product::class);
$result = $this->executor->execute($createProduct, $request->toCreateProductInput());
return match (true) {
$result instanceof ProductId => redirect()->route('back.products.edit', $result)
->with('success', trans('uwil-backend::crud.messages.has_been_created', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
default => redirect()->back()
->with('error', trans('uwil-backend::crud.messages.cannot_be_created', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
};
}
public function edit(Product $product): Response
{
$this->authorize('update', $product);
return $this->inertiaRender('back/Pages/Products/Edit', [
'data' => CommonResource::make($product),
'enumProductCategory' => ProductCategory::toArray(),
'enumTechnology' => Technology::toArray(),
'enumBreedingMethod' => BreedingMethod::toArray(),
'enumBusiness' => Business::toArray(),
'enumProductFormat' => ProductFormat::toArray(),
'enumNutritionnalUnit' => NutritionnalUnit::toArray(),
]);
}
public function update(
UpdateProductRequest $request,
Product $product,
UpdateProduct $updateProduct,
): RedirectResponse {
$this->authorize('update', $product);
$result = $this->executor->execute($updateProduct, $request->toUpdateProductInput($product));
return match (true) {
$result instanceof ProductDto => redirect()->route('back.products.edit', $product)
->with('success', trans('uwil-backend::crud.messages.has_been_updated', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
default => redirect()->route('back.products.edit', $product)
->with('error', trans('uwil-backend::crud.messages.cannot_be_updated', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
};
}
public function duplicate(Product $product): Response
{
return $this->create($product->replicate());
}
public function restore(string $id, RestoreProduct $restoreProduct): RedirectResponse
{
$product = Product::withTrashed()->findOrFail($id);
$this->authorize('restore', $product);
$previousQueries = $this->getPreviousQueries();
$result = $this->executor->execute($restoreProduct, new RestoreProductInput($product->getId()));
return match (true) {
$result instanceof ProductId => redirect()->route('back.products.trash', $previousQueries)
->with('success', trans('uwil-backend::crud.messages.has_been_restored', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
default => redirect()->back()
->with('error', trans('uwil-backend::crud.messages.cannot_be_restored', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
};
}
public function destroy(Product $product, DeleteProduct $deleteProduct): RedirectResponse
{
$this->authorize('delete', $product);
$previousQueries = $this->getPreviousQueries();
$result = $this->executor->execute($deleteProduct, new DeleteProductInput($product->getId()));
return match (true) {
$result instanceof ProductId => redirect()->route('back.products.index', $previousQueries)
->with('success', trans('uwil-backend::crud.messages.has_been_deleted', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
default => redirect()->back()
->with('error', trans('uwil-backend::crud.messages.cannot_be_deleted', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
};
}
public function forceDestroy(string $id, ForceDeleteProduct $forceDeleteProduct): RedirectResponse
{
$product = Product::withTrashed()->findOrFail($id);
$this->authorize('forceDelete', $product);
$previousQueries = $this->getPreviousQueries();
$result = $this->executor->execute($forceDeleteProduct, new ForceDeleteProductInput($product->getId()));
return match (true) {
$result instanceof ProductId => redirect()->route('back.products.trash', $previousQueries)
->with('success', trans('uwil-backend::crud.messages.has_been_deleted', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
default => redirect()->back()
->with('error', trans('uwil-backend::crud.messages.cannot_be_deleted', [
'model' => Str::ucfirst(trans_choice('models.classes.product', 1)),
])),
};
}
/** @return array<array-key,string|array<mixed>> */
private function getPreviousQueries(): array
{
$previousQueries = [];
$previousQueryString = \parse_url($this->getPreviousUrl(), \PHP_URL_QUERY) ?? '' ?: '';
\parse_str($previousQueryString, $previousQueries);
return $previousQueries;
}
private function getPreviousUrl(): string
{
return url()->previous(route('back.dashboard.index'));
}
}