Hello,
While studying SAP Gateway OData Channel, my first need was to create a sales order using a Gateway Service. I came accros a lot of documents to create simple Gateway Services, but most of them were for Query or read operations. There is not a lot of documentation for create operation, especially for sales orders where the input structure can be very complex since there is a header and line items. In fact, when you want to manage collections of items related to a single entity (the order header), you need to build complex business entities.
Prerequisites:
- Create complex entities: How To... Create Complex Business Entities using the Gateway OData Channel
- The following document also explains how to build an application frontend with the UI Development Toolkit for HTML5 (from page 23): End-to-End How-to Guide: Building SAPUI5 Applications on SAP NetWeaver AS ABAP 7.31 Consuming Gateway OData Services
1. Create your complex entities using the provided link
2. Create a SAP UI5 Application project Within Eclipse
3. Edit the controller part of the application
- Implement the onInit function to declare the oData model that will be used for the application:
onInit : function() { // URL of the OData service - IMPORTANT: relative to the server var sServiceUrl = this.getUrl("/sap/opu/odata/sap/SALESORDERTSCH/"); // create OData model instance with service URL and JSON var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true, user, password); // Save the model sap.ui.getCore().setModel(oModel);
- Create the executeOrderCreation method: here, the order header and line items are hard coded.
executeOrderCreation : function() { // Retreive previously created Model oModel = sap.ui.getCore().getModel(); // Set order header data var requestORderHeader = {}; requestORderHeader.OrderId = '0'; requestORderHeader.DocumentType = 'TA'; requestORderHeader.CustomerId = 'C6603'; requestORderHeader.SalesOrg = 'S010'; requestORderHeader.DistChannel = '01'; requestORderHeader.Division = '01'; requestORderHeader.DocumentDate = null; requestORderHeader.OrderValue = null; requestORderHeader.Currency = 'EUR'; // Create item data var articles = ["C10010", "C10011", "C10150", "C17100", "C17200", "C17300", "C18000", "C18001", "C18002", "C18100", "C18200", "C18201", "C18202", "C20010", "C20011", "C20012", "C20013", "C20014", "C20020", "C20030", "C20040", "C20050", "C20070", "C10010", "C10011", "C10150", "C17100", "C17200", "C17300", "C18000", "C18001", "C18002", "C18100", "C18200", "C18201", "C18202", "C20010", "C20011", "C20012", "C20013", "C20014", "C20020", "C20030", "C20040", "C20050", "C20070"]; var itemData = []; var poste = 10; for (var i = 0; i < articles.length; i++) { var posteBis = ""+ poste; // Create line items itemData.push({ OrderId: '0', Item: posteBis , Material: articles[i], Plant : "P010", Quantity : '200', Description : null, UoM : null, Value : null }); poste = poste +10; } // Link items to the order header requestORderHeader.SOItems = itemData; // Retrieve model from controller var oModel = sap.ui.getCore().getModel(); oModel.setHeaders( { "Access-Control-Allow-Origin" : "*", "Content-Type": "application/x-www-form-urlencoded", "X-CSRF-Token":"Fetch" } ); // Declare a variable to handle the security token var token; // Create a read request to retreive the X-CSRF token oModel.read('/SOHeaders', null, null, false, function(oData, oResponse) { token = oResponse.headers['x-csrf-token']; }, function() { alert("Error on read process"); } ); // Set POST request header using the X-CSRF token oModel.setHeaders( { "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/json", "DataServiceVersion": "2.0", "Accept": "application/atom+xml,application/atomsvc+xml,application/xml", "X-CSRF-Token": token } ); // Call the create request oModel.create('/SOHeaders', requestORderHeader, null, function(oData, oResponse) { alert ('Order creation succeed !'); }, function() { alert('Call service creation failed'); } ); },
On the code above, the request header for the POST request has the following: "Content-Type": "application/json". At the beginning, I was using application/xml and it was not working. Here, my line items and header content are Json content. I think it is easier to use JSon because you don't need to manage xml markers. You just link your parameters with the associated value and this is all you need to have concerns about.
4. Edit the view
In the view file, I have simply created a button in the createContent() function that will be used to call and test the service:
createContent : function(oController) { // Create service call button var oButton = new sap.ui.commons.Button({ text : "Call service", enabled : true, press : function() { oController.executeOrderCreation();} // Execution of method executeService defined in the controller }); // Place button in button div in html page oButton.placeAt("button"); },
5. Test your application:
- Locally:
- You can also deploy the application on the ABAP server
Then you can test it from SE80 transaction in the backend:
Enjoy !