Magento 2:目前无法在Controller中更改产品价格!


9

我试图这样更改我的产品的价格:

Controller.php:

[编辑]

   <?php

namespace MassiveArt\ShoppingCart\Controller\Index;

use Magento\Catalog\Model\ProductFactory;
use Magento\Checkout\Model\Cart;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Data\Form\FormKey;

class Index extends Action
{
    /**
     * @var FormKey
     */
    protected $formKey;

    /**
     * @var Session
     */
    protected $checkoutSession;

    /**
     * @var Cart
     */
    protected $cart;

    /**
     * @var ProductFactory
     */
    protected $productFactory;

    /**
     * Constructor.
     *
     * @param Context                         $context
     * @param \Magento\Checkout\Model\Session $checkoutSession
     * @param \Magento\Customer\Model\Session $customerSession
     * @param JsonFactory                     $resultJsonFactory
     * @param FormKey                         $formKey
     * @param Cart                            $cart
     * @param ProductFactory                  $productFactory
     */
    public function __construct(
        Context $context,
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Customer\Model\Session $customerSession,
        JsonFactory $resultJsonFactory,
        FormKey $formKey,
        Cart $cart,
        ProductFactory $productFactory
    ) {
        $this->checkoutSession = $checkoutSession;
        $this->customerSession = $customerSession;
        $this->formKey = $formKey;
        $this->resultJsonFactory = $resultJsonFactory;
        $this->cart = $cart;
        $this->productFactory = $productFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        try {

            // Set result data and pass back
            $result = $this->resultJsonFactory->create();


            $allItems = $this->checkoutSession->getQuote()->getAllVisibleItems();
            foreach ($allItems as $item) {
                $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
                $price = 100; //set your price here
                $item->setCustomPrice($price);
                $item->setOriginalCustomPrice($price);
                $item->setSubtotal($price);
                $item->getProduct()->setIsSuperMode(true);
            }
            $this->checkoutSession->setTotalsCollectedFlag(false);
            $this->checkoutSession->getQuote()->save();
            $this->checkoutSession->getQuote()->setTotalsCollectedFlag(false);
            $this->setTotalsCollectedFlag(false);

            $result->setData(['message' => __("Products added succesfully")]);

            return $result;
        } catch (\Exception $e) {
            $result->setData(['error' => __($e->getMessage())]);
            return $result;
        }
    }
}

(编辑)使用新代码,价格会发生变化,但小计不会!如您所见: 在此处输入图片说明

提前致谢!


嗨,你能详细点吗?您使用哪个控制器,您的任务是什么?当客户将产品添加到购物车时,是否要更改价格?
索尼

您好索尼,不,我想更改价格,如果单击按钮,而不是将产品添加到购物车。现在,我只想将所有产品的价格更改为100美元以进行测试。我会更新我的问题向您展示更多的代码
费利克斯·圣豪

抱歉,恐怕无法理解您正在尝试什么。当我查看您的代码时,您希望更改购物篮中物品的价格。确实,您是quote从拨打电话的checkoutSession。我有点困惑。
索尼

是的,我想更改购物篮中物品的价格。我还尝试了其他一些方法来实现此目的,而我尝试的最后一个方法是带有引号的当前代码。
FelixSchönherr19年

使用您需要使用插件或观察器的控制器,价格更改将不起作用。
Aasim Goriya

Answers:


5

我知道了,我认为您的做法正确,但是我认为您必须保存报价。如果您看一下此类: \Magento\Checkout\Controller\Cart\Add 您可以在114行看到:

$this->cart->addProduct($product, $params);
            if (!empty($related)) {
                $this->cart->addProductsByIds(explode(',', $related));
            }

            $this->cart->save();

我从addProduct()方法结尾处调用的事件中更改价格,Magento在末尾保存购物车。因此,您必须将报价保存在控制器中。


好的,价格现在已更改(请查看我更新的问题),但是小计不会更改,有什么想法吗?
FelixSchönherr19年

如果您再单击结帐,价格也会再次相同
FelixSchönherr19年

我认为您必须看一下报价模型,尤其是collectTotals()方法。您必须设置标志$ this-> setTotalsCollectedFlag(false),要求Magento重新计算。
索尼

不幸的是,这对我不起作用:(
FelixSchönherr19'Aug

以许多不同的方式对其进行了尝试,但从未成功。
FelixSchönherr19年


3

您想使用方法$item->setRowTotal()或更新行总计而不是小计$item->setBaseRowTotal()。另外,$item->save()在循环结束前添加可能会有所帮助。

小计是订单/购物车小计。


不幸的是,这并没有改变。但感谢你的答案
费利克斯·圣豪

3

@felix,您需要设置setSubtotal()报价。在f之外设置小计or loop

$subTotal = $cart->getQuote()->setSubtotal($price);
$this->checkoutSession->getQuote()->save();

像这样

foreach ($allItems as $item) {
                $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
                $price = 100; //set your price here
                $item->setCustomPrice($price);
                $item->setOriginalCustomPrice($price);
                $item->getProduct()->setIsSuperMode(true);
            }
            $subtotalprice=100;
            $subTotal = $cart->getQuote()->setSubtotal($subtotalprice);
            $this->checkoutSession->setTotalsCollectedFlag(false);
            $this->checkoutSession->getQuote()->save();

注意:经过测试的代码


可能为您工作,但不为我工作。
FelixSchönherr19年

您是否在此循环之外尝试过此($ subTotal = $ cart-> getQuote()-> setSubtotal($ subtotalprice);)
Arunprabakaran M

是的,我正是按照您的意思说的
FelixSchönherr19年

setSubtotal仅不起作用。正确?其他set方法像setprice一样工作正常吗?正确?
Arunprabakaran M

是正确的....
费利克斯·圣豪

3

对于Upadate购物车价格,您必须使用Model购物车而不是结帐会话。从购物车中加载商品并进行更新。

<?php 
$items = $this->cart->getQuote()->getAllItems(); //Magento\Checkout\Model\Cart $cart
foreach($items as $item) {

    $item = $this->cart->getQuote()->getItemById($item->getId());
    if (!$item) {
      continue;
    }

    $price = 100;
    $item->setCustomPrice($price);
    $item->setOriginalCustomPrice($price);
    $item->getProduct()->setIsSuperMode(true);
    $item->save();           
}
$this->cart->save();
?>

实际上它不起作用,对不起
FelixSchönherr19年

这是我的工作代码,我正在按API通过自定义价格创建报价。它必须正常工作。可能是任何模块与您的一方冲突
Ketan Borada

0

试试下面的代码:

您需要根据需要修改process()功能。

供应商/ magento /模块销售规则/模型/Validator.php

/**
     * Quote item discount calculation process
     *
     * @param AbstractItem $item
     * @return $this
     */
    public function process(AbstractItem $item)
    {
        $item->setDiscountAmount(0);
        $item->setBaseDiscountAmount(0);
        $item->setDiscountPercent(0);
        $itemPrice = $this->getItemPrice($item);
        if ($itemPrice < 0) {
            return $this;
        }

        $appliedRuleIds = $this->rulesApplier->applyRules(
            $item,
            $this->_getRules($item->getAddress()),
            $this->_skipActionsValidation,
            $this->getCouponCode()
        );
        $this->rulesApplier->setAppliedRuleIds($item, $appliedRuleIds);
        /*Your custom code START here*/
        $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
        $price = 499; //set your price here
        $item->setCustomPrice($price);
        $item->setOriginalCustomPrice($price);
        $item->getProduct()->setIsSuperMode(true);
        //echo "sku: ".$item->getSku()."=== Name: ".$item->getName();die;
        /* Your custom code END here */
        return $this;
    }

注意:请勿修改magento核心文件。为此创建插件。

希望对您有所帮助... !!!


但是,如果我为此插件创建了一个插件,并且在同一商店中运行了另一个扩展,还创建了Validator.php插件,那么只有一个插件可以使用。真正?
FelixSchönherr19年

@felix:不,您只需要为validator.php文件的处理功能创建插件。它会在所有商店中运行。首先,您只需对核心文件进行更改,然后检查是否满足您的要求?如果此修改一切正常,则在为此创建插件之后。
Balwant Singh,

好的,明天再尝试,然后给您答复。
FelixSchönherr19年

这仅更改了购物车摘要中的价格,但产品的价格保持不变
FelixSchönherr19年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.