【问题标题】:How to change the order state programmatically inside a cron job?如何在 cron 作业中以编程方式更改订单状态?
【发布时间】:2012-06-18 09:17:14
【问题描述】:

我正在使用 cron 作业将所有“待处理”网上银行订单更改为“待付款”
(这是为了解决我的问题:Why is state not transitioning to "payment_pending" for orders cancelled at gateway?

这是我的代码- [已编辑]

const MINUTES_DELAY = 15; //Orders younger than this are not changed

public function run() {

  //      date_default_timezone_set('Asia/Kolkata');
  $old_time = time() - (self::MINUTES_DELAY*60);
  $out = date('d.m.y h:i:s A', $old_time)."\n";
  $out .= date('d.m.y h:i:s A')."\n";
  file_put_contents('/home/vinayak/cron.txt', '1'.$out, FILE_APPEND); //Out1

  $orders = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status', 'pending')
    ->addFieldToFilter('cod_fee', array('null' => true))
    ->addAttributeToSelect('customer_email')
    ->addAttributeToSelect('created_at')
    ;
  foreach ($orders as $order) {
    if (strtotime($order->getCreatedAt()) < $old_time){
      $order->setState('pending_payment', true)->save();
      $out .= $order->getCustomerEmail()." @ ".$order->getCreatedAt()."\n";
    }
  }
  file_put_contents('/home/vinayak/cron.txt', '2'.$out, FILE_APPEND); //Out2

  return true;
}

我已检查 cron 是否正常工作。但是状态/状态没有改变。我现在没有出错了。

[EDITED] 现在的问题 - 我在代码中将输出标记为“out1”,而不是“out2”

更改代码后,我发现,只要if 条件为真,就会出现问题(如上)。这指出了$order-&gt;setState('pending_payment', true)-&gt;save(); 行的问题(我已经注释掉了if 中的另一行,问题仍然存在,但是如果我注释掉这一行,out2 就会被打印出来)。似乎执行被卡在了这一行(无限循环?还是一些内部问题?)

$order-&gt;setState('pending_payment', true)-&gt;save(); 有什么问题?还有其他方法可以完成上述事情吗?

我是否也可以按订单“创建时间”进行过滤,这样我就不会更改几秒钟前创建的订单的状态。[已解决]

谢谢!

【问题讨论】:

  • 如果你在没有 cron 的情况下运行脚本,它会改变状态吗?如果不能,你能缩小导致问题的那条线吗?我认为问题可能出在 getModel 或 setState 上。
  • @Rachael:编辑了问题。问题在于setState
  • 你在哪里添加这段代码?
  • @LouisW:我为 Cron 作业创建了一个模块。 IIRC 我在 /app/code/local/SOMENAME/Cron/Model/Observer.php 中添加了这段代码。但我不再从事这方面的工作,所以我记不太清了。

标签: php magento magento-1.6


【解决方案1】:

试着把$order->setState('pending_payment'); $order->setStatus('pending_payment'); $order->save(); 我认为您没有更改可能造成问题的订单状态。

【讨论】:

  • setState() 也应该设置状态。所以不,这是行不通的。无论如何,我已经解决了这个问题。请参阅我的解决方案。谢谢!
【解决方案2】:

终于解决了我的问题。现在这项工作完全按照预期工作了!

这是工作程序-

  const MINUTES_DELAY = 15; //Orders younger than this are not changed
  const OUT_FILE = '/home/vinayak/cron.txt';

  public function run() {
    $old_time = time() - (self::MINUTES_DELAY*60);

    $out = "-------------------------------------------\n";
    $out .= date('d.m.y h:i:s A')."\n";

    $orders = Mage::getModel('sales/order')->getCollection()
      ->addFieldToFilter('status', 'pending')
      ->addFieldToFilter('cod_fee', array('null' => true))
      ;

    foreach ($orders as $order) {
      if (strtotime($order->getCreatedAt()) < $old_time)  {
        try{
          $id = $order->getIncrementId();

          Mage::getModel('sales/order')
            ->loadByIncrementId($id)
            ->setState('pending_payment', true)
            ->save();

          $out .= $id."\n";
        } catch (Exception $e)  {
          $out .= "Caught exception : ".$e->getMessage()."\n";
        }
      }
    }
    file_put_contents(self::OUT_FILE, $out, FILE_APPEND);
    return true;
  }

希望这对某人有所帮助。

【讨论】:

    【解决方案3】:

    我还没有掌握 Zend 查询,所以在直接与数据库交互时,我总是编写正确的 MySQL 查询。请记住,在更新版本的 Magento 之前,订单状态是不灵活的(除非您购买扩展程序)。

    mysql> select status from sales_flat_order group by status;
    +-----------------+
    | status          |
    +-----------------+
    | canceled        | 
    | closed          | 
    | complete        | 
    | pending         | 
    | pending_payment | 
    | processing      | 
    +-----------------+
    6 rows in set (0.00 sec)
    mysql> select state from sales_flat_order group by state;
    
    +-----------------+
    | state           |
    +-----------------+
    | canceled        | 
    | closed          | 
    | complete        | 
    | new             | 
    | pending_payment | 
    | processing      | 
    +-----------------+
    6 rows in set (1.03 sec)
    

    为了帮助自己理解表结构,我写了一个php script to make a CSV of all the tables with fields。因此,您可以使用SELECT entity_id, state, status, created_at, increment_id FROM sales_flat_order WHERE status="pending" 获得第一位。我查看并没有在我的 1.4.2 安装中存在的任何字段名中看到“cod_fee”。注意上述查询的输出格式:

    SELECT entity_id, state, status, created_at, increment_id FROM sales_flat_order WHERE status="pending";
    +-----------+------------+---------+---------------------+--------------+
    | entity_id | state      | status  | created_at          | increment_id |
    +-----------+------------+---------+---------------------+--------------+
    |      2493 | new        | pending | 2011-09-14 18:09:47 | 200025332    | 
    |      2683 | complete   | pending | 2011-10-04 17:19:07 | 200025523    | 
    |      2686 | new        | pending | 2011-10-04 20:43:52 | 200025526    | 
    |      3022 | processing | pending | 2011-11-15 01:11:34 | 200025849    | 
    |      3428 | complete   | pending | 2012-01-12 17:56:57 | 200026236    | 
    |      4493 | processing | pending | 2012-04-11 16:16:55 | 200027230    | 
    |      5071 | new        | pending | 2012-05-21 18:05:43 | 200027759    | 
    |      5091 | new        | pending | 2012-05-22 17:48:11 | 200027779    | 
       ...
    |      5399 | new        | pending | 2012-06-14 17:46:46 | 200028069    | 
    |      5443 | new        | pending | 2012-06-18 18:50:55 | 200028111    | 
    |      5486 | new        | pending | 2012-06-20 21:18:24 | 200028152    | 
    |      5491 | new        | pending | 2012-06-20 23:54:53 | 200028157    | 
    +-----------+------------+---------+---------------------+--------------+
    23 rows in set (0.79 sec)
    

    【讨论】:

      猜你喜欢
      • 2016-10-17
      • 2014-06-26
      • 1970-01-01
      • 2019-09-28
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多