Magento: envie um novo email de pedido apenas com cronjobs

11

Como posso enviar e-mails do novo pedido usando:

$order->sendNewOrderEmail();

somente de um cronjob usado em Meu módulo personalizado.

Obrigado pela ajuda.

Bizboss
fonte

Respostas:

8

Eu desabilitaria System > Configuration > Sales Email > Order > Enabled

isso garante que durante a execução normal não seja enviado

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

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

Em seguida, no seu módulo personalizado, inclua 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();
    }

A idéia principal é substituir o valor da configuração desabilitada no tempo de execução. O código não foi testado, mas deve fornecer um ponto de partida. Leitura adicional recomendada no blog de Alan: http://alanstorm.com/magento_loading_config_variables http://alanstorm.com/magento_config_a_critique_and_caching

Um problema que você pode encontrar é um valor em cache para o acima.

A segunda opção seria duplicar o código de sendNewOrderEmail ().

Kristof na Fooman
fonte
Gênio. Gênio puro, inalterado.
philwinkle
1
bajulação vai chegar em todos os lugares ;-)
Kristof em Fooman
3

A essência de fazer esse tipo de mudança (radical) é a seguinte:

  • Reescreva sendNewOrderEmail para atuar como uma fila e enviar / não enviar condicionalmente com base no modo de fila (veja alguns pseudo-códigos abaixo)
  • Com base no modo de fila do modelo de pedido de vendas, enviamos o email da fila carregando o pedido no trabalho cron e enviando manualmente o email.

Algum código de amostra para o modelo de pedido de venda reescrito:

O código a seguir dependerá da presença de uma tabela chamada yourmodule_sales_email_queuee eu estarei referenciando algumas colunas com getters mágicos. Não vou fornecer um esquema, pois esse código não é totalmente funcional e é uma espécie de prova de conceito; não é um módulo de trabalho.

Adicione isso ao arquivo etc / config.xml do seu 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>

app / code / 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 daí, você precisa definir um modelo de recursos, uma coleção e um trabalhador cron.

A definição do cron no etc / config.xml seria algo como isto:

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

O que invoca um método da classe YourCompany_YourModule_Model_Observer. Carregaremos as últimas 24 horas de emails da fila, carregaremos o pedido associado e definiremos o sinalizador para permitir o envio de emails. Em seguida, chamaremos o método de envio de 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();
        }

    }
}

Aviso Legal:

Observe que o código acima não foi testado e não funcionará por si próprio. Ele espera que muitas funcionalidades (como coleções) existam. Eu também escrevi sobre isso e pode haver inconsistências , pois mudei de idéia sobre como lidaria com isso uma ou duas vezes desde o início desta resposta.

Isso significa que você deve começar e pensar em como conseguir isso. Estou disposto a responder a quaisquer perguntas que você possa ter. Também estou disposto a contribuir no Github para uma versão de código aberto desse tipo de módulo.

Boa sorte!

philwinkle
fonte
Esta é overengineered comparação com @ solução de fooman e eu como seu melhor que a minha :)
philwinkle