J'ai une catégorie de produits qui (légalement) doivent voir leur taux de taxe modifié lorsque vous commandez plus qu'une certaine quantité. J'ai étendu les différents modèles de taxe pour que cela fonctionne lorsque vous ajoutez un nouveau produit au panier, mais je rencontre des problèmes lorsque l'utilisateur met à jour les quantités dans le panier ou ajoute des produits supplémentaires qui font basculer les quantités déjà dans le panier au-delà du seuil montant.
Problème 1:
Tout d'abord, je ne suis pas à 100% quel (s) événement (s) observer. J'ai essayé ce qui suit;
checkout_cart_save_after
(basé sur ceci -> https://stackoverflow.com/questions/14362702/magento-programately-update-cart-via-event )
checkout_cart_update_items_after
(basé sur ceci -> https://stackoverflow.com/questions/5104482/programmatically-add-product-to-cart-with-price-change )
sales_quote_save_before
(basé sur ceci -> https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer )
Problème 2:
Je suis en mesure d'accéder aux articles du devis à partir du panier, il existe de nombreuses façons de le faire, semble-t-il. Je peux également parcourir les articles individuels du panier, mettre à jour les propriétés de ces articles, puis enregistrer les articles (au moins temporairement). Cependant, je ne suis pas en mesure de sauvegarder le devis et de recalculer les taxes lors du paiement.
Une partie de la raison est que même si je peux accéder au devis du panier, je ne sais pas quelle méthode utiliser pour pouvoir y écrire.
Ce que j'ai essayé:
Ce que j'ai essayé en termes d'accès au contenu du panier dépend de l'événement que j'ai observé, mais j'ai essayé tout ce qui suit;
1.
$item = $observer->getQuoteItem;
2.
$cart = Mage::getSingleton('checkout/cart');
$cartItems = $cart->getCart()->getItems();
3.
$cart = $observer->getData('cart');
$quote = $cart->getData('quote');
$cartItems = $quote->getAllVisibleItems();
4.
$cartHelper = Mage::helper('checkout/cart');
$cartItems = $cartHelper->getCart()->getItems();
5.
$quote = Mage::getModel('checkout/cart');
$cartItems = $quote->getItems();
Celui qui semble au moins me permettre d'accéder au devis, de le parcourir et de mettre à jour les articles est
6.
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
Cela me permet de mettre à jour chaque élément de devis lorsque je répète (je crois que l'utilisation de setters magiques car je ne trouve aucune méthode correspondante). J'espérais pouvoir mettre à jour l'ID de classe de taxe pour l'élément de devis, puis recalculer les taxes. Si j'utilise ce qui suit (où $ taxClassId est différent de celui déjà utilisé par chaque élément de devis);
$item->setTaxClassId( $taxClassId );
$item->getProduct()->setIsSuperMode(true);
$item->save;
Et puis enregistrez les résultats;
Mage::log($item->debug(), null,'taxobserver.log', true);
Cela montre que j'ai effectivement mis à jour cet élément de devis et changé le numéro d'identification fiscale. Cependant, si je continue et essaie d'enregistrer le devis modifié;
$quote->setTotalsCollectedFlag(false)->collectTotals();
$quote->save();
Et puis déboguez à nouveau;
Mage::log($item->debug(), null,'taxobserver.log', true);
Mes modifications n'ont pas été enregistrées, la modification de l'élément de devis a été réinitialisée et les totaux du panier ne sont pas recalculés. Commencer à se demander si trouver un grand bâtiment pour sauter pourrait être la solution pour celui-ci.
la source
Réponses:
Ma suggestion serait de mettre un observateur sur l'
sales_quote_collect_totals_before
événement qui est déclenché dans laMage_Sales_Model_Quote::collectTotals
méthode avant qu'il ne commence le processus de collecte totale. Ensuite, à l'intérieur de cette méthode d'observation, itérez les éléments de devis et modifiez la classe de taxe sur l'objet produit (déjà chargé) que vous pouvez récupérer à partir de l'élément de devis.Après avoir défini les informations sur l'objet produit, quoi que vous fassiez, N'ESSAYEZ PAS de l'enregistrer dans la base de données. Le fait d'avoir la classe de taxe définie en tant que de besoin sur l'objet produit en mémoire sera suffisant pour que la logique de collecte des totaux soit trouvée dans la
Mage_Tax_Model_Sales_Total_Quote_Tax
collecte sur la classe de taxe sur laquelle elle doit baser ses calculs. L'enregistrement du produit (comme vous semblez essayer de le faire dans votre exemple de code ci-dessus) entraînera des problèmes de performances majeurs, créera des conditions de concurrence critique dans le processus de calcul et n'est tout simplement pas une bonne pratique.La raison pour laquelle les événements avec lesquels vous essayez de travailler ne vous permettent pas d'accomplir ce que vous essayez d'accomplir, car ils surviennent tous après le calcul total, un processus qui n'est exécuté qu'une seule fois avant d'enregistrer le devis.
Il convient de souligner le processus de collecte des totaux: une fois exécuté, sans faire de travail supplémentaire, vous ne pouvez pas le rappeler pour le recalculer en fonction des modifications que vous avez apportées aux éléments de devis. Voir ce lien que j'ai extrait de la série de blogs qu'un de mes collègues a récemment mis en place sur le processus de collecte des totaux:
S'il vous arrive d'avoir une idée de vraiment plonger dans les profondeurs du fonctionnement du processus de collecte des totaux, vous pouvez consulter la première des quatre séries de parties sur la collecte totale ici pour une lecture plus approfondie: Démêler les collectTotals de Magento: Introduction
Pour résumer, vous devez intercepter un événement qui s'exécute avant le processus de collecte des totaux (et avant que getAllItems soit appelé sur les adresses de devis) afin que les modifications que vous apportez aux articles soient utilisées par l'ensemble des collecteurs. Je n'ai pas vérifié que l'
sales_quote_collect_totals_before
événement suggéré s'exécute avant tout appel à l'getAllItems
adresse de devis, mais je suis presque certain qu'il fonctionnera pour ce dont vous avez besoin. Si ce n'est pas le cas, j'espère avoir fourni suffisamment de contexte pour que vous puissiez déterminer quel événement vous devez attraper pour le faire fonctionner.la source
Il y a un autre événement:
sales_quote_item_set_product
dans Mage_Sales_Model_Quote_Item :: setProductVous pouvez modifier la classe de taxe sur les produits à l'aide de cet événement. Utilisez la méthode quoteItem getQty pour trouver la quantité ajoutée au panier.
la source
Peut-être que tenter de changer la classe fiscale n'est peut-être pas la meilleure approche. Pourquoi ne pas créer un produit similaire pour les produits qui utilisent la classe d'imposition la plus élevée et définir une quantité minimale dans le panier pour ce produit. Ensuite, utilisez le
checkout_cart_update_items_after
pour échanger des produits en fonction de la quantité totale dans le panier?Ce n'est certainement pas une «meilleure pratique», mais cela pourrait vous aider à penser dans une autre direction.
Vous pouvez également essayer de configurer quelque chose avec http://www.mageworx.com/multi-fees-magento-extension.html où vous ajoutez des «frais» pour la taxe supplémentaire. Cela pourrait en fait être une meilleure façon de le faire, mais cela n'apparaîtra pas dans les totaux de taxe, plus comme une ligne de total de commande supplémentaire.
la source
Utilisez ceci
<sales_quote_collect_totals_before>
et dans votre fonction aimez
J'espère que cela fonctionnera définitivement
la source