0

I am using the open source library xmlrpc.net and am trying to make a call to a service that has an input parameter that is an associative array.

Documentation on call (I am trying to integrate with a phpsite called Magento and by the errors it is throwing I know it is using the Zend xmlrpc library.)

Method Name: sales_order_shipment.create Create new shipment for order

Return: string - shipment increment id

Arguments:

string orderIncrementId - order increment id array itemsQty - items qty to ship as associative array (order_item_id ⇒ qty) string comment - shipment comment (optional) boolean email - send e-mail flag (optional) boolean includeComment - include comment in e-mail flag (optional)

So In .Net I have been able to get the following to work

proxy.Create(sessionId, "sales_order_shipment.create", new object[] { 100000010, new object[] { }, "Shipment Created", true, true });

but I can't seem to figure out what .Net type I should pass in for itemsQty. new object[]{} works but I need to be able to pass in what items shipped not just create a shipment with 0 items shipping in it. What .Net type can be used that will map to an Associated Array using xmlrpc.net

mttjohnson
  • 462
  • 3
  • 13
runxc1 Bret Ferrier
  • 8,096
  • 14
  • 61
  • 100

2 Answers2

2

Without seeing the XML-RPC request that should be generated, the spec is not clear to me but how about using XmlRpcStruct like this:

XmlRpcStruct items = new XmlRpcStruct();
items["orderid1"] = 1;
items["orderid2"] = 2;

(assuming order id is a string)

Charles Cook
  • 1,989
  • 1
  • 16
  • 7
1

I've been playing with a related method sales_order_invoice.create and ran into the same problem you did. I just found that for whatever reason I had to insert an extra element into the array of arguments passed to the server if I included a comment on the invoice.

I'm running Magento EE ver. 1.11.0.2 using C# and the XML-RPC.Net v2 library (CookComputing.XmlRpcV2.dll) to integrate data with Magento.

I stumbled upon this resolution by noticing the comment on the empty invoices was "0", which was the value I was feeding for the Send invoice on email (optional) field, and decided to try inserting an empty element before the comment, and the comment showed up but the items were still not getting invoiced. I then moved the empty element before the list of items and everything worked. I checked the code for the API /app/code/core/Mage/Sales/Model/Order/Invoice/Api.php but couldn't find where or why this would be the case. My only guess is that it has something to do with the library that is parsing the XML-RPC request isn't getting something right since this call has an array in the middle of the other arguments.

In trying to diagnose this I've used the XML-RPC logger

logger = new RequestResponseLogger();
logger.Directory = "C:\Temp\";
magentoProxy.AttachLogger(logger);
logger.UnsubscribeFrom(magentoProxy);

Then anytime I want to see what the request responses are on a call I just put these calls before and after the XML-RPC call

logger.SubscribeTo(magentoProxy);
// call to Magento that I want to see the XML for request and responses to
logger.UnsubscribeFrom(magentoProxy);

I didn't see any problems with the XML that was sent to Magento for the API calls. The only other thing I could think of would be to launch magento with a debugger attached and watch what happens when it gets to that create method in the Api.php file or in the stack prior where things are getting messed up, but I didn't have my dev environment setup for active debugging of the Magento code at the time, and didn't want to spend the time digging into that aspect of things right now.

What I did as a work around was to add some code after the call to create the invoice that pulls down the order_info again from Magento and checks to see if all the items on the order have been invoiced, and if not it throws up an ugly error. I figure that way if at some point this "bug" or whatever is causing this to happen gets fixed or changes I'll at least know if it affects the order items getting invoiced from this call.

        // Get the order items that need to be invoiced
        // this.orderInfo is the XmlRpcStruct returned from a sales_order.info call
        XmlRpcStruct[] orderItems = this.orderInfo.Contains("items") ? (XmlRpcStruct[]) this.orderInfo["items"] : new XmlRpcStruct[] { };

        XmlRpcStruct orderItemsToInvoice = new XmlRpcStruct();
        Int32 orderItemId;
        Int32 qtyOrdered;
        Int32 qtyInvoiced;
        Int32 qtyToInvoice;

        foreach (XmlRpcStruct item in orderItems)
        {
            orderItemId = item.Contains("item_id") ? Convert.ToInt32(item["item_id"]) : 0;
            qtyOrdered = item.Contains("qty_ordered") ? Convert.ToInt32(Convert.ToDecimal(item["qty_ordered"])) : 0;
            qtyInvoiced = item.Contains("qty_invoiced") ? Convert.ToInt32(Convert.ToDecimal(item["qty_invoiced"])) : 0;
            qtyToInvoice = qtyOrdered - qtyInvoiced;

            orderItemsToInvoice[Convert.ToString(orderItemId)] = Convert.ToString(qtyToInvoice);
        }

        // Invoice This Order with a comment
        String newInvoiceId = magentoProxy.salesOrderInvoiceCreate(sessionId: sessionId, arguments: new Object[] {
                this.MageIncrementId, // Order increment ID
                "", // this should not need to be here, but for some reason if I want to include a comment
                    // on the invoice I have to thave this extra empty element before the array of order items
                    // if no comment is included on the invoice this extra element is not needed, rather weird, I can not explain it.
                orderItemsToInvoice, // array    itemsQty    Array of orderItemIdQty (quantity of items to invoice)
                "Automatically invoiced prior to CounterPoint import." // Invoice Comment (optional)
                //"0", // Send invoice on email (optional) defaults to false
                //"0" // Include comments in email (optional) defaults to false
            });

        // Invoice This Order without a comment
        String newInvoiceId = magentoProxy.salesOrderInvoiceCreate(sessionId: sessionId, arguments: new Object[] {
                this.MageIncrementId, // Order increment ID
                orderItemsToInvoice // array    itemsQty    Array of orderItemIdQty (quantity of items to invoice)
            });
mttjohnson
  • 462
  • 3
  • 13
  • Thanks - that XmlRpcStruct was really helpfull! – Eleasar Nov 19 '13 at 10:21
  • Magento EE 1.13 fixed a lot of bugs with the API calls. I also found that I was able to easily get a SOAP example to work with EE 1.13 so there is an alternative to using XML-RPC. I did a proof of concept project (working with gift cards) using SOAP and EE 1.13 and it was so much simpler to code. I'm hoping to transition away from XML-RPC to SOAP for the Magento API calls going forward. – mttjohnson Nov 22 '13 at 16:34