Creating Invoice & Capturing on Shipment

天大地大妈咪最大 提交于 2019-12-12 08:54:31

问题


We've got some API integrations that will periodically create shipments for orders.

What I'd like to do is create an observer to also create an appropriate invoice & capture payment when this shipment is created. I have this tied to 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);

}

(The code for the actual capture is somewhat naive, but bear with me.)

What's strange is that this code works just fine -- the shipment is created, the invoice is created and marked as 'Paid.' However, the order itself stays in limbo and retains a status 'Pending.'

Looking into it further, the items on the order itself have the correct quantities for both Ordered and Shipped, but there's no listing of the quantity Invoiced. I think this is what's causing the status hangup. It's as though the qty_invoiced on the sales_order_item table is getting reverted somehow.

Again, the Invoice shows the right items, so I'm quite confused here.

Any ideas?


回答1:


This is indeed a very interesting one @bahoo.

maybe try:

$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:


After lots of testing using the API, I found if I created the invoice first, then the shipment, Magento Enterprise 1.13.01. would correctly set the order status to Complete. Trying to make the shipment first, then the invoice, would result in the Pending Order status remaining even if all items had been invoiced and shipped.

The bridging system code below uses information about orders placed in Magento, routed to the bridging system via an Observer on checkout_submit_all_after, sent to NetSuite via web services, and fulfilled in NetSuite. The bridging system gets sales order fulfillments from NetSuite via web service, and saves items shipped, package, and tracking information, to use in the code below. Code shows creating invoice, then shipment and tracking.

Note that while testing, I just saw Magento incorrectly create an invoice for all three items in an order, even though it was passed an array that just contained two of the items. Magento did correctly create a shipment record for just the two items. Puzzling that the invoice API and the shipment API when passed the same array of items and quantities have such different behavior. Anyone else seen this?

        $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;
            }
        }


来源:https://stackoverflow.com/questions/6380536/creating-invoice-capturing-on-shipment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!