Tenho uma categoria de produtos que (legalmente) precisam ter sua taxa de imposto alterada quando você está solicitando mais do que uma determinada quantidade. Estendi os vários modelos de impostos para que isso funcione quando você adiciona um novo produto ao carrinho, mas estou com problemas quando o usuário atualiza as quantidades no carrinho ou adiciona produtos adicionais que ultrapassam o limite do carrinho. montante.
Problema 1:
Antes de tudo, não sou 100% dos eventos a serem observados. Eu tentei o seguinte;
checkout_cart_save_after
(com base nisso -> https://stackoverflow.com/questions/14362702/magento-programatically-update-cart-via-event )
checkout_cart_update_items_after
(com base nisso -> https://stackoverflow.com/questions/5104482/programmatically-add-product-to-cart-with-price-change )
sales_quote_save_before
(com base nisso -> https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer )
Problema 2:
Consigo acessar os itens de cotação do carrinho, existem várias maneiras de fazer isso ao que parece. Também posso percorrer os itens individuais no carrinho, atualizar as propriedades desses itens e salvá-los (pelo menos temporariamente). No entanto, não consigo salvar a cotação e recalcular os impostos na finalização da compra.
Parte do motivo é que, embora eu possa acessar a cotação do carrinho, não sei ao certo qual método usar para poder escrever nele.
O que eu tentei:
O que eu tentei em termos de acesso ao conteúdo do carrinho dependeu do evento que observei, mas tentei o seguinte;
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();
O que parece pelo menos permitir que eu acesse a cotação, execute-a e atualize os itens é
6.
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
Isso me permite atualizar cada item de cotação quando iterar (acredito que usando setters mágicos, pois não consigo encontrar nenhum método correspondente). Esperava poder atualizar o ID da classe de imposto para o item de cotação e recalcular os impostos. Se eu usar o seguinte (onde $ taxClassId é diferente daquele já usado por cada item de cotação);
$item->setTaxClassId( $taxClassId );
$item->getProduct()->setIsSuperMode(true);
$item->save;
E então registre os resultados;
Mage::log($item->debug(), null,'taxobserver.log', true);
Isso mostra que eu realmente atualizei este item de cotação e alterei a identificação fiscal. No entanto, se eu seguir adiante e tentar salvar a cotação modificada;
$quote->setTotalsCollectedFlag(false)->collectTotals();
$quote->save();
E então depure novamente;
Mage::log($item->debug(), null,'taxobserver.log', true);
Minhas alterações não foram salvas, a alteração do item de cotação foi redefinida e os totais do carrinho não são recalculados. Começando a pensar se encontrar um prédio alto para pular pode ser a solução para este.
fonte
Respostas:
Minha sugestão seria colocar um observador no
sales_quote_collect_totals_before
evento disparado noMage_Sales_Model_Quote::collectTotals
método antes de iniciar o processo total de coleta. Em seguida, de dentro desse método do observador, itere os itens da cotação e altere a classe de imposto no objeto do produto (já carregado) que você pode recuperar do item da cotação.Depois de definir as informações no objeto do produto, faça o que fizer, NÃO tente salvá-las no banco de dados. A definição da classe de imposto conforme necessário no objeto do produto na memória será suficiente para que a lógica de totais coletados seja encontrada na
Mage_Tax_Model_Sales_Total_Quote_Tax
coleta em qual classe de imposto ela deve basear seus cálculos. Salvar o produto (como você parece estar tentando fazer no seu exemplo de código acima) causará grandes problemas de desempenho, criará condições de corrida no processo de cálculo e simplesmente não é uma boa prática.A razão pela qual os eventos com os quais você está tentando trabalhar não está permitindo que você realize o que está tentando realizar é porque todos vêm após o cálculo total, um processo que só é executado uma vez antes de salvar a cotação.
Vale ressaltar sobre o processo de coletar totais é que, uma vez executado, sem fazer um trabalho extra, você não pode chamá-lo novamente para que ele seja recalculado com base nas alterações feitas nos itens de cotação. Veja este artigo que tirei da série de blogs que um colega meu recentemente montou no processo de coletar totais:
Se você tem uma idéia de realmente mergulhar nas profundezas de como o processo de coletar totais funciona, você pode conferir a primeira das quatro partes da coleção total aqui para uma leitura mais aprofundada: Desvendando o collectTotals do Magento: Introdução
Para resumir, você precisa capturar um evento que é executado antes do processo de coleta total (e antes que getAllItems seja chamado nos endereços de cotação), para que as alterações feitas nos itens sejam usadas pelo total de coletores. Não verifiquei se o
sales_quote_collect_totals_before
evento sugerido é executado antes de qualquer chamada para ogetAllItems
endereço de cotação, mas estou quase certo de que ele funcionará para o que você precisa. Mas, se não, espero que eu tenha fornecido contexto suficiente para você descobrir qual evento você precisa capturar para fazê-lo funcionar.fonte
Há outro evento:
sales_quote_item_set_product
em Mage_Sales_Model_Quote_Item :: setProductVocê pode modificar a classe de imposto do produto usando este evento. Use o método quoteItem getQty para encontrar o qty adicionado ao carrinho.
fonte
Talvez tentar alterar a classe fiscal não seja a melhor abordagem. Por que não criar um produto semelhante para os produtos que usam a classe de imposto mais alta e definem uma quantidade mínima no carrinho para esse produto. Em seguida, use o
checkout_cart_update_items_after
para trocar produtos com base na quantidade total no carrinho?Definitivamente, essa não é uma 'melhor prática', mas pode ajudá-lo a pensar em outra direção.
Como alternativa, tente configurar algo com http://www.mageworx.com/multi-fees-magento-extension.html, onde você adiciona uma "taxa" pelo imposto extra. Na verdade, essa pode ser uma maneira mais agradável de fazê-lo, mas não aparecerá nos totais dos impostos, mais como uma linha total do pedido extra.
fonte
Usa isto
<sales_quote_collect_totals_before>
e na sua função gosta
Espero que isso funcione definitivamente
fonte