diff --git a/app/Http/Controllers/Dashboard/Category/Controller.php b/app/Http/Controllers/Dashboard/Category/Controller.php
index c0ea18d..29cbeb8 100755
--- a/app/Http/Controllers/Dashboard/Category/Controller.php
+++ b/app/Http/Controllers/Dashboard/Category/Controller.php
@@ -14,7 +14,9 @@ use App\Jobs\Dashboard\Category\Update as UpdateJob;
use App\Models\Characteristic;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
+use Throwable;
class Controller extends ExController
{
@@ -25,17 +27,46 @@ class Controller extends ExController
public function index()
{
$this->authorize('view', 'categories');
- $categories = Category::select('id', 'name->ru as category', 'position', 'parent_id', 'image')
- ->where('parent_id', null)
- ->with(['children' => function ($parent) {
- return $parent->select('id', 'name->ru as category', 'parent_id', 'position', 'image')->orderBy('position', 'asc')->with(['children' => function ($parent) {
- return $parent->select('id', 'name->ru as category', 'parent_id', 'position', 'image')->orderBy('position', 'asc');
- }]);
- }])->orderBy('position', 'asc')->get();
+ $categories = $this->categoryTree();
return view('dashboard.category.index', compact('categories'));
}
+ private function categoryTree($parentId = null, array $visited = [])
+ {
+ return Category::select('id', 'name', 'position', 'parent_id', 'image')
+ ->when($parentId === null, function ($query) {
+ $query->whereNull('parent_id');
+ }, function ($query) use ($parentId) {
+ $query->where('parent_id', $parentId);
+ })
+ ->orderBy('position', 'asc')
+ ->get()
+ ->map(function (Category $category) use ($visited) {
+ if (in_array($category->id, $visited, true)) {
+ return [
+ 'id' => $category->id,
+ 'category' => $category->name['ru'] ?? $category->name['uz'] ?? '',
+ 'position' => $category->position,
+ 'parent_id' => $category->parent_id,
+ 'image' => $category->image,
+ 'image_url' => $category->image_url,
+ 'children' => [],
+ ];
+ }
+
+ return [
+ 'id' => $category->id,
+ 'category' => $category->name['ru'] ?? $category->name['uz'] ?? '',
+ 'position' => $category->position,
+ 'parent_id' => $category->parent_id,
+ 'image' => $category->image,
+ 'image_url' => $category->image_url,
+ 'children' => $this->categoryTree($category->id, [...$visited, $category->id]),
+ ];
+ });
+ }
+
/**
* @param StoreRequest $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View
@@ -55,20 +86,39 @@ class Controller extends ExController
return view('dashboard.category.store', compact('brands', 'parent_categories'));
}
- $category = $this->dispatchSync(new StoreJob($request));
+ try {
+ $category = DB::transaction(function () use ($request) {
+ $category = $this->dispatchSync(new StoreJob($request));
- if (!empty($request->char)) {
- foreach ($request->char as $char) {
- Characteristic::create([
- 'name' => $char['name'],
- 'type' => $char['type'],
- 'category_id' => $category->id,
- 'filter' => $char['filter'] == 'true' ? 1 : 0
- ]);
- }
+ if (!empty($request->char)) {
+ foreach ($request->char as $char) {
+ Characteristic::create([
+ 'name' => $char['name'] ?? ['ru' => '', 'uz' => ''],
+ 'type' => $char['type'] ?? 'text',
+ 'category_id' => $category->id,
+ 'filter' => filter_var($char['filter'] ?? false, FILTER_VALIDATE_BOOLEAN)
+ ]);
+ }
+ }
+
+ return $category;
+ });
+ } catch (Throwable $exception) {
+ Log::error('Category store failed', [
+ 'message' => $exception->getMessage(),
+ 'trace' => $exception->getTraceAsString(),
+ ]);
+
+ return response()->json([
+ 'status' => false,
+ 'message' => 'Category could not be saved.',
+ 'error' => config('app.debug') ? $exception->getMessage() : null,
+ ], 500);
}
- $this->success(trans('admin.messages.created'));
+ if ($category) {
+ $this->success(trans('admin.messages.created'));
+ }
return response()->json([
'status' => true
@@ -103,39 +153,52 @@ class Controller extends ExController
return view('dashboard.category.update', compact('parent_categories', 'category', 'brands'));
}
- $image = $request->getImage($category);
+ try {
+ $image = $request->getImage($category);
- $this->dispatchSync(new UpdateJob($category, $request, $image));
+ DB::transaction(function () use ($category, $request, $image) {
+ $this->dispatchSync(new UpdateJob($category, $request, $image));
- if (!empty($request->char)) {
- foreach ($request->char as $char) {
- if ($char['id'] == null || $char['id'] == 'null') {
- Characteristic::create([
- 'name' => $char['name'],
- 'type' => $char['type'],
- 'category_id' => $category->id,
- 'filter' => $char['filter'] == 'true' ? 1 : 0
- ]);
- } else {
- Characteristic::where('id', $char['id'])->update([
- 'name' => $char['name'],
- 'type' => $char['type'],
- 'filter' => $char['filter'] == 'true' ? 1 : 0
- ]);
+ if (!empty($request->char)) {
+ foreach ($request->char as $char) {
+ if ($char['id'] == null || $char['id'] == 'null') {
+ Characteristic::create([
+ 'name' => $char['name'] ?? ['ru' => '', 'uz' => ''],
+ 'type' => $char['type'] ?? 'text',
+ 'category_id' => $category->id,
+ 'filter' => filter_var($char['filter'] ?? false, FILTER_VALIDATE_BOOLEAN)
+ ]);
+ } else {
+ Characteristic::where('id', $char['id'])->update([
+ 'name' => $char['name'] ?? ['ru' => '', 'uz' => ''],
+ 'type' => $char['type'] ?? 'text',
+ 'filter' => filter_var($char['filter'] ?? false, FILTER_VALIDATE_BOOLEAN)
+ ]);
+ }
+ }
}
- }
- }
- if (!empty($request->deletes['char'])) {
- $chars = Characteristic::whereIn('id', $request->deletes['char'])->get();
+ if (!empty($request->deletes['char'])) {
+ $chars = Characteristic::whereIn('id', $request->deletes['char'])->get();
- foreach ($chars as $char) {
- $char->values()->detach();
- // foreach ($char->values as $value) {
- // $value->delete();
- // }
- $char->delete();
- }
+ foreach ($chars as $char) {
+ $char->values()->detach();
+ $char->delete();
+ }
+ }
+ });
+ } catch (Throwable $exception) {
+ Log::error('Category update failed', [
+ 'category_id' => $category->id,
+ 'message' => $exception->getMessage(),
+ 'trace' => $exception->getTraceAsString(),
+ ]);
+
+ return response()->json([
+ 'status' => false,
+ 'message' => 'Category could not be saved.',
+ 'error' => config('app.debug') ? $exception->getMessage() : null,
+ ], 500);
}
$this->success(trans('admin.messages.updated'));
@@ -145,7 +208,6 @@ class Controller extends ExController
]);
}
-
/**
* @param Category $category
* @return \Illuminate\Http\RedirectResponse
diff --git a/app/Http/Controllers/Dashboard/Product/Controller.php b/app/Http/Controllers/Dashboard/Product/Controller.php
index 5104a8d..3dcb6e8 100755
--- a/app/Http/Controllers/Dashboard/Product/Controller.php
+++ b/app/Http/Controllers/Dashboard/Product/Controller.php
@@ -82,17 +82,7 @@ class Controller extends ExController
{
if ($request->isMethod('get')) {
$this->authorize('create', 'products');
- $categories = $this->categories->select('id', 'name->ru as category')
- ->where('parent_id', null)
- ->with([
- 'parents' => function ($parent) {
- return $parent->select('id', 'name->ru as category', 'parent_id')->with([
- 'parents' => function ($parent) {
- return $parent->select('id', 'name->ru as category', 'parent_id');
- }
- ]);
- }
- ])->get();
+ $categories = $this->categoryTree();
$brands = $this->brands->get();
$colors = $this->colors->get();
$measurement = Measurement::query()->get();
@@ -146,6 +136,31 @@ class Controller extends ExController
}
}
+ private function categoryTree($parentId = null, array $visited = [])
+ {
+ return Category::select('id', 'name', 'parent_id')
+ ->when($parentId === null, function ($query) {
+ $query->whereNull('parent_id');
+ }, function ($query) use ($parentId) {
+ $query->where('parent_id', $parentId);
+ })
+ ->orderBy('position', 'asc')
+ ->get()
+ ->map(function (Category $category) use ($visited) {
+ $children = in_array($category->id, $visited, true)
+ ? collect()
+ : $this->categoryTree($category->id, [...$visited, $category->id]);
+
+ return [
+ 'id' => $category->id,
+ 'category' => $category->name['ru'] ?? $category->name['uz'] ?? '',
+ 'parent_id' => $category->parent_id,
+ 'parents' => $children,
+ '$isDisabled' => $children->isNotEmpty(),
+ ];
+ });
+ }
+
/**
* @param $id
* @return array
@@ -309,17 +324,7 @@ class Controller extends ExController
}
- $categories = $this->categories->select('id', 'name->ru as category')
- ->where('parent_id', null)
- ->with([
- 'parents' => function ($parent) {
- return $parent->select('id', 'name->ru as category', 'parent_id')->with([
- 'parents' => function ($parent) {
- return $parent->select('id', 'name->ru as category', 'parent_id');
- }
- ]);
- }
- ])->get();
+ $categories = $this->categoryTree();
$brands = $this->brands->get();
$measurement = Measurement::query()->get();
diff --git a/resources/js/components/Dashboard/Category/Store.vue b/resources/js/components/Dashboard/Category/Store.vue
index 1154bce..67e15b1 100755
--- a/resources/js/components/Dashboard/Category/Store.vue
+++ b/resources/js/components/Dashboard/Category/Store.vue
@@ -793,7 +793,16 @@ export default {
.catch((error) => {
if (error.response) {
this.error = true;
- this.errors = error.response.data.errors;
+ this.errors =
+ error.response.data.errors ||
+ error.response.data.details ||
+ [
+ [
+ error.response.data.error ||
+ error.response.data.message ||
+ "Server error",
+ ],
+ ];
}
});
},
diff --git a/resources/js/components/Dashboard/Category/Update.vue b/resources/js/components/Dashboard/Category/Update.vue
index 946a5e2..1ded507 100755
--- a/resources/js/components/Dashboard/Category/Update.vue
+++ b/resources/js/components/Dashboard/Category/Update.vue
@@ -804,7 +804,16 @@ export default {
.catch((error) => {
if (error.response) {
this.error = true;
- this.errors = error.response.data.errors;
+ this.errors =
+ error.response.data.errors ||
+ error.response.data.details ||
+ [
+ [
+ error.response.data.error ||
+ error.response.data.message ||
+ "Server error",
+ ],
+ ];
}
});
},
diff --git a/resources/js/components/ProductEdit.vue b/resources/js/components/ProductEdit.vue
index 75d0d06..4607234 100755
--- a/resources/js/components/ProductEdit.vue
+++ b/resources/js/components/ProductEdit.vue
@@ -63,51 +63,28 @@