Magento 2: la modifica del prezzo del prodotto nel controller non funziona al momento!


9

Ho provato a cambiare il prezzo dei miei prodotti in questo modo:

controller.php:

[MODIFICARE]

   <?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) Con il nuovo codice il prezzo cambia, ma il totale parziale no! Come puoi vedere qui: inserisci qui la descrizione dell'immagine

Grazie in anticipo!


Ciao, puoi elaborare? quale controller utilizzi e qual è il tuo compito? Vuoi cambiare il prezzo quando un cliente aggiunge un prodotto al carrello?
Sony,

Ciao Sony, no, voglio cambiare il prezzo, se si fa clic su un pulsante, non se un prodotto viene aggiunto al carrello. Per ora voglio solo cambiare il prezzo di tutti i prodotti a 100 $ per i test. Aggiornerò la mia domanda per mostrarvi altro codice
Felix Schönherr,

Scusa, ho paura di non capire cosa stai provando. Quando guardo il tuo codice, sembri voler cambiare i prezzi degli articoli che sono nel carrello. In effetti stai chiamando il quoteda checkoutSession. Sono un po 'confuso.
Sony,

Sì, voglio cambiare i prezzi degli articoli nel mio carrello. Ho provato anche altre cose per raggiungere questo obiettivo e l'ultimo che ho provato è il codice corrente con virgolette.
Felix Schönherr,

La modifica del prezzo non funzionerà utilizzando il controller necessario per utilizzare plugin o osservatore.
Aasim Goriya,

Risposte:


5

Ho capito, penso che tu sia nel modo giusto, ma penso che devi salvare il preventivo. Se dai un'occhiata a questa classe: \Magento\Checkout\Controller\Cart\Add puoi vedere alla Linea 114:

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

            $this->cart->save();

Cambio il prezzo dall'evento che si chiama alla fine del addProduct()metodo e Magento salva il carrello alla fine. Quindi, nel tuo caso, devi salvare il preventivo nel tuo controller.


Ok, il prezzo viene cambiato ora (guarda la mia domanda aggiornata), ma il totale parziale non cambierà, qualche idea?
Felix Schönherr,

anche se fai clic sul checkout, il prezzo è di nuovo lo stesso
Felix Schönherr,

Penso che tu debba dare un'occhiata al modello di preventivo, specialmente al metodo collectTotals (). Devi impostare il flag $ this-> setTotalsCollectedFlag (false) che chiede a Magento di eseguire nuovamente il calcolo.
Sony,

Purtroppo questo non ha funzionato per me :(
Felix Schönherr,

L'ho provato in molti modi diversi e non ha mai funzionato.
Felix Schönherr,


3

Si desidera aggiornare il totale della riga e non il totale parziale, utilizzare il metodo $item->setRowTotal()o $item->setBaseRowTotal(). Inoltre, potrebbe essere utile aggiungere $item->save()prima della fine del ciclo.

Il totale parziale è il totale parziale ordine / carrello.


Purtroppo questo non ha cambiato nulla. Ma grazie per la risposta
Felix Schönherr,

3

@ Felix, devi impostare setSubtotal()un preventivo. Imposta subtotale esterno f or loop.

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

come questo

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

Nota: codice testato


May ha lavorato per te, ma non per me.
Felix Schönherr,

Hai provato questo ($ subTotal = $ cart-> getQuote () -> setSubtotal ($ subtotalprice);) al di fuori di questo per loop
Arunprabakaran M

sì, l'ho fatto esattamente come hai detto
Felix Schönherr,

setSubtotal non funziona. corretta? altri metodi set funzionano bene come setprice? corretta?
Arunprabakaran M,

Sì, corretto ....
Felix Schönherr,

3

Per il prezzo del carrello Upadate devi usare il carrello Modello invece della sessione di pagamento. Carica l'articolo dal carrello e aggiornalo.

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

In realtà non funziona, mi dispiace
Felix Schönherr,

È il mio codice di lavoro, sto creando un preventivo per prezzo personalizzato per API. Deve essere possibile che qualsiasi modulo sia in conflitto con te
Ketan Borada,

0

Prova sotto il codice:

è necessario modificare la process()funzione in base alle proprie esigenze.

vendor / magento / module-vendite-regola / modello / 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;
    }

NOTA: non modificare i file core di magento. Crea plugin per questo.

Spero che questo possa aiutare...!!!


Ma se creo un plugin per questa e un'altra estensione, che gira nello stesso negozio, crea anche un plugin di Validator.php, solo uno funzionerà. vero?
Felix Schönherr,

@felix: No, devi solo creare un plugin per la funzione di processo del file validator.php. funzionerà per tutti i tuoi negozi. prima devi solo cambiare il file principale e controllare una volta che il tuo requisito è soddisfatto o no? Se tutto va bene con questa modifica, dopo aver creato il plugin per questo.
Balwant Singh,

Ok, ci proverò domani e ti darà una risposta.
Felix Schönherr,

Ciò ha cambiato solo il prezzo nel riepilogo del carrello, ma il prezzo dei prodotti è rimasto lo stesso
Felix Schönherr,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.