feat: Added bo fields to set nutritionnal values on products

This commit is contained in:
Noah Lancien 2024-10-01 16:15:39 +02:00
parent 63a05f809a
commit c524b584d7
5 changed files with 325 additions and 25 deletions

View file

@ -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'))

View file

@ -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'),

View file

@ -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();
}
}

View file

@ -263,6 +263,28 @@
</div>
</fieldset>
</div>
{{-- NUTRITIONNAL VALUES --}}
<div class="col-12 mb-3">
<fieldset class="border p-3">
<legend>{{ Str::ucfirst(__('validation.custom.nutritionnal_values')) }}</legend>
<div class="row mb-3">
<div class="col-12">
@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'),
])
</div>
</div>
</fieldset>
</div>
{{-- PICTURE --}}
<div class="col-12 pb-3">
<fieldset class="h-100 border p-3">

View file

@ -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
--}}
<table class="table-striped table-hover table">
<thead>
<tr>
<th>
{{ __('Label') }}
</th>
<th>
{{ __('Valeurs pour 100g') }}
</th>
<th>
{{ __('Valeurs pour le produit') }}
</th>
</tr>
</thead>
<tbody>
{{-- ENERGIE EN KCAL --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}Energy">
{{ __('Energie en kcal') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Energy"
name="nutritionnal_values[energy_percent]" type="number"
value="{{ old('nutritionnal_values.energy_percent', $model->energy_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('204') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Energy"
name="nutritionnal_values[energy]" type="number" value="{{ old('nutritionnal_values.energy', $model->energy ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('204') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
</tr>
{{-- ENERGIE EN KJ --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}EnergyKj">
{{ __('Energie en kJ') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}EnergyKj"
name="nutritionnal_values[energy_kj_percent]" type="number"
value="{{ old('nutritionnal_values.energy_kj_percent', $model->energy_kj_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('846') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}EnergyKj"
name="nutritionnal_values[energy_kj]" type="number"
value="{{ old('nutritionnal_values.energy_kj', $model->energy_kj ?? 0) }}" aria-describedby="{{ $id }}Help"
placeholder="{{ __('846') }}" step="0.01" min="0" @if (!empty($required)) required @endif>
</td>
</tr>
{{-- PROTEINES --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}Proteins">
{{ __('Protéines') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Proteins"
name="nutritionnal_values[protein_percent]" type="number"
value="{{ old('nutritionnal_values.protein_percent', $model->protein_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('9.0') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Proteins"
name="nutritionnal_values[protein]" type="number"
value="{{ old('nutritionnal_values.protein', $model->protein ?? 0) }}" aria-describedby="{{ $id }}Help"
placeholder="{{ __('9.0') }}" step="0.01" min="0" @if (!empty($required)) required @endif>
</td>
</tr>
{{-- GLUCIDES --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}Carbohydrate">
{{ __('Glucides') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Carbohydrate"
name="nutritionnal_values[carbohydrates_percent]" type="number"
value="{{ old('nutritionnal_values.carbohydrates_percent', $model->carbohydrates_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('3.5') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Carbohydrate"
name="nutritionnal_values[carbohydrates]" type="number"
value="{{ old('nutritionnal_values.carbohydrates', $model->carbohydrates ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('3.5') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
</tr>
{{-- DONT SUCRES --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}Sugar">
{{ __('dont sucres') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Sugar"
name="nutritionnal_values[sugar_percent]" type="number"
value="{{ old('nutritionnal_values.sugar_percent', $model->sugar_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('0.9') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Sugar"
name="nutritionnal_values[sugar]" type="number" value="{{ old('nutritionnal_values.sugar', $model->sugar ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('0.9') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
</tr>
{{-- MATIERES GRASSES --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}Fat">
{{ __('Matières grasses') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Fat"
name="nutritionnal_values[fat_percent]" type="number"
value="{{ old('nutritionnal_values.fat_percent', $model->fat_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('17') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Fat"
name="nutritionnal_values[fat]" type="number" value="{{ old('nutritionnal_values.fat', $model->fat ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('17') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
</tr>
{{-- ACIDES GRAS SATURES --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}SaturatedFat">
{{ __('dont acides gras saturés') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}SaturatedFat"
name="nutritionnal_values[saturated_fatty_acids_percent]" type="number"
value="{{ old('nutritionnal_values.saturated_fatty_acids_percent', $model->saturated_fatty_acids_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('2.2') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}SaturatedFat"
name="nutritionnal_values[saturated_fatty_acids]" type="number"
value="{{ old('nutritionnal_values.saturated_fatty_acids', $model->saturated_fatty_acids ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('2.2') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
</tr>
{{-- FIBRES ALIMENTAIRES --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}Sugar">
{{ __('Fibres alimentaires') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}DietaryFiber"
name="nutritionnal_values[dietary_fiber_percent]" type="number"
value="{{ old('nutritionnal_values.dietary_fiber_percent', $model->dietary_fiber_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('0.9') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}DietaryFiber"
name="nutritionnal_values[dietary_fiber]" type="number"
value="{{ old('nutritionnal_values.dietary_fiber', $model->dietary_fiber ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('0.9') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
</tr>
{{-- SEL --}}
<tr>
<td>
<label class="col-form-label" for="{{ $id }}Salt">
{{ __('Sel') }} {{ $required ?? false ? '*' : '' }}
</label>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Salt"
name="nutritionnal_values[salt_percent]" type="number"
value="{{ old('nutritionnal_values.salt_percent', $model->salt_percent ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('1.27') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
<td>
<input class="form-control @if ($errors->has($name)) is-invalid @endif" id="{{ $id }}Salt"
name="nutritionnal_values[salt]" type="number" value="{{ old('nutritionnal_values.salt', $model->salt ?? 0) }}"
aria-describedby="{{ $id }}Help" placeholder="{{ __('1.27') }}" step="0.01" min="0"
@if (!empty($required)) required @endif>
</td>
</tr>
</tbody>
</table>
@include('modules.input-error', [
'inputName' => $name,
'helperId' => $id . 'Help',
'helper' => $helper,
])