Magento: Neue Bestell-E-Mail nur mit Cronjobs senden

11

Wie kann ich die neue Bestellung senden? E-Mails mit:

$order->sendNewOrderEmail();

Nur von einem Cronjob, der in Mein benutzerdefiniertes Modul verwendet wird.

Danke für die Hilfe.

Bizboss
quelle

Antworten:

8

Ich würde deaktivieren System > Configuration > Sales Email > Order > Enabled

Dies stellt sicher, dass es während der normalen Ausführung nicht gesendet wird

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

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

Dann fügen Sie in Ihrem benutzerdefinierten Modul so etwas wie

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

Die Hauptidee besteht darin, den deaktivierten Konfigurationswert zur Laufzeit zu überschreiben. Der Code wird nicht getestet, sollte Ihnen aber einen Ausgangspunkt geben. Weitere empfohlene Lektüre aus Alans Blog: http://alanstorm.com/magento_loading_config_variables http://alanstorm.com/magento_config_a_critique_and_caching

Ein Problem, auf das Sie möglicherweise stoßen, ist ein zwischengespeicherter Wert für die oben genannten.

Die zweite Möglichkeit wäre, den Code von sendNewOrderEmail () zu duplizieren.

Kristof bei Fooman
quelle
Genius. Rein, unverfälscht, genial.
Philwinkle
1
Schmeichelei bringt dich überall hin ;-)
Kristof bei Fooman
3

Das Wesentliche für diese Art von (radikalen) Veränderungen ist das Folgende:

  • Schreiben Sie sendNewOrderEmail neu, um als Warteschlange zu fungieren und basierend auf dem Warteschlangenmodus bedingt zu senden / nicht zu senden (siehe Pseudocode unten).
  • Basierend auf dem Warteschlangenmodus des Kundenauftragsmodells senden wir die E-Mail aus der Warteschlange, indem wir die Bestellung aus dem Cron-Job laden und die E-Mail manuell senden.

Einige Beispielcodes für das Umschreiben des Kundenauftragsmodells:

Der folgende Code hängt vom Vorhandensein einer aufgerufenen Tabelle ab, yourmodule_sales_email_queueund ich verweise auf einige Spalten mit Magic Getter. Ich werde kein Schema bereitstellen, da dies kein voll funktionsfähiger Code ist und eine Art Proof of Concept darstellt. kein Arbeitsmodul.

Fügen Sie dies der Datei etc / config.xml Ihres Moduls hinzu :

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


}

Von dort aus müssen Sie ein Ressourcenmodell, eine Sammlung und einen Cron-Worker definieren.

Die Cron-Definition in etc / config.xml würde ungefähr so aussehen:

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

Was eine Methode aus der Klasse aufruft YourCompany_YourModule_Model_Observer. Wir laden die letzten 24 Stunden von E-Mails aus der Warteschlange, laden die zugehörige Bestellung hoch und setzen das Flag, damit E-Mails gesendet werden können. Dann rufen wir die E-Mail-Versandmethode auf:

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

    }
}

Haftungsausschluss:

Beachten Sie, dass der obige Code nicht getestet wird und nicht alleine funktioniert . Es wird erwartet, dass viele Funktionen (wie Sammlungen) vorhanden sind. Ich habe es auch top-of-mind geschrieben und es kann zu Inkonsistenzen kommen , da ich meine Meinung geändert habe, wie ich ein- oder zweimal damit umgehen würde, seit ich mit dieser Antwort angefangen habe.

Dies soll Ihnen den Einstieg erleichtern und darüber nachdenken, wie Sie dies erreichen würden. Ich bin bereit, Ihre Fragen zu beantworten. Ich bin auch bereit, auf Github zu einer Open-Source-Version dieses Modultyps beizutragen.

Viel Glück!

philwinkle
quelle
Dies ist im Vergleich zu @ foomans Lösung überarbeitet und ich mag seine besser als meine :)
Philwinkle