Magento – (Solved) Magento 2.2.2 – Update product price per website programmatically not working

magento2.2.2multicurrencymultistoreprice

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:

  1. B2B – EUR
  2. B2B – DKK
  3. B2C – EUR
  4. 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;
}

Best Answer

Do you have any explanation for why this is happening? I've implemented the same solution by I can't figure why the first solution works

Related Topic