cancel
Showing results for 
Search instead for 
Did you mean: 

Deep insert using Model.create()?

Former Member
0 Kudos

Hi,

     Can we use model.create() of  class sap.ui.model.odata.ODataModel for deep insert operation.

     I have an OData service for PO creation in which the header and item details has to be inserted in a single POST operation.

     Is it possible to use model.create() for this.

     The xml format of POST data is

<?xml version="1.0" encoding="UTF-8"?>

<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">

  <atom:content type="application/xml">

   <m:properties>

    <d:PurGroup>AR1</d:PurGroup>

    <d:PurchOrg>7500</d:PurchOrg>

    <d:Vendor>0000100073</d:Vendor>

    <d:DocType>NB</d:DocType>

    <d:CoCode>7500</d:CoCode>

    </m:properties>

  </atom:content>

<atom:link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/PurchaseOrderItem" type="application/atom+xml;type=feed" title="Z_DEEP_INSERT_SRV.A_T_ITEMS">

  <m:inline>

   <atom:feed>

    <atom:entry>

     <atom:content type="application/xml">

      <m:properties>

       <d:Plant>7500</d:Plant>

       <d:PurMat>PAPEL</d:PurMat>

       <d:Material>PAPEL</d:Material>

       <d:PoItem>00001</d:PoItem>

       <d:PoNumber>01234</d:PoNumber>

      </m:properties>

     </atom:content>

    </atom:entry>

    <atom:entry>

     <atom:content type="application/xml">

      <m:properties>

       <d:Plant>7500</d:Plant>

       <d:PurMat>PAPEL1</d:PurMat>

       <d:Material>PAPEL1</d:Material>

       <d:PoItem>00002</d:PoItem>

       <d:PoNumber>01234</d:PoNumber>

      </m:properties>

     </atom:content>

    </atom:entry>

   </atom:feed>

  </m:inline>

</atom:link>

</atom:entry>

Accepted Solutions (1)

Accepted Solutions (1)

kammaje_cis
Active Contributor

Here it is,

//Create Model

oModel = new sap.ui.model.odata.ODataModel('<URL>');

//Create Body

var requestBody = {};

requestBody.PurGroup = '123';

requestBody.PurOrg = 'WW';

//Child Body

var child = [];

child.push({ Plant: '123'. PurMat: '234234', Material: 'XCF'});

child.push({ Plant: '153'. PurMat: '23334', Material: 'YCF'});

//Add child to request

requestBody.<navigation_name> = child;

//Issue Create

oModel.create('/<collection_name>', requestBody, null, function() { alert ('success')}, function() { alert('failed'} );

Thanks

Krishna

Former Member
0 Kudos

Thank you Krishna bhai.

karanbahl
Active Participant
0 Kudos

Hi Krishna,

We have the same requirement.

requestBody.<navigation_name> = child;


Q1. We have specified the navigation name as Header_Items, which has been defined as association in the OData Model Class. Is it the correct one or what do we need to specify?


Q2. oModel.create('/<collection_name>',


Which collection name we have to supply in this, Headers or Items?? Can you please elaborate?

We are declaring odata model as:

var oModel = new sap.ui.model.odata.ODataModel("http://xx:8000/sap/opu/odata/sap/SERVICENAME/");
Do we need to specify any entity set in the url such as

sap.ui.model.odata.ODataModel("http://xx:8000/sap/opu/odata/sap/SERVICENAME/Headers"); or
sap.ui.model.odata.ODataModel("http://xx:8000/sap/opu/odata/sap/SERVICENAME/Items");?

If possible, Can you share any working code for the same. We are stuck in this for a long time now.

Regards,

Karan

Former Member
0 Kudos

Hello Karan,

Were you able to figure out how to resolve your issue ?

kammaje_cis
Active Contributor
0 Kudos

1. Yes, Navigation name has to be used.

2. Collection name is that of the Parent.

Thanks

Krishna

saurabh_vakil
Active Contributor
0 Kudos

Hi Thibault,

Yes we were able to figure this out using the response provided by Krishna.

Thanks for your valuable suggestion!!!

Regards

Saurabh

Former Member
0 Kudos

Hi Krishna,

Using your guidelines and from another example I'm trying to CREATE a Sales Order using deep insert using the following code:


executeOrderCreation: function () {

       

        oModel = sap.ui.getCore().getModel();

        

        var requestORderHeader = {};

        requestORderHeader.OrderId = '0';

        requestORderHeader.DocumentType = 'MOR';

        requestORderHeader.CustomerId = 'MP-CUST201';

        requestORderHeader.SalesOrg = 'M210';

        requestORderHeader.DistChannel = '01';

        requestORderHeader.Division = 'M1';

        requestORderHeader.DocumentDate = null;

        requestORderHeader.OrderValue = null;

        requestORderHeader.Currency = 'USD';

         

        var articles = ["MP_SHEET_MIO_00", "MP_SHEET_MIO_10", "MP_SHEET_MIO_11", "MP_SHEET_MIO_20", "MP_SHEET_MIO_21"];

        var itemData = [];

        var poste = 10;

        for (var i = 0; i < articles.length; i++) {

            var posteBis = "0000" + poste;

             

            itemData.push({

                OrderId: '0',

                Item: posteBis,

                Material: articles[i],

                Plant: "M210",

                Quantity: '200',

                Description: "",

                UoM: "LBR",

                Value: null

            });

            poste = poste + 10;

        }

        

        requestORderHeader.SOItems = itemData;

        

        var oModel = sap.ui.getCore().getModel();

        oModel.setHeaders({

            "Access-Control-Allow-Origin": "*",

            "Content-Type": "application/x-www-form-urlencoded",

            "X-CSRF-Token": "Fetch"

        });

       

        var token;

       

        oModel.read('/SOHeaders',

            null,

            null,

            false,

            function (oData, oResponse) {

                token = oResponse.headers['x-csrf-token'];

            },

            function () {

                alert("Error on read process");

            }

        );

       

        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

        });

     

        oModel.create('/SOHeaders',

            requestORderHeader,

            null,

            function (oData, oResponse) {

                alert('Order creation succeed !');

            },

            function () {

                alert('Call service creation failed');

            }

        );

    },

I'm getting an error code 500. On debugging, I found this was caused due to "The termination type was: RABAX_STATE"

Can you shed some light on this matter? I need this.

Former Member
0 Kudos

Hi,

I think the error is with the OData service. Can you execute the POST operation of OData service in your server and post the entire response.

Regards,

Akhil Das

Former Member
0 Kudos

The service works fine Akhil. All GET, POST operations work fine in Rest Client.

Former Member
0 Kudos

Ok Sreyan, I mostly got RABAX_STATE error in the server which will be again reflected in the network response part when we debug the application in the browser. And we will mostly get some clue regarding the reason for the error from ABAP dump analysis(tcode st22) in the netweaver server.

Former Member
0 Kudos

hi Krishna ,

I am also facing similar issue

<?xml version="1.0" encoding="UTF-8"?>

<atom:entry

xmlns:atom="http://www.w3.org/2005/Atom"

xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"

xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">

<atom:content type="application/xml">

<m:properties>

<d:MANDT>100</d:MANDT>

<d:PLAN_ID>123</d:PLAN_ID>

<d:PLAN_DESC>Gateway Plan1</d:PLAN_DESC>

<d:PLAN_STDT>20140513</d:PLAN_STDT>

<d:PLAN_ENDT>20140613</d:PLAN_ENDT>

<d:DATA_START_DATE>20140513</d:DATA_START_DATE>

<d:DATA_END_DATE>20140613</d:DATA_END_DATE>

<d:SALES_ORG_ID>01</d:SALES_ORG_ID>

<d:DIST_CHANNEL_ID>01</d:DIST_CHANNEL_ID>

<d:DIVISION_ID>01</d:DIVISION_ID>

<d:PRIC_STRGY_ID>1</d:PRIC_STRGY_ID>

<d:PLAN_STATUS>D</d:PLAN_STATUS>

<d:STATUS_REMARKS>Created</d:STATUS_REMARKS>

<d:USER_ID>Shakthi</d:USER_ID>

</m:properties>

</atom:content>

<atom:link

rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/PLAN_DTLSet"

type="application/atom+xml;type=feed"

title="ZCL_PLAN_HDR_DTL_SRV.PLAN_DTLSet">

<m:inline>

<atom:feed>

<atom:entry>

<atom:content type="application/xml">

<m:properties>

<d:PLAN_ID>123</d:PLAN_ID>

<d:COMP_BANNER_ID>CVS</d:COMP_BANNER_ID>

</m:properties>

</atom:content>

</atom:entry>

<atom:entry>

<atom:content type="application/xml">

<m:properties>

<d:PLAN_ID>123</d:PLAN_ID>

<d:COMP_BANNER_ID>WALGREENS</d:COMP_BANNER_ID></m:properties>

</atom:content>

</atom:entry>

</atom:feed>

</m:inline>

</atom:link>

</atom:entry>

My client code

var requestBody = {};
requestBody.MANDT='100';
requestBody.PLAN_ID='123';
requestBody.PLAN_DESC='123';
requestBody.PLAN_STDT='20140513T00:00:00';
requestBody.PLAN_ENDT='20140513T00:00:00';
requestBody.DATA_START_DATE='20140513T00:00:00';
requestBody.DATA_END_DATE='20140513T00:00:00';
requestBody.SALES_ORG_ID='01';
requestBody.DIST_CHANNEL_ID='01';
requestBody.DIVISION_ID='01';
requestBody.PRIC_STRGY_ID='01';
requestBody.PLAN_STATUS='D';
requestBody.STATUS_REMARK='Created';
requestBody.USER_ID='Shakthi';
 
//Child Body
var child = [];
child.push({ PLAN_ID : "123", COMP_BANNER_ID : "APJ" });
child.push({ PLAN_ID : "123", COMP_BANNER_ID : "HI" });
 
//Add child to request
requestBody.PLAN_DTLSet = child;
   

                 var oModel1 = new sap.ui.model.odata.ODataModel( serviceUrl , true );

               

                 oModel1.setDefaultBindingMode(sap.ui.model.BindingMode.TwoWay);                                                                 

               

                oModel1.create('/PLAN_HDRSet', requestBody, null, function(){

                    alert("Create successful" );

                  },function(oError){

                    alert("Create failed");});

I am getting Error while passing XMLStream in my chrome javascript console ? Can you help

Former Member
0 Kudos

Hi Kishor.

I have another issue regarding deep create implementation in UI side using model.create.

Actually some of the browsers are not supporting model.create() like chrome browser version 34 , but at the same time it is being supported by Internet Explorer version 9.

In chrome it is showing the error ' undefined is not a function - '. While debugging i also found that the error was caused when the model.create() function was executed.

While checking the class sap.ui.model.odata.ODataModel, i noticed that in  the definition of create function, it is given

create(sPath, oData, mParameters?) : object

Trigger a POST request to the odata service that was specified in the model constructor. Please note that deep creates are not supported and may not work.

Is this the reason for that error. And is there any other way to implement deep create in UI side.

Thanks

Akhil Das

Former Member
0 Kudos

Hi Krishna,

I tried the exactly same way without setting header etc.But its not working.The create_entity method is only called and not the create_deep_entity.

miguelangel_daz
Explorer
0 Kudos

hello, have you resolved your problem? thanks in advance

Answers (3)

Answers (3)

Former Member
0 Kudos

On my side, I user a proxy servlet in the web.xml file, but I think this is for local test only:


<servlet>

  <servlet-name>SimpleProxyServlet</servlet-name>

  <servlet-class>com.sap.ui5.proxy.SimpleProxyServlet</servlet-class>

  </servlet>

  <servlet-mapping>

  <servlet-name>SimpleProxyServlet</servlet-name>

  <url-pattern>/proxy/*</url-pattern>

  </servlet-mapping>

  <context-param>

  <param-name>com.sap.ui5.proxy.REMOTE_LOCATION</param-name>

  <param-value>http://<serveur>:<port></param-value>

  </context-param>

Whereas, I do not use the proxy in the URL of the service declaration:


var sServiceUrl = this.getUrl("/sap/opu/odata/sap/<SERVICE_NAME/");

Have you tried removing the proxy keyword in the URL ?

Former Member
0 Kudos

It doesn't work without the proxy. The url pattern is defined for proxy (/proxy/*) in web.xml.

Former Member
0 Kudos

I guess your executeOrderCreation function is mapped to a button on your html page. Is the error triggered when you try to execute the function or when you just display the html page ?

What if you debug the while function to see which instruction is generating the error ?

Former Member
0 Kudos

The error does not come on page load. It is triggered when I clicked the button mapped to the function that executes the service call.

The error is throws when the debugger hits:


oModel.create('/SOHeaders',

            requestORderHeader,

            null,

            function (oData, oResponse) {

                alert('Order creation succeed !');

            },

            function () {

                alert('Call service creation failed');

            }

        );

Also, it is showing the value of token as undefined, when it is being read (token = oResponse.headers['x-csrf-token']; )


oModel.read('/SOHeaders',

            null,

            null,

            false,

            function (oData, oResponse) {

               token = oResponse.headers['x-csrf-token'];

            },

            function () {

                alert("Error on read process");

            }

        );

What is wrong? I'm totally confused.

Former Member
0 Kudos

I think you are facing an error with the token generation. The security token is needed for the post request. You can see it in the following code:

  1. oModel.setHeaders({ 
  2.             "X-Requested-With": "XMLHttpRequest"
  3.             "Content-Type": "application/json"
  4.             "DataServiceVersion": "2.0"
  5.             "Accept": "application/atom+xml,application/atomsvc+xml,application/xml"
  6.             "X-CSRF-Token": token 
  7.         }); 

The variable 'token' is used to insert the previously fetched token in the post request header.

Everytime you call a post request, you first need to trigger a simple get request to retreive the XCSRF token then use this token in the post request.

Maybe you should have a look at this point !

Former Member
0 Kudos

Well Thibault, I posted the entire code a while back. The token fetching and assigning was done with the following piece of code.

          


var oModel = sap.ui.getCore().getModel(); 

        oModel.setHeaders({ 

            "Access-Control-Allow-Origin": "*", 

            "Content-Type": "application/x-www-form-urlencoded", 

            "X-CSRF-Token": "Fetch" 

        }); 

         

        var token; 

         

        oModel.read('/SOHeaders', 

            null, 

            null, 

            false, 

            function (oData, oResponse) { 

                token = oResponse.headers['x-csrf-token']; 

            }, 

            function () { 

                alert("Error on read process"); 

            } 

        ); 

         

        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 

        });

Yes, there seems to be a problem in token fetching, but I can't figure it out from the above piece of code.

Former Member
0 Kudos

What is in your var oModel variable ? Did you store your service in the onInit function of your controller as done in the following code ?


onInit : function() {

  // URL of the OData service - IMPORTANT: relative to the

  // server

  var sServiceUrl = this.getUrl("/sap/opu/odata/sap/<YOUR_GTW_SERVICE>/");

  // create OData model instance with service URL and JSON

  // format

  var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true, "user", "pswd");  // your credentials to the backend system

  sap.ui.getCore().setModel(oModel);

  },

Former Member
0 Kudos

Yes Thibault, onInit() is properly defined.


onInit: function() {

       

    var sServiceUrl = "proxy/http/<server>:<port>/sap/opu/odata/sap/SALESORDER03"; 

    var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true, "user", "pass");     

    sap.ui.getCore().setModel(oModel); 

        

    },

Former Member
0 Kudos

Hi Sreyan
Did you come up with any solution to this ?

Former Member
0 Kudos

Nope. Not yet.

Former Member
0 Kudos

Hi sreyan
I suggest try it using IE getting token as
token =oModel.getHeaders()['x-csrf-token'];

Former Member
0 Kudos

Hello Sreyan,

Maybe you can debug the Javascript code in Firefox or Chrome Web Browser and check which instruction is generating the error.  Then we might be able to gove you a more accurate answer.

Former Member
0 Kudos

I'll post a screenshot of the debugger and the error.

Take a look.

Kindly suggest!

Former Member
0 Kudos

Hello,

Did you implement the CREATE_DEEP_ENTITY function in your Data Model ?

I guess the Javascript error is trigger when ever the following code is executed in your application:

  1. oModel.create('/SOHeaders'
  2.             requestORderHeader, 
  3.             null
  4.             function (oData, oResponse) { 
  5.                 alert('Order creation succeed !'); 
  6.             }, 
  7.             function () { 
  8.                 alert('Call service creation failed'); 
  9.             } 

Maybe you should try and place a breakpoint in your Abap function to see what is wrong in the order creation process.

Former Member
0 Kudos

Yes Akhil, we did implement the CREATE_DEEP_ENTITY function in our OData model.

I'll try what you said.

Former Member
0 Kudos

Akhil, the external break point never gets hit!

Former Member
0 Kudos

Sreyan, the error is happening in the Netweaver server side, not UI side. So if you execute the HTTP POST method in the Netweaver Gateway Client with HTTP request body, you will get more information regarding the error in the HTTP response body. During this process you can also place the breakpoint in the Deep Create function.

Former Member
0 Kudos

I placed the break point in CREATE_DEEP_ENTITY method. I realize that the error is on the Netweaver side. The service works fine in Rest Client if that is what is meant by Netweaver Gateway client? I just can't implement the same from UI5 code.