Tengo una categoría de productos a los que (legalmente) se les debe cambiar su tasa de impuestos cuando realiza un pedido de más de una cantidad determinada. He ampliado los diversos modelos de impuestos para que esto funcione cuando agrega un nuevo producto al carrito, pero tengo problemas cuando el usuario actualiza las cantidades en el carrito o agrega productos adicionales que inclinan las cantidades que ya están en el carrito por encima del umbral cantidad.
Problema 1:
En primer lugar, no estoy al 100% de los eventos que debo observar. He intentado lo siguiente;
checkout_cart_save_after
(basado en esto -> https://stackoverflow.com/questions/14362702/magento-programatic-update-cart-via-event )
checkout_cart_update_items_after
(basado en esto -> https://stackoverflow.com/questions/5104482/programmatic-add-product-to-cart-with-price-change )
sales_quote_save_before
(basado en esto -> https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer )
Problema 2:
Puedo acceder a los artículos de presupuesto desde el carrito, parece que hay muchas maneras de hacerlo. También puedo iterar a través de los artículos individuales en el carrito, actualizar las propiedades de esos artículos y luego guardarlos (al menos temporalmente). Sin embargo, no puedo guardar la cotización y volver a calcular los impuestos en el proceso de pago.
Parte de la razón es que, si bien puedo acceder a la cotización del carrito, no estoy seguro de qué método utilizar para poder escribir en él.
Lo que he probado:
Lo que he intentado en términos de acceso al contenido del carrito ha dependido del evento que he observado, pero he intentado todo lo siguiente;
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();
El que parece al menos permitirme acceder a la cotización, revisarlo y actualizar los elementos es
6.
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
Esto me permite actualizar cada elemento de cotización cuando itero (creo que usando setters mágicos ya que no puedo encontrar ningún método correspondiente). Esperaba poder actualizar la identificación de la clase de impuestos para el artículo de la cotización y luego volver a calcular los impuestos. Si uso lo siguiente (donde $ taxClassId es diferente al que ya usa cada artículo de cotización);
$item->setTaxClassId( $taxClassId );
$item->getProduct()->setIsSuperMode(true);
$item->save;
Y luego registrar los resultados;
Mage::log($item->debug(), null,'taxobserver.log', true);
Muestra que efectivamente actualicé este artículo de cotización y cambié la identificación fiscal. Sin embargo, si sigo adelante e intento guardar la cita modificada;
$quote->setTotalsCollectedFlag(false)->collectTotals();
$quote->save();
Y luego depurar de nuevo;
Mage::log($item->debug(), null,'taxobserver.log', true);
Mis cambios no se han guardado, el cambio del artículo de presupuesto se ha restablecido y los totales del carrito no se vuelven a calcular. Comenzar a preguntarse si encontrar un edificio alto para saltar podría ser la solución para este.
fuente
Respuestas:
Mi sugerencia sería poner un observador en el
sales_quote_collect_totals_before
evento que se activa en elMage_Sales_Model_Quote::collectTotals
método antes de que comience el proceso de recolección total. Luego, desde el interior de este método de observación, itere los artículos de cotización y cambie la clase de impuestos en el objeto del producto (ya cargado) que puede recuperar del artículo de cotización.Después de configurar la información sobre el objeto del producto, haga lo que haga, NO intente guardarlo en la base de datos. Tener la clase de impuestos establecida según sea necesario en el objeto del producto en la memoria será lo suficientemente buena como para que la lógica de recopilación de totales se encuentre en la
Mage_Tax_Model_Sales_Total_Quote_Tax
recolección en qué clase de impuestos debería basar sus cálculos. Guardar el producto (como parece estar tratando de hacer en el ejemplo de código anterior) causará problemas importantes de rendimiento, creará condiciones de carrera en el proceso de cálculo y simplemente no es una buena práctica.La razón por la cual los eventos con los que está tratando de trabajar no le permiten lograr lo que está tratando de lograr es porque todos ocurren después del cálculo total, un proceso que solo se ejecuta una vez antes de guardar la cotización.
Vale la pena señalar que el proceso de recopilación de totales es que una vez ejecutado, sin hacer un trabajo adicional, no puede volver a llamarlo para que se vuelva a calcular en función de los cambios que haya realizado en los elementos de la cotización. Vea este enlace que tomé de la serie de blogs, una colección mía recientemente reunida en el proceso de recopilación de totales:
Si tiene la menor idea de sumergirse realmente en las profundidades de cómo funciona el proceso de recopilación de totales, puede consultar la primera de las series de cuatro partes sobre la recopilación total aquí para obtener una lectura más profunda: Desvelando los Totales de recopilación de Magento: Introducción
Para resumir, debe capturar un evento que se ejecute antes del proceso de recopilación de totales (y antes de que se llame a getAllItems en las direcciones de cotización) para que los cambios que realice en los artículos sean utilizados por los recolectores totales. No he verificado que el
sales_quote_collect_totals_before
evento sugerido se ejecute antes de cualquier llamada a lagetAllItems
dirección de presupuesto, pero estoy casi seguro de que funcionará para lo que necesita. Pero si no, espero haber proporcionado suficiente contexto para que descubras qué evento necesitas atrapar para que funcione.fuente
Hay otro evento:
sales_quote_item_set_product
en Mage_Sales_Model_Quote_Item :: setProductPuede modificar la clase de impuestos del producto utilizando este evento. Use el método quoteItem getQty para encontrar la cantidad agregada al carrito.
fuente
Quizás intentar cambiar la clase de impuestos podría no ser el mejor enfoque. ¿Por qué no crear un producto similar para aquellos productos que usan la clase de impuestos más alta y establecer una cantidad mínima en el carrito para ese producto? Luego, use
checkout_cart_update_items_after
para intercambiar productos según la cantidad total en el carrito.Definitivamente, esta no es una "mejor práctica", pero podría ayudarlo a pensar en otra dirección.
Alternativamente, intente configurar algo con http://www.mageworx.com/multi-fees-magento-extension.html donde agrega una 'tarifa' por el impuesto adicional. En realidad, esta podría ser una mejor manera de hacerlo, pero no aparecerá en los totales de impuestos, más como una línea total de pedido adicional.
fuente
Utilizar esta
<sales_quote_collect_totals_before>
y en tu función te gusta
Espero que esto funcione definitivamente
fuente