Magento: invia email per il nuovo ordine solo con cronjobs


11

Come posso inviare le e-mail del nuovo ordine usando:

$order->sendNewOrderEmail();

solo da un cronjob utilizzato nel mio modulo personalizzato.

Grazie per l'aiuto.

Risposte:


8

Disabiliterei System > Configuration > Sales Email > Order > Enabled

questo si assicura che durante la normale esecuzione non venga inviato

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

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

Quindi nel tuo modulo personalizzato includi qualcosa di simile

    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();
    }

L'idea principale è quella di sovrascrivere il valore di configurazione disabilitato in fase di esecuzione. Il codice non è testato ma dovrebbe darti un punto di partenza. Ulteriori letture consigliate dal blog di Alan: http://alanstorm.com/magento_loading_config_variables http://alanstorm.com/magento_config_a_critique_and_caching

Un problema che potresti riscontrare è un valore memorizzato nella cache per quanto sopra.

La seconda opzione sarebbe quella di duplicare il codice da sendNewOrderEmail ().


Genio. Puro, puro, geniale.
Filwinkle,

1
l'adulazione ti porterà ovunque ;-)
Kristof a Fooman il

3

L'essenza di questo tipo di cambiamento (radicale) è la seguente:

  • Riscrivi sendNewOrderEmail per agire come una coda e inviare / non inviare in modo condizionale in base alla modalità della coda (vedi alcuni pseudo-codici di seguito)
  • In base alla modalità coda del modello di ordine cliente, inviamo l'e-mail dalla coda caricando l'ordine dal processo cron e inviando manualmente l'e-mail.

Alcuni codici di esempio per il modello di ordine di vendita riscrivono:

Il seguente codice dipenderà dalla presenza di una tabella chiamata yourmodule_sales_email_queuee farò riferimento ad alcune colonne con getter magici. Non ho intenzione di fornire uno schema in quanto questo non è un codice completamente funzionale ed è una sorta di prova del concetto; non un modulo funzionante.

Aggiungi questo al tuo etc / config.xml del tuo modulo :

<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>

app / code / local / YourCompany / nomemodulo / Modello / 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');
    }


}

Da lì è necessario definire un modello di risorsa, una raccolta e un cronista.

La definizione cron in etc / config.xml sarebbe simile a questa:

<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>

Che invoca un metodo dalla classe YourCompany_YourModule_Model_Observer. Caricheremo le ultime 24 ore di e-mail dalla coda, cariceremo l'ordine associato e imposteremo il flag per consentirgli di inviare e-mail. Quindi invocheremo il metodo di invio email:

<?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();
        }

    }
}

Disclaimer:

Si noti che il codice sopra non è testato e non funzionerà da solo. Si aspetta che esistano molte funzionalità (come le raccolte). L'ho anche scritto a testa alta e potrebbero esserci delle incoerenze , dal momento che ho cambiato idea su come gestirlo una o due volte da quando ho iniziato questa risposta.

Questo ha lo scopo di farti iniziare e pensare a come lo faresti. Sono disposto a rispondere a qualsiasi domanda tu possa avere. Sono anche disposto a contribuire su Github a una versione open source di questo tipo di modulo.

Buona fortuna!


Questo è troppo ingegnoso rispetto alla soluzione di @ fooman e mi piace il suo meglio del mio :)
philwinkle
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.