diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php index 6b0ef9c..5e232a6 100644 --- a/app/Http/Controllers/ProductController.php +++ b/app/Http/Controllers/ProductController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Http\Controllers\Controller; +use App\Http\Requests\Products\IndexFilterRequest; use App\Http\Requests\Products\StoreProductRequest; use App\Http\Requests\Products\UpdateProductRequest; use App\Jobs\ExportProduct; @@ -12,7 +13,6 @@ use App\Models\Product; use App\Traits\Controllers\HasDocuments; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; -use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; @@ -23,27 +23,29 @@ class ProductController extends Controller /** * Display a listing of the resource. * - * @param \Illuminate\Http\Request $request + * @param \App\Http\Requests\Products\IndexFilterRequest $request * @return \Illuminate\Contracts\View\View */ - public function index(Request $request) + public function index(IndexFilterRequest $request) { + // DB::enableQueryLog(); /** @var \Illuminate\Database\Eloquent\Builder $brands */ - $brands = Brand::query(); + $brandsQuery = Brand::query(); - /** @var \Illuminate\Database\Eloquent\Builder $products */ - $products = Product::query(); + /** @var \Illuminate\Database\Eloquent\Builder $productsQuery */ + $productsQuery = Product::query(); - $this->requestFilters($products, $request); + $this->requestFilters($request, $productsQuery); - $this->sortQuery($products); + $this->sortQuery($productsQuery); - $products = $this->paginate($products); + $products = $this->paginate($productsQuery); + // dd(DB::getQueryLog(), $products->items()); /** @var array $printMultiProduct Array of id */ $printMultiProduct = session('printMultiProduct') ?? []; - $brands = $brands->get(); + $brands = $brandsQuery->get(); $keywords = Keyword::query()->where('keyword_cat', 'LIKE', 'product_%')->get(); @@ -51,8 +53,7 @@ class ProductController extends Controller 'products' => $products, 'brands' => $brands, 'keywords' => $keywords, - 'printMultiProduct' => $printMultiProduct, - 'queryParameters' => $request->all(), + 'printMultiProduct' => $printMultiProduct ]); } @@ -385,47 +386,60 @@ class ProductController extends Controller } /** - * Show the form for creating a new resource. + * Applies filters from products.index * - * @param \Illuminate\Database\Eloquent\Builder $products - * @param \Illuminate\Http\Request $request + * @param \App\Http\Requests\Products\IndexFilterRequest $request + * @param \Illuminate\Database\Eloquent\Builder $productsQuery * @return \Illuminate\Contracts\View\View * @phpcs:disable Generic.Metrics.NestingLevel.TooHigh */ - private function requestFilters(Builder $products, Request $request): \Illuminate\Database\Eloquent\Builder - { + private function requestFilters( + IndexFilterRequest $request, + Builder $productsQuery + ): \Illuminate\Database\Eloquent\Builder { //phpcs:enable - $queryFetch = ['name', 'claims', 'origins', 'keywords', 'date_before', 'date_after']; - foreach (Arr::only($request->all(), $queryFetch) as $key => $queryParameter) { - if ($request->sort_col === null && $request->sort_way === null && $request->rst === null) { - $products->when( - isset($queryParameter) && $queryParameter != 0, - function ($q) use ($queryParameter, $key) { - if ($key === "name") { - $q->where($key, 'LIKE', '%' . $queryParameter . '%'); - } elseif ($key === "claims" || $key === "origins") { - foreach ($queryParameter as $item) { - $q->where($key, 'LIKE', '%{"id":"' . $item['value'] . '"}%'); - } - } elseif ($key === "keywords") { - foreach ($queryParameter as $keyword) { - $q->whereHas('productKeywords', function ($q) use ($keyword, $key) { - $q->where($key . '.id', intval($keyword['value'])); - }); - } - } elseif ($key === "date_before" || $key === "date_after") { - if ($key === "date_before") { - $q->whereDate('created_at', '>=', $queryParameter); - } else { - $q->whereDate('created_at', '<=', $queryParameter); - } - } else { - $q->where($key, $queryParameter); - } //end if - } - ); - } //end if + foreach ($request->validated() as $parameterName => $queryParameter) { + $productsQuery->when( + !empty($queryParameter), + function (Builder $q) use ($queryParameter, $parameterName) { + switch ($parameterName) { + // * String type parameters (Approx search) + case 'name': + case 'shop': + case 'fair': + case 'catalogue': + case 'specified_claim': + $q->where($parameterName, 'LIKE', "%{$queryParameter}%"); + break; + // * Number type parameters (Approx search) + case 'gencode': + $q->where($parameterName, \intval($queryParameter)); + break; + // * Date type parameters + case 'date_before': + $q->whereDate('created_at', '>=', $queryParameter); + break; + case 'date_after': + $q->whereDate('created_at', '<=', $queryParameter); + break; + // * Enums Array + case 'claims': + case 'origins': + $q->whereJsonContains($parameterName, \collect($queryParameter) + ->map(fn ($enumValue) => \intval($enumValue))); + break; + // * RelationShips parameters + case 'keywords': + $q->whereHas('productKeywords', function (Builder $subQ) use ($queryParameter) { + $subQ->whereIn('keywords.id', $queryParameter); + }); + break; + default: + $q->where($parameterName, $queryParameter); + } //end switch + } + ); } //end foreach - return $products; + return $productsQuery; } } diff --git a/app/Http/Requests/Products/IndexFilterRequest.php b/app/Http/Requests/Products/IndexFilterRequest.php new file mode 100644 index 0000000..e6009cd --- /dev/null +++ b/app/Http/Requests/Products/IndexFilterRequest.php @@ -0,0 +1,60 @@ + + */ + public function rules(): array + { + return [ + 'name' => 'nullable|string', + 'brand_id' => 'nullable|exists:brands,id', + 'gencod' => 'nullable|string', + + 'source' => ['nullable', new Enum(SourceEnum::class)], + 'shop' => 'nullable|string', + 'fair' => 'nullable|string', + 'catalogue' => 'nullable|string', + 'claims' => 'nullable|array', + 'claims.*' => ['required', new Enum(ClaimEnum::class)], + 'specified_claim' => 'nullable|string', + 'origins' => 'nullable|array', + 'origins.*' => ['required', new Enum(OriginEnum::class)], + 'certification' => ['nullable', new Enum(CertificationEnum::class)], + 'distribution_network' => ['nullable', new Enum(DistributionNetworkEnum::class)], + 'ray' => ['nullable', new Enum(RayEnum::class)], + 'product_range' => ['nullable', new Enum(RangeEnum::class)], + 'geo_area' => ['nullable', new Enum(GeoAreaEnum::class)], + 'keywords' => 'nullable|array', + 'keywords.*' => 'required|exists:keywords,id', + 'date_before' => 'nullable|date:Y-m-d', + 'date_after' => 'nullable|date:Y-m-d', + ]; + } +} diff --git a/resources/ts/components/SelectMultipleEnumComponent.vue b/resources/ts/components/SelectMultipleEnumComponent.vue index 63353e7..78d3d00 100644 --- a/resources/ts/components/SelectMultipleEnumComponent.vue +++ b/resources/ts/components/SelectMultipleEnumComponent.vue @@ -41,7 +41,7 @@ {{ intHelper }} @@ -149,13 +149,13 @@ export default defineComponent({ parseTags(intSelectedItem: number[]): CustomTag[] { const out: CustomTag[] = []; intSelectedItem.forEach((intItem: number) => { - const selectedItem = this.intAllItems.find(item => String(item.value) === String(intItem)); + const selectedItem = this.intAllItems.find(item => String(item.id ?? item.value) === String(intItem)); if (!selectedItem) { console.debug(intItem); throw new Error(`Could not find enum ${intItem}`); } out.push({ - id: String(selectedItem.value), + id: String(selectedItem.id ?? selectedItem.value), value: String(selectedItem.value), text: String(selectedItem.text) } as LaravelModel as CustomTag); diff --git a/resources/views/pages/products/product-filters.blade.php b/resources/views/pages/products/product-filters.blade.php index 430f80d..366b139 100644 --- a/resources/views/pages/products/product-filters.blade.php +++ b/resources/views/pages/products/product-filters.blade.php @@ -1,10 +1,10 @@ @php $iArgs = []; - if(request()->sort_col) { + if (request()->sort_col) { $iArgs['sort_col'] = request()->sort_col; } - if(request()->search) { + if (request()->search) { $iArgs['search'] = request()->sort_way; } @endphp @@ -12,173 +12,181 @@