Magento: envoyer un e-mail de nouvelle commande uniquement avec des tâches cron

11

Comment puis-je envoyer les nouveaux e-mails de commande en utilisant:

$order->sendNewOrderEmail();

uniquement à partir d'un cronjob utilisé dans Mon module personnalisé.

Merci pour l'aide.

Bizboss
la source

Réponses:

8

Je désactiverais System > Configuration > Sales Email > Order > Enabled

cela garantit que lors de l'exécution normale, il n'est pas envoyé

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

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

Ensuite, dans votre module personnalisé, incluez quelque chose comme

    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'idée principale étant de remplacer la valeur de configuration désactivée lors de l'exécution. Le code n'est pas testé mais devrait vous donner un point de départ. Autres lectures recommandées sur le blog d'Alan: http://alanstorm.com/magento_loading_config_variables http://alanstorm.com/magento_config_a_critique_and_caching

Un problème que vous pourriez rencontrer est une valeur mise en cache pour ce qui précède.

La deuxième option serait de dupliquer le code de sendNewOrderEmail ().

Kristof chez Fooman
la source
Génie. Génie pur et pur.
philwinkle
1
la flatterie vous
emmènera
3

L'essence de ce type de changement (radical) est la suivante:

  • Réécrivez sendNewOrderEmail pour agir comme une file d'attente et envoyer / ne pas envoyer conditionnellement en fonction du mode de file d'attente (voir un pseudo-code ci-dessous)
  • En fonction du mode de file d'attente du modèle de commande client, nous envoyons l'e-mail à partir de la file d'attente en chargeant la commande à partir du travail cron et en envoyant manuellement l'e-mail.

Quelques exemples de code pour la réécriture du modèle de commande client:

Le code suivant dépendra de la présence d'une table appelée yourmodule_sales_email_queueet je ferai référence à certaines colonnes avec des getters magiques. Je ne vais pas fournir de schéma car il ne s'agit pas d'un code pleinement fonctionnel et d'une sorte de preuve de concept; pas un module de travail.

Ajoutez ceci à etc / config.xml de votre module :

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


}

De là, vous devez définir un modèle de ressource, une collection et un travailleur cron.

La définition de cron dans etc / config.xml ressemblerait à ceci:

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

Qui invoque une méthode de la classe YourCompany_YourModule_Model_Observer. Nous chargerons les dernières 24 heures d'e-mails de la file d'attente, chargerons la commande associée et définirons le drapeau pour lui permettre d'envoyer des e-mails. Ensuite, nous invoquerons la méthode d'envoi d'e-mails:

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

    }
}

Avertissement:

Notez que le code ci-dessus n'est pas testé et ne fonctionnera pas seul. Il s'attend à ce que beaucoup de fonctionnalités (comme les collections) existent. Je l'ai également écrit en tête et il peut y avoir des incohérences , car j'ai changé d'avis sur la façon dont je gérerais cela une ou deux fois depuis le début de cette réponse.

Ceci est destiné à vous aider à démarrer et à réfléchir à la façon dont vous pourriez y parvenir. Je suis prêt à répondre à toutes vos questions. Je suis également prêt à contribuer sur Github à une version open source de ce type de module.

Bonne chance!

philwinkle
la source
C'est trop ingénieux par rapport à la solution de @ fooman et j'aime mieux la sienne que la mienne :)
philwinkle