2011-10-03 21 views
11

Tengo un observador que quita los artículos del carro si están agotados (es decir, el cliente regresa a su carrito x tiempo, y un artículo en el carro se ha agotado), y muestra un mensaje al usuario.Magento recalcula el total del carrito en el observador

La eliminación de los elementos funciona, pero la actualización del total del carrito no. ¡Cualquier ayuda sería muy apreciada!

Mi observador observa el evento sales_quote_save_before:

public function checkStockStatus($observer) 
{ 
    // return if disabled or observer already executed on this request 
    if (!Mage::helper('stockcheck')->isEnabled() || Mage::registry('stockcheck_observer_executed')) { 
     return $this; 
    } 

    $quote = $observer->getEvent()->getQuote(); 
    $outOfStockCount = 0; 

    foreach ($quote->getAllItems() as $item) { 
     $product = Mage::getModel('catalog/product')->load($item->getProductId()); 
     $stockItem = $product->getStockItem(); 
     if ($stockItem->getIsInStock()) { 
      // in stock - for testing only 
      $this->_getSession()->addSuccess(Mage::helper('stockcheck')->__('in stock')); 
      $item->setData('calculation_price', null); 
      $item->setData('original_price', null); 
     } 
     else { 
      //remove item 
      $this->_getCart()->removeItem($item->getId()); 
      $outOfStockCount++; 
      $this->_getSession()->addError(Mage::helper('stockcheck')->__('Out of Stock')); 
     } 
    } 

    if ($outOfStockCount) > 0) {  
     $quote->setTotalsCollectedFlag(false)->collectTotals(); 
    } 

    Mage::register('stockcheck_observer_executed', true); 

    return $this;   
} 

protected function _getCart() 
{ 
    return Mage::getSingleton('checkout/cart'); 
} 

protected function _getSession() 
{ 
    return Mage::getSingleton('checkout/session'); 
} 

Respuesta

3

Gracias @Anton por su ayuda!

La respuesta que terminó trabajando para mí era hacer una llamada a session_write_close(); antes de la redirección (en el observador):

if (// products are out-of-stock and were removed...) { 
    $this->_getSession()->addError('Error message here.'); 
    $this->_getSession()->getQuote()->setTotalsCollectedFlag(false)->collectTotals(); 
    session_write_close(); 
    Mage::app()->getResponse()->setRedirect('index'); 
} 
+0

puede aceptar la respuesta para que otros sepan que está resuelta –

20

Sugerencia del día: observando la * _save_after y tratando de forzar el mismo objeto para cambiar normalmente llamar guardar de nuevo y terminará en bucle sin fin .oO

Sin embargo, si observa el método collectTotals() en la clase de cotización, notará que le falta un indicador importante ->setTotalsCollectedFlag(false)->collectTotals() para hacer el cálculo posible una vez que ya ha sido calculado.

vida sería algo diferente si no hubiera algunos errores en su camino a la gloria por lo que tener en cuenta el problema siguiente en Magento: Issue #26145

+0

Gracias por el consejo del día! Editó el código para eliminar el bucle infinito (observando * _save_before y no haciendo nuevas llamadas a 'save()'). Sin embargo, incluso cuando agrego '-> setTotalsCollectedFlag (false)' antes de llamar a '-> collectTotals()', los totales no se actualizan. ¿Qué más me estoy perdiendo? –

+0

¿verá los cambios después de una recarga? –

+0

sí, pero el mensaje desaparece. Si hago un redireccionamiento en mi observador, obtengo los totales actualizados inmediatamente, pero también ningún mensaje. Lo que busco es que ambos :) –

0

¿Qué hay de flujo siguiente:

  1. eliminar elementos en observador en sales_quote_save_before y añadir un poco de la bandera de registro: Mage::register('ooops_we_need_a_redirect', $url)

  2. en observador sales_quote_save_after qué redirigir si es necesario:

    si (Mago :: registro ('ooops_we_need_a_redirect')) {// hacer redirigir }

+0

No veo cómo solucionaría el problema de que los mensajes de la sesión (es decir, 'Mage :: getSingleton ('chekout/session') -> addError ('mensaje de error aquí'); ') se pierden en una actualización de redirección/página? –

+0

No veo cómo "recalcular el total del carro en el observador" está relacionado con "mensajes de sesión (es decir,' Mage :: getSingleton ('chekout/session') -> addError ('mensaje de error aquí'); ') se pierde en un redirigir/actualizar página? ... – Zyava

+0

tiene toda la razón, el título de mi pregunta no es tan descriptivo como podría haber sido. Para empeorar las cosas, había editado la pregunta, eliminando involuntariamente aclaraciones adicionales (en aras de la brevedad). El desafío fue poder volver a calcular el total del carrito ** y ** mostrar un mensaje de sesión al usuario. Pude lograr quitar los elementos y el recálculo total (a través de un redireccionamiento en el observador después de una llamada a 'collectTotals()') ** o ** eliminar los elementos y mostrar el mensaje (sin redirección), pero quedar atrapado con un total incorrecto –

Cuestiones relacionadas