migrate/resources/views/products/index.blade.php

349 lines
20 KiB
PHP

@extends('layouts.app')
@section('content')
<!-- Migrate Single Product Section -->
<div class="section">
<h2>🔍 Migrate Single Product</h2>
<div class="info-box" style="margin-bottom: 20px;">
<h3 style="margin-bottom: 10px; color: #1976D2; font-size: 1.1em;">Compare Product Values</h3>
<p style="margin: 5px 0; color: #1976D2;">Enter a product SKU to see all differences between Magento 1 and Magento 2 values:</p>
<ul style="margin: 10px 0 0 20px; color: #1976D2; line-height: 1.8;">
<li><strong>M1 Values:</strong> Values from Magento 1 that will be used to update Magento 2</li>
<li><strong>M2 Current Values:</strong> Current values in Magento 2</li>
<li><strong>Action:</strong> Shows whether the value will be INSERTED, UPDATED, or DELETED</li>
</ul>
</div>
<div style="margin-top: 20px; display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
<div style="display: flex; gap: 10px; align-items: center;">
<label for="productSkuInput" style="font-weight: 600; color: #333;">Product SKU:</label>
<input
type="text"
id="productSkuInput"
placeholder="Enter product SKU"
style="padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 1em; min-width: 200px;"
/>
</div>
<button id="compareProductBtn" class="btn btn-primary" onclick="compareProductBySku()">
Compare Product
</button>
</div>
<!-- Comparison Results -->
<div id="productComparisonSection" style="display: none; margin-top: 30px;">
<h3 style="margin-bottom: 15px; color: #333;">Comparison Results</h3>
<div id="productComparisonMessage" style="margin-bottom: 15px; padding: 10px; border-radius: 4px; background: #f0f0f0;"></div>
<div id="productComparisonTablesContainer">
<!-- Tables will be dynamically inserted here -->
</div>
</div>
</div>
<!-- Product Migration Section -->
<div class="section" style="margin-top: 30px;">
<h2>🚀 Product Migration</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 Migration"?</h3>
<p style="margin: 5px 0; color: #1976D2;">The product migration process will:</p>
<ul style="margin: 10px 0 0 20px; color: #1976D2; line-height: 1.8;">
<li><strong>Create new products:</strong> If a product with the same SKU doesn't exist in Magento 2, it will be created with all its attributes</li>
<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>
</div>
<div style="margin-top: 20px; display: flex; gap: 15px; flex-wrap: wrap;">
<button id="startProductMigrationBtn" class="btn btn-primary" onclick="startProductMigration(false)">
Start Product Migration
</button>
<button id="deleteProductsAboveM1MaxBtn" class="btn btn-danger" onclick="deleteProductsAboveM1Max()">
Delete M2 Products Above M1 Max ID
</button>
</div>
<!-- Progress Bar -->
<div id="migrationProgressContainer" style="display: none; margin-top: 20px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
<span id="progressStatus" style="font-weight: 600; color: #333;">Starting migration...</span>
<span id="progressPercentage" style="font-weight: 600; color: #1976D2;">0%</span>
</div>
<div style="width: 100%; height: 24px; background-color: #e0e0e0; border-radius: 12px; overflow: hidden;">
<div id="progressBar" style="width: 0%; height: 100%; background: linear-gradient(90deg, #1976D2 0%, #42a5f5 100%); transition: width 0.3s ease; display: flex; align-items: center; justify-content: center; color: white; font-size: 0.85em; font-weight: 600;"></div>
</div>
<div id="progressDetails" style="margin-top: 8px; font-size: 0.9em; color: #666;">
<span id="currentProduct">-</span> |
Added: <span id="progressAdded">0</span> |
Updated: <span id="progressUpdated">0</span> |
Errors: <span id="progressErrors">0</span>
</div>
</div>
</div>
<!-- Migration Logs Section -->
<div class="section" style="margin-top: 30px;">
<h2>📋 Product Migration Logs</h2>
<p style="margin-bottom: 15px; color: #666;">Error logs showing which products 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 "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>
<p style="margin-bottom: 15px; color: #666;">The following attributes exist in Magento 1 but are missing in Magento 2. These need to be created before migration:</p>
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 20px; max-height: 400px; overflow-y: auto;">
<table class="products-table" id="missingAttributesTable">
<thead>
<tr>
<th>Attribute Code</th>
<th>Label</th>
<th>Backend Type</th>
</tr>
</thead>
<tbody id="missingAttributesTableBody">
</tbody>
</table>
</div>
</div>
<!-- Product Statistics -->
<div class="section" style="margin-top: 30px;">
<h2>📊 Product Statistics</h2>
<div class="stats">
<div class="stat-card">
<div class="number">{{ $m1Products->count() }}</div>
<div class="label">Magento 1 Products</div>
</div>
<div class="stat-card">
<div class="number">{{ $m2Products->count() }}</div>
<div class="label">Magento 2 Products</div>
</div>
<div class="stat-card">
<div class="number">{{ $m1ProductsNotInM2->count() }}</div>
<div class="label">M1 Products Not in M2</div>
</div>
<div class="stat-card">
<div class="number">{{ $m2ProductsNotInM1->count() }}</div>
<div class="label">M2 Products Not in M1</div>
</div>
</div>
</div>
<!-- Products Not in M2 Section -->
@if($m1ProductsNotInM2->count() > 0)
<div class="section" style="margin-top: 30px;">
<h2>⚠️ Magento 1 Products Not in Magento 2</h2>
<p>These products exist in Magento 1 but are missing in Magento 2:</p>
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 20px; max-height: 400px; overflow-y: auto; margin-top: 15px;">
<table class="products-table">
<thead>
<tr>
<th>ID</th>
<th>SKU</th>
<th>Name</th>
<th>Type</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@foreach($m1ProductsNotInM2->take(50) as $product)
<tr>
<td>{{ $product->entity_id }}</td>
<td>{{ $product->sku ?? 'N/A' }}</td>
<td>{{ $product->name ?? 'Unnamed Product' }}</td>
<td>{{ $product->type_id ?? 'N/A' }}</td>
<td>
@if(($product->status ?? 0) == 1)
<span style="color: #28a745;">Enabled</span>
@else
<span style="color: #dc3545;">Disabled</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
@if($m1ProductsNotInM2->count() > 50)
<p style="margin-top: 15px; color: #666;">Showing first 50 of {{ $m1ProductsNotInM2->count() }} products.</p>
@endif
</div>
</div>
@endif
<!-- Products Not in M1 Section -->
@if($m2ProductsNotInM1->count() > 0)
<div class="section" style="margin-top: 30px;">
<h2>⚠️ Magento 2 Products Not in Magento 1</h2>
<p>These products exist in Magento 2 but are missing in Magento 1:</p>
<div style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 20px; max-height: 400px; overflow-y: auto; margin-top: 15px;">
<table class="products-table">
<thead>
<tr>
<th>ID</th>
<th>SKU</th>
<th>Name</th>
<th>Type</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($m2ProductsNotInM1->take(50) as $product)
<tr>
<td>{{ $product->entity_id }}</td>
<td>{{ $product->sku ?? 'N/A' }}</td>
<td>{{ $product->name ?? 'Unnamed Product' }}</td>
<td>{{ $product->type_id ?? 'N/A' }}</td>
<td>
@if(($product->status ?? 0) == 1)
<span style="color: #28a745;">Enabled</span>
@else
<span style="color: #dc3545;">Disabled</span>
@endif
</td>
<td>
<button
class="btn btn-danger"
onclick="deleteM2Product({{ $product->entity_id }}, '{{ addslashes($product->name ?? 'Unnamed Product') }}', '{{ addslashes($product->sku ?? 'N/A') }}')"
style="padding: 6px 12px; font-size: 0.85em;">
Delete
</button>
</td>
</tr>
@endforeach
</tbody>
</table>
@if($m2ProductsNotInM1->count() > 50)
<p style="margin-top: 15px; color: #666;">Showing first 50 of {{ $m2ProductsNotInM1->count() }} products.</p>
@endif
</div>
</div>
@endif
<!-- Sync Product Categories Section -->
<div class="section" style="margin-top: 30px;">
<h2>🔄 Sync Product Categories</h2>
<p>Sync product category assignments from Magento 1 to Magento 2:</p>
<button id="syncProductCategoriesBtn" class="btn btn-primary" onclick="syncProductCategories()" style="margin-top: 15px;">
Sync Product Categories
</button>
</div>
<!-- Fix Category Products Section -->
<div class="section" style="margin-top: 30px;">
<h2>🔧 Fix Category Products</h2>
<div class="info-box" style="margin-bottom: 20px;">
<h3 style="margin-bottom: 10px; color: #1976D2; font-size: 1.1em;">What does this do?</h3>
<p style="margin: 5px 0; color: #1976D2;">This tool checks the Magento 2 <code>catalog_category_product</code> table and ensures products are added to categories if they are missing:</p>
<ul style="margin: 10px 0 0 20px; color: #1976D2; line-height: 1.8;">
<li><strong>Finds missing products:</strong> Identifies products in Magento 2 that are not in the <code>catalog_category_product</code> table</li>
<li><strong>Checks category_ids attribute:</strong> For each missing product, reads the <code>category_ids</code> attribute value</li>
<li><strong>Adds to categories:</strong> Adds the product to the categories specified in its <code>category_ids</code> attribute</li>
<li><strong>Validates categories:</strong> Only adds products to categories that exist in Magento 2</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>
<button id="fixCategoryProductsBtn" class="btn btn-primary" style="margin-top: 15px;">
Fix Category Products
</button>
<div class="log-container" id="fixCategoryProductsLogContainer" style="display: none; margin-top: 20px; overflow: visible; max-height: none;">
<h3 style="margin-bottom: 10px; color: white;">Fix Logs</h3>
<div id="fixCategoryProductsLogContent" 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>
<!-- Category Tree with Products Section -->
<div class="section" style="margin-top: 30px;">
<h2>🌳 Category Tree with Products</h2>
<p>View all categories with their associated products in a tree structure</p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px;">
<!-- Magento 1 Tree with Products -->
<div>
<h3 style="margin-bottom: 15px; color: #667eea;">Magento 1 Categories</h3>
<button onclick="loadM1CategoryTreeWithProducts()" style="padding: 10px 20px; font-size: 1em; background: #667eea; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: 600; margin-bottom: 15px;">
Load M1 Category Tree with Products
</button>
<div class="tree-container" id="m1-category-products-tree-container">
<div class="tree-loading">Click the button above to load categories with products</div>
</div>
</div>
<!-- Magento 2 Tree with Products -->
<div>
<h3 style="margin-bottom: 15px; color: #764ba2;">Magento 2 Categories</h3>
<button onclick="loadM2CategoryTreeWithProducts()" style="padding: 10px 20px; font-size: 1em; background: #764ba2; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: 600; margin-bottom: 15px;">
Load M2 Category Tree with Products
</button>
<div class="tree-container" id="m2-category-products-tree-container">
<div class="tree-loading">Click the button above to load categories with products</div>
</div>
</div>
</div>
</div>
@endsection
{{-- CSS is loaded globally via app.css --}}
@push('scripts')
@vite(['resources/js/products.js'])
<script>
window.productRoutes = {
migrateProducts: '{{ route("products.migrate-products") }}',
migrationProgress: '{{ route("products.migration-progress") }}',
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") }}',
fixCategoryProducts: '{{ route("products.fix-category-products") }}',
compareProductBySku: '{{ route("products.compare-product-by-sku") }}',
magento1CategoryTreeWithProducts: '{{ route("categories.magento1-category-tree-with-products") }}',
magento2CategoryTreeWithProducts: '{{ route("categories.magento2-category-tree-with-products") }}'
};
</script>
@endpush