fix for missing product columns
This commit is contained in:
parent
e77f4447b4
commit
d195fd62ab
|
|
@ -147,5 +147,30 @@ public function fixCategoryProducts(Request $request)
|
|||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate product options from M1 mageworx_custom_option_ tables to M2 mageworx_optiontemplates_ tables
|
||||
*/
|
||||
public function migrateProductOptions(Request $request)
|
||||
{
|
||||
try {
|
||||
$dryRun = $request->input('dry_run', false);
|
||||
$result = $this->migrationService->migrateProductOptions($dryRun);
|
||||
|
||||
return response()->json($result, $result['success'] ? 200 : 400);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Product options migration error: ' . $e->getMessage());
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Migration failed: ' . $e->getMessage(),
|
||||
'migrated' => 0,
|
||||
'skipped' => 0,
|
||||
'errors' => 0,
|
||||
'log' => []
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -452,8 +452,103 @@ function createCategoryWithProductsNode(node) {
|
|||
return nodeDiv;
|
||||
}
|
||||
|
||||
function startProductOptionsMigration(dryRun) {
|
||||
// Check if routes are available
|
||||
if (!routes || !routes.migrateProductOptions) {
|
||||
console.error('Product options routes not available', routes);
|
||||
alert('Error: Routes not initialized. Please refresh the page.');
|
||||
return;
|
||||
}
|
||||
|
||||
const button = dryRun ? document.getElementById('dryRunProductOptionsMigrationBtn') : document.getElementById('startProductOptionsMigrationBtn');
|
||||
const otherButton = dryRun ? document.getElementById('startProductOptionsMigrationBtn') : document.getElementById('dryRunProductOptionsMigrationBtn');
|
||||
const logContainer = document.getElementById('productOptionsMigrationLogContainer');
|
||||
const logContent = document.getElementById('productOptionsMigrationLogContent');
|
||||
|
||||
if (!button) {
|
||||
console.error('Button not found');
|
||||
alert('Error: Button not found. Please refresh the page.');
|
||||
return;
|
||||
}
|
||||
|
||||
const originalText = button.textContent;
|
||||
button.disabled = true;
|
||||
if (otherButton) {
|
||||
otherButton.disabled = true;
|
||||
}
|
||||
button.textContent = dryRun ? 'Running Dry Run...' : 'Migrating...';
|
||||
button.style.cursor = 'not-allowed';
|
||||
|
||||
logContainer.style.display = 'block';
|
||||
logContent.innerHTML = '<div class="log-entry">' + (dryRun ? 'Running dry run...' : 'Starting migration...') + '</div>';
|
||||
|
||||
fetch(routes.migrateProductOptions, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': csrfToken
|
||||
},
|
||||
body: JSON.stringify({ dry_run: dryRun })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
button.disabled = false;
|
||||
if (otherButton) {
|
||||
otherButton.disabled = false;
|
||||
}
|
||||
button.textContent = originalText;
|
||||
button.style.cursor = 'pointer';
|
||||
|
||||
if (data.success) {
|
||||
const successEntry = document.createElement('div');
|
||||
successEntry.className = 'log-entry success';
|
||||
successEntry.textContent = `✓ ${dryRun ? 'Dry run' : 'Migration'} completed! Migrated: ${data.migrated || 0}, Skipped: ${data.skipped || 0}, Errors: ${data.errors || 0}`;
|
||||
logContent.appendChild(successEntry);
|
||||
|
||||
if (data.log && data.log.length > 0) {
|
||||
data.log.forEach(log => {
|
||||
const entry = document.createElement('div');
|
||||
entry.className = 'log-entry ' + (log.includes('ERROR') ? 'error' : (log.includes('WARNING') ? 'warning' : (log.includes('INFO') ? 'info' : 'success')));
|
||||
entry.textContent = log;
|
||||
logContent.appendChild(entry);
|
||||
});
|
||||
}
|
||||
|
||||
logContent.scrollTop = logContent.scrollHeight;
|
||||
} else {
|
||||
const errorEntry = document.createElement('div');
|
||||
errorEntry.className = 'log-entry error';
|
||||
errorEntry.textContent = '✗ ' + (dryRun ? 'Dry run' : 'Migration') + ' failed: ' + (data.message || 'Unknown error');
|
||||
logContent.appendChild(errorEntry);
|
||||
|
||||
if (data.log && data.log.length > 0) {
|
||||
data.log.forEach(log => {
|
||||
const entry = document.createElement('div');
|
||||
entry.className = 'log-entry ' + (log.includes('ERROR') ? 'error' : 'warning');
|
||||
entry.textContent = log;
|
||||
logContent.appendChild(entry);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
button.disabled = false;
|
||||
if (otherButton) {
|
||||
otherButton.disabled = false;
|
||||
}
|
||||
button.textContent = originalText;
|
||||
button.style.cursor = 'pointer';
|
||||
|
||||
const errorEntry = document.createElement('div');
|
||||
errorEntry.className = 'log-entry error';
|
||||
errorEntry.textContent = '✗ Error: ' + error.message;
|
||||
logContent.appendChild(errorEntry);
|
||||
});
|
||||
}
|
||||
|
||||
// Make functions available globally
|
||||
window.startProductMigration = startProductMigration;
|
||||
window.startProductOptionsMigration = startProductOptionsMigration;
|
||||
window.deleteM2Product = deleteM2Product;
|
||||
window.deleteProductsAboveM1Max = deleteProductsAboveM1Max;
|
||||
window.syncProductCategories = syncProductCategories;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
<li><strong>Update existing products:</strong> If a product with the same SKU already exists in Magento 2, it will be updated with the latest data from Magento 1</li>
|
||||
<li><strong>Migrate product attributes:</strong> All product attributes including SKU, name, description, price, weight, status, visibility, and tax class will be migrated</li>
|
||||
<li><strong>Assign to categories:</strong> Products will be assigned to the corresponding categories in Magento 2</li>
|
||||
<li><strong>Migrate product options:</strong> All <code>catalog_product_option</code> tables will be migrated, including options, prices, titles, and type values</li>
|
||||
<li><strong>Generate logs:</strong> Detailed migration logs showing which products were added, updated, or encountered errors</li>
|
||||
</ul>
|
||||
<p style="margin: 10px 0 0 0; color: #d32f2f; font-weight: 600;">⚠️ <strong>Warning:</strong> This will modify your Magento 2 database. Make sure you have a backup before proceeding.</p>
|
||||
|
|
@ -30,6 +31,52 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Migration Logs Section -->
|
||||
<div class="section" style="margin-top: 30px;">
|
||||
<h2>📋 Product Migration Logs</h2>
|
||||
<p style="margin-bottom: 15px; color: #666;">Detailed logs showing which products were added, updated, or encountered errors during migration:</p>
|
||||
<div class="log-container" id="productMigrationLogContainer" style="display: block;">
|
||||
<div id="productMigrationLogContent">
|
||||
<div class="log-entry" style="color: #999; font-style: italic;">
|
||||
No product migration logs yet. Click "Run Dry Run" or "Start Product Migration" to begin.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Migrate Product Options Section -->
|
||||
<div class="section" style="margin-top: 30px;">
|
||||
<h2>📦 Migrate Product Options</h2>
|
||||
<div class="info-box" style="margin-bottom: 20px;">
|
||||
<h3 style="margin-bottom: 10px; color: #1976D2; font-size: 1.1em;">What happens when you click "Start Product Options Migration"?</h3>
|
||||
<p style="margin: 5px 0; color: #1976D2;">The product options migration process will:</p>
|
||||
<ul style="margin: 10px 0 0 20px; color: #1976D2; line-height: 1.8;">
|
||||
<li><strong>Find mageworx tables:</strong> Automatically discovers all <code>mageworx_custom_option_*</code> tables in Magento 1</li>
|
||||
<li><strong>Map to M2 tables:</strong> Maps M1 tables to corresponding <code>mageworx_optiontemplates_*</code> tables in Magento 2</li>
|
||||
<li><strong>Migrate data:</strong> Migrates all records from M1 mageworx custom option tables to M2 option templates tables</li>
|
||||
<li><strong>Update existing records:</strong> If a record already exists in M2 (by primary key), it will be updated</li>
|
||||
<li><strong>Insert new records:</strong> New records will be inserted into M2 tables</li>
|
||||
<li><strong>Generate logs:</strong> Detailed migration logs showing which tables and records were migrated</li>
|
||||
</ul>
|
||||
<p style="margin: 10px 0 0 0; color: #d32f2f; font-weight: 600;">⚠️ <strong>Warning:</strong> This will modify your Magento 2 database. Make sure you have a backup before proceeding.</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px; display: flex; gap: 15px; flex-wrap: wrap;">
|
||||
<button id="dryRunProductOptionsMigrationBtn" class="btn btn-secondary" onclick="startProductOptionsMigration(true)">
|
||||
Run Dry Run (Check for Errors)
|
||||
</button>
|
||||
<button id="startProductOptionsMigrationBtn" class="btn btn-primary" onclick="startProductOptionsMigration(false)">
|
||||
Start Product Options Migration
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="log-container" id="productOptionsMigrationLogContainer" style="display: none; margin-top: 20px; overflow: visible; max-height: none;">
|
||||
<h3 style="margin-bottom: 10px; color: white;">Migration Logs</h3>
|
||||
<div id="productOptionsMigrationLogContent" style="max-height: 400px; overflow-y: auto; background: #000000; color: #ffffff; padding: 15px; border-radius: 4px; font-family: monospace; font-size: 0.9em;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Missing Attributes Section -->
|
||||
<div class="section" id="missingAttributesSection" style="margin-top: 30px; display: none;">
|
||||
<h2>⚠️ Missing Attributes</h2>
|
||||
|
|
@ -49,19 +96,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Migration Logs Section -->
|
||||
<div class="section" style="margin-top: 30px;">
|
||||
<h2>📋 Product Migration Logs</h2>
|
||||
<p style="margin-bottom: 15px; color: #666;">Detailed logs showing which products were added, updated, or encountered errors during migration:</p>
|
||||
<div class="log-container" id="productMigrationLogContainer" style="display: block;">
|
||||
<div id="productMigrationLogContent">
|
||||
<div class="log-entry" style="color: #999; font-style: italic;">
|
||||
No product migration logs yet. Click "Run Dry Run" or "Start Product Migration" to begin.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Product Statistics -->
|
||||
<div class="section" style="margin-top: 30px;">
|
||||
<h2>📊 Product Statistics</h2>
|
||||
|
|
@ -247,6 +281,7 @@ class="btn btn-danger"
|
|||
<script>
|
||||
window.productRoutes = {
|
||||
migrateProducts: '{{ route("products.migrate-products") }}',
|
||||
migrateProductOptions: '{{ route("products.migrate-product-options") }}',
|
||||
deleteProduct: '{{ route("products.delete-product", ["productId" => ":id"]) }}',
|
||||
deleteProductsAboveM1Max: '{{ route("products.delete-products-above-m1-max") }}',
|
||||
syncProductCategories: '{{ route("products.sync-product-categories") }}',
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
Route::prefix('products')->name('products.')->group(function () {
|
||||
Route::get('/', [ProductsController::class, 'index'])->name('index');
|
||||
Route::post('/migrate', [ProductsController::class, 'migrateProducts'])->name('migrate-products');
|
||||
Route::post('/migrate-options', [ProductsController::class, 'migrateProductOptions'])->name('migrate-product-options');
|
||||
Route::post('/sync-categories', [ProductsController::class, 'syncProductCategories'])->name('sync-product-categories');
|
||||
Route::post('/fix-category-products', [ProductsController::class, 'fixCategoryProducts'])->name('fix-category-products');
|
||||
Route::delete('/{productId}', [ProductsController::class, 'deleteM2Product'])->name('delete-product');
|
||||
|
|
|
|||
Loading…
Reference in New Issue