我在Magento管理员中创建了一个链接来创建单个产品的发票,但在调用函数$order->prepareInvoice($qtys)
时,它会将所有产品添加到发票中,即使我只传递了一个项目。
我正在使用以下代码。
$order = Mage::getModel('sales/order')->load($this->getRequest()->getParam('order_id'));
$count = $order->getTotalItemCount();
$qtys = Array
(
[370] => 1
);
$invoice = $order->prepareInvoice($qtys);
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$amount = $invoice->getGrandTotal();
$invoice->register()->pay();
$invoice->getOrder()->setIsInProcess(true);
$history = $invoice->getOrder()->addStatusHistoryComment('Partial amount of $'. $amount .' captured automatically.', false);
$history->setIsCustomerNotified(true);
$order->save();
Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder())
->save();
$invoice->save();
有任何建议吗?
答案 0 :(得分:3)
在Mage_Sales_Model_Service_Order :: prepareInvoice中找到的逻辑,您最终调用以准备发票的方法,揭示了这里发挥作用的方法。使用以下循环,并且在传入qtys数组时,内部else-if块是设置数量的位置:
foreach ($this->_order->getAllItems() as $orderItem) {
if (!$this->_canInvoiceItem($orderItem, array())) {
continue;
}
$item = $this->_convertor->itemToInvoiceItem($orderItem);
if ($orderItem->isDummy()) {
$qty = $orderItem->getQtyOrdered() ? $orderItem->getQtyOrdered() : 1;
} else if (!empty($qtys)) {
if (isset($qtys[$orderItem->getId()])) {
$qty = (float) $qtys[$orderItem->getId()];
}
} else {
$qty = $orderItem->getQtyToInvoice();
}
$totalQty += $qty;
$item->setQty($qty);
$invoice->addItem($item);
}
$qtys
变量是您传入prepareInvoice调用的数组。在您的情况下,您只传递要添加到发票中的项目的索引。根据文档(以及上面的循环),这个应该工作,除了一个小问题:上面的循环没有将循环顶部的$ qty的值重置为0.这不是当从管理员通过预先存在的表单创建发票初始化时核心代码调用时出现问题,因为正在提交的表单将始终包含订单中每个项目的值,并且在案例中只有1个项目被开票,所有其他项目将保持0个数值,因此无法重置$ qty的值。
要解决您的问题,请尝试设置$qtys
变量(我假设370和371是两个订单商品实体ID):
$qtys = array(
370 => 1,
371 => 0,
);
我建议的另一种方法是简单地让您的“创建发票”链接在表单中设置适当的值,以便为单个项目开具发票,然后直接提交表单。通过这种方式,您将依靠已知的工作核心控制器来完成繁重的工作。当然,只有在除了开具单个项目开票之外没有做任何相当自定义的事情时,这才会起作用。 :)