在发货时创建发票和捕获
Posted
技术标签:
【中文标题】在发货时创建发票和捕获【英文标题】:Creating Invoice & Capturing on Shipment 【发布时间】:2011-09-16 20:32:21 【问题描述】:我们有一些 API 集成,可以定期为订单创建发货。
我想做的是创建一个观察者,以便在创建此货件时创建适当的发票并获取付款。我有这个绑定到sales_order_shipment_save_after
:
public function autoInvoice($observer)
$shipment = $observer->getEvent()->getShipment();
$order = $shipment->getOrder();
$items = $shipment->getItemsCollection();
$qty = array();
foreach($items as $item)
$qty[$item['order_item_id']] = $item['qty'];
$invoice = Mage::getModel('sales/order_invoice_api');
$invoiceId = $invoice->create($order->getIncrementId(), $qty);
$invoice->capture($invoiceId);
(实际捕获的代码有点幼稚,但请耐心等待。)
奇怪的是,这段代码运行良好——货件已创建,发票已创建并标记为“已付款”。但是,订单本身仍处于不确定状态并保持“待处理”状态。
进一步查看,订单本身的商品数量对于已订购和已发货都是正确的,但没有发票数量列表。我认为这是导致状态挂断的原因。好像 sales_order_item 表上的 qty_invoiced
以某种方式被还原了。
再一次,发票显示了正确的项目,所以我在这里很困惑。
有什么想法吗?
【问题讨论】:
我放弃了!我已经看了两天这个问题,并决定采取不同的方法。我的代码看起来不错;我认为可能是操作顺序导致了这个问题。因此,我没有使用观察者,而是重写了货件创建 API 以包含一些用于自动开票的代码。 munyah 下面的代码起到了作用。如果有人可以通过观察者找到一种更清洁的方法来实现这一点,我很想听听。谢谢大家! 【参考方案1】:这确实是一个非常有趣的@bahoo。
也许可以试试:
$shipment = $observer->getEvent()->getShipment();
$order = $shipment->getOrder();
$qty = array();
$invoice = Mage::getModel('sales/order_invoice_api');
$invoiceId = $invoice->create($order->getIncrementId(), $qty);
$invoice->capture($invoiceId);
【讨论】:
我不得不以不同的方式使用它,但这最终是让我到达我想去的地方的代码。谢谢!【参考方案2】:在使用 API 进行大量测试后,我发现如果我先创建发票,然后是发货,Magento Enterprise 1.13.01。将正确地将订单状态设置为完成。尝试先发货,然后开票,即使所有商品都已开票并发货,也会导致待处理订单状态保持不变。
下面的桥接系统代码使用有关在 Magento 中下达的订单的信息,通过 checkout_submit_all_after 上的 Observer 路由到桥接系统,通过 Web 服务发送到 NetSuite,并在 NetSuite 中完成。桥接系统通过 Web 服务从 NetSuite 获取销售订单履行情况,并保存发货、包裹和跟踪信息,以便在下面的代码中使用。 代码显示创建发票,然后发货和跟踪。
请注意,在测试时,我刚刚看到 Magento 错误地为订单中的所有三个项目创建了发票,即使它传递了一个仅包含两个项目的数组。 Magento 确实为这两个项目正确创建了发货记录。令人费解的是,发票 API 和发货 API 在传递相同的项目和数量数组时具有如此不同的行为。其他人看到了吗?
$proxy = new SoapClient($proxyUrl); /* V2 version */
$sessionId = $proxy->login($apiUser, $apiKey);
try
/* try to create invoice in Magento */
$invoiceIncrementId = $proxy->salesOrderInvoiceCreate($sessionId, $orderIncrementId, $shipItemsQty, 'invoice created', false, false);
catch( SoapFault $fault )
$error = $fault->getMessage(); /* will return 'Cannot do invoice for order' if invoice already exists for these items */
if (!stristr($error,'Cannot do invoice') and !empty($error))
/* some other invoicing problem, log what returned, on to next order */
$ins = "insert into order_error_log values(NULL, ".$orderId.", '".date("Y-m-d H:i:s")."', '".$program."', '".$error."')";
$result = $mysqli->query($ins);
$upd = "update orders set orderStatusId = ".ERROR_ADDING_MAGENTO_INVOICE.",
dateStatusUpdated = '".date("Y-m-d H:i:s")."'
where id = ".$orderId;
$result = $mysqli->query($upd);
continue;
if ((stristr($error,'Cannot do invoice') or empty($error)) and $complete)
/* if all fulfilled, may change status */
$upd = "update orders set orderStatusId = ".STORE_INVOICE_CREATED.",
dateStatusUpdated = '".date("Y-m-d H:i:s")."'
where id = ".$orderId;
$result = $mysqli->query($upd);
/* send Magento salesOrderShipmentCreate and get returned shipment Id, re-using proxy login and session */
$comment = 'Fulfillment(s) shipped on: '.$netsuiteShipDate;
try
/* returns value such as string(9) "100002515" */
$shipmentIncrementId = $proxy->salesOrderShipmentCreate($sessionId, $orderIncrementId, $shipItemsQty, $comment);
catch( SoapFault $fault )
$error = $fault->getMessage().': SOAP error received when trying to add shipment to Magento for morocco order id '.$orderId.
' store order id '.$orderIncrementId.' with items qty array of: '.var_dump($itemsQty);
$ins = "insert into order_error_log values(NULL, ".$orderId.", '".date("Y-m-d H:i:s")."', '".$program."', '".$error."')";
$result = $mysqli->query($ins);
$upd = "update orders set orderStatusId = ".MAGENTO_SOAP_EXCEPTION.",
dateStatusUpdated = '".date("Y-m-d H:i:s")."'
where id = ".$orderId;
$result = $mysqli->query($upd);
continue; /* on to next order */
/* Using that shipmentId, send info re each package shipped for these fulfillments to Magento via salesOrderShipmentAddTrack. */
foreach ($packageIds as $packageId => $package)
try
$trackingNumberId = $proxy->salesOrderShipmentAddTrack($sessionId, $shipmentIncrementId,
$package['carrier'], 'tracking number', $package['trackNumber']);
catch( SoapFault $fault )
$error = $fault->getMessage().': SOAP error received when trying to add tracking number '.$package['trackNumber'].' to
Magento for morocco order id '.$orderId.' store order id '.$orderIncrementId;;
$ins = "insert into order_error_log values(NULL, ".$orderId.", '".date("Y-m-d H:i:s")."', '".$program."', '".$error."')";
$result = $mysqli->query($ins);
$upd = "update orders set orderStatusId = ".MAGENTO_SOAP_EXCEPTION.",
dateStatusUpdated = '".date("Y-m-d H:i:s")."'
where id = ".$orderId;
$result = $mysqli->query($upd);
continue;
【讨论】:
以上是关于在发货时创建发票和捕获的主要内容,如果未能解决你的问题,请参考以下文章
找BUG第三弹——出具发票日期和时间创建日期不一致问题解决方案