|
@@ -17,6 +17,7 @@ use App\Services\Access\FieldAccessService;
|
|
|
use App\Services\NotificationService;
|
|
use App\Services\NotificationService;
|
|
|
use App\Services\ProductionOrderService;
|
|
use App\Services\ProductionOrderService;
|
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Contracts\View\View;
|
|
|
|
|
+use Illuminate\Database\Eloquent\Builder;
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\JsonResponse;
|
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\RedirectResponse;
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Request;
|
|
@@ -24,44 +25,54 @@ use Illuminate\Support\Arr;
|
|
|
|
|
|
|
|
class ProductionOrderController extends Controller
|
|
class ProductionOrderController extends Controller
|
|
|
{
|
|
{
|
|
|
|
|
+ private const INDEX_HEADER = [
|
|
|
|
|
+ 'id' => 'ID',
|
|
|
|
|
+ 'order_number' => 'Номер заказа',
|
|
|
|
|
+ 'customer_name' => 'Заказчик',
|
|
|
|
|
+ 'object_address' => 'Адрес объекта',
|
|
|
|
|
+ 'invoice_number' => '№ счёта',
|
|
|
|
|
+ 'payment_date' => 'Дата оплаты',
|
|
|
|
|
+ 'supply_working_days' => 'Срок поставки',
|
|
|
|
|
+ 'contract_shipment_date' => 'Дата отгрузки по договору',
|
|
|
|
|
+ 'application_shipment_date' => 'Дата отгрузки по заявке',
|
|
|
|
|
+ 'status_name' => 'Статус',
|
|
|
|
|
+ 'delivery_dates' => 'Дата доставки',
|
|
|
|
|
+ 'installation_dates' => 'Дата монтажа',
|
|
|
|
|
+ 'manager_id' => 'Менеджер',
|
|
|
|
|
+ 'note' => 'Примечание',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ private const SEARCH_FIELDS = [
|
|
|
|
|
+ 'order_number',
|
|
|
|
|
+ 'customer_name',
|
|
|
|
|
+ 'object_address',
|
|
|
|
|
+ 'invoice_number',
|
|
|
|
|
+ 'contract_number',
|
|
|
|
|
+ 'note',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
private const FIELD_MAP = [
|
|
private const FIELD_MAP = [
|
|
|
'status_name' => 'status',
|
|
'status_name' => 'status',
|
|
|
'execution_type_name' => 'execution_type',
|
|
'execution_type_name' => 'execution_type',
|
|
|
'items_count' => 'id',
|
|
'items_count' => 'id',
|
|
|
|
|
+ 'delivery_dates' => 'delivery_date',
|
|
|
|
|
+ 'installation_dates' => 'installation_date',
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
protected array $data = [
|
|
protected array $data = [
|
|
|
'active' => 'schedule_orders',
|
|
'active' => 'schedule_orders',
|
|
|
'title' => 'График заказов',
|
|
'title' => 'График заказов',
|
|
|
'id' => 'schedule_orders',
|
|
'id' => 'schedule_orders',
|
|
|
- 'header' => [
|
|
|
|
|
- 'id' => 'ID',
|
|
|
|
|
- 'order_number' => 'Номер заказа',
|
|
|
|
|
- 'customer_name' => 'Заказчик',
|
|
|
|
|
- 'object_address' => 'Адрес объекта',
|
|
|
|
|
- 'invoice_number' => '№ счёта',
|
|
|
|
|
- 'payment_date' => 'Дата оплаты',
|
|
|
|
|
- 'supply_working_days' => 'Срок поставки',
|
|
|
|
|
- 'contract_shipment_date' => 'Дата отгрузки по договору',
|
|
|
|
|
- 'application_shipment_date' => 'Дата отгрузки по заявке',
|
|
|
|
|
- 'status_name' => 'Статус',
|
|
|
|
|
- 'execution_type_name' => 'Тип',
|
|
|
|
|
- 'manager_id' => 'Менеджер',
|
|
|
|
|
- 'items_count' => 'МАФ',
|
|
|
|
|
- 'note' => 'Примечание',
|
|
|
|
|
- ],
|
|
|
|
|
- 'searchFields' => [
|
|
|
|
|
- 'order_number',
|
|
|
|
|
- 'customer_name',
|
|
|
|
|
- 'object_address',
|
|
|
|
|
- 'invoice_number',
|
|
|
|
|
- 'contract_number',
|
|
|
|
|
- 'note',
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ 'header' => self::INDEX_HEADER,
|
|
|
|
|
+ 'searchFields' => self::SEARCH_FIELDS,
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
public function index(Request $request): View
|
|
public function index(Request $request): View
|
|
|
{
|
|
{
|
|
|
|
|
+ $this->data['header'] = self::INDEX_HEADER;
|
|
|
|
|
+ $this->data['searchFields'] = self::SEARCH_FIELDS;
|
|
|
|
|
+ unset($this->data['dates'], $this->data['ranges'], $this->data['filters']);
|
|
|
|
|
+
|
|
|
session(['gp_schedule_orders' => $request->query()]);
|
|
session(['gp_schedule_orders' => $request->query()]);
|
|
|
$nav = $this->startNavigationContext($request);
|
|
$nav = $this->startNavigationContext($request);
|
|
|
$model = new ProductionOrder;
|
|
$model = new ProductionOrder;
|
|
@@ -98,8 +109,16 @@ class ProductionOrderController extends Controller
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $query = ProductionOrder::query()->with('manager')->withCount('items');
|
|
|
|
|
- $this->acceptFilters($query, $request);
|
|
|
|
|
|
|
+ $query = ProductionOrder::query()
|
|
|
|
|
+ ->with([
|
|
|
|
|
+ 'manager',
|
|
|
|
|
+ 'deliveries:id,production_order_id,delivery_date',
|
|
|
|
|
+ 'installations:id,production_order_id,installation_date',
|
|
|
|
|
+ ])
|
|
|
|
|
+ ->withCount('items')
|
|
|
|
|
+ ->withMin('deliveries', 'delivery_date')
|
|
|
|
|
+ ->withMin('installations', 'installation_date');
|
|
|
|
|
+ $this->acceptOrderFilters($query, $request);
|
|
|
$this->acceptSearch($query, $request);
|
|
$this->acceptSearch($query, $request);
|
|
|
|
|
|
|
|
$requestedSort = $request->string('sortBy')->toString();
|
|
$requestedSort = $request->string('sortBy')->toString();
|
|
@@ -107,6 +126,8 @@ class ProductionOrderController extends Controller
|
|
|
'status_name' => 'status',
|
|
'status_name' => 'status',
|
|
|
'execution_type_name' => 'execution_type',
|
|
'execution_type_name' => 'execution_type',
|
|
|
'items_count' => 'items_count',
|
|
'items_count' => 'items_count',
|
|
|
|
|
+ 'delivery_dates' => 'deliveries_min_delivery_date',
|
|
|
|
|
+ 'installation_dates' => 'installations_min_installation_date',
|
|
|
];
|
|
];
|
|
|
if (isset($sortMap[$requestedSort])) {
|
|
if (isset($sortMap[$requestedSort])) {
|
|
|
$request->merge(['sortBy' => $sortMap[$requestedSort]]);
|
|
$request->merge(['sortBy' => $sortMap[$requestedSort]]);
|
|
@@ -160,6 +181,8 @@ class ProductionOrderController extends Controller
|
|
|
'status_name',
|
|
'status_name',
|
|
|
'execution_type_name',
|
|
'execution_type_name',
|
|
|
'manager_id',
|
|
'manager_id',
|
|
|
|
|
+ 'delivery_dates',
|
|
|
|
|
+ 'installation_dates',
|
|
|
'note',
|
|
'note',
|
|
|
]),
|
|
]),
|
|
|
's' => $validated['s'] ?? null,
|
|
's' => $validated['s'] ?? null,
|
|
@@ -172,7 +195,7 @@ class ProductionOrderController extends Controller
|
|
|
$this->data['ranges'] = ['supply_working_days' => true];
|
|
$this->data['ranges'] = ['supply_working_days' => true];
|
|
|
|
|
|
|
|
$query = ProductionOrder::query();
|
|
$query = ProductionOrder::query();
|
|
|
- $this->acceptFilters($query, $request);
|
|
|
|
|
|
|
+ $this->acceptOrderFilters($query, $request);
|
|
|
$this->acceptSearch($query, $request);
|
|
$this->acceptSearch($query, $request);
|
|
|
$orderIds = $query->orderByDesc('created_at')->orderByDesc('id')->pluck('id')->all();
|
|
$orderIds = $query->orderByDesc('created_at')->orderByDesc('id')->pluck('id')->all();
|
|
|
|
|
|
|
@@ -302,6 +325,7 @@ class ProductionOrderController extends Controller
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
$items = CommonCatalogItem::query()
|
|
$items = CommonCatalogItem::query()
|
|
|
|
|
+ ->with('imageFile')
|
|
|
->where(function ($query) use ($search): void {
|
|
->where(function ($query) use ($search): void {
|
|
|
$query
|
|
$query
|
|
|
->where('article', 'like', "%{$search}%")
|
|
->where('article', 'like', "%{$search}%")
|
|
@@ -310,10 +334,12 @@ class ProductionOrderController extends Controller
|
|
|
})
|
|
})
|
|
|
->orderBy('article')
|
|
->orderBy('article')
|
|
|
->limit(50)
|
|
->limit(50)
|
|
|
- ->get(['id', 'article', 'calculator_name', 'print_name'])
|
|
|
|
|
|
|
+ ->get(['id', 'image_file_id', 'article', 'calculator_name', 'print_name'])
|
|
|
->map(static fn (CommonCatalogItem $item): array => [
|
|
->map(static fn (CommonCatalogItem $item): array => [
|
|
|
'id' => $item->id,
|
|
'id' => $item->id,
|
|
|
'label' => $item->article.' — '.($item->calculator_name ?: $item->print_name ?: 'Без наименования'),
|
|
'label' => $item->article.' — '.($item->calculator_name ?: $item->print_name ?: 'Без наименования'),
|
|
|
|
|
+ 'image' => $item->imageFile?->thumbnail_link,
|
|
|
|
|
+ 'image_full' => $item->imageFile?->link,
|
|
|
])
|
|
])
|
|
|
->values();
|
|
->values();
|
|
|
|
|
|
|
@@ -387,8 +413,9 @@ class ProductionOrderController extends Controller
|
|
|
->orderBy('name')
|
|
->orderBy('name')
|
|
|
->pluck('name', 'id'),
|
|
->pluck('name', 'id'),
|
|
|
'catalogItems' => CommonCatalogItem::query()
|
|
'catalogItems' => CommonCatalogItem::query()
|
|
|
|
|
+ ->with('imageFile')
|
|
|
->whereKey($catalogItemIds)
|
|
->whereKey($catalogItemIds)
|
|
|
- ->get(['id', 'article', 'calculator_name', 'print_name'])
|
|
|
|
|
|
|
+ ->get(['id', 'image_file_id', 'article', 'calculator_name', 'print_name'])
|
|
|
->keyBy('id'),
|
|
->keyBy('id'),
|
|
|
'statuses' => ProductionOrderStatus::options(),
|
|
'statuses' => ProductionOrderStatus::options(),
|
|
|
'executionTypes' => ProductionOrderExecutionType::options(),
|
|
'executionTypes' => ProductionOrderExecutionType::options(),
|
|
@@ -400,4 +427,45 @@ class ProductionOrderController extends Controller
|
|
|
'chatResponsibleUserIds' => $responsibleUserIds,
|
|
'chatResponsibleUserIds' => $responsibleUserIds,
|
|
|
]);
|
|
]);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ private function acceptOrderFilters(Builder $query, Request $request): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $filters = (array) $request->input('filters', []);
|
|
|
|
|
+ $relationFilters = [
|
|
|
|
|
+ 'delivery_dates' => ['deliveries', 'delivery_date'],
|
|
|
|
|
+ 'installation_dates' => ['installations', 'installation_date'],
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($relationFilters as $filterName => [$relation, $column]) {
|
|
|
|
|
+ $value = trim((string) ($filters[$filterName] ?? ''));
|
|
|
|
|
+ if ($value === '') {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $values = explode('||', $value);
|
|
|
|
|
+ $dates = array_values(array_filter(
|
|
|
|
|
+ $values,
|
|
|
|
|
+ static fn (string $date): bool => $date !== '-пусто-',
|
|
|
|
|
+ ));
|
|
|
|
|
+ $includeEmpty = in_array('-пусто-', $values, true);
|
|
|
|
|
+
|
|
|
|
|
+ $query->where(function ($relationQuery) use ($relation, $column, $dates, $includeEmpty): void {
|
|
|
|
|
+ if ($dates !== []) {
|
|
|
|
|
+ $relationQuery->whereHas(
|
|
|
|
|
+ $relation,
|
|
|
|
|
+ static fn ($dateQuery) => $dateQuery->whereIn($column, $dates),
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($includeEmpty) {
|
|
|
|
|
+ $dates !== []
|
|
|
|
|
+ ? $relationQuery->orWhereDoesntHave($relation)
|
|
|
|
|
+ : $relationQuery->whereDoesntHave($relation);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $request->merge(['filters' => Arr::except($filters, array_keys($relationFilters))]);
|
|
|
|
|
+ $this->acceptFilters($query, $request);
|
|
|
|
|
+ $request->merge(['filters' => $filters]);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|