diff --git a/app/Http/Controllers/Bo/ProductController.php b/app/Http/Controllers/Bo/ProductController.php index 37e08df..c948c2a 100644 --- a/app/Http/Controllers/Bo/ProductController.php +++ b/app/Http/Controllers/Bo/ProductController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Bo; use App\Http\Controllers\Controller; use App\Http\Requests\Bo\Products\StoreProductRequest; use App\Http\Requests\Bo\Products\UpdateProductRequest; +use App\Models\Commitment; use App\Models\Product; use App\Models\Range; use App\Traits\Controllers\ChangesModelOrder; @@ -73,10 +74,12 @@ class ProductController extends Controller */ public function create(Product $product): \Illuminate\Contracts\View\View { - $rangeModels = Range::all(); + $rangeModels = Range::all(); + $commitmentModels = Commitment::all(); return view('bo.pages.products.create', [ 'productModel' => $product, 'rangeModels' => $rangeModels, + 'commitmentModels' => $commitmentModels, ]); } @@ -90,9 +93,13 @@ class ProductController extends Controller { return DB::transaction(function () use ($request) { $product = new Product(); - $product->fill($request->validated()); + // Method safe() don't return formatted nutritionnal values, but we need this method to exclude commitments. + $product->fill($request->safe()->except(['commitments', 'nutritionnal_values'])); + // We don't take $request->validated('nutritionnal_values') because it returned undesired datas. + $product->nutritionnal_values = $request->validated()['nutritionnal_values']; if ($product->saveOrFail()) { + $product->commitments()->attach(collect($request->validated('commitments'))->pluck('id')); return redirect()->route('bo.products.edit', $product) ->with('success', __('crud.messages.has_been_created', [ 'model' => Str::ucfirst(__('models.classes.product')) @@ -113,10 +120,12 @@ class ProductController extends Controller */ public function edit(Product $product): \Illuminate\Contracts\View\View { - $rangeModels = Range::all(); + $rangeModels = Range::all(); + $commitmentModels = Commitment::all(); return view('bo.pages.products.edit', [ 'productModel' => $product, 'rangeModels' => $rangeModels, + 'commitmentModels' => $commitmentModels, ]); } @@ -130,8 +139,9 @@ class ProductController extends Controller public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse { return DB::transaction(function () use ($request, $product) { - $product->fill($request->validated()); - + $product->fill($request->safe()->except('commitments')); + $product->commitments()->sync(collect($request->validated('commitments'))->pluck('id')); + $product->nutritionnal_values = $request->validated()['nutritionnal_values']; if ($product->saveOrFail()) { return redirect()->route('bo.products.edit', $product) ->with('success', __('crud.messages.has_been_updated', [ diff --git a/app/Http/Requests/Bo/Products/StoreProductRequest.php b/app/Http/Requests/Bo/Products/StoreProductRequest.php index 7219c9c..5ec2463 100644 --- a/app/Http/Requests/Bo/Products/StoreProductRequest.php +++ b/app/Http/Requests/Bo/Products/StoreProductRequest.php @@ -61,6 +61,8 @@ class StoreProductRequest extends FormRequest 'nutritionnal_values' => 'required|array', 'nutritionnal_values.*' => 'required|numeric|min:0', 'range_id' => 'required|exists:ranges,id', + 'commitments' => 'nullable|array', + 'commitments.*.id' => 'required|exists:commitments,id', 'published' => 'required|boolean', ]; return \array_merge( @@ -76,11 +78,14 @@ class StoreProductRequest extends FormRequest * * @param array|integer|string|null $key * @param mixed $default - * @return array + * @return array|null * @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed */ - public function validated($key = null, mixed $default = null): array + public function validated($key = null, mixed $default = null): array|null { + if ($key === 'commitments') { + return parent::validated($key, $default); + } // phpcs:enable $nutritionnal_values = json_encode([ "energyKj" => [ @@ -118,7 +123,7 @@ class StoreProductRequest extends FormRequest ]); return array_merge( - parent::validated(), + parent::validated($key, $default), [ 'nutritionnal_values' => $nutritionnal_values ] @@ -150,6 +155,8 @@ class StoreProductRequest extends FormRequest 'ingredients' => trans('validation.custom.ingredients'), 'nutritionnal_values' => trans('validation.custom.nutritionnal_values'), 'range_id' => trans('models.classes.range'), + 'commitments' => trans('Engagements associés au produit'), + 'commitments.*.id' => trans('Élément parmis les engagements associés au produit'), 'published' => trans('validation.custom.activated'), ]; } diff --git a/resources/lang/en/crud.php b/resources/lang/en/crud.php index 04fe327..22a0fb9 100644 --- a/resources/lang/en/crud.php +++ b/resources/lang/en/crud.php @@ -61,7 +61,7 @@ return [ 'minicrud' => [ 'visibility_label' => 'Visibility', 'visibility_helper' => 'Check to make it visible.', - 'enum_select' => 'Select :enum from the list.', + 'select' => 'Select :entity from the list.', 'associated_enum' => 'Associated :enum', 'dimensions_must_be' => 'Must be :widthpx (width) by :heightpx (height).', 'picture_title_helper' => 'Useful for users, displayed by moving the mouse over the image', diff --git a/resources/lang/fr/crud.php b/resources/lang/fr/crud.php index 644d141..a731cff 100644 --- a/resources/lang/fr/crud.php +++ b/resources/lang/fr/crud.php @@ -63,7 +63,7 @@ return [ 'minicrud' => [ 'visibility_label' => 'Visibilité', 'visibility_helper' => 'Cocher pour rendre visible.', - 'enum_select' => 'Sélectionnez :enum dans la liste.', + 'select' => 'Sélectionnez :entity dans la liste.', 'associated_enum' => 'Associé :enum', 'dimensions_must_be' => 'Doit être :widthpx (largeur) par :heightpx (hauteur).', 'picture_title_helper' => 'Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image', diff --git a/resources/ts/bo/components/BelongsToManyDropdownComponent.vue b/resources/ts/bo/components/BelongsToManyDropdownComponent.vue index bda8283..ba0ab8c 100644 --- a/resources/ts/bo/components/BelongsToManyDropdownComponent.vue +++ b/resources/ts/bo/components/BelongsToManyDropdownComponent.vue @@ -77,26 +77,6 @@ export default defineComponent({ components: { VueTagsInputCls, }, - beforeMount() { - if (!this.$attrs.json) { - throw new Error("this component requires json"); - } - }, - mounted() { - const json = String(this.$attrs.json ?? "{}"), - data = JSON.parse(json); - this.name = data.name; - this.selectedItems = this.parseTags(data.value); - this.allItems = this.parseTags(data.itemsList); - this.placeholder = data.placeholder; - // * Min and max calc. - this.min = Number.parseInt((data?.itemLimit ?? [])[0] ?? 0); - this.min = this.min < 0 ? 0 : this.min; - this.max = Number.parseInt((data?.itemLimit ?? [])[1] ?? 0); - this.max = this.max <= this.min ? null : this.max; - // * Error parsing - this.allErrors = data.errors; - }, data(): { name: string; item: string; @@ -124,6 +104,26 @@ export default defineComponent({ message: null, }; }, + beforeMount() { + if (!this.$attrs.json) { + throw new Error("this component requires json"); + } + }, + mounted() { + const json = String(this.$attrs.json ?? "{}"), + data = JSON.parse(json); + this.name = data.name; + this.selectedItems = this.parseTags(data.value); + this.allItems = this.parseTags(data.itemsList); + this.placeholder = data.placeholder; + // * Min and max calc. + this.min = Number.parseInt((data?.itemLimit ?? [])[0] ?? 0); + this.min = this.min < 0 ? 0 : this.min; + this.max = Number.parseInt((data?.itemLimit ?? [])[1] ?? 0); + this.max = this.max <= this.min ? null : this.max; + // * Error parsing + this.allErrors = data.errors; + }, methods: { parseTags(selectedItems: Array): Array { return selectedItems.map((item: CustomTag) => { diff --git a/resources/views/bo/pages/products/form.blade.php b/resources/views/bo/pages/products/form.blade.php index 84c3e4f..521ab10 100644 --- a/resources/views/bo/pages/products/form.blade.php +++ b/resources/views/bo/pages/products/form.blade.php @@ -154,10 +154,39 @@ 'associatedModels' => $rangeModels ?? null, 'foreignLabel' => 'title', 'helper' => __('crud.minicrud.select', [ - 'entity' => __('models.classes.product'), + 'entity' => __('models.classes.range'), + ]), + ]) + + + + + {{-- COMMITMENTS --}} +
+
+ {{ Str::of(__('models.classes.commitment'))->plural()->ucfirst() }} +
+
+ @include('bo.partials.inputs.pivot-belongsToMany', [ + 'id' => 'productCommitments', + 'label' => __(':field :inter:model', [ + 'field' => Str::of(__('models.classes.commitment'))->plural()->ucfirst(), + 'inter' => __('validation.custom.of_the.male'), + 'model' => __('models.classes.product'), + ]), + 'name' => 'commitments', + 'required' => false, + 'model' => $productModel ?? null, + 'itemsList' => $commitmentModels ?? null, + 'itemLimit' => [0, 4], + 'placeholder' => 'Rechercher un engagement', + 'helper' => __('Séléctionnez le ou les :model1 à associer à ce :model2 (minimum :min, maximum :max)', [ + 'model1' => Str::plural(__('models.classes.commitment')), + 'model2' => __('models.classes.product'), + 'min' => 0, + 'max' => 4, ]), ]) -
diff --git a/resources/views/bo/partials/inputs/pivot-belongsToMany.blade.php b/resources/views/bo/partials/inputs/pivot-belongsToMany.blade.php index 2f8adbe..3b33cbe 100644 --- a/resources/views/bo/partials/inputs/pivot-belongsToMany.blade.php +++ b/resources/views/bo/partials/inputs/pivot-belongsToMany.blade.php @@ -10,10 +10,15 @@ $model || The model we're creating/editing || Model class || OPTIONNAL || null --}} +@if(!empty($label)) + +@endif @php $data = [ 'name' => $name, - 'value' => Arr::wrap(old($name) ?? ($model->{$name} ?? [])), + 'value' => old($name, $model->{$name} ?? []) ?? [], 'placeholder' => $placeholder, 'itemsList' => $itemsList, 'itemLimit' => $itemLimit ?? null, diff --git a/resources/views/modules/minicrud-form-inputs.blade.php b/resources/views/modules/minicrud-form-inputs.blade.php index afd71c7..4386189 100644 --- a/resources/views/modules/minicrud-form-inputs.blade.php +++ b/resources/views/modules/minicrud-form-inputs.blade.php @@ -278,7 +278,7 @@ 'value' => old("data.{$k}.value", $model->data[$k]['value'] ?? null), 'required' => true, 'associatedModels' => $selectedEnum ?? [], - 'helper' => __('crud.minicrud.enum_select', ['enum' => $input['label']]), + 'helper' => __('crud.minicrud.select', ['entity' => $input['label']]), ]) @include('modules.input-error', [ 'inputName' => "data.{$k}.value",