Browse Source

refactored filters, ranges, dates. added sku index

Alexander Musikhin 8 tháng trước cách đây
mục cha
commit
977af10b2d

+ 0 - 34
app/Helpers/DBHelper.php

@@ -1,34 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace App\Helpers;
-
-use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Str;
-
-class DBHelper
-{
-    /**
-     * @param $column
-     * @return array
-     */
-    public static function getFilters($column, $model): array
-    {
-        $uniqueValues =  DB::table((new $model)->getTable())
-            ->select($column)
-            ->distinct()
-            ->get()
-            ->pluck($column)
-            ->toArray();
-        $result = [];
-        foreach ($uniqueValues as $val){
-            if(str_ends_with($column, '_id')) {
-                $relation = Str::camel(str_replace('_id', '', $column));
-                $result[$val] = $model::query()->where($column, '=', $val)->first()->$relation->name;
-            } else {
-                $result[$val] = $val;
-            }
-        }
-        return $result;
-    }
-}

+ 154 - 0
app/Http/Controllers/Controller.php

@@ -2,11 +2,165 @@
 
 namespace App\Http\Controllers;
 
+use App\Helpers\DateHelper;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
 use Illuminate\Foundation\Validation\ValidatesRequests;
+use Illuminate\Http\Request;
 use Illuminate\Routing\Controller as BaseController;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Str;
 
 class Controller extends BaseController
 {
     use AuthorizesRequests, ValidatesRequests;
+
+    protected array $data;
+
+    /**
+     * @param Model $model
+     * @param string ...$columnNames
+     * @return void
+     */
+    protected function createDateFilters(Model $model, string ...$columnNames): void
+    {
+        foreach ($columnNames as $columnName) {
+            $this->data['dates'][$columnName] = [
+                'title' => $this->data['header'][$columnName],
+                'min'   => DateHelper::getDateForDB($model::query()->min($columnName) ?? ''),
+                'max'   => DateHelper::getDateForDB($model::query()->max($columnName) ?? ''),
+            ];
+        }
+    }
+
+    /**
+     * @param Model $model
+     * @param array $columnNames
+     * @return void
+     */
+    protected function createRangeFilters(Model $model, string ...$columnNames): void
+    {
+        foreach ($columnNames as $columnName) {
+            if(str_ends_with($columnName, '_price')) {
+                $this->data['ranges'][$columnName] = [
+                    'title' => $this->data['header'][$columnName . '_txt'],
+                    'min'   => $model::query()->min($columnName) / 100,
+                    'max'   => $model::query()->max($columnName) / 100,
+                ];
+            } else {
+                $this->data['ranges'][$columnName] =  [
+                    'title' => $this->data['header'][$columnName ],
+                    'min'   => $model::query()->min($columnName),
+                    'max'   => $model::query()->max($columnName),
+                ];
+            }
+        }
+    }
+
+    /**
+     * @param Model $model
+     * @param array $columns
+     * @return void
+     */
+    protected function createFilters(Model $model, string ...$columns): void
+    {
+        foreach ($columns as $column) {
+            $uniqueValues =  DB::table(($model)->getTable())
+                ->select($column)
+                ->distinct()
+                ->get()
+                ->pluck($column)
+                ->toArray();
+            $result = [];
+            foreach ($uniqueValues as $val){
+                if(str_ends_with($column, '_id')) {
+                    $relation = Str::camel(str_replace('_id', '', $column));
+                    $result[$val] = $model::query()->where($column, '=', $val)->first()->$relation->name;
+                } else {
+                    $result[$val] = $val;
+                }
+            }
+            $this->data['filters'][$column] = [
+                'title'     => $this->data['header'][$column],
+                'values'    => $result
+            ];
+        }
+    }
+
+
+    /**
+     * @param Model $model
+     * @param Request $request
+     * @return void
+     */
+    protected function setSortAndOrderBy(Model $model, Request $request)
+    {
+        // ------- setup sort and order --------------------------------------------------------------------------------
+        $this->data['sortBy'] = (!empty($request->sortBy))
+            ? Str::replace('_txt', '', $request->sortBy) // remove '_txt' fields modifier
+            : $model::DEFAULT_SORT_BY ?? 'created_at';
+
+        // check for sortBy is valid field
+        $p = new $model();
+        if(!in_array($this->data['sortBy'], array_merge(['id', 'created_at'], $p->getFillable()))) {
+            $this->data['sortBy'] = $model::DEFAULT_SORT_BY ?? 'created_at';
+        }
+
+        // set order
+        $this->data['orderBy'] = (!empty($request->order)) ? 'desc' : 'asc';
+    }
+
+    /**
+     * @param Builder $query
+     * @param Request $request
+     * @return void
+     */
+    protected function acceptFilters(Builder $query, Request $request)
+    {
+        // accept filters
+        if(!empty($request->filters) && is_array($request->filters)) {
+            foreach ($request->filters as $filterName => $filterValue) {
+                if(!$filterValue) continue;
+
+                if(Str::contains($filterName, 'price')) {
+                    $filterValue = $filterValue * 100;
+                }
+
+                if(Str::endsWith($filterName, '_from')) {
+                    if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
+                        $filterValue .= ' 00:00:00';
+                    }
+                    $query->where(Str::replace('_from', '', $filterName), '>=', $filterValue);
+                } elseif(Str::endsWith($filterName, '_to')) {
+                    if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
+                        $filterValue .= ' 23:59:59';
+                    }
+                    $query->where(Str::replace('_to', '', $filterName), '<=', $filterValue);
+                } else {
+                    $query->where($filterName, '=', $filterValue);
+                }
+            }
+        }
+    }
+
+    /**
+     * @param Builder $query
+     * @param Request $request
+     * @return void
+     */
+    protected function acceptSearch(Builder $query, Request $request)
+    {
+        // accept search
+        if(!empty($request->s)) {
+            $s = $request->s;
+            $searchFields = $this->data['searchFields'];
+            $query->where(function ($query) use ($searchFields, $s) {
+                foreach ($searchFields as $searchField) {
+                    $query->orWhere($searchField, 'LIKE', '%' . $s . '%');
+                }
+            });
+        }
+    }
+
 }

+ 17 - 94
app/Http/Controllers/OrderController.php

@@ -2,8 +2,6 @@
 
 namespace App\Http\Controllers;
 
-use App\Helpers\DateHelper;
-use App\Helpers\DBHelper;
 use App\Http\Requests\Order\StoreOrderRequest;
 use App\Models\Brigadier;
 use App\Models\Dictionary\Area;
@@ -11,10 +9,8 @@ use App\Models\Dictionary\District;
 use App\Models\ObjectType;
 use App\Models\Order;
 use App\Models\OrderStatus;
-use App\Models\Product;
 use App\Models\User;
 use Illuminate\Http\Request;
-use Illuminate\Support\Str;
 
 class OrderController extends Controller
 {
@@ -37,7 +33,14 @@ class OrderController extends Controller
             'order_status_id'           => 'Статус',
             'tg_group_name'             => 'Имя группы в ТГ',
             'tg_group_link'             => 'Ссылка на группу в ТГ',
-        ]
+        ],
+        'searchFields' => [
+            'comment',
+            'object_address',
+            'tg_group_name',
+            'tg_group_link',
+            'contract_number',
+        ],
     ];
 
     public function __construct()
@@ -56,98 +59,18 @@ class OrderController extends Controller
      */
     public function index(Request $request)
     {
-        $this->data['searchFields'] = [
-            'comment',
-            'object_address',
-            'tg_group_name',
-            'tg_group_link',
-            'contract_number',
-        ];
-
-        $filters = [
-            'user_id' => [
-                'title' => 'Менеджер',
-                'values' => DBHelper::getFilters('user_id', Order::class),
-            ],
-            'district_id' => [
-                'title' => 'Округ',
-                'values' => DBHelper::getFilters('district_id', Order::class),
-            ],
-            'area_id' => [
-                'title' => 'Район',
-                'values' => DBHelper::getFilters('area_id', Order::class),
-            ],
-            'object_type_id' => [
-                'title' => 'Тип объекта',
-                'values' => DBHelper::getFilters('object_type_id', Order::class),
-            ],
-            'brigadier_id' => [
-                'title' => 'Бригадир',
-                'values' => DBHelper::getFilters('brigadier_id', Order::class),
-            ],
-            'order_status_id' => [
-                'title' => 'Статус',
-                'values' => DBHelper::getFilters('order_status_id', Order::class),
-            ],
-        ];
-        $ranges = [];
-        $dates = [];
-
+        $model = new Order;
         // fill filters
-        $this->data['filters'] = $filters;
-        $this->data['dates'] = $dates;
-        $this->data['ranges'] = $ranges;
-
-        $q = Order::query();
-
-        // accept filters
-        if(!empty($request->filters) && is_array($request->filters)) {
-            foreach ($request->filters as $filterName => $filterValue) {
-                if(!$filterValue) continue;
-
-                if(Str::contains($filterName, 'price')) {
-                    $filterValue = $filterValue * 100;
-                }
-
-                if(Str::endsWith($filterName, '_from')) {
-                    if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
-                        $filterValue .= ' 00:00:00';
-                    }
-                    $q->where(Str::replace('_from', '', $filterName), '>=', $filterValue);
-                } elseif(Str::endsWith($filterName, '_to')) {
-                    if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
-                        $filterValue .= ' 23:59:59';
-                    }
-                    $q->where(Str::replace('_to', '', $filterName), '<=', $filterValue);
-                } else {
-                    $q->where($filterName, '=', $filterValue);
-                }
-            }
-        }
+        $this->createFilters($model, 'user_id', 'district_id', 'area_id', 'object_type_id', 'brigadier_id', 'order_status_id');
+        $this->createDateFilters($model, 'contract_date', 'installation_date');
+        $this->data['ranges'] = [];
 
-        // accept search
-        if(!empty($request->s)) {
-            $s = $request->s;
-            $searchFields = $this->data['searchFields'];
-            $q->where(function ($query) use ($searchFields, $s) {
-                foreach ($searchFields as $searchField) {
-                    $query->orWhere($searchField, 'LIKE', '%' . $s . '%');
-                }
-            });
-        }
-        // ------- setup sort and order --------------------------------------------------------------------------------
-        $this->data['sortBy'] = (!empty($request->sortBy))
-            ? Str::replace('_txt', '', $request->sortBy) // remove '_txt' fields modifier
-            : Order::DEFAULT_SORT_BY;
-
-        // check for sortBy is valid field
-        $p = new Order();
-        if(!in_array($this->data['sortBy'], array_merge(['id', 'created_at'], $p->getFillable()))) {
-            $this->data['sortBy'] = Order::DEFAULT_SORT_BY;
-        }
+        $q = $model::query();
+
+        $this->acceptFilters($q, $request);
+        $this->acceptSearch($q, $request);
+        $this->setSortAndOrderBy($model, $request);
 
-        // set order
-        $this->data['orderBy'] = (!empty($request->order)) ? 'desc' : 'asc';
         $q->orderBy($this->data['sortBy'], $this->data['orderBy']);
         $this->data['orders'] = $q->paginate()->withQueryString();
 

+ 8 - 99
app/Http/Controllers/ProductController.php

@@ -2,8 +2,6 @@
 
 namespace App\Http\Controllers;
 
-use App\Helpers\DateHelper;
-use App\Helpers\DBHelper;
 use App\Jobs\Export\ExportCatalog;
 use App\Jobs\Import\ImportCatalog;
 use App\Models\Product;
@@ -49,109 +47,20 @@ class ProductController extends Controller
 
     public function index(Request $request)
     {
-        $filters = [
-            'type_tz' => [
-                'title'     => 'Тип по ТЗ',
-                'values'    => DBHelper::getFilters('type_tz', Product::class)
-            ],
-            'type' => [
-                'title'     => 'Тип',
-                'values'    => DBHelper::getFilters('type', Product::class)
-            ],
-        ];
-
-        $ranges = [
-            'product_price' => [
-                'title' => 'Цена товара',
-                'min'   => Product::query()->min('product_price') / 100,
-                'max'   => Product::query()->max('product_price') / 100,
-            ],
-            'installation_price' => [
-                'title' => 'Цена установки',
-                'min'   => Product::query()->min('installation_price') / 100,
-                'max'   => Product::query()->max('installation_price') / 100,
-            ],
-            'service_price' => [
-                'title' => 'Цена обслуживания',
-                'min'   => Product::query()->min('service_price') / 100,
-                'max'   => Product::query()->max('service_price') / 100,
-            ],
-            'total_price' => [
-                'title' => 'Итоговая цена',
-                'min'   => Product::query()->min('total_price') / 100,
-                'max'   => Product::query()->max('total_price') / 100,
-            ],
-        ];
-
-        $dates = [
-            'created_at' => [
-                'title' => 'Дата создания',
-                'min'   => DateHelper::getDateForDB(Product::query()->min('created_at') ?? ''),
-                'max'   => DateHelper::getDateForDB(Product::query()->max('created_at') ?? ''),
-            ]
-        ];
-
+        $model = new Product;
         // fill filters
-        $this->data['filters'] = $filters;
-        $this->data['dates'] = $dates;
-        $this->data['ranges'] = $ranges;
-
-
+        $this->createFilters($model, 'type_tz', 'type');
+        $this->createRangeFilters($model, 'nomenclature_number', 'product_price', 'installation_price', 'service_price', 'total_price');
+        $this->createDateFilters($model, 'created_at');
 
         // create request
-        $q = Product::query();
-
-        // accept filters
-        if(!empty($request->filters) && is_array($request->filters)) {
-            foreach ($request->filters as $filterName => $filterValue) {
-                if(!$filterValue) continue;
-
-                if(Str::contains($filterName, 'price')) {
-                    $filterValue = $filterValue * 100;
-                }
-
-                if(Str::endsWith($filterName, '_from')) {
-                    if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
-                        $filterValue .= ' 00:00:00';
-                    }
-                    $q->where(Str::replace('_from', '', $filterName), '>=', $filterValue);
-                } elseif(Str::endsWith($filterName, '_to')) {
-                    if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
-                        $filterValue .= ' 23:59:59';
-                    }
-                    $q->where(Str::replace('_to', '', $filterName), '<=', $filterValue);
-                } else {
-                    $q->where($filterName, '=', $filterValue);
-                }
-            }
-        }
+        $q = $model::query();
 
-        // accept search
-        if(!empty($request->s)) {
-            $s = $request->s;
-            $searchFields = $this->data['searchFields'];
-            $q->where(function ($query) use ($searchFields, $s) {
-                foreach ($searchFields as $searchField) {
-                    $query->orWhere($searchField, 'LIKE', '%' . $s . '%');
-                }
-            });
-        }
-
-        // ------- setup sort and order --------------------------------------------------------------------------------
-        $this->data['sortBy'] = (!empty($request->sortBy))
-            ? Str::replace('_txt', '', $request->sortBy) // remove '_txt' fields modifier
-            : Product::DEFAULT_SORT_BY;
-
-        // check for sortBy is valid field
-        $p = new Product();
-        if(!in_array($this->data['sortBy'], array_merge(['id', 'created_at'], $p->getFillable()))) {
-            $this->data['sortBy'] = Product::DEFAULT_SORT_BY;
-        }
+        $this->acceptFilters($q, $request);
+        $this->acceptSearch($q, $request);
 
-        // set order
-        $this->data['orderBy'] = (!empty($request->order)) ? 'desc' : 'asc';
+        $this->setSortAndOrderBy($model, $request);
         $q->orderBy($this->data['sortBy'], $this->data['orderBy']);
-//        $q->dumpRawSql();
 
         $this->data['products'] = $q->paginate()->withQueryString();
         return view('catalog.index', $this->data);

+ 57 - 1
app/Http/Controllers/ProductSKUController.php

@@ -2,9 +2,65 @@
 
 namespace App\Http\Controllers;
 
+use App\Helpers\DateHelper;
+use App\Models\ProductSKU;
 use Illuminate\Http\Request;
+use Illuminate\Support\Str;
 
+// Склад - Заказы МАФ
 class ProductSKUController extends Controller
 {
-    //
+    protected array $data = [
+        'active'    => 'product_sku',
+        'title'     => 'Заказы МАФ',
+        'id'        => 'product_sku',
+        'header'    => [
+            'id'                                => 'ID',
+
+            'order-id'                          => 'ID площадки',
+
+            'status'                            => 'Статус',
+            'rfid'                              => 'RFID',
+            'factory_number'                    => 'Номер фабрики',
+            'manufacture_date'                  => 'Дата производства',
+            'service_life'                      => 'Срок службы',
+            'certificate_number'                => 'Номер сертификата',
+            'certificate_date'                  => 'Дата сертификата',
+            'certificate_issuer'                => 'Орган сертификации',
+            'certificate_type'                  => 'Вид сертификации',
+
+            'product-nomenclature_number'       => 'Номер номенклатуры',
+            'product-article'                   => 'Артикул',
+            'product-name_tz'                   => 'Наименование ТЗ',
+            'product-type_tz'                   => 'Тип по ТЗ',
+            'product-type'                      => 'Тип',
+            'product-manufacturer_name'         => 'Наименование производителя',
+
+        ],
+        'searchFields' =>  [
+            'rfid',
+            'factory_number',
+            'certificate_number',
+        ],
+    ];
+    public function index(Request $request)
+    {
+        $model = new ProductSKU;
+
+        $this->createFilters($model, 'status');
+        $this->createDateFilters($model, 'certificate_date', 'manufacture_date');
+        $this->data['ranges'] = [];
+
+        $q = $model::query();
+
+        $this->acceptFilters($q, $request);
+        $this->acceptSearch($q, $request);
+        $this->setSortAndOrderBy($model, $request);
+
+        $q->orderBy($this->data['sortBy'], $this->data['orderBy']);
+
+
+        $this->data['products_sku'] = $q->paginate()->withQueryString();
+        return view('products_sku.index', $this->data);
+    }
 }

+ 16 - 0
app/Models/ProductSKU.php

@@ -3,11 +3,14 @@
 namespace App\Models;
 
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\SoftDeletes;
 
 class ProductSKU extends Model
 {
     use SoftDeletes;
+
+    const DEFAULT_SORT_BY = 'created_at';
     protected $fillable = [
         'product_id',
         'order_id',
@@ -22,4 +25,17 @@ class ProductSKU extends Model
         'certificate_type',
     ];
     public $table = 'products_sku';
+
+    /**
+     * @return BelongsTo
+     */
+    public function product(): BelongsTo
+    {
+        return $this->belongsTo(Product::class, 'product_id', 'id');
+    }
+
+    public function order(): BelongsTo
+    {
+        return $this->belongsTo(Order::class, 'order_id', 'id');
+    }
 }

+ 1 - 0
resources/views/layouts/menu.blade.php

@@ -1,4 +1,5 @@
 <li class="nav-item"><a class="nav-link" href="{{ route('order.index') }}">Площадки</a></li>
+<li class="nav-item"><a class="nav-link" href="{{ route('product_sku.index') }}">Заказы МАФ</a></li>
 
 <li class="nav-item"><a class="nav-link" href="{{ route('catalog.index') }}">Каталог</a></li>
 

+ 8 - 2
resources/views/partials/table.blade.php

@@ -47,13 +47,19 @@
             <tr>
                 @foreach($header as $headerName => $headerTitle)
                     <td class="column_{{$headerName}}" @isset($routeName) onclick="location.href='{{ route($routeName, $string->id) }}'" @endisset>
-                        @if(str_ends_with($headerName, '_id'))
+                        @if(str_contains($headerName, '-'))
+                            @php
+                                list($rel, $field) = explode('-', $headerName);
+
+                            @endphp
+                            {!! $string->$rel->$field !!}
+                        @elseif(str_ends_with($headerName, '_id'))
                             @php
                                 $relation = \Illuminate\Support\Str::camel(str_replace('_id', '', $headerName));
                             @endphp
                             {!! $string->$relation?->name; !!}
                         @elseif(str_ends_with($headerName, '_date'))
-                            {{ \App\Helpers\DateHelper::getHumanDate($string->$headerName) }}
+                            {{ \App\Helpers\DateHelper::getHumanDate($string->$headerName, true) }}
                         @else
                             {!! $string->$headerName !!}
                         @endif

+ 33 - 0
resources/views/products_sku/index.blade.php

@@ -0,0 +1,33 @@
+@extends('layouts.app')
+
+@section('content')
+
+    <div class="row mb-3">
+        <div class="col-6">
+            <h3>Заказы МАФ</h3>
+        </div>
+        <div class="col-6 text-end">
+
+
+        </div>
+    </div>
+
+
+    @include('partials.table', [
+        'id'        => $id,
+        'header'    => $header,
+        'strings'   => $products_sku
+    ])
+
+    <div class="row pt-3 px-3">
+        <div class="col-12 pagination">
+            {{ $products_sku->links() }}
+        </div>
+    </div>
+
+
+    @if($errors->count())
+        @dump($errors)
+    @endif
+@endsection
+

+ 6 - 0
routes/web.php

@@ -3,6 +3,7 @@
 use App\Http\Controllers\AreaController;
 use App\Http\Controllers\OrderController;
 use App\Http\Controllers\ProductController;
+use App\Http\Controllers\ProductSKUController;
 use App\Http\Controllers\UserController;
 use App\Models\Role;
 use Illuminate\Support\Facades\Auth;
@@ -48,6 +49,11 @@ Route::middleware('auth:web')->group(function () {
     Route::post('order/{order}/store', [OrderController::class, 'store'])->name('order.update');
     Route::get('order/destroy', [OrderController::class, 'destroy'])->name('order.destroy');
 
+    // Склад - Заказы МАФ
+    Route::get('product_sku', [ProductSKUController::class, 'index'])->name('product_sku.index');
+    Route::get('product_sku/{product_sku}', [ProductSKUController::class, 'show'])->name('product_sku.show');
+
+
     // ajax search products
     Route::get('product/search', [ProductController::class, 'search'])->name('product.search');