2

我在 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();

在此处输入图像描述

有什么建议吗?

4

1 回答 1

3

在 Mage_Sales_Model_Service_Order::prepareInvoice 中找到的逻辑,您最终调用以准备发票的方法,揭示了这里的作用。采用以下循环,内部 else-if 块是传入 qtys 数组时设置 qty 的位置:

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,
);

我可能建议的另一种选择是简单地让您的“创建发票”链接在表单中设置适当的值来为单个项目开具发票,然后直接提交表单。这样,您将依靠已知的工作核心控制器来完成繁重的工作。当然,这只有在您除了为单个项目开票之外没有做任何相当定制的事情时才有效。:)

于 2013-01-04T14:48:21.603 回答