Skip to main content

Creating sales orders from XML

This document has been migrated from TechNet.Navision.com - In this article we will show how a sales order may be created using the XML interface. We show a simple XML file containing the sales order, and describe how it ends up as a sales order in Axapta.
Consider a scenario where an application needs to create a sales order in Axapta. This application could be an MS office application (e.g a spreadsheet containing the sales order lines) or a web site created in another environment, that needs to access Axapta to do create a sales order. This sort of integration is easily done with XML, as we show in this example.
Consider a sales order:

4010
4012


OL-1000
3


OL-1500
4


PL-2500/Art
5

In this sales order, the customer with account number 4010 is ordering 4 Ol-1000, 4 OL-1500 and 5 PL-2500/ART. Although this is a simplified sales order, it will suffice for the presentation herein.Consider now the job below, where the XML document is read, the information extracted and then used to create the salesorder. Note carefully, that the code presented below is designed to show the how the sales order information is extracted from XML; it is not designed to show how to create sales orders as such. Better methods may exist for doing that, but the one presented here is reasonably simple, and does not clutter the picture with issues that are irrelevant to the XML content of this article. 1 static void Job5(Args _args)
2 {
3 SalesBasketLine salesBasketLine;
4 SalesBasket salesBasket;
5 SalesBasketId salesBasketId;
6 SalesAutoCreate_Basket salesAutoCreate;
7
8 XMLDocument doc;
9 XMLNode rootNode;
10 XMLNode custAccountNode, contactPersonIdNode, salesLineNode;
11 XMLNodeList salesLines;
12 XMLParseError xmlError;
13 int i;
14
15 // Get the XML document
16 doc = new XMLDocument();
17 doc.async(FALSE);
18 doc.load("salesorder.xml");
19 xmlError = doc.parseError();
20
21 if (xmlError && xmlError.errorCode() != 0)
22 {
23 print "Error: " + xmlError.reason();
24 pause;
25 return;
26 }
27
28 rootNode = doc.documentElement();
29
30 ttsbegin;
31
32 // At this point we have an xml document containing the sales order.
33 // Get the customer account from the document
34 custAccountNode = rootNode.selectSingleNode("//CustomerAccount");
35 contactPersonIdNode = rootNode.selectSingleNode("//ContactPersonId");
36
37 salesBasket.initValue();
38 salesBasket.custAccount = custAccountNode.text();
39 salesBasket.initFromCustTable();
40
41 salesBasket.salesBasketId = NumberSeq::newGetNum(ECPParameters::numRefSalesBasketId()).num();
42 salesBasket.ContactPersonId = contactPersonIdNode.text();
43
44 salesBasket.insert();
45
46 // Select all the sales lines into a nodelist
47 salesLines = rootNode.selectNodes("//SalesOrderLine");
48
49 for (i = 0; i < salesLines.length(); i++)
50 {
51 salesLineNode = salesLines.item(i);
52 salesBasketLine.clear();
53 salesBasketLine.initValue();
54
55 salesBasketLine.initFromSalesBasket(salesBasket);
56
57 salesBasketLine.itemId = salesLineNode.selectSingleNode("ItemId").text();
58 salesBasketLine.configId = '';
59 salesBasketLine.salesQty = str2num(salesLineNode.selectSingleNode("Qty").text());
60
61 salesBasketLine.insert();
62 }
63
64 ttscommit;
65
66 // Create the sales order from the basket info.
67 select forupdate salesBasketLine where salesBasketLine.salesBasketId == salesBasket.SalesBasketId;
68
69 salesAutoCreate = new SalesAutoCreate_Basket(salesBasketLine);
70 salesAutoCreate.create();
71
72 pause;
73 }
Let's walk through the code and see what happens. In line 16, after we have declared the objects we need and started a transaction, we create an XMLDocument variable and load the salesorder.xml file, with the sales order given above. The load call will read in the file and build an internal tree representation of the sales order. If this fails (because of syntax errors) the load method will return FALSE and an object (of type XMLParseError) is retrieved (using the parseError() method, in line 19). This object may then be used to diagnose what the problem is. There are several methods on the XMLParseError class that may be used to pinpoint precisely what went wrong, and where the error occurred. Once the document is correctly loaded, from line 28 and onwards, we may begin extracting information from it. We start off by storing the document's rootElement in the rootNode variable (in line 28). The rootNode will represent the toplevel node of the document, i.e. the node. We then proceed to fetch the node representing the customer account and contact person (lines 34 and 35). This is done by querying the tree, asking: "return the first node having the name CustomerAccount" and "return the first node having the name ContactPersonId". This is a simple application of the query language called XPath, that may be used to query the tree using arbitrarily complex search criteria. Once we have thes nodes in hand, we may call the text() method (lines 38 and 42), to retrieve the text values ("4010" and "4012" repectively). These values are used to initialize the salesBasket parameters. After we have created the sales basket (in line 44), we're ready to start adding items to it. We do this by selecting all the nodes named "SalesOrderLine" and collecting them in a list (called salesLines). This is what goes on in line 47. This list is then traversed in the for loop starting at line 49: The individual nodes are retrieved from the list using the item method (in line 51). Again, the selectSingleNode method is used to reference the ItemId (line 57) and the quantity fields (line 59). The item is then inserted in the sales basket (line 61). After this, we only have to actually generate the sales order from the sales basket, which is what goes on from line 66.As it may be seen from this example it is actually quite easy to use the XML classes to retrieve the information needed to perform a task in the application. All you need to do is to load the file into an XMLDocument (which performs error checking), and then you may use XPath queries to retrieve the nodes in the tree. In fact, the XML need not even be stored in a file, in which case you would use the loadXML method to load the tree from a string representing the XML.Remember, that the XML classes used in this example are written in the application layer (and not in the kernel), so they do not require any specific version of Axapta.

www.dynamic-ax.co.uk

Popular posts from this blog

What does this mean: "The form datasource query object does not support changing its AllowCrossCompany property after the form has executed the query."?

I have made a form with datasources vendtable and vendtrans. Inside vendtable_ds.executequery() looks like this: QueryBuildDataSource queryBuildDatasource ,queryBDS_VendTrans_Invoice; ; queryBuildDatasource = this.query().dataSourceTable(tablenum(vendtable)); queryBDS_VendTrans_Invoice = this.query().dataSourceTable(tablenum(vendtrans)); if (curext() == "MASTERCOMP") { this.query().allowCrossCompany(true); } else { this.query().allowCrossCompany(false); } //FilterVendorName = stringedit control on form if (FilterVendorName.text()) { queryBuildDatasource.addRange(fieldNum(VendTable,Name)).value(strfmt("*%1*", FilterVendorName.text())); } else { queryBuildDatasource.clearRange(fieldNum(VendTable,Name)); } //FilterInvoiceNumber = stringedit control on form if (FilterInvoiceNumber.valueStr() == "") { queryBDS_VendTrans_Invoice.enabled(false); } else { queryBDS_VendTrans_Invoice.enabled(true); queryBDS_VendTrans_In...

Credit Note [Dynamics AX] using X++

This post will help to create credit note for a sales order based on the invent lot id. All the invoices raised for a particular sales line – Lot Id will be raised back as a credit note. Information on Credit Note: A credit note or credit memorandum (memo) is a commercial document issued by a seller to a buyer. The seller usually issues a Credit Memo for the same or lower amount than the invoice, and then repays the money to the buyer or sets it off against a balance due from other transactions Below Code will help to create credit note for all the invoices raised against the sales line -lot id. Please note: This code can be customized as per your requirements. This is just a template to help creating credit note using X++ code. Please test the code before use. static void SR_CreateCreditNote_Sales(Args _args) { // Coded by Sreenath Reddy CustInvoiceTrans custInvoiceTrans; Dialog dialog = new Dialog(“Create credit note – for sales.”); DialogField dfInv...