I'm trying to import product prices from an XML file, which contains prices in two different currencies for the same product (EUR and DKK). I've created a website for each currency and set the "Catalog Price Scope" to "Website".
We also have websites for B2B and B2C, so we use the following website setup:
- B2B - EUR
- B2B - DKK
- B2C - EUR
- B2C - DKK
The problem is in the code below. In the foreach($storeIds as $storeId) loop, only the first store get updated correctly and the following stores will be set to "Use Default Price". Has anyone experienced something like this?
/**
* Update product price
* @param $line
*/
private function _updateProduct($sku, $price, $currency) {
//EUR website store Ids
$storeIds = $this->moduleHelper->getStoreIdsByCurrency($currency);
foreach($storeIds as $storeId) {
try {
$product = $this->productRepository->get($sku, false, $storeId);
if($product->getId()) {
if ($product->getTypeId() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) {
//set price on associated simple products
foreach ($product->getTypeInstance()->getUsedProducts($product) as $_product) {
$this->_updateProductPrice($_product, $price, $storeId);
}
} else {
//set price on simple product
$this->_updateProductPrice($product, $price, $storeId);
}
}
} catch (\Exception $e) {
// Intentionally left empty.
}
}
}
/**
* Update product price for specific store
* @param $_product
* @param $price
* @param $storeId
* @return bool
*/
private function _updateProductPrice($_product, $price, $storeId) {
try {
$product = $this->productRepository->getById($_product->getId(),false, $storeId);
$product->setStoreId($storeId);
$product->setPrice($price);
$product->save($product);
} catch (\Exception $e) {
// Intentionally left empty.
return false;
}
return true;
}
If I change the array $storeIds to only have one store id, then the product price will be set correctly for that specific website.
I've found a working solution using ProductResourceModel instead of ProductRepositoryInterface.
/**
* Update product price for specific store
* @param int $productId
* @param string $price
* @param int $storeId
* @return bool
*/
private function _updateProductPrice($productId, $storeId, $price) {
try {
$product = $this->productFactory->create();
$this->productResourceModel->load($product, $productId);
$product->setStoreId($storeId);
$product->setPrice($price);
$this->productResourceModel->saveAttribute($product, 'price');
} catch (\Exception $e) {
return false;
}
return true;
}