Updated product sync to include stock and urls
This commit is contained in:
parent
0b93c87b93
commit
e77f4447b4
|
|
@ -2209,6 +2209,12 @@ public function migrateProducts($dryRun = false)
|
|||
if ($isNew) {
|
||||
$this->migrateProductUrlRewrites($m1Product->entity_id, $m2ProductId);
|
||||
}
|
||||
|
||||
// Migrate stock inventory for all products
|
||||
$this->migrateProductStock($m1Product->entity_id, $m2ProductId);
|
||||
|
||||
// Migrate product website assignments for all products
|
||||
$this->migrateProductWebsites($m1Product->entity_id, $m2ProductId);
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
|
@ -3499,6 +3505,153 @@ protected function getStoreMapping()
|
|||
return $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get website mapping by matching website codes or IDs from stores
|
||||
*/
|
||||
protected function getWebsiteMapping()
|
||||
{
|
||||
$mapping = [];
|
||||
|
||||
try {
|
||||
$m1Stores = $this->getMagento1Stores();
|
||||
$m2Stores = $this->getMagento2Stores();
|
||||
|
||||
// Build website mapping from store website_ids
|
||||
// Group stores by website_id and match by store codes
|
||||
$m1WebsiteMap = [];
|
||||
foreach ($m1Stores as $m1Store) {
|
||||
$websiteId = $m1Store->website_id ?? 0;
|
||||
if ($websiteId > 0 && !isset($m1WebsiteMap[$websiteId])) {
|
||||
$m1WebsiteMap[$websiteId] = $m1Store->code ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
$m2WebsiteMap = [];
|
||||
foreach ($m2Stores as $m2Store) {
|
||||
$websiteId = $m2Store->website_id ?? 0;
|
||||
if ($websiteId > 0 && !isset($m2WebsiteMap[$websiteId])) {
|
||||
$m2WebsiteMap[$websiteId] = $m2Store->code ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
// Match websites by store codes (websites with stores that have matching codes)
|
||||
foreach ($m1WebsiteMap as $m1WebsiteId => $m1StoreCode) {
|
||||
$m1StoreCodeLower = strtolower(trim($m1StoreCode));
|
||||
if (!empty($m1StoreCodeLower)) {
|
||||
// Find M2 website with matching store code
|
||||
foreach ($m2WebsiteMap as $m2WebsiteId => $m2StoreCode) {
|
||||
$m2StoreCodeLower = strtolower(trim($m2StoreCode));
|
||||
if ($m1StoreCodeLower === $m2StoreCodeLower) {
|
||||
$mapping[$m1WebsiteId] = $m2WebsiteId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no match found, try to match by website_id (fallback)
|
||||
if (!isset($mapping[$m1WebsiteId])) {
|
||||
// Check if M2 has a website with the same ID
|
||||
if (isset($m2WebsiteMap[$m1WebsiteId])) {
|
||||
$mapping[$m1WebsiteId] = $m1WebsiteId;
|
||||
} else {
|
||||
// Default to website ID 1 (main website) if no match
|
||||
$mapping[$m1WebsiteId] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no mapping found, ensure at least default website (ID 1) is mapped
|
||||
if (empty($mapping)) {
|
||||
$mapping[1] = 1; // Default website mapping
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::warning('Error building website mapping: ' . $e->getMessage());
|
||||
// Default to website ID 1 if error
|
||||
$mapping[1] = 1;
|
||||
}
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate product website assignments from M1 catalog_product_website to M2 catalog_product_website
|
||||
*/
|
||||
protected function migrateProductWebsites($m1ProductId, $m2ProductId)
|
||||
{
|
||||
try {
|
||||
// Get website mapping
|
||||
$websiteMapping = $this->getWebsiteMapping();
|
||||
|
||||
// Get product websites from M1
|
||||
$m1ProductWebsites = DB::connection($this->magento1Connection)
|
||||
->table($this->magento1Prefix . 'catalog_product_website')
|
||||
->where('product_id', $m1ProductId)
|
||||
->get();
|
||||
|
||||
if ($m1ProductWebsites->isEmpty()) {
|
||||
// No websites assigned in M1, assign to default website (ID 1)
|
||||
$this->assignProductToWebsite($m2ProductId, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Migrate each website assignment
|
||||
foreach ($m1ProductWebsites as $m1ProductWebsite) {
|
||||
$m1WebsiteId = $m1ProductWebsite->website_id ?? 1;
|
||||
$m2WebsiteId = isset($websiteMapping[$m1WebsiteId]) ? $websiteMapping[$m1WebsiteId] : 1;
|
||||
|
||||
// Check if assignment already exists
|
||||
$exists = DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'catalog_product_website')
|
||||
->where('product_id', $m2ProductId)
|
||||
->where('website_id', $m2WebsiteId)
|
||||
->exists();
|
||||
|
||||
if (!$exists) {
|
||||
DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'catalog_product_website')
|
||||
->insert([
|
||||
'product_id' => $m2ProductId,
|
||||
'website_id' => $m2WebsiteId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error migrating product websites for M1 ID {$m1ProductId}, M2 ID {$m2ProductId}: " . $e->getMessage());
|
||||
// Don't throw - just log the error and assign to default website
|
||||
try {
|
||||
$this->assignProductToWebsite($m2ProductId, 1);
|
||||
} catch (Exception $e2) {
|
||||
Log::error("Error assigning product to default website: " . $e2->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a product to a website
|
||||
*/
|
||||
protected function assignProductToWebsite($productId, $websiteId)
|
||||
{
|
||||
try {
|
||||
// Check if assignment already exists
|
||||
$exists = DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'catalog_product_website')
|
||||
->where('product_id', $productId)
|
||||
->where('website_id', $websiteId)
|
||||
->exists();
|
||||
|
||||
if (!$exists) {
|
||||
DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'catalog_product_website')
|
||||
->insert([
|
||||
'product_id' => $productId,
|
||||
'website_id' => $websiteId,
|
||||
]);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error assigning product {$productId} to website {$websiteId}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate URL rewrites from M1 core_url_rewrite to M2 url_rewrite for a product
|
||||
*/
|
||||
|
|
@ -3573,6 +3726,161 @@ protected function migrateProductUrlRewrites($m1ProductId, $m2ProductId)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate stock inventory from M1 cataloginventory_stock_item to M2 cataloginventory_stock_item
|
||||
*/
|
||||
protected function migrateProductStock($m1ProductId, $m2ProductId)
|
||||
{
|
||||
try {
|
||||
// Get stock item from M1
|
||||
$m1StockItem = DB::connection($this->magento1Connection)
|
||||
->table($this->magento1Prefix . 'cataloginventory_stock_item')
|
||||
->where('product_id', $m1ProductId)
|
||||
->first();
|
||||
|
||||
if (!$m1StockItem) {
|
||||
// No stock record in M1, create a default one in M2
|
||||
$this->createDefaultStockItem($m2ProductId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if stock item already exists in M2
|
||||
$existingStockItem = DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_item')
|
||||
->where('product_id', $m2ProductId)
|
||||
->first();
|
||||
|
||||
// Prepare stock data for M2
|
||||
$stockData = [
|
||||
'product_id' => $m2ProductId,
|
||||
'stock_id' => $m1StockItem->stock_id ?? 1, // Default to 1 if not set
|
||||
'qty' => $m1StockItem->qty ?? 0,
|
||||
'is_in_stock' => $m1StockItem->is_in_stock ?? 0,
|
||||
'manage_stock' => $m1StockItem->manage_stock ?? 1,
|
||||
'use_config_manage_stock' => $m1StockItem->use_config_manage_stock ?? 1,
|
||||
'min_qty' => $m1StockItem->min_qty ?? 0,
|
||||
'min_sale_qty' => $m1StockItem->min_sale_qty ?? 1,
|
||||
'max_sale_qty' => $m1StockItem->max_sale_qty ?? 0,
|
||||
'is_qty_decimal' => $m1StockItem->is_qty_decimal ?? 0,
|
||||
'backorders' => $m1StockItem->backorders ?? 0,
|
||||
'notify_stock_qty' => $m1StockItem->notify_stock_qty ?? 0,
|
||||
'use_config_notify_stock_qty' => $m1StockItem->use_config_notify_stock_qty ?? 1,
|
||||
'use_config_min_qty' => $m1StockItem->use_config_min_qty ?? 1,
|
||||
'use_config_min_sale_qty' => $m1StockItem->use_config_min_sale_qty ?? 1,
|
||||
'use_config_max_sale_qty' => $m1StockItem->use_config_max_sale_qty ?? 1,
|
||||
'use_config_backorders' => $m1StockItem->use_config_backorders ?? 1,
|
||||
'use_config_enable_qty_inc' => $m1StockItem->use_config_enable_qty_inc ?? 1,
|
||||
'enable_qty_increments' => $m1StockItem->enable_qty_increments ?? 0,
|
||||
'use_config_qty_increments' => $m1StockItem->use_config_qty_increments ?? 1,
|
||||
'qty_increments' => $m1StockItem->qty_increments ?? 0,
|
||||
];
|
||||
|
||||
// Add optional fields if they exist in M1
|
||||
if (isset($m1StockItem->low_stock_date)) {
|
||||
$stockData['low_stock_date'] = $m1StockItem->low_stock_date;
|
||||
}
|
||||
if (isset($m1StockItem->is_decimal_divided)) {
|
||||
$stockData['is_decimal_divided'] = $m1StockItem->is_decimal_divided;
|
||||
}
|
||||
|
||||
if ($existingStockItem) {
|
||||
// Update existing stock item
|
||||
DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_item')
|
||||
->where('product_id', $m2ProductId)
|
||||
->update($stockData);
|
||||
} else {
|
||||
// Insert new stock item
|
||||
DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_item')
|
||||
->insert($stockData);
|
||||
}
|
||||
|
||||
// Also update cataloginventory_stock_status if it exists
|
||||
try {
|
||||
$stockStatusData = [
|
||||
'product_id' => $m2ProductId,
|
||||
'website_id' => 0, // Default website
|
||||
'stock_id' => $m1StockItem->stock_id ?? 1,
|
||||
'qty' => $m1StockItem->qty ?? 0,
|
||||
'stock_status' => $m1StockItem->is_in_stock ?? 0,
|
||||
];
|
||||
|
||||
$existingStatus = DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_status')
|
||||
->where('product_id', $m2ProductId)
|
||||
->where('website_id', 0)
|
||||
->where('stock_id', $stockStatusData['stock_id'])
|
||||
->first();
|
||||
|
||||
if ($existingStatus) {
|
||||
DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_status')
|
||||
->where('product_id', $m2ProductId)
|
||||
->where('website_id', 0)
|
||||
->where('stock_id', $stockStatusData['stock_id'])
|
||||
->update($stockStatusData);
|
||||
} else {
|
||||
DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_status')
|
||||
->insert($stockStatusData);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Stock status table might not exist or have different structure, log and continue
|
||||
Log::debug("Could not update stock status table: " . $e->getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error migrating stock for product M1 ID {$m1ProductId}, M2 ID {$m2ProductId}: " . $e->getMessage());
|
||||
// Don't throw - just log the error and continue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default stock item for a product
|
||||
*/
|
||||
protected function createDefaultStockItem($productId)
|
||||
{
|
||||
try {
|
||||
// Check if stock item already exists
|
||||
$exists = DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_item')
|
||||
->where('product_id', $productId)
|
||||
->exists();
|
||||
|
||||
if (!$exists) {
|
||||
// Create default stock item
|
||||
DB::connection($this->magento2Connection)
|
||||
->table($this->magento2Prefix . 'cataloginventory_stock_item')
|
||||
->insert([
|
||||
'product_id' => $productId,
|
||||
'stock_id' => 1,
|
||||
'qty' => 0,
|
||||
'is_in_stock' => 0,
|
||||
'manage_stock' => 1,
|
||||
'use_config_manage_stock' => 1,
|
||||
'min_qty' => 0,
|
||||
'min_sale_qty' => 1,
|
||||
'max_sale_qty' => 0,
|
||||
'is_qty_decimal' => 0,
|
||||
'backorders' => 0,
|
||||
'notify_stock_qty' => 0,
|
||||
'use_config_notify_stock_qty' => 1,
|
||||
'use_config_min_qty' => 1,
|
||||
'use_config_min_sale_qty' => 1,
|
||||
'use_config_max_sale_qty' => 1,
|
||||
'use_config_backorders' => 1,
|
||||
'use_config_enable_qty_inc' => 1,
|
||||
'enable_qty_increments' => 0,
|
||||
'use_config_qty_increments' => 1,
|
||||
'qty_increments' => 0,
|
||||
]);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error("Error creating default stock item for product ID {$productId}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure product is enabled and visible (required for products to appear in categories after reindex)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue