From c524b584d7ac480540da513648a821d3c927a35d Mon Sep 17 00:00:00 2001 From: Noah Lancien Date: Tue, 1 Oct 2024 16:15:39 +0200 Subject: [PATCH] feat: Added bo fields to set nutritionnal values on products --- app/Http/Controllers/Bo/ProductController.php | 71 ++++-- .../Bo/Products/StoreProductRequest.php | 21 ++ app/Models/Product.php | 10 + .../views/bo/pages/products/form.blade.php | 22 ++ .../inputs/json-nutritionnal-values.blade.php | 226 ++++++++++++++++++ 5 files changed, 325 insertions(+), 25 deletions(-) create mode 100644 resources/views/bo/partials/inputs/json-nutritionnal-values.blade.php diff --git a/app/Http/Controllers/Bo/ProductController.php b/app/Http/Controllers/Bo/ProductController.php index e6d0a0c4..ac311278 100644 --- a/app/Http/Controllers/Bo/ProductController.php +++ b/app/Http/Controllers/Bo/ProductController.php @@ -8,6 +8,7 @@ use App\Http\Requests\Bo\Products\StoreProductRequest; use App\Http\Requests\Bo\Products\UpdateProductRequest; use App\Models\Approach; use App\Models\Claim; +use App\Models\IncoNutritionalValue; use App\Models\Meat; use App\Models\Product; use App\Models\ProductType; @@ -89,21 +90,21 @@ class ProductController extends Controller public function create(Product $product): \Illuminate\Contracts\View\View { return view('bo.pages.products.create', [ - 'productModel' => $product, - 'rangeModels' => $this->getModelsPaginate((new Range())->query()), - 'subrangeModels' => $this->getModelsPaginate((new Subrange())->query()), - 'meatModels' => $this->getModelsPaginate((new Meat())->query()), - 'submeatModels' => $this->getModelsPaginate((new Submeat())->query()), - 'approachDemarchModels' => $this->getModelsPaginate( + 'productModel' => $product, + 'rangeModels' => $this->getModelsPaginate((new Range())->query()), + 'subrangeModels' => $this->getModelsPaginate((new Subrange())->query()), + 'meatModels' => $this->getModelsPaginate((new Meat())->query()), + 'submeatModels' => $this->getModelsPaginate((new Submeat())->query()), + 'approachDemarchModels' => $this->getModelsPaginate( Approach::query()->where('type', ApproachTypeEnum::demarche), 'name' ), - 'approachLabelModels' => $this->getModelsPaginate( + 'approachLabelModels' => $this->getModelsPaginate( Approach::query()->where('type', ApproachTypeEnum::label), 'name' ), - 'productTypeModels' => $this->getModelsPaginate((new ProductType())->query()), - 'claimModels' => $this->getModelsPaginate((new Claim())->query()), + 'productTypeModels' => $this->getModelsPaginate((new ProductType())->query()), + 'claimModels' => $this->getModelsPaginate((new Claim())->query()), ]); } @@ -117,15 +118,27 @@ class ProductController extends Controller { return DB::transaction(function () use ($request) { $product = new Product(); - $product->fill(Arr::except($request->validated(), ['labels', 'productTypes', 'claims'])); + $product->fill(Arr::except( + $request->validated(), + ['labels', 'productTypes', 'claims', 'nutritionnal_values'] + )); + + if ($product->saveOrFail()) { $product->labels()->sync(collect($request->validated()['labels'] ?? [])->pluck('id')); $product->productTypes()->sync(collect($request->validated()['productTypes'] ?? [])->pluck('id')); $product->claims()->sync(collect($request->validated()['claims'] ?? [])->pluck('id')); - return redirect()->route('bo.products.edit', $product) - ->with('success', trans('crud.messages.has_been_created', [ - 'model' => Str::ucfirst(trans('models.classes.product')) - ])); + + $nutritionnalValueModel = new IncoNutritionalValue(); + $nutritionnalValueModel->fill(Arr::first($request->safe()->only('nutritionnal_values'))); + $nutritionnalValueModel->product()->associate($product); + + if ($nutritionnalValueModel->saveOrFail()) { + return redirect()->route('bo.products.edit', $product) + ->with('success', trans('crud.messages.has_been_created', [ + 'model' => Str::ucfirst(trans('models.classes.product')) + ])); + } } return redirect()->back() ->with('error', trans('crud.messages.cannot_be_created', [ @@ -143,21 +156,22 @@ class ProductController extends Controller public function edit(Product $product): \Illuminate\Contracts\View\View { return view('bo.pages.products.edit', [ - 'productModel' => $product, - 'rangeModels' => $this->getModelsPaginate((new Range())->query()), - 'subrangeModels' => $this->getModelsPaginate((new Subrange())->query()), - 'meatModels' => $this->getModelsPaginate((new Meat())->query()), - 'submeatModels' => $this->getModelsPaginate((new Submeat())->query()), - 'approachDemarchModels' => $this->getModelsPaginate( + 'productModel' => $product, + 'nutritionnalValueModel' => $product->getNutritionnalValue(), + 'rangeModels' => $this->getModelsPaginate((new Range())->query()), + 'subrangeModels' => $this->getModelsPaginate((new Subrange())->query()), + 'meatModels' => $this->getModelsPaginate((new Meat())->query()), + 'submeatModels' => $this->getModelsPaginate((new Submeat())->query()), + 'approachDemarchModels' => $this->getModelsPaginate( Approach::query()->where('type', ApproachTypeEnum::demarche), 'name' ), - 'approachLabelModels' => $this->getModelsPaginate( + 'approachLabelModels' => $this->getModelsPaginate( Approach::query()->where('type', ApproachTypeEnum::label), 'name' ), - 'productTypeModels' => $this->getModelsPaginate((new ProductType())->query()), - 'claimModels' => $this->getModelsPaginate((new Claim())->query()), + 'productTypeModels' => $this->getModelsPaginate((new ProductType())->query()), + 'claimModels' => $this->getModelsPaginate((new Claim())->query()), ]); } @@ -171,12 +185,19 @@ class ProductController extends Controller public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse { return DB::transaction(function () use ($request, $product) { - $product->fill(Arr::except($request->validated(), ['labels', 'productTypes', 'claims'])); + $product->fill(Arr::except($request->validated(), ['labels', 'productTypes', 'claims', 'nutritionnal_values'])); $product->labels()->sync(collect($request->validated()['labels'] ?? [])->pluck('id')); $product->productTypes()->sync(collect($request->validated()['productTypes'] ?? [])->pluck('id')); $product->claims()->sync(collect($request->validated()['claims'] ?? [])->pluck('id')); - if ($product->saveOrFail()) { + $nutritionnalValueModel = $product->getNutritionnalValue(); + if (is_null($nutritionnalValueModel)) { + $nutritionnalValueModel = new IncoNutritionalValue(); + $nutritionnalValueModel->product()->associate($product); + } + $nutritionnalValueModel->fill(Arr::first($request->safe()->only('nutritionnal_values'))); + + if ($product->saveOrFail() && $nutritionnalValueModel->saveOrFail()) { return redirect()->route('bo.products.edit', $product) ->with('success', trans('crud.messages.has_been_updated', [ 'model' => Str::ucfirst(trans('models.classes.product')) diff --git a/app/Http/Requests/Bo/Products/StoreProductRequest.php b/app/Http/Requests/Bo/Products/StoreProductRequest.php index 97a0f440..e5f9f198 100644 --- a/app/Http/Requests/Bo/Products/StoreProductRequest.php +++ b/app/Http/Requests/Bo/Products/StoreProductRequest.php @@ -67,6 +67,25 @@ class StoreProductRequest extends FormRequest 'details' => ['required', 'string', new WysiwygLength()], 'preparation' => ['required', 'string', new WysiwygLength()], 'ingredients' => ['required', 'string', new WysiwygLength()], + 'nutritionnal_values' => 'required|array', + 'nutritionnal_values.energy' => 'required|numeric|between:0,999999', + 'nutritionnal_values.energy_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.energy_kj' => 'required|numeric|between:0,999999', + 'nutritionnal_values.energy_kj_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.protein' => 'required|numeric|between:0,999999', + 'nutritionnal_values.protein_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.carbohydrates' => 'required|numeric|between:0,999999', + 'nutritionnal_values.carbohydrates_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.sugar' => 'required|numeric|between:0,999999', + 'nutritionnal_values.sugar_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.fat' => 'required|numeric|between:0,999999', + 'nutritionnal_values.fat_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.saturated_fatty_acids' => 'required|numeric|between:0,999999', + 'nutritionnal_values.saturated_fatty_acids_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.dietary_fiber' => 'required|numeric|between:0,999999', + 'nutritionnal_values.dietary_fiber_percent' => 'required|numeric|between:0,999999', + 'nutritionnal_values.salt' => 'required|numeric|between:0,999999', + 'nutritionnal_values.salt_percent' => 'required|numeric|between:0,999999', 'range_id' => [ 'required_if:subrange_id,null', 'sometimes', @@ -208,6 +227,8 @@ class StoreProductRequest extends FormRequest 'details' => trans('validations.custom.details'), 'preparation' => trans('validations.custom.preparation'), 'ingredients' => trans('validations.custom.ingredients'), + + 'approach_id' => trans('models.classes.demarche'), 'range_id' => trans('models.classes.range'), 'subrange_id' => trans('models.classes.subrange'), diff --git a/app/Models/Product.php b/app/Models/Product.php index 28a1e3ed..cf892ff4 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -319,4 +319,14 @@ class Product extends Model implements SeoInterface { return $this->hasMany(Video::class); } + + /** + * Get the nutritionnal values for the product. + * + * @return \App\Models\IncoNutritionalValue|null + */ + public function getNutritionnalValue(): \App\Models\IncoNutritionalValue|null + { + return $this->hasMany(IncoNutritionalValue::class)->first(); + } } diff --git a/resources/views/bo/pages/products/form.blade.php b/resources/views/bo/pages/products/form.blade.php index a442e2a2..298ebfcd 100644 --- a/resources/views/bo/pages/products/form.blade.php +++ b/resources/views/bo/pages/products/form.blade.php @@ -263,6 +263,28 @@ + {{-- NUTRITIONNAL VALUES --}} +
+
+ {{ Str::ucfirst(__('validation.custom.nutritionnal_values')) }} +
+
+ @include('bo.partials.inputs.json-nutritionnal-values', [ + 'id' => 'productNutritionnalValues', + 'label' => __(':field :inter:model', [ + 'field' => str(__('validation.custom.nutritionnal_values'))->ucfirst(), + 'inter' => __('validation.custom.of_the.male'), + 'model' => __('models.classes.product'), + ]), + 'name' => 'nutritionnal_values', + 'model' => $nutritionnalValueModel ?? null, + 'required' => true, + 'helper' => __('crud.helpers.nutritionnal_values'), + ]) +
+
+
+
{{-- PICTURE --}}
diff --git a/resources/views/bo/partials/inputs/json-nutritionnal-values.blade.php b/resources/views/bo/partials/inputs/json-nutritionnal-values.blade.php new file mode 100644 index 00000000..3d27b16c --- /dev/null +++ b/resources/views/bo/partials/inputs/json-nutritionnal-values.blade.php @@ -0,0 +1,226 @@ +{{-- + VARIABLE || COMMENT || TYPE || REQUIRED || DEFAULT + + $id || The id of the input tag. || string || REQUIRED || + $name || The name of the input tag. || string || REQUIRED || + $helper || The helper of the input. || string || REQUIRED || + $required || Is the field required ? || boolean || OPTIONNAL || false + $model || The model we're creating/editing || Model class || OPTIONNAL || null +--}} + + + + + + + + + + + {{-- ENERGIE EN KCAL --}} + + + + + + {{-- ENERGIE EN KJ --}} + + + + + + {{-- PROTEINES --}} + + + + + + + {{-- GLUCIDES --}} + + + + + + {{-- DONT SUCRES --}} + + + + + + {{-- MATIERES GRASSES --}} + + + + + + {{-- ACIDES GRAS SATURES --}} + + + + + + {{-- FIBRES ALIMENTAIRES --}} + + + + + + {{-- SEL --}} + + + + + + +
+ {{ __('Label') }} + + {{ __('Valeurs pour 100g') }} + + {{ __('Valeurs pour le produit') }} +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ +@include('modules.input-error', [ + 'inputName' => $name, + 'helperId' => $id . 'Help', + 'helper' => $helper, +])