Создание счета-фактуры и получение отгрузки - PullRequest
5 голосов
/ 17 июня 2011

У нас есть несколько 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);

}

(Код для фактического захвата несколько наивный, но потерпите меня.)

Что странно, так это то, что этот код работает просто отлично - отгрузка создана, счет создан и помечен как «Оплаченный». Однако сам ордер остается в подвешенном состоянии и сохраняет статус «Ожидание».

Если посмотреть дальше, позиции в самом заказе имеют правильные количества как для Заказанного, так и для Отправленного, но нет списка количества Выставленного счета. Я думаю, что это является причиной зависания статуса. Это похоже на то, что qty_invoiced в таблице sales_order_item как-то возвращается.

Опять же, в Счете указаны правильные позиции, поэтому я совершенно запутался.

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 02 июля 2013

После многих испытаний с использованием API я обнаружил, что сначала я создал счет, а затем поставку, Magento Enterprise 1.13.01. правильно установит статус заказа на Завершено. Попытка сначала выполнить отгрузку, а затем счет-фактуру, приведет к тому, что статус «Ожидающий заказ» останется, даже если все товары были выставлены и выставлены счета.

В приведенном ниже коде мостовой системы используется информация о заказах, размещенных в Magento, перенаправленных в мостовую систему через Observer на checkout_submit_all_after, отправленных в NetSuite через веб-сервисы и выполненных в NetSuite. Мостовая система получает заказы на продажу от 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;
            }
        }
2 голосов
/ 18 июня 2011

Это действительно очень интересный @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);
...