Magento 2: Зміна ціни продукту в контролері наразі не працює!


9

Я намагався змінити ціну своїх товарів так:

Controller.php:

[EDIT]

   <?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;
        }
    }
}

(EDIT) З новим кодом ціна змінюється, але підсумкова інформація ні! Як ви можете бачити тут: введіть тут опис зображення

Спасибі заздалегідь!


Привіт, ви можете розробити? який контролер ви використовуєте, і яке ваше завдання? Ви хочете змінити ціну, коли клієнт додає товар у кошик?
Sony

Привіт Sony, ні, я не хочу змінювати ціну, якщо натискається кнопка, а не якщо продукт додається в кошик. На даний момент я просто хочу змінити ціну всіх товарів на 100 доларів для тестування. Я
Фелікс

Вибачте, я боюся не зрозуміти, що ви намагаєтесь. Коли я дивлюсь на ваш код, ви хочете змінити ціни на товари, які знаходяться у вашій кошику. Дійсно, вам дзвонять quoteз checkoutSession. Я трохи розгублений.
Sony

Так, я хочу змінити ціни на товари в кошику. Я також спробував деякі інші речі, щоб досягти цього, і останній, що я спробував, - це поточний код з цитатою.
Фелікс

Зміна ціни не працюватиме за допомогою контролера, для якого потрібно використовувати плагін або спостерігач.
Аасим Горія

Відповіді:


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 зберігає візок в кінці. Тож у вашому випадку ви повинні зберегти цитату у своєму контролері.


Гаразд, ціна зараз змінюється (дивіться на моє оновлене запитання), але підсумкові зміни не будуть, будь-які ідеї?
Фелікс

також якщо ви натискаєте на замовлення, ціна знову така ж
Felix Schönherr

Я думаю, що вам доведеться поглянути на модель котирування, особливо на метод collectionTotals (). Ви повинні встановити прапор $ this-> setTotalsCollectedFlag (false), який просить Magento провести розрахунок заново.
Sony

На жаль, це не спрацювало для мене :(
Фелікс

Спробував це різними способами, і це ніколи не спрацювало.
Фелікс

3

Я зробив фрагмент, який дозволяє змінити ціну. Насправді це змінює ціну після того, як ви додасте товар у свій кошик. Іншими словами, це змінює ціни ваших товарів у вашій котируванні. https://gist.github.com/0-Sony/d9d2ea792b5533bfeaff28827e6f207a

Сподіваюся, це допомагає.


Вибачте, що це не допомагає, я не можу використовувати спостерігача, мені потрібно використовувати свій контролер
Felix Schönherr

3

Ви хочете оновити підсумковий рядок, а не підсумковий, використовувати метод $item->setRowTotal()або $item->setBaseRowTotal(). Також це може допомогти додати $item->save()до кінця циклу.

Subtotal - це підсумковий запис порядку / кошика.


На жаль, це нічого не змінило. Але дякую за вашу відповідь
Фелікс

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();

Примітка: Код випробуваний


Мей працював на вас, але не на мене.
Фелікс

Ви спробували це ($ subTotal = $ cart-> getQuote () -> setSubtotal ($ subtotalprice);) поза цим для циклу
Arunprabakaran M

так, я зробив це саме так, як ви сказали
Фелікс

setSubtotal працює не тільки. правильно? інші методи набору, які добре працюють, як setprice? правильно?
Arunprabakaran M

Так правильно ....
Фелікс

3

Для ціни на кошик для оновлення вам потрібно використовувати модельний кошик, а не сеанс оформлення замовлення. Завантажте товар із кошика та оновіть його.

<?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();
?>

Насправді це не працює, вибачте
Фелікс

Це мій робочий код, я створюю котирування за власною ціною API. Потрібно працювати. Можливо, будь-який модуль конфліктує з вашою стороною
Кетан Борада

0

Спробуйте нижче код:

вам потрібно змінити process()функцію для вашої потреби.

постачальник / магент / модуль-продаж-правило / Модель / 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, буде працювати лише один. правда?
Фелікс

@felix: Ні, вам просто потрібно створити плагін для функції процесу файлу validator.php. він працюватиме для всіх ваших магазинів. Перший ви просто внесете зміни в основний файл і перевірте, чи виконується ваша вимога чи ні? Якщо з цією модифікацією все гаразд, то після створення плагіна для цього.
Balwant Singh

Гаразд, спробуй це завтра, а потім дасть відповідь.
Фелікс

Це змінило лише ціну в підсумку кошика, але ціна на продукцію залишається такою ж
Фелікс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.