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!

Felix Schönherr
la source
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.

Sony
la source
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

J'ai fait un extrait qui vous permet de changer le prix. En fait, cela change le prix après avoir ajouté un produit dans votre panier. En d'autres termes, cela modifie les prix de vos articles dans votre devis. https://gist.github.com/0-Sony/d9d2ea792b5533bfeaff28827e6f207a

J'espère que cela aide.

Sony
la source
Désolé cela n'aide pas, je ne peux pas utiliser un observateur, j'ai besoin d'utiliser mon contrôleur
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.

coderGeek
la source
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é

Arunprabakaran M
la source
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();
?>
Ketan Borada
la source
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...!!!

Balwant Singh
la source
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