Получение частичной суммы после размещения заказа

Я создал ссылку в администраторе 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();

введите здесь описание изображения

Любое предложение ?


person MagentoDiary    schedule 27.12.2012    source источник
comment
Нет комментариев и предложений?   -  person MagentoDiary    schedule 28.12.2012
comment
Я делал частичные счета несколько раз, и когда я сравниваю старый код, он очень похож. Я не звоню pay(), потому что register() делает это, когда это уместно. Также нет необходимости вызывать $invoice->save(), потому что он уже сохранен транзакцией, но я сомневаюсь, что это ваша проблема. Возможно, тип оплаты запрещает частичный захват — это функция, которая обычно тоже имеет значение false.   -  person clockworkgeek    schedule 30.12.2012
comment
Спасибо, что предложили меня. На самом деле я могу получить частичную сумму после авторизации при размещении заказа в том же порядке (тот же код выше), но при попытке сделать то же самое от администратора он создает счет для всех оставшихся продуктов.   -  person MagentoDiary    schedule 30.12.2012


Ответы (1)


Логика, найденная в Mage_Sales_Model_Service_Order::prepareInvoice, методе, который вы в конечном итоге вызываете для подготовки счета, показывает, что здесь происходит. Используется следующий цикл, и во внутреннем блоке 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, что позволит обойти проблему сброса значения $ qty.

Чтобы решить вашу проблему, попробуйте установить переменную $qtys следующим образом (я предполагаю, что 370 и 371 - это два идентификатора объекта заказа):

$qtys = array(
    370 => 1,
    371 => 0,
);

Альтернативой, которую я мог бы предложить, было бы просто установить ссылку «Создать счет» в форме, чтобы выставить счет на отдельный элемент, а затем отправить форму напрямую. Таким образом, вы будете полагаться на заведомо работающий основной контроллер для тяжелой работы. Это, конечно, будет работать только в том случае, если вы не делаете ничего достаточно индивидуального, кроме выставления счета за один элемент. :)

person davidalger    schedule 04.01.2013