cancel
Showing results for 
Search instead for 
Did you mean: 

SAPUI5 and oData: Task completion problem

Former Member
0 Kudos

Dear all,

We've got a BPM process which is based on WDJ approval screens.

Now I would like to replace WDJ by SAPUI5.

I've succeeded to display some task input data in my SAPUI5 application:


oPanel.bindElement("/InputData('"+taskId+"')", {expand:"ContextTypeINPUT/Context/Requester"});


var oInputFirstName = new sap.ui.commons.TextField("textFirstName", {

    value : "{ContextTypeINPUT/Context/Requester/FirstName}"

});

var oInputLastName = new sap.ui.commons.TextField("textLastName", {

    value : "{ContextTypeINPUT/Context/Requester/LastName}"

});

But I can't manage to complete the task.

For a simpler example that worked for me.

It seems that I don't fill the output data correctly.

Normally I should fill the Status (fields Action, ChangedBy, ChangedOn and Details) and the Request->ReferenceNumber:

Please find attached the XSD of the task.

I tried the following:


var outputData = {};

var status = odataModel.getProperty("/InputData('" + taskId "') " +

                  "/ContextTypeINPUT/Context/Status");

status.Action = "approved";

status.ChangedBy = "TEST";

status.ChangedOn = "2014-07-29";

outputData.HandleRequestCompleteEventTypeOUTPUT = status;

// send request to BPM Task Data OData service to complete

odataModel.create("/OutputData", outputData, null,

    function sendData_OnSuccess(oData, response) {

        alert("Task has been completed successfully");

    },

    function sendData_OnError(oError) {

        alert("Task could not be completed");

    }

);

But it stops when executing the second statement (var status = odataModel.getProperty("/InputData('" + taskId "')...).

I would really appreciate if you could help me!

Thanks in advance.

Best regards,

Thorsten.

P.S.: Our system is running NW 7.40 SP07.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi again,

As most of the time, I had to solve my issues published on SCN on my own

My mistake was, that I've retrieved the 'handleRequestType' of my OutputData from the InputData.

It seems that having all subtypes in the structure causes trouble, because I fill only to fill two fields.

In the end I build OutputData myself and it works now...

So in fact it's possible to create an proper OutputData without a binding of InputData.

controller.js


completeTask : function() {

// Get TaskID and data model

var taskId = getValueOfURLParameter("taskId");

var odataModel = this.getView().getModel();

// Create OutputData

var outputData = {};

// Create all needed subtypes

var handleRequestType = {};

var status = {};

var request = {};


// Fill values for fields that need to be sent

status.ChangedBy = sap.ui.getCore().byId("inputStatus").getValue();

request.ReferenceNumber = sap.ui.getCore().byId("inputRequest").getValue();

// Build OutputData

handleRequestType.Status = status;

handleRequestType.Request = request;

outputData.HandleRequestType = handleRequestType;

// Complete task with built OutputData

odataModel.create( "/OutputData", outputData, null,

     function sendData_OnSuccess(oData, response) {

          alert("Task has been completed successfully");

     },

     function sendData_OnError(oError) {

          alert("Task could not be completed");

     });

}

view.js


createContent : function(oController) {

...

// Text input fields which will feed the OutputData

var oInputStatus = new sap.ui.commons.TextField("inputStatus");

var oInputRequest = new sap.ui.commons.TextField("inputRequest");

// Button to complete the task

var oButton = new sap.ui.commons.Button( {

     text : "Complete",

     style : sap.ui.commons.ButtonStyle.Accept,

     press : (function() {

     oController.completeTask();

}).

...

}

Just make sure that you explore your OuputData before via a tool like Postman (Chrome Addon).

First do a GET request:

http://<host>:<port>/bpmodata/taskdata.svc/<taskID>/OutputData

Then look for a "/XYZ" part in the response.

In my case it looked like that:


...

<link href="OutputData('<TaskID>')" rel="edit" title="OutputData"/>

<link href="OutputData('<TaskID>')/HandleRequestType" .../>

...

So I could go on to explore my output data, by sending the following GET request in Postman:

http://<host>:<port>/bpmodata/taskdata.svc/<taskID>/OutputData?$expand=HandleRequestType

Now you have to repeat that until you find the data type that you want manipulate.

If you found out how your OutputData looks like, you can build it easily on your own (see my controller.js).

Maybe I'll write my first blog about it

Jocelyn_Dart
Product and Topic Expert
Product and Topic Expert
0 Kudos

Well done in solving the problem... I notice that http://scn.sap.com/people/jan.nyfeler  may have beaten you to a blog on this topic... you might want to look and see if there is something else you can add?

But thanks for posting the response... mapping is always something everyone struggles with.

Jocelyn

Answers (3)

Answers (3)

Former Member
0 Kudos

Unfortunately I didn't proceed since yesterday.

I have a general question:

Do I have to fill all fields in the output type?
Or can I only do it for the fields that are included in the output mapping of my BPM?

The output mapping looks like that:

In my opinion I only have to fill the structure "Status" in my outputData structure:


var outputData = {};

// Get output type

var handleRequestType = odataModel.getProperty("/InputData('" + taskId

  + "')/HandleRequestType");

// Get status

var status = odataModel.getProperty("/InputData('" + taskId

  + "')/HandleRequestType/Status");

// Set status

handleRequestType.Status = status;

// Complete task

odataModel.create("/OutputData", outputData);

This is how the output structure looks like in Postman:

This is how my outputData looks like before sending the complete request:


outputData: Object

     HandleRequestType: Object

          Approver: Object

          EDM_Key: "a4a1c11a189311e4b3240000254e17a2_I_1"

          Exception: null

          Initiator: Object

          Request: Object

               __deferred: Object

               __proto__: Object

          Requester: Object

               __ref: "RequesterType('a4a1c11a189311e4b3240000254e17a2_I_1_4')"

               __proto__: Object

          Status: Object

               Action: null

               ChangedBy: "Dummy"

               ChangedOn: null

               Details: null

               EDM_Key: "a4a1c11a189311e4b3240000254e17a2_I_1_5"

               __metadata: Object

               __proto__: Object

          __metadata: Object

          __proto__: Object

     __proto__: Object

Normally things like that should be 'business as usual'.

But unfortunately I'm stuck with this now since two days 😞

Former Member
0 Kudos

Hi again,

I've changed now the task's input/output structure to this one (before it used the one generated from the automatic WDJ creation):


<complexType name="HandleRequestType">

  <sequence>

  <element name="Approver" type="tns:ApproverType"

    maxOccurs="1" minOccurs="1">

  </element>

  <element name="Exception" type="string" maxOccurs="1"

    minOccurs="0">

  </element>

  <element name="Initiator" type="tns:PersonType"

    maxOccurs="1" minOccurs="0">

  </element>

  <element name="Request" type="tns:RequestType" maxOccurs="1"

    minOccurs="1">

  </element>

  <element name="Requester" type="tns:RequesterType"

    maxOccurs="1" minOccurs="1">

  </element>

  <element name="Status" type="tns:StatusType" maxOccurs="1"

    minOccurs="0">

  </element>

  </sequence>

</complexType>

But even now I get an error message when trying to complete the task like that:


var outputData = {};

  var handleRequestType = odataModel.getProperty("/InputData('" + taskId

  + "')/HandleRequestType");

  var status = {};

  status.Action = "approved";

  status.ChangedBy = "TEST";

  handleRequestType.Status = status;

  outputData.HandleRequestType = handleRequestType;

  odataModel.create("/OutputData", outputData, null,

  function sendData_OnSuccess(oData, response) {

  alert("Task has been completed successfully");

  }, function sendData_OnError(oError) {

  alert("Task could not be completed");

  alert("error: " + oError);

  });

I get the following error in NWA log viewer:


[EXCEPTION]

com.sap.bpm.odata.exception.BPMODataException: Illegal argument for method call with message '__ref'.

at com.sap.bpm.odata.tm.BPMTaskDataODataSingleProcessor.createEntity(BPMTaskDataODataSingleProcessor.java:300)

at com.sap.core.odata.core.Dispatcher.dispatch(Dispatcher.java:60)

at com.sap.core.odata.core.ODataRequestHandler.handle(ODataRequestHandler.java:96)

at com.sap.core.odata.core.rest.ODataSubLocator.handle(ODataSubLocator.java:128)

at com.sap.core.odata.core.rest.ODataSubLocator.handlePost(ODataSubLocator.java:63)

at sun.reflect.GeneratedMethodAccessor6353.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

Could it be that some mandatory fields are missing?

Currently I only map the Status in my output structure.

Best regards,

Thorsten.

Former Member
0 Kudos

Hi,

I've tried some more, but unfortunately did not succeed.

This is what I see in Postman for my output data:

This is what my code looks like:


var outputData = {};

var handleRequestCompleteEventTypeOUTPUT = {};

outputData.HandleRequestCompleteEventTypeOUTPUT =

handleRequestCompleteEventTypeOUTPUT;

var context = odataModel.getProperty("/InputData('" + taskId

  + "')/ContextTypeINPUT/Context");

var status = {};

status.Action = "approved";

status.ChangedBy = "TEST";

//status.ChangedOn = "2014-07-29";

context.Status = status;

handleRequestCompleteEventTypeOUTPUT.HandleRequestCompleteEvent = context;

odataModel.create("/OutputData", outputData, null,

function sendData_OnSuccess(oData, response) {

alert("Task has been completed successfully");

},

function sendData_OnError(oError) {

alert("Task could not be completed");

}

);

The context is now read correctly from the input data (line 5).

In NWA I get the following error:


[EXCEPTION]

com.sap.bpm.odata.exception.BPMODataException: Illegal argument for method call with message '__ref'.

at com.sap.bpm.odata.tm.BPMTaskDataODataSingleProcessor.createEntity(BPMTaskDataODataSingleProcessor.java:300)

at com.sap.core.odata.core.Dispatcher.dispatch(Dispatcher.java:60)

at com.sap.core.odata.core.ODataRequestHandler.handle(ODataRequestHandler.java:96)

at com.sap.core.odata.core.rest.ODataSubLocator.handle(ODataSubLocator.java:128)

at com.sap.core.odata.core.rest.ODataSubLocator.handlePost(ODataSubLocator.java:63)

at sun.reflect.GeneratedMethodAccessor6353.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

Jocelyn_Dart
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi, Suggest you include a screenshot of the input mapping as you mention it is when reading the input data that seems to be the point of failure.

Rgds,

Jocelyn

Former Member
0 Kudos

Hi Jocelyn,

this is how the input mapping looks like:

But as I've written before, I'm able to display input data on my SAPUI5 screen (e.g. requester first/last name).

I'm just not able to complete the task.