Open piotrekkaminski opened 7 years ago
@dmanners , I was able to reproduce this issue on ver. 2.3.0-dev.
Can anyone tell me why this was closed?
Oh thanks for catching this @Rickertje this was closed due to human error on my part :( I will reopen it now.
following class can be altered to ensure positions do not get lost on import: \Magento\CatalogImportExport\Model\Import\Product
replacement within di.xml:
<preference for="Magento\CatalogImportExport\Model\Import\Product" type="Vendor\Module\Model\Import\Product" />
The problematic function is _saveProductCategories where the position is manually set to 1 instead of the preset values from the backend. All relations are gonna be reinserted with the wrongly set position.
This could be fixed with following adaption of the method (preloading of position values if they exist) and reseting them into the inserOnDuplicate array: `protected function _saveProductCategories(array $categoriesData) { static $tableName = null;
if (!$tableName) {
$tableName = $this->_resourceFactory->create()->getProductCategoryTable();
}
if ($categoriesData) {
$categoriesIn = [];
$delProductId = [];
$positionsData = [];
foreach ($this->fetchCategoryProductPositions($tableName, $categoriesData) as $relation) {
$positionsData[$relation['product_id'].'__##__'.$relation['category_id']] = intval($relation['position']);
}
foreach ($categoriesData as $delSku => $categories) {
$productId = $this->skuProcessor->getNewSku($delSku)['entity_id'];
$delProductId[] = $productId;
foreach (array_keys($categories) as $categoryId) {
$position = isset($positionsData[$productId.'__##__'.$categoryId])?$positionsData[$productId.'__##__'.$categoryId] :1;
$categoriesIn[] = ['product_id' => $productId, 'category_id' => $categoryId, 'position' => $position];
}
}
if (Import::BEHAVIOR_APPEND != $this->getBehavior()) {
$this->_connection->delete(
$tableName,
$this->_connection->quoteInto('product_id IN (?)', $delProductId)
);
}
if ($categoriesIn) {
$this->_connection->insertOnDuplicate($tableName, $categoriesIn, ['product_id', 'category_id']);
}
}
return $this;
}
protected function fetchCategoryProductPositions($tableName, $categoriesData) {
return $this->_connection->fetchAll($this->_connection->select()
->from($tableName, ['product_id', 'category_id', 'position'])
->where('product_id IN (?)', array_map(function ($sku) {
return $this->skuProcessor->getNewSku($sku);
}, array_keys($categoriesData))));
}`
From @piotrekkaminski on November 2, 2017 21:17
Setting product position setting, exporting products, and reimporting products causes product position setting to be erased.
Preconditions
STEPS TO REPRODUCE
1) Sign into admin panel 2) Create 4 test products 3) Add them all to test category 4) Go to Category settings and set positions for all 4 products 5) Export file 6) Look over exported CSV file - no column showing for category position 7) Import file - replace data 8) Look at category settings - note product order is erased
Actual results
Random: 2 of the positions stay but one of them gets changed (See attached trunk category position settings after.png and trunk category position settings before.png).
EXPECTED RESULTS:
Positions for products in categories should be retained from before import to after export.
Copied from original issue: magento/magento2#11981