diff --git a/app/Http/Controllers/MagentoMigrationController.php b/app/Http/Controllers/MagentoMigrationController.php index 62e0f70..2cc5020 100644 --- a/app/Http/Controllers/MagentoMigrationController.php +++ b/app/Http/Controllers/MagentoMigrationController.php @@ -180,6 +180,38 @@ public function getMagento2CategoryTree() } } + /** + * Get M2 categories not in M1 (for AJAX refresh) + */ + public function getM2CategoriesNotInM1() + { + try { + $categories = $this->migrationService->getM2CategoriesNotInM1(); + + return response()->json([ + 'success' => true, + 'categories' => $categories->map(function($category) { + return [ + 'entity_id' => $category->entity_id, + 'name' => $category->name ?? 'Unnamed Category', + 'level' => $category->level ?? 'N/A', + 'is_active' => $category->is_active ?? 0, + 'root_category_name' => $category->root_category_name ?? 'N/A', + 'root_category_id' => $category->root_category_id ?? null, + 'path' => $category->path ?? 'N/A', + ]; + }), + 'count' => $categories->count(), + ]); + } catch (\Exception $e) { + Log::error('Error fetching M2 categories not in M1: ' . $e->getMessage()); + return response()->json([ + 'success' => false, + 'message' => 'Failed to fetch categories: ' . $e->getMessage(), + ], 500); + } + } + /** * Delete a category */ diff --git a/resources/views/migration/index.blade.php b/resources/views/migration/index.blade.php index 4c30ba1..a8a9394 100644 --- a/resources/views/migration/index.blade.php +++ b/resources/views/migration/index.blade.php @@ -786,7 +786,7 @@

These categories exist in Magento 2 but do not have a matching name in Magento 1:

@if($m2CategoriesNotInM1->count() > 0) -
+
@@ -798,7 +798,7 @@ - + @foreach($m2CategoriesNotInM1 as $category) @@ -825,11 +825,11 @@
Path
{{ $category->entity_id }}
-
+
Total: {{ $m2CategoriesNotInM1->count() }} {{ Str::plural('category', $m2CategoriesNotInM1->count()) }} found in Magento 2 but not in Magento 1.
@else -
+
✓ All Magento 2 categories have matching names in Magento 1.
@endif @@ -2198,6 +2198,99 @@ function closeDeleteConfirmPopup() { if (overlay) overlay.remove(); } + // Refresh M2 categories not in M1 table + function refreshM2CategoriesNotInM1() { + fetch('{{ route("migration.m2-categories-not-in-m1") }}', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': '{{ csrf_token() }}' + } + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + const tbody = document.getElementById('m2-categories-not-in-m1-tbody'); + const totalDiv = document.getElementById('m2-categories-not-in-m1-total'); + const emptyDiv = document.getElementById('m2-categories-not-in-m1-empty'); + + if (!tbody) return; + + // Clear existing rows + tbody.innerHTML = ''; + + if (data.categories && data.categories.length > 0) { + // Show table and total, hide empty message + const tableWrapper = document.getElementById('m2-categories-not-in-m1-table-wrapper'); + if (tableWrapper) tableWrapper.style.display = 'block'; + if (emptyDiv) emptyDiv.style.display = 'none'; + if (totalDiv) { + totalDiv.style.display = 'block'; + totalDiv.innerHTML = `Total: ${data.count} ${data.count === 1 ? 'category' : 'categories'} found in Magento 2 but not in Magento 1.`; + } + + // Add rows + data.categories.forEach(category => { + const row = document.createElement('tr'); + row.style.borderBottom = '1px solid #dee2e6'; + + const statusClass = category.is_active ? 'active' : 'inactive'; + const statusText = category.is_active ? 'Active' : 'Inactive'; + + let rootCategoryHtml = ''; + if (category.root_category_name && category.root_category_name !== 'N/A') { + rootCategoryHtml = `${category.root_category_name}`; + if (category.root_category_id) { + rootCategoryHtml += ` (ID: ${category.root_category_id})`; + } + } else { + rootCategoryHtml = 'N/A'; + } + + row.innerHTML = ` + ${category.entity_id} + ${category.name || 'Unnamed Category'} + ${category.level || 'N/A'} + + ${statusText} + + ${rootCategoryHtml} + ${category.path || 'N/A'} + `; + + tbody.appendChild(row); + }); + } else { + // Hide table and total, show empty message + const tableWrapper = document.getElementById('m2-categories-not-in-m1-table-wrapper'); + if (tableWrapper) tableWrapper.style.display = 'none'; + if (totalDiv) totalDiv.style.display = 'none'; + if (emptyDiv) { + emptyDiv.style.display = 'block'; + } else { + // Create empty message if it doesn't exist + const section = tbody.closest('.section'); + if (section) { + const newEmptyDiv = document.createElement('div'); + newEmptyDiv.id = 'm2-categories-not-in-m1-empty'; + newEmptyDiv.style.marginTop = '15px'; + newEmptyDiv.style.padding = '15px'; + newEmptyDiv.style.background = '#d4edda'; + newEmptyDiv.style.borderLeft = '4px solid #28a745'; + newEmptyDiv.style.borderRadius = '4px'; + newEmptyDiv.style.color = '#155724'; + newEmptyDiv.textContent = '✓ All Magento 2 categories have matching names in Magento 1.'; + section.appendChild(newEmptyDiv); + } + } + } + } + }) + .catch(error => { + console.error('Error refreshing M2 categories not in M1:', error); + }); + } + // Delete category function deleteCategory(categoryId, categoryName, source) { const container = source === 'm1' ? document.getElementById('m1-tree-container') : document.getElementById('m2-tree-container'); @@ -2222,6 +2315,8 @@ function deleteCategory(categoryId, categoryName, source) { loadM1Tree(); } else { loadM2Tree(); + // Refresh M2 categories not in M1 table after deleting from M2 + refreshM2CategoriesNotInM1(); } } else { container.innerHTML = originalContent; diff --git a/routes/web.php b/routes/web.php index ac748f3..ecbc5a9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -16,6 +16,7 @@ Route::get('/magento1-category-tree-with-products', [MagentoMigrationController::class, 'getMagento1CategoryTreeWithProducts'])->name('migration.magento1-category-tree-with-products'); Route::get('/magento2-category-tree', [MagentoMigrationController::class, 'getMagento2CategoryTree'])->name('migration.magento2-category-tree'); Route::get('/magento2-category-tree-with-products', [MagentoMigrationController::class, 'getMagento2CategoryTreeWithProducts'])->name('migration.magento2-category-tree-with-products'); + Route::get('/m2-categories-not-in-m1', [MagentoMigrationController::class, 'getM2CategoriesNotInM1'])->name('migration.m2-categories-not-in-m1'); Route::delete('/category/{categoryId}', [MagentoMigrationController::class, 'deleteCategory'])->name('migration.delete-category'); Route::put('/category/{categoryId}/rename', [MagentoMigrationController::class, 'renameCategory'])->name('migration.rename-category'); Route::post('/attribute/{attributeId}/migrate', [MagentoMigrationController::class, 'migrateAttribute'])->name('migration.migrate-attribute');