Magento 2: Changer le prix du produit dans le contrôleur ne fonctionne pas pour le moment!


9

J'ai essayé de changer le prix de mes produits comme ceci:

Controller.php:

[ÉDITER]

   <?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) Avec le nouveau code, le prix change, mais pas le sous-total! Comme vous pouvez le voir ici: entrez la description de l'image ici

Merci d'avance!


Salut, pouvez-vous élaborer? quel contrôleur utilisez-vous et quelle est votre tâche? Voulez-vous modifier le prix lorsqu'un client ajoute un produit au panier?
Sony

Bonjour Sony, non, je veux changer le prix, si un bouton est cliqué, pas si un produit est ajouté au panier. Pour l'instant, je veux juste changer le prix de tous les produits à 100 $ pour les tests. Je mettrai à jour ma question pour vous montrer un peu plus de code
Felix Schönherr

Désolé, j'ai peur de ne pas comprendre ce que vous essayez. Quand je regarde votre code, vous cherchez à changer les prix des articles qui sont dans votre panier. En effet, vous appelez le quotedu checkoutSession. Je suis un peu confus.
Sony

Oui, je souhaite modifier les prix des articles de mon panier. J'ai également essayé d'autres choses pour y parvenir et le dernier que j'ai essayé est le code actuel avec citation.
Felix Schönherr

Le changement de prix ne fonctionnera pas en utilisant le contrôleur dont vous avez besoin pour utiliser le plugin ou l'observateur.
Aasim Goriya

Réponses:


5

Je comprends, je pense que vous êtes dans la bonne voie, mais je pense que vous devez enregistrer la citation. Si vous jetez un œil à cette classe: \Magento\Checkout\Controller\Cart\Add vous pouvez voir à la ligne 114:

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

            $this->cart->save();

Je modifie le prix de l'événement qui est appelé à la fin de la addProduct()méthode et Magento enregistre le panier à la fin. Donc, dans votre cas, vous devez enregistrer le devis dans votre contrôleur.


Ok, le prix est changé maintenant (regardez ma question mise à jour), mais le sous-total ne changera pas, des idées?
Felix Schönherr

aussi si vous cliquez ensuite sur la caisse, le prix est à nouveau le même
Felix Schönherr

Je pense que vous devez jeter un œil au modèle de devis, en particulier à la méthode collectTotals (). Vous devez définir le drapeau $ this-> setTotalsCollectedFlag (false) qui demande à Magento de calculer à nouveau.
Sony

Malheureusement, cela n'a pas fonctionné pour moi :(
Felix Schönherr

Je l'ai essayé de différentes manières et cela n'a jamais fonctionné.
Felix Schönherr


3

Vous souhaitez mettre à jour le total des lignes et non le sous-total, utilisez la méthode $item->setRowTotal()ou $item->setBaseRowTotal(). En outre, il peut être utile d'ajouter $item->save()avant la fin de la boucle.

Le sous-total est le sous-total de la commande / du panier.


Malheureusement, cela n'a rien changé. Mais merci pour votre réponse
Felix Schönherr

3

@ felix, vous devez définir setSubtotal()un devis. Définir le sous-total à l'extérieur f or loop.

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

comme ça

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

Remarque: Code testé


May a travaillé pour vous, mais pas pour moi.
Felix Schönherr

Avez-vous essayé cela ($ subTotal = $ cart-> getQuote () -> setSubtotal ($ subtotalprice);) en dehors de cette boucle
Arunprabakaran M

oui, je l'ai fait exactement comme vous l'avez dit
Felix Schönherr

setSubtotal ne fonctionne pas seulement. correct? d'autres méthodes de jeu fonctionnent bien comme setprice? correct?
Arunprabakaran M

Oui correct ....
Felix Schönherr

3

Pour le prix du panier Upadate, vous devez utiliser le panier modèle à la place de la session de paiement. Chargez l'article du panier et mettez-le à jour.

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

En fait, cela ne fonctionne pas, désolé
Felix Schönherr

C'est mon code de travail, je crée un devis par prix personnalisé par API. Il doit fonctionner. Tout module peut être en conflit avec vous
Ketan Borada

0

Essayez le code ci-dessous:

vous devez modifier la process()fonction selon vos besoins.

vendeur / magento / module-sales-rule / Model / 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;
    }

REMARQUE: ne modifiez pas les fichiers de base de magento. Créez un plugin pour cela.

J'espère que cela aidera...!!!


Mais si je crée un plugin pour cela et une autre extension, qui s'exécute sur le même magasin, crée également un plugin de Validator.php, un seul fonctionnera. vrai?
Felix Schönherr

@felix: Non, il vous suffit de créer un plugin pour la fonction de processus du fichier validator.php. il fonctionnera pour tous vos magasins. Tout d'abord, vous modifiez simplement le fichier principal et vérifiez une fois que votre exigence est remplie ou non? Si tous sont d'accord avec cette modification, après avoir créé le plugin pour cela.
Balwant Singh

Ok, j'essaierai cela demain et je vous répondrai ensuite.
Felix Schönherr

Cela n'a changé que le prix dans le résumé du panier, mais le prix des produits reste le même
Felix Schönherr
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.