Magento: envíe un correo electrónico de pedido nuevo solo con cronjobs

11

¿Cómo puedo enviar los correos electrónicos del nuevo pedido usando:

$order->sendNewOrderEmail();

solo desde un cronjob utilizado en Mi módulo personalizado.

Gracias por la ayuda.

Bizboss
fuente

Respuestas:

8

Deshabilitaría System > Configuration > Sales Email > Order > Enabled

esto asegura que durante la ejecución normal no se envíe

public function sendNewOrderEmail()
{
    $storeId = $this->getStore()->getId();

    if (!Mage::helper('sales')->canSendNewOrderEmail($storeId)) {
        return $this;
    }

Luego, en su módulo personalizado, incluya algo como

    Mage::getConfig()->setNode(
        'default/'.Mage_Sales_Model_Order::XML_PATH_EMAIL_ENABLED, true
    );
    foreach(Mage::app()->getStores() as $storeCode=>$store){
        Mage::getConfig()->setNode(
            "stores/{$storeCode}/".Mage_Sales_Model_Order::XML_PATH_EMAIL_ENABLED, true
        );
    }
    $collection = Mage::getModel('sales/order')->getCollection()->addAttributeToFilter('email_sent', 0);
    foreach ($collection as $order){
        $order->sendNewOrderEmail();
    }

La idea principal es anular el valor de configuración deshabilitado en tiempo de ejecución. El código no se prueba, pero debería darle un punto de partida. Lectura adicional recomendada del blog de Alan: http://alanstorm.com/magento_loading_config_variables http://alanstorm.com/magento_config_a_critique_and_caching

Un problema que puede encontrar es un valor en caché para lo anterior.

La segunda opción sería duplicar el código de sendNewOrderEmail ().

Kristof en Fooman
fuente
Genio. Puro, sin adulterar, genio.
philwinkle
1
la adulación te llevará a todas partes ;-)
Kristof en Fooman
3

La esencia de hacer este tipo de cambio (radical) es la siguiente:

  • Reescriba sendNewOrderEmail para que actúe como una cola y condicionalmente envíe / no envíe según el modo de cola (vea algunos pseudocódigos a continuación)
  • Según el modo de cola del modelo de pedido de ventas, enviamos el correo electrónico desde la cola cargando el pedido desde el trabajo cron y enviando manualmente el correo electrónico.

Algún código de muestra para la reescritura del modelo de orden de venta:

El siguiente código dependerá de la presencia de una tabla llamada yourmodule_sales_email_queuey haré referencia a algunas columnas con captadores mágicos. No voy a proporcionar un esquema ya que este no es un código completamente funcional y es una especie de prueba de concepto; No es un módulo de trabajo.

Agregue esto a etc / config.xml de su módulo :

<global>
    <model>
        <emailqueue>
            <class>YourCompany_YourModule_Model</class>
            <resourceModel>emailqueue_resource</resourceModel>
        </emailqueue>
        <emailqueue_resource>
            <class>YourCompany_YourModule_Model_Resource</class>
            <entities>
                <queue>
                    <table>yourmodule_sales_email_queue</table>
                </queue>
            </entities>
        </emailqueue_resource>
        <sales>
            <rewrite>
                <order>YourCompany_YourModule_Model_Order</order>
            </rewrite>
        </sales>
    </model>
</global>

aplicación / código / local / YourCompany / YourModule / Model / Order.php

<?php

class YourCompany_YourModule_Model_Order extends Mage_Sales_Model_Order
{
    protected $_isQueueMode = false;

    public function sendNewOrderEmail()
    {       
        //send order email if our custom queue mode is set
        if($this->_isQueueMode){
            parent::sendNewOrderEmail();
            return;
        }

        //not running from queue, let's shove stuff into the queue
        $this->getEmailQueue()->load($this)->save();
    }


    public function getEmailQueue()
    {
        if(!isset($this->queue)){
            $this->queue = $this->_getEmailQueue();
        }
        return $this->queue;
    }

    protected function _getEmailQueue()
    {
        return Mage::getResourceModel('emailqueue/queue');
    }


}

A partir de ahí, debe definir un modelo de recurso, una colección y un trabajador cron.

La definición de cron en etc / config.xml se vería así:

<crontab>
    <jobs>
        <emailqueue_send_order_emails>
            <schedule>
                <cron_expr>0 0 * * *</cron_expr>
            </schedule>
            <run>
                <model>emailqueue/observer::sendEmailsFromQueue</model>
            </run>
        </emailqueue_send_order_emails>
    </jobs>
</crontab>

Que invoca un método de la clase YourCompany_YourModule_Model_Observer. Cargaremos las últimas 24 horas de correos electrónicos de la cola, cargaremos el pedido asociado y configuraremos el indicador para permitir que envíe correos electrónicos. Luego invocaremos el método de envío por correo electrónico:

<?php

class YourCompany_YourModule_Model_Observer
{
    public function sendEmailsFromQueue($observer)
    {
        //load queue and define the run window
        $queue = Mage::getModel('emailqueue/queue')->getCollection()->getSelect()
                ->where('created_at',array('lt'=>Zend_Db_Expr('NOW()')))
                ->where('created_at',array('gt'=>Zend_Db_Expr('NOW() - INTERVAL 24 HOUR')));

        foreach($queue as $worker){
            //logic to send the email e.g.:
            $order = Mage::getModel('sales/order')->loadByIncrementId($worker->getOrderIncrementId());
            $order->_isQueueMode = true;
            $order->sendNewOrderEmail();
        }

    }
}

Descargo de responsabilidad:

Tenga en cuenta que el código anterior no se prueba y no funcionará solo. Espera que exista mucha funcionalidad (como colecciones). También lo escribí en la mente y puede haber inconsistencias , ya que he cambiado de opinión sobre cómo manejaría esto una o dos veces desde que comencé esta respuesta.

Esto tiene el propósito de ayudarlo a comenzar y pensar en cómo lo lograría. Estoy dispuesto a responder cualquier pregunta que pueda tener. También estoy dispuesto a contribuir en Github a una versión de código abierto de este tipo de módulo.

¡La mejor de las suertes!

philwinkle
fuente
Esto está diseñado en exceso en comparación con la solución de @ fooman y me gusta más suya que la mía :)
philwinkle