Magento: wysyłaj e-mail z nowym zamówieniem tylko z cronjobs

11

Jak mogę wysłać wiadomość e-mail z nowym zamówieniem, używając:

$order->sendNewOrderEmail();

tylko z cronjobu używanego w Moim niestandardowym module.

Dzięki za pomoc.

Bizboss
źródło

Odpowiedzi:

8

Chciałbym wyłączyć System > Configuration > Sales Email > Order > Enabled

zapewnia to, że podczas normalnego wykonania nie zostanie wysłane

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

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

Następnie w niestandardowym module dołącz coś podobnego

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

Główną ideą jest zastąpienie wyłączonej wartości konfiguracji w czasie wykonywania. Kod nie jest testowany, ale powinien dać ci punkt wyjścia. Dalsze zalecane czytanie z bloga Alana: http://alanstorm.com/magento_loading_config_variables http://alanstorm.com/magento_config_a_critique_and_caching

Jednym z problemów, które możesz napotkać, jest buforowana wartość powyższego.

Drugą opcją byłoby skopiowanie kodu z sendNewOrderEmail ().

Kristof w Fooman
źródło
Geniusz. Czysty, nieskażony, geniusz.
philwinkle
1
pochlebstwa
zabiorą
3

Istota dokonania tego rodzaju (radykalnej) zmiany jest następująca:

  • Przepisz sendNewOrderEmail, aby działał jako kolejka i warunkowo wysyłał / nie wysyłał w oparciu o tryb kolejki (patrz niektóre pseudo-kody poniżej)
  • W oparciu o tryb kolejki modelu zamówienia sprzedaży wysyłamy wiadomość e-mail z kolejki, ładując zamówienie z zadania cron i ręcznie wysyłając wiadomość e-mail.

Przykładowy kod do przepisania modelu zamówienia sprzedaży:

Poniższy kod będzie zależał od obecności tabeli o nazwie yourmodule_sales_email_queuei będę odwoływał się do niektórych kolumn za pomocą magicznych programów pobierających. Nie zamierzam przedstawiać schematu, ponieważ nie jest to w pełni funkcjonalny kod i jest swego rodzaju dowodem koncepcji; nie działający moduł.

Dodaj to do pliku etc / config.xml modułu :

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


}

Następnie musisz zdefiniować model zasobów, kolekcję i proces roboczy cron.

Definicja crona w pliku etc / config.xml wyglądałaby mniej więcej tak:

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

Który wywołuje metodę z klasy YourCompany_YourModule_Model_Observer. Załadujemy ostatnie 24 godziny wiadomości e-mail z kolejki, załadujemy powiązane zamówienie i ustawimy flagę, aby umożliwić wysyłanie wiadomości e-mail. Następnie wywołamy metodę wysyłania wiadomości e-mail:

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

    }
}

Zrzeczenie się:

Pamiętaj, że powyższy kod nie jest testowany i nie będzie działał samodzielnie. Oczekuje, że istnieje wiele funkcji (takich jak kolekcje). Napisałem to również w myślach i mogą wystąpić niekonsekwencje , ponieważ zmieniłem zdanie na temat tego, jak poradzę sobie z tym raz lub dwa razy od momentu rozpoczęcia tej odpowiedzi.

Ma to na celu pomóc Ci zacząć i zastanowić się, jak to osiągnąć. Jestem gotów odpowiedzieć na wszelkie pytania. Jestem również gotów przyczynić się na Github do wersji tego typu modułu typu open source.

Powodzenia!

philwinkle
źródło
Jest to nadinżynieria w porównaniu do rozwiązania @ fooman i podoba mi się jego lepsze niż moje :)
philwinkle 24.10.2013