|
@@ -0,0 +1,305 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+declare(strict_types=1);
|
|
|
|
|
+
|
|
|
|
|
+namespace App\Http\Controllers;
|
|
|
|
|
+
|
|
|
|
|
+use App\Http\Requests\StoreCommonCatalogItemRequest;
|
|
|
|
|
+use App\Jobs\Export\ExportCommonCatalogJob;
|
|
|
|
|
+use App\Jobs\Import\ImportJob;
|
|
|
|
|
+use App\Models\CommonCatalogItem;
|
|
|
|
|
+use App\Models\File;
|
|
|
|
|
+use App\Models\Import;
|
|
|
|
|
+use App\Services\FileService;
|
|
|
|
|
+use Illuminate\Contracts\View\View;
|
|
|
|
|
+use Illuminate\Http\RedirectResponse;
|
|
|
|
|
+use Illuminate\Http\Request;
|
|
|
|
|
+use Illuminate\Support\Facades\Storage;
|
|
|
|
|
+use Illuminate\Support\Str;
|
|
|
|
|
+use Throwable;
|
|
|
|
|
+
|
|
|
|
|
+class CommonCatalogController extends Controller
|
|
|
|
|
+{
|
|
|
|
|
+ protected array $data = [
|
|
|
|
|
+ 'active' => 'common_catalog',
|
|
|
|
|
+ 'title' => 'Каталог общий',
|
|
|
|
|
+ 'id' => 'common_catalog_items',
|
|
|
|
|
+ 'header' => [
|
|
|
|
|
+ 'id' => 'ID',
|
|
|
|
|
+ 'image' => 'Внешний вид',
|
|
|
|
|
+ 'article' => 'Артикул',
|
|
|
|
|
+ 'calculator_name' => 'Наименование по калькулятору',
|
|
|
|
|
+ 'kind' => 'Вид',
|
|
|
|
|
+ 'dimensions' => 'Габаритные размеры',
|
|
|
|
|
+ 'fall_height' => 'Высота падения',
|
|
|
|
|
+ 'additional_info' => 'Дополнительные сведения',
|
|
|
|
|
+ 'dimension_unit' => 'Единица измерения габаритов',
|
|
|
|
|
+ 'weight' => 'Вес, кг.',
|
|
|
|
|
+ 'volume' => 'Объем, м3',
|
|
|
|
|
+ 'places' => 'Места',
|
|
|
|
|
+ 'composition' => 'Состав',
|
|
|
|
|
+ 'age_group' => 'Возрастная группа',
|
|
|
|
|
+ 'max_users' => 'Макс. кол-во пользователей',
|
|
|
|
|
+ 'unit' => 'Ед.',
|
|
|
|
|
+ 'series' => 'Серия',
|
|
|
|
|
+ 'trademark' => 'ТМ',
|
|
|
|
|
+ 'note' => 'Примечание',
|
|
|
|
|
+ ],
|
|
|
|
|
+ 'searchFields' => [
|
|
|
|
|
+ 'article',
|
|
|
|
|
+ 'calculator_name',
|
|
|
|
|
+ 'kind',
|
|
|
|
|
+ 'dimensions',
|
|
|
|
|
+ 'additional_info',
|
|
|
|
|
+ 'composition',
|
|
|
|
|
+ 'series',
|
|
|
|
|
+ 'trademark',
|
|
|
|
|
+ 'note',
|
|
|
|
|
+ ],
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ public function index(Request $request): View
|
|
|
|
|
+ {
|
|
|
|
|
+ session(['gp_common_catalog' => $request->query()]);
|
|
|
|
|
+ $nav = $this->startNavigationContext($request);
|
|
|
|
|
+ $model = new CommonCatalogItem;
|
|
|
|
|
+
|
|
|
|
|
+ $this->createFilters(
|
|
|
|
|
+ $model,
|
|
|
|
|
+ 'kind',
|
|
|
|
|
+ 'dimension_unit',
|
|
|
|
|
+ 'age_group',
|
|
|
|
|
+ 'unit',
|
|
|
|
|
+ 'series',
|
|
|
|
|
+ 'trademark',
|
|
|
|
|
+ );
|
|
|
|
|
+ $this->createRangeFilters(
|
|
|
|
|
+ $model,
|
|
|
|
|
+ 'fall_height',
|
|
|
|
|
+ 'weight',
|
|
|
|
|
+ 'volume',
|
|
|
|
|
+ 'places',
|
|
|
|
|
+ 'max_users',
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ $query = CommonCatalogItem::query()->with('imageFile');
|
|
|
|
|
+ $this->acceptFilters($query, $request);
|
|
|
|
|
+ $this->acceptSearch($query, $request);
|
|
|
|
|
+ $this->setSortAndOrderBy($model, $request);
|
|
|
|
|
+ $this->applyStableSorting($query);
|
|
|
|
|
+
|
|
|
|
|
+ $this->data['items'] = $query->paginate($this->data['per_page'])->withQueryString();
|
|
|
|
|
+ $this->data['nav'] = $nav;
|
|
|
|
|
+
|
|
|
|
|
+ return view('common_catalog.index', $this->data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function create(Request $request): View
|
|
|
|
|
+ {
|
|
|
|
|
+ return $this->itemView($request);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function show(Request $request, CommonCatalogItem $commonCatalogItem): View
|
|
|
|
|
+ {
|
|
|
|
|
+ return $this->itemView(
|
|
|
|
|
+ $request,
|
|
|
|
|
+ $commonCatalogItem->load(['imageFile', 'documents']),
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function store(StoreCommonCatalogItemRequest $request): RedirectResponse
|
|
|
|
|
+ {
|
|
|
|
|
+ $item = CommonCatalogItem::query()->create($request->validated());
|
|
|
|
|
+
|
|
|
|
|
+ return redirect()
|
|
|
|
|
+ ->route('common-catalog.show', $this->withNav(
|
|
|
|
|
+ ['commonCatalogItem' => $item],
|
|
|
|
|
+ $this->resolveNavToken($request),
|
|
|
|
|
+ ))
|
|
|
|
|
+ ->with('success', 'Позиция общего каталога создана.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function update(
|
|
|
|
|
+ StoreCommonCatalogItemRequest $request,
|
|
|
|
|
+ CommonCatalogItem $commonCatalogItem,
|
|
|
|
|
+ ): RedirectResponse {
|
|
|
|
|
+ $commonCatalogItem->update($request->validated());
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToItem($request, $commonCatalogItem)
|
|
|
|
|
+ ->with('success', 'Позиция общего каталога обновлена.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function destroy(
|
|
|
|
|
+ Request $request,
|
|
|
|
|
+ CommonCatalogItem $commonCatalogItem,
|
|
|
|
|
+ FileService $fileService,
|
|
|
|
|
+ ): RedirectResponse {
|
|
|
|
|
+ $commonCatalogItem->load(['imageFile', 'documents']);
|
|
|
|
|
+ $files = $commonCatalogItem->documents;
|
|
|
|
|
+ if ($commonCatalogItem->imageFile) {
|
|
|
|
|
+ $files->push($commonCatalogItem->imageFile);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $commonCatalogItem->documents()->detach();
|
|
|
|
|
+ $commonCatalogItem->update(['image_file_id' => null]);
|
|
|
|
|
+ $commonCatalogItem->delete();
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($files->unique('id') as $file) {
|
|
|
|
|
+ $fileService->deleteFileWithThumbnail($file);
|
|
|
|
|
+ $file->delete();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return redirect()
|
|
|
|
|
+ ->route('common-catalog.index', session('gp_common_catalog'))
|
|
|
|
|
+ ->with('success', 'Позиция общего каталога удалена.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function uploadImage(
|
|
|
|
|
+ Request $request,
|
|
|
|
|
+ CommonCatalogItem $commonCatalogItem,
|
|
|
|
|
+ FileService $fileService,
|
|
|
|
|
+ ): RedirectResponse {
|
|
|
|
|
+ $data = $request->validate([
|
|
|
|
|
+ 'image' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:10240'],
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $oldImage = $commonCatalogItem->imageFile;
|
|
|
|
|
+ $image = $fileService->saveUploadedFile(
|
|
|
|
|
+ "common_catalog/items/{$commonCatalogItem->id}/image",
|
|
|
|
|
+ $data['image'],
|
|
|
|
|
+ );
|
|
|
|
|
+ $commonCatalogItem->update(['image_file_id' => $image->id]);
|
|
|
|
|
+
|
|
|
|
|
+ if ($oldImage) {
|
|
|
|
|
+ $fileService->deleteFileWithThumbnail($oldImage);
|
|
|
|
|
+ $oldImage->delete();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Throwable $exception) {
|
|
|
|
|
+ report($exception);
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToItem($request, $commonCatalogItem)
|
|
|
|
|
+ ->with('error', 'Не удалось загрузить изображение.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToItem($request, $commonCatalogItem)
|
|
|
|
|
+ ->with('success', 'Изображение загружено.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function deleteImage(
|
|
|
|
|
+ Request $request,
|
|
|
|
|
+ CommonCatalogItem $commonCatalogItem,
|
|
|
|
|
+ FileService $fileService,
|
|
|
|
|
+ ): RedirectResponse {
|
|
|
|
|
+ $image = $commonCatalogItem->imageFile;
|
|
|
|
|
+ if ($image) {
|
|
|
|
|
+ $commonCatalogItem->update(['image_file_id' => null]);
|
|
|
|
|
+ $fileService->deleteFileWithThumbnail($image);
|
|
|
|
|
+ $image->delete();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToItem($request, $commonCatalogItem)
|
|
|
|
|
+ ->with('success', 'Изображение удалено.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function uploadDocument(
|
|
|
|
|
+ Request $request,
|
|
|
|
|
+ CommonCatalogItem $commonCatalogItem,
|
|
|
|
|
+ FileService $fileService,
|
|
|
|
|
+ ): RedirectResponse {
|
|
|
|
|
+ $data = $request->validate([
|
|
|
|
|
+ 'document' => ['required', 'file', 'max:20480'],
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $document = $fileService->saveUploadedFile(
|
|
|
|
|
+ "common_catalog/items/{$commonCatalogItem->id}/documents",
|
|
|
|
|
+ $data['document'],
|
|
|
|
|
+ );
|
|
|
|
|
+ $commonCatalogItem->documents()->attach($document);
|
|
|
|
|
+ } catch (Throwable $exception) {
|
|
|
|
|
+ report($exception);
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToItem($request, $commonCatalogItem)
|
|
|
|
|
+ ->with('error', 'Не удалось загрузить документ.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToItem($request, $commonCatalogItem)
|
|
|
|
|
+ ->with('success', 'Документ загружен.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function deleteDocument(
|
|
|
|
|
+ Request $request,
|
|
|
|
|
+ CommonCatalogItem $commonCatalogItem,
|
|
|
|
|
+ File $file,
|
|
|
|
|
+ FileService $fileService,
|
|
|
|
|
+ ): RedirectResponse {
|
|
|
|
|
+ abort_unless($commonCatalogItem->documents()->whereKey($file->getKey())->exists(), 404);
|
|
|
|
|
+
|
|
|
|
|
+ $commonCatalogItem->documents()->detach($file);
|
|
|
|
|
+ $fileService->deleteFileWithThumbnail($file);
|
|
|
|
|
+ $file->delete();
|
|
|
|
|
+
|
|
|
|
|
+ return $this->redirectToItem($request, $commonCatalogItem)
|
|
|
|
|
+ ->with('success', 'Документ удалён.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function export(Request $request): RedirectResponse
|
|
|
|
|
+ {
|
|
|
|
|
+ ExportCommonCatalogJob::dispatch((int) $request->user()->getKey());
|
|
|
|
|
+
|
|
|
|
|
+ return redirect()
|
|
|
|
|
+ ->route('common-catalog.index', session('gp_common_catalog'))
|
|
|
|
|
+ ->with('success', 'Задача экспорта общего каталога создана.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function import(Request $request): RedirectResponse
|
|
|
|
|
+ {
|
|
|
|
|
+ $data = $request->validate([
|
|
|
|
|
+ 'import_file' => ['required', 'file', 'mimes:xlsx', 'max:20480'],
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ $path = Str::random(2).'/'.Str::uuid().'.xlsx';
|
|
|
|
|
+ Storage::disk('upload')->put($path, $data['import_file']->getContent());
|
|
|
|
|
+
|
|
|
|
|
+ $import = Import::query()->create([
|
|
|
|
|
+ 'type' => 'common_catalog',
|
|
|
|
|
+ 'year' => null,
|
|
|
|
|
+ 'filename' => $path,
|
|
|
|
|
+ 'status' => 'new',
|
|
|
|
|
+ 'user_id' => $request->user()->getKey(),
|
|
|
|
|
+ 'original_filename' => $data['import_file']->getClientOriginalName(),
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ ImportJob::dispatch($import, (int) $request->user()->getKey());
|
|
|
|
|
+
|
|
|
|
|
+ return redirect()
|
|
|
|
|
+ ->route('common-catalog.index', session('gp_common_catalog'))
|
|
|
|
|
+ ->with('success', 'Задача импорта общего каталога создана.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function itemView(Request $request, ?CommonCatalogItem $item = null): View
|
|
|
|
|
+ {
|
|
|
|
|
+ $nav = $this->resolveNavToken($request);
|
|
|
|
|
+ $this->rememberNavigation($request, $nav);
|
|
|
|
|
+ $this->data['nav'] = $nav;
|
|
|
|
|
+ $this->data['back_url'] = $this->navigationBackUrl(
|
|
|
|
|
+ $request,
|
|
|
|
|
+ $nav,
|
|
|
|
|
+ route('common-catalog.index', session('gp_common_catalog')),
|
|
|
|
|
+ );
|
|
|
|
|
+ $this->data['item'] = $item;
|
|
|
|
|
+
|
|
|
|
|
+ return view('common_catalog.edit', $this->data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function redirectToItem(
|
|
|
|
|
+ Request $request,
|
|
|
|
|
+ CommonCatalogItem $commonCatalogItem,
|
|
|
|
|
+ ): RedirectResponse {
|
|
|
|
|
+ return redirect()->route('common-catalog.show', $this->withNav(
|
|
|
|
|
+ ['commonCatalogItem' => $commonCatalogItem],
|
|
|
|
|
+ $this->resolveNavToken($request),
|
|
|
|
|
+ ));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|