Question

I have different prices in differents websites but I want to show the other store price in a particular store, I tried this:

$storePriceProduct->setStoreId(1)->getFinalPrice();

But always returns the default price, looks like it.

$productModel = $objectManager->create('Magento\Catalog\Model\Product');
$productStore = $productModel->setStoreId(4)->load($product->getId());
var_dump($productStore->getFinalPrice());

I have the product object in the current viewed store available, setting the storeId on top of that and calling getPrice does not work

Magento version 2.2.3

Was it helpful?

Solution

Here's how to do it with proper DI:

use Magento\Catalog\Api\ProductRepositoryInterface;

class Price
{
    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    public function __construct(ProductRepositoryInterface $productRepository)
    {
        $this->productRepository = $productRepository;
    }

    /**
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getPriceForStore(string $sku, int $storeId): float
    {
        // 3rd argument is the store ID
        $product = $this->productRepository->get($sku, false, $storeId);
        return (float)$product->getFinalPrice();        
    }
}

Please note that the product repository returns an object that complies to the \Magento\Catalog\Api\Data\ProductInterface, which does not have a getFinalPrice()-method. So this code may work now, but it could potentially break ik future updates that are not backward compatible. For example, if Magento decides in the future that Product objects become Product Data objects (like with customers), this code will break.

The most safe approach then would be to implement your own getFinalPrice()-method, for example:

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product\Type;

class Price
{
    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var Type
     */
    protected $productType;

    public function __construct(ProductRepositoryInterface $productRepository, Type $productType)
    {
        $this->productRepository = $productRepository;
        $this->productType = $productType;
    }

    /**
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getPriceForStore(string $sku, int $storeId): float
    {
        // 3rd argument is the store ID
        $product = $this->productRepository->get($sku, false, $storeId);
        return (float)$this->productType
            ->priceFactory($product->getTypeId())
            ->getFinalPrice(1, $product);
    }
}

The safest way to write future-proof Magento code is to depend on abstractions (interfaces), not concretions, even though this sometimes means that you have to look for different solutions.

OTHER TIPS

To load a single product by storeview use this code

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->create('Magento\Catalog\Model\Product')->setStoreId(0)->load($product->getId());

echo  $product->getFinalPrice();

And to load Product collection for specific store view

You should use the product collection like this:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

$collection = $productCollection->create()
              ->addAttributeToSelect('*')
              ->setStoreId(0)
              ->load();

then

foreach($collection as $product) {
 // you can get from product object here 
  $product->getFinalPrice();
}

hope this will work for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top