Added commitments select in product CRUD

This commit is contained in:
Noah Lancien 2023-10-23 16:49:40 +02:00
parent 6e433628b5
commit a17953deb1
8 changed files with 85 additions and 34 deletions

View file

@ -5,6 +5,7 @@ namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\Products\StoreProductRequest; use App\Http\Requests\Bo\Products\StoreProductRequest;
use App\Http\Requests\Bo\Products\UpdateProductRequest; use App\Http\Requests\Bo\Products\UpdateProductRequest;
use App\Models\Commitment;
use App\Models\Product; use App\Models\Product;
use App\Models\Range; use App\Models\Range;
use App\Traits\Controllers\ChangesModelOrder; use App\Traits\Controllers\ChangesModelOrder;
@ -73,10 +74,12 @@ class ProductController extends Controller
*/ */
public function create(Product $product): \Illuminate\Contracts\View\View public function create(Product $product): \Illuminate\Contracts\View\View
{ {
$rangeModels = Range::all(); $rangeModels = Range::all();
$commitmentModels = Commitment::all();
return view('bo.pages.products.create', [ return view('bo.pages.products.create', [
'productModel' => $product, 'productModel' => $product,
'rangeModels' => $rangeModels, 'rangeModels' => $rangeModels,
'commitmentModels' => $commitmentModels,
]); ]);
} }
@ -90,9 +93,13 @@ class ProductController extends Controller
{ {
return DB::transaction(function () use ($request) { return DB::transaction(function () use ($request) {
$product = new Product(); $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()) { if ($product->saveOrFail()) {
$product->commitments()->attach(collect($request->validated('commitments'))->pluck('id'));
return redirect()->route('bo.products.edit', $product) return redirect()->route('bo.products.edit', $product)
->with('success', __('crud.messages.has_been_created', [ ->with('success', __('crud.messages.has_been_created', [
'model' => Str::ucfirst(__('models.classes.product')) 'model' => Str::ucfirst(__('models.classes.product'))
@ -113,10 +120,12 @@ class ProductController extends Controller
*/ */
public function edit(Product $product): \Illuminate\Contracts\View\View public function edit(Product $product): \Illuminate\Contracts\View\View
{ {
$rangeModels = Range::all(); $rangeModels = Range::all();
$commitmentModels = Commitment::all();
return view('bo.pages.products.edit', [ return view('bo.pages.products.edit', [
'productModel' => $product, 'productModel' => $product,
'rangeModels' => $rangeModels, 'rangeModels' => $rangeModels,
'commitmentModels' => $commitmentModels,
]); ]);
} }
@ -130,8 +139,9 @@ class ProductController extends Controller
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
{ {
return DB::transaction(function () use ($request, $product) { 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()) { if ($product->saveOrFail()) {
return redirect()->route('bo.products.edit', $product) return redirect()->route('bo.products.edit', $product)
->with('success', __('crud.messages.has_been_updated', [ ->with('success', __('crud.messages.has_been_updated', [

View file

@ -61,6 +61,8 @@ class StoreProductRequest extends FormRequest
'nutritionnal_values' => 'required|array', 'nutritionnal_values' => 'required|array',
'nutritionnal_values.*' => 'required|numeric|min:0', 'nutritionnal_values.*' => 'required|numeric|min:0',
'range_id' => 'required|exists:ranges,id', 'range_id' => 'required|exists:ranges,id',
'commitments' => 'nullable|array',
'commitments.*.id' => 'required|exists:commitments,id',
'published' => 'required|boolean', 'published' => 'required|boolean',
]; ];
return \array_merge( return \array_merge(
@ -76,11 +78,14 @@ class StoreProductRequest extends FormRequest
* *
* @param array|integer|string|null $key * @param array|integer|string|null $key
* @param mixed $default * @param mixed $default
* @return array * @return array|null
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed * @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 // phpcs:enable
$nutritionnal_values = json_encode([ $nutritionnal_values = json_encode([
"energyKj" => [ "energyKj" => [
@ -118,7 +123,7 @@ class StoreProductRequest extends FormRequest
]); ]);
return array_merge( return array_merge(
parent::validated(), parent::validated($key, $default),
[ [
'nutritionnal_values' => $nutritionnal_values 'nutritionnal_values' => $nutritionnal_values
] ]
@ -150,6 +155,8 @@ class StoreProductRequest extends FormRequest
'ingredients' => trans('validation.custom.ingredients'), 'ingredients' => trans('validation.custom.ingredients'),
'nutritionnal_values' => trans('validation.custom.nutritionnal_values'), 'nutritionnal_values' => trans('validation.custom.nutritionnal_values'),
'range_id' => trans('models.classes.range'), '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'), 'published' => trans('validation.custom.activated'),
]; ];
} }

View file

@ -61,7 +61,7 @@ return [
'minicrud' => [ 'minicrud' => [
'visibility_label' => 'Visibility', 'visibility_label' => 'Visibility',
'visibility_helper' => 'Check to make it visible.', 'visibility_helper' => 'Check to make it visible.',
'enum_select' => 'Select :enum from the list.', 'select' => 'Select :entity from the list.',
'associated_enum' => 'Associated :enum', 'associated_enum' => 'Associated :enum',
'dimensions_must_be' => 'Must be :widthpx (width) by :heightpx (height).', 'dimensions_must_be' => 'Must be :widthpx (width) by :heightpx (height).',
'picture_title_helper' => 'Useful for users, displayed by moving the mouse over the image', 'picture_title_helper' => 'Useful for users, displayed by moving the mouse over the image',

View file

@ -63,7 +63,7 @@ return [
'minicrud' => [ 'minicrud' => [
'visibility_label' => 'Visibilité', 'visibility_label' => 'Visibilité',
'visibility_helper' => 'Cocher pour rendre visible.', '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', 'associated_enum' => 'Associé :enum',
'dimensions_must_be' => 'Doit être :widthpx (largeur) par :heightpx (hauteur).', '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', 'picture_title_helper' => 'Utile pour les utilisateurs, s\'affiche en passant la souris sur l\'image',

View file

@ -77,26 +77,6 @@ export default defineComponent({
components: { components: {
VueTagsInputCls, 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(): { data(): {
name: string; name: string;
item: string; item: string;
@ -124,6 +104,26 @@ export default defineComponent({
message: null, 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: { methods: {
parseTags(selectedItems: Array<CustomTag>): Array<CustomTag> { parseTags(selectedItems: Array<CustomTag>): Array<CustomTag> {
return selectedItems.map((item: CustomTag) => { return selectedItems.map((item: CustomTag) => {

View file

@ -154,10 +154,39 @@
'associatedModels' => $rangeModels ?? null, 'associatedModels' => $rangeModels ?? null,
'foreignLabel' => 'title', 'foreignLabel' => 'title',
'helper' => __('crud.minicrud.select', [ 'helper' => __('crud.minicrud.select', [
'entity' => __('models.classes.product'), 'entity' => __('models.classes.range'),
]),
])
</div>
</div>
</fieldset>
</div>
{{-- COMMITMENTS --}}
<div class="col-12 col-md-6 mb-3">
<fieldset class="h-100 border p-3">
<legend>{{ Str::of(__('models.classes.commitment'))->plural()->ucfirst() }}</legend>
<div class="row">
<div class="col-12">
@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,
]), ]),
]) ])
</div> </div>
</div> </div>
</fieldset> </fieldset>

View file

@ -10,10 +10,15 @@
$model || The model we're creating/editing || Model class || OPTIONNAL || null $model || The model we're creating/editing || Model class || OPTIONNAL || null
--}} --}}
@if(!empty($label))
<label for="{{ $id }}" class="col-form-label">
<b>{{ $label }} {{ $required ? '*' : '' }}</b>
</label>
@endif
@php @php
$data = [ $data = [
'name' => $name, 'name' => $name,
'value' => Arr::wrap(old($name) ?? ($model->{$name} ?? [])), 'value' => old($name, $model->{$name} ?? []) ?? [],
'placeholder' => $placeholder, 'placeholder' => $placeholder,
'itemsList' => $itemsList, 'itemsList' => $itemsList,
'itemLimit' => $itemLimit ?? null, 'itemLimit' => $itemLimit ?? null,

View file

@ -278,7 +278,7 @@
'value' => old("data.{$k}.value", $model->data[$k]['value'] ?? null), 'value' => old("data.{$k}.value", $model->data[$k]['value'] ?? null),
'required' => true, 'required' => true,
'associatedModels' => $selectedEnum ?? [], 'associatedModels' => $selectedEnum ?? [],
'helper' => __('crud.minicrud.enum_select', ['enum' => $input['label']]), 'helper' => __('crud.minicrud.select', ['entity' => $input['label']]),
]) ])
@include('modules.input-error', [ @include('modules.input-error', [
'inputName' => "data.{$k}.value", 'inputName' => "data.{$k}.value",