diff --git a/app/Http/Controllers/Admin/ProductCategoryController.php b/app/Http/Controllers/Admin/ProductCategoryController.php index 64ea698..b864892 100644 --- a/app/Http/Controllers/Admin/ProductCategoryController.php +++ b/app/Http/Controllers/Admin/ProductCategoryController.php @@ -150,7 +150,11 @@ class ProductCategoryController extends Controller // 檢查是否已有商品使用此分類 if ($category->products()->count() > 0) { - return redirect()->back()->with('error', __('Cannot delete category that has products. Please move products first.')); + $errorMsg = __('Cannot delete category that has products. Please move products first.'); + if (request()->ajax()) { + return response()->json(['success' => false, 'message' => $errorMsg], 422); + } + return redirect()->back()->with('error', $errorMsg); } if ($category->name_dictionary_key) { @@ -159,8 +163,18 @@ class ProductCategoryController extends Controller $category->delete(); + if (request()->ajax()) { + return response()->json([ + 'success' => true, + 'message' => __('Category deleted successfully') + ]); + } + return redirect()->back()->with('success', __('Category deleted successfully')); } catch (\Exception $e) { + if (request()->ajax()) { + return response()->json(['success' => false, 'message' => $e->getMessage()], 500); + } return redirect()->back()->with('error', $e->getMessage()); } } diff --git a/app/Http/Controllers/Admin/ProductController.php b/app/Http/Controllers/Admin/ProductController.php index 271679f..d8b9633 100644 --- a/app/Http/Controllers/Admin/ProductController.php +++ b/app/Http/Controllers/Admin/ProductController.php @@ -19,12 +19,16 @@ class ProductController extends Controller public function index(Request $request) { $user = auth()->user(); - $query = Product::with(['category.translations', 'translations', 'company']); + $tab = $request->input('tab', 'products'); + $per_page = $request->input('per_page', 10); + + // Products Query + $productQuery = Product::with(['category.translations', 'translations', 'company']); // 搜尋 - if ($request->filled('search')) { - $search = $request->search; - $query->where(function($q) use ($search) { + if ($request->filled('product_search')) { + $search = $request->product_search; + $productQuery->where(function($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('barcode', 'like', "%{$search}%") ->orWhere('spec', 'like', "%{$search}%"); @@ -33,29 +37,66 @@ class ProductController extends Controller // 分類篩選 if ($request->filled('category_id')) { - $query->where('category_id', $request->category_id); + $productQuery->where('category_id', $request->category_id); } - $per_page = $request->input('per_page', 10); - - $companyId = $user->company_id; if ($user->isSystemAdmin()) { - if ($request->filled('company_id')) { - $companyId = $request->company_id; - $query->where('company_id', $companyId); + if ($request->filled('product_company_id')) { + $productQuery->where('company_id', $request->product_company_id); } } - $products = $query->latest()->paginate($per_page)->withQueryString(); - $categories = ProductCategory::with('translations')->get(); + $products = $productQuery->latest()->paginate($per_page, ['*'], 'product_page')->withQueryString(); + + // Categories Query + $categoryQuery = ProductCategory::with(['translations', 'company']); + + if ($user->isSystemAdmin() && $request->filled('category_company_id')) { + $categoryQuery->where('company_id', $request->category_company_id); + } + + if ($request->filled('category_search')) { + $search = $request->category_search; + $categoryQuery->where(function($q) use ($search) { + $q->where('name', 'like', "%{$search}%"); + }); + } + + $categories = $categoryQuery->latest()->paginate($per_page, ['*'], 'category_page')->withQueryString(); $companies = $user->isSystemAdmin() ? Company::all() : collect(); - // 系統管理員在過濾特定公司時,應顯示該公司的功能開關 (如物料代碼、點數規則) - $selectedCompany = $companyId ? Company::find($companyId) : $user->company; + // Settings for Modal (use current user company or fallback) + $selectedCompanyId = $user->isSystemAdmin() + ? ($request->input('product_company_id') ?: $request->input('category_company_id')) + : $user->company_id; + $selectedCompany = $selectedCompanyId ? Company::find($selectedCompanyId) : $user->company; $companySettings = $selectedCompany ? ($selectedCompany->settings ?? []) : []; $routeName = 'admin.data-config.products.index'; + if ($request->ajax() || $request->wantsJson()) { + if ($tab === 'products') { + return response()->json([ + 'success' => true, + 'html' => view('admin.products.partials.tab-products', [ + 'products' => $products, + 'companySettings' => $companySettings, + 'companies' => $companies, + 'routeName' => $routeName + ])->render() + ]); + } else { + return response()->json([ + 'success' => true, + 'html' => view('admin.products.partials.tab-categories', [ + 'categories' => $categories, + 'companies' => $companies, + 'routeName' => $routeName + ])->render() + ]); + } + } + return view('admin.products.index', [ 'products' => $products, 'categories' => $categories, @@ -313,8 +354,23 @@ class ProductController extends Controller $product->save(); $status = $product->is_active ? __('Enabled') : __('Disabled'); + + if (request()->ajax()) { + return response()->json([ + 'success' => true, + 'message' => __('Product status updated to :status', ['status' => $status]), + 'is_active' => $product->is_active + ]); + } + return redirect()->back()->with('success', __('Product status updated to :status', ['status' => $status])); } catch (\Exception $e) { + if (request()->ajax()) { + return response()->json([ + 'success' => false, + 'message' => $e->getMessage() + ], 500); + } return redirect()->back()->with('error', $e->getMessage()); } } @@ -337,8 +393,21 @@ class ProductController extends Controller $product->delete(); + if (request()->ajax()) { + return response()->json([ + 'success' => true, + 'message' => __('Product deleted successfully') + ]); + } + return redirect()->back()->with('success', __('Product deleted successfully')); } catch (\Exception $e) { + if (request()->ajax()) { + return response()->json([ + 'success' => false, + 'message' => $e->getMessage() + ], 500); + } return redirect()->back()->with('error', $e->getMessage()); } } diff --git a/lang/en.json b/lang/en.json index 7fa4133..f3b5b29 100644 --- a/lang/en.json +++ b/lang/en.json @@ -85,6 +85,7 @@ "Apply changes to all identical products in this machine": "Apply changes to all identical products in this machine", "Apply to all identical products in this machine": "Apply to all identical products in this machine", "Are you sure to delete this customer?": "Are you sure to delete this customer?", + "Are you sure you want to change the status of this item? This will affect its visibility on vending machines.": "Are you sure you want to change the status of this item? This will affect its visibility on vending machines.", "Are you sure you want to change the status of this product? Disabled products will not be visible on the machine.": "Are you sure you want to change the status of this product? Disabled products will not be visible on the machine.", "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.": "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.", "Are you sure you want to change the status? This may affect associated accounts.": "Are you sure you want to change the status? This may affect associated accounts.", @@ -95,6 +96,7 @@ "Are you sure you want to delete this configuration?": "您確定要刪除此金流配置嗎?", "Are you sure you want to delete this configuration? This action cannot be undone.": "Are you sure you want to delete this configuration? This action cannot be undone.", "Are you sure you want to delete this item? This action cannot be undone.": "Are you sure you want to delete this item? This action cannot be undone.", + "Are you sure you want to delete this product or category? This action cannot be undone.": "Are you sure you want to delete this product or category? This action cannot be undone.", "Are you sure you want to delete this product?": "Are you sure you want to delete this product?", "Are you sure you want to delete this product? All related historical translation data will also be removed.": "Are you sure you want to delete this product? All related historical translation data will also be removed.", "Are you sure you want to delete this role? This action cannot be undone.": "Are you sure you want to delete this role? This action cannot be undone.", @@ -828,6 +830,7 @@ "Search by name or S\/N...": "Search by name or S\/N...", "Search cargo lane": "Search cargo lane", "Search Company Title...": "Search Company Title...", + "Search categories...": "Search categories...", "Search company...": "Search company...", "Search configurations...": "Search configurations...", "Search customers...": "Search customers...", @@ -1155,5 +1158,8 @@ "Expired Time": "Expired Time", "Inventory synced with machine": "Inventory synced with machine", "Failed to load tab content": "Failed to load tab content", - "No machines found": "No machines found" + "No machines found": "No machines found", + "No products found matching your criteria.": "No products found matching your criteria.", + "No categories found.": "No categories found.", + "Track Limit (Track/Spring)": "Track Limit (Track/Spring)" } \ No newline at end of file diff --git a/lang/ja.json b/lang/ja.json index 7f6c714..663b582 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -85,6 +85,7 @@ "Apply changes to all identical products in this machine": "この機台の同一商品すべてに変更を適用", "Apply to all identical products in this machine": "この機体内のすべての同一商品に適用する", "Are you sure to delete this customer?": "この顧客を削除してもよろしいですか?", + "Are you sure you want to change the status of this item? This will affect its visibility on vending machines.": "この項目のステータスを変更してもよろしいですか?自動販売機での表示に影響します。", "Are you sure you want to change the status of this product? Disabled products will not be visible on the machine.": "この商品のステータスを変更してもよろしいですか?無効にすると機体に表示されなくなります。", "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.": "ステータスを変更してもよろしいですか?無効にすると、このアカウントはシステムにログインできなくなります。", "Are you sure you want to change the status? This may affect associated accounts.": "ステータスを変更してもよろしいですか?関連するアカウントに影響を与える可能性があります。", @@ -95,6 +96,7 @@ "Are you sure you want to delete this configuration?": "この設定を削除してもよろしいですか?", "Are you sure you want to delete this configuration? This action cannot be undone.": "この設定を削除してもよろしいですか?この操作は取り消せません。", "Are you sure you want to delete this item? This action cannot be undone.": "この項目を削除してもよろしいですか?この操作は取り消せません。", + "Are you sure you want to delete this product or category? This action cannot be undone.": "この商品またはカテゴリーを削除してもよろしいですか?この操作は取り消せません。", "Are you sure you want to delete this product?": "この商品を削除してもよろしいですか?", "Are you sure you want to delete this product? All related historical translation data will also be removed.": "この商品を削除してもよろしいですか?関連するすべての翻訳履歴データも削除されます。", "Are you sure you want to delete this role? This action cannot be undone.": "この権限を削除してもよろしいですか?この操作は取り消せません。", @@ -827,6 +829,7 @@ "Search by name or S\/N...": "名称または製造番号で検索...", "Search cargo lane": "貨道を検索", "Search Company Title...": "会社名を検索...", + "Search categories...": "カテゴリーを検索...", "Search company...": "会社を検索...", "Search configurations...": "設定を検索...", "Search customers...": "顧客を検索...", @@ -1154,5 +1157,8 @@ "Expired Time": "終了時間", "Inventory synced with machine": "在庫が機体と同期されました", "Failed to load tab content": "タブコンテンツの読み込みに失敗しました", - "No machines found": "マシンが見つかりません" + "No machines found": "マシンが見つかりません", + "No products found matching your criteria.": "条件に一致する商品が見つかりませんでした。", + "No categories found.": "カテゴリーが見つかりませんでした。", + "Track Limit (Track/Spring)": "在庫上限 (ベルト/スプリング)" } \ No newline at end of file diff --git a/lang/zh_TW.json b/lang/zh_TW.json index 44f6840..a5a0e2a 100644 --- a/lang/zh_TW.json +++ b/lang/zh_TW.json @@ -87,6 +87,7 @@ "Apply changes to all identical products in this machine": "同步套用至此機台內的所有相同商品", "Apply to all identical products in this machine": "同步套用至此機台內的所有相同商品", "Are you sure to delete this customer?": "您確定要刪除此客戶嗎?", + "Are you sure you want to change the status of this item? This will affect its visibility on vending machines.": "您確定要變更此項目的狀態嗎?這將會影響其在販賣機上的顯示內容。", "Are you sure you want to change the status of this product? Disabled products will not be visible on the machine.": "確定要變更此商品的狀態嗎?停用的商品將不會在機台上顯示。", "Are you sure you want to change the status? After disabling, this account will no longer be able to log in to the system.": "您確定要變更狀態嗎?停用之後,該帳號將會立即被登出且無法再登入系統。", "Are you sure you want to change the status? This may affect associated accounts.": "您確定要變更狀態嗎?這可能會影響相關帳號的權限效力。", @@ -97,6 +98,7 @@ "Are you sure you want to delete this configuration?": "您確定要刪除此金流配置嗎?", "Are you sure you want to delete this configuration? This action cannot be undone.": "您確定要刪除此金流配置嗎?此操作將無法復原。", "Are you sure you want to delete this item? This action cannot be undone.": "確定要刪除此項目嗎?此操作無法復原。", + "Are you sure you want to delete this product or category? This action cannot be undone.": "您確定要刪除此商品或分類嗎?此操作將無法復原。", "Are you sure you want to delete this product?": "您確定要刪除此商品嗎?", "Are you sure you want to delete this product? All related historical translation data will also be removed.": "確定要刪除此商品嗎?所有相關的歷史翻譯數據也將被移除。", "Are you sure you want to delete this role? This action cannot be undone.": "您確定要刪除此角色嗎?此操作將無法復原。", @@ -636,6 +638,7 @@ "OEE.Sales": "銷售", "of": "/共", "Offline": "離線", + "of items": "筆項目", "Offline Machines": "離線機台", "Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "一旦您的帳號被刪除,其所有資源和數據將被永久刪除。在刪除帳號之前,請下載您希望保留的任何數據或資訊。", "Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "帳號一旦刪除,所有關連數據將被永久移除。請輸入您的密碼以確認您希望永久刪除此帳號。", @@ -831,6 +834,7 @@ "Search by name or S\/N...": "搜尋名稱或序號...", "Search cargo lane": "搜尋貨道編號或商品名稱", "Search Company Title...": "搜尋公司名稱...", + "Search categories...": "搜尋分類...", "Search company...": "搜尋公司...", "Search configurations...": "搜尋設定...", "Search customers...": "搜尋客戶...", @@ -880,7 +884,7 @@ "Show": "顯示", "Show material code field in products": "在商品資料中顯示物料編號欄位", "Show points rules in products": "在商品資料中顯示點數規則相關欄位", - "Showing": "顯示第", + "Showing": "目前顯示", "Showing :from to :to of :total items": "顯示第 :from 到 :to 項,共 :total 項", "Sign in to your account": "隨時隨地掌控您的業務。", "Signed in as": "登入身份", @@ -985,7 +989,10 @@ "Track Channel Limit": "履帶貨道上限", "Track device health and maintenance history": "追蹤設備健康與維修歷史", "Track Limit": "履帶貨道上限", + "Track Limit (Track/Spring)": "貨道上限(履帶/彈簧)", "Traditional Chinese": "繁體中文", + "Track": "履帶", + "Spring": "彈簧", "Transfer Audit": "調撥單", "Transfers": "調撥單", "Trigger": "觸發", @@ -1160,5 +1167,7 @@ "Expired Time": "下架時間", "Inventory synced with machine": "庫存已與機台同步", "Failed to load tab content": "載入分頁內容失敗", - "No machines found": "未找到機台" + "No machines found": "未找到機台", + "No products found matching your criteria.": "找不到符合條件的商品。", + "No categories found.": "找不到分類。" } \ No newline at end of file diff --git a/resources/views/admin/products/index.blade.php b/resources/views/admin/products/index.blade.php index 123059b..0f8d718 100644 --- a/resources/views/admin/products/index.blade.php +++ b/resources/views/admin/products/index.blade.php @@ -17,7 +17,7 @@ $roleSelectConfig = [ @section('content')