Wednesday, August 27, 2014

Connecting to SAP Cloud for Customer from a Mobile App build with SAPUI5

Recently, a colleague found this document describing a REST/OData service that is available in Cloud for Customer. Using this service, it's possible to read, create and update data in your Cloud for Customer system from other systems or applications. I started to think about a nice scenario to create a mobile app using SAPUI5I came up with the idea of an app that enables customers to view and create service requests in the Cloud for Customer system by filling in a simple form. In this blog I will describe the basic steps to connect to the cloud for customer system using odata.

1. Set up a basic SAPUI5 Mobile application.


To set-up a basic SAPUI5 mobile app, I would recommend the steps described here. The documentation that you can find there is a basic step by step guide to set up a SAPUI5 application. I created a basic app with the following screens:

  • Main Screen for the menu
  • TicketList that lists the customers service requests
  • CreateTicket to create new service requests in the Cloud for Customer system.
  • Settings screen to facilitate customer authentication (not in this example)

2. Create a service that connects to Cloud for Customer

Since the service we are talking about is an OData service, we can use the ODataModel class in SAPUI5 to connect to it:

var oModel = new sap.ui.model.odata.ODataModel(
"<your cloud for customer system>/sap/byd/odata/v1/c4c.svc/", true, "username", "password");

3. Reading Customer Information

Let's assume that the customer was already identified inside the app. Using the customer's unique id (guid) from the system, we can read the account details:

oModel.read("/CorporateAccountCollection('<ACCOUNT GUID>')",  { 
      success: function(odata,response){ 
          // handle results here 
      },
      error: function(error){ 
          //handle error here 
      }
});

The result will contain information about the account, here is a small snippet from the JSON formatted result:

Country"NL"
AddressThirdLineDescription""
AddressSecondLineDescription"Netherlands"
AddressFirstLineDescription" Den Bosch"
AdditionalName3""
AdditionalName2""
AdditionalName""
Name"Acorel"

ProspectIndicatortrue
FormattedName"Acorel"
POBox""
HouseNumber""
StreetPrefix""
StreetName""
Street2""
CityName"Den Bosch"
PostalCode""
Phone""
Fax""
Website"www.acorel.nl"
PrimaryContact"1000851"

4. Reading Service Requests

To read the customer's service requests, we have to append /ServiceRequest to the url we used to read the customer information:

oModel.read("/CorporateAccountCollection('<ACCOUNT GUID>')/ServiceRequest",  { 
        success: function(odata,response){ 
             // handle results here 
        },
        error: function(error){ 
              //handle error here 
        }


});

The result looks something like this:


ReportedByID"1000851"
RequiresWorkfalse
DistributionChannelCode"01"
SalesOrganisation"NL1200"
ChangedBy"Acorel Administrator"
CreatedBy"Acorel Administrator"
ServiceLevel""
ProductDescription""
CustomerName"Acorel"
PartnerName"Arjan Nieuwenhuizen"
ProductID""
Description"Fix email to customer"
Status"1"
AssignedToID"8000000341"

5. Creating Service Requests

I struggled a bit to get the create working. The Cloud for Customer OData service uses CSRF token validation, but the base url it uses to fetch a token from the server gives an error in the current version of Cloud for Customer (500 internal server error), so CSRF validation and creation fails. I made a small modification in the ODataModel class of SAPUI5 to get it to work again. I adjusted the refreshSecurityToken method use another url instead of the base url to get a new CSRF token. It reads one ticket from the server to get a valid response and a valid csrf token. Here's a snippet from the refreshSecurityToken method where the modification is done:

ODataModel.prototype.refreshSecurityToken = function(fnSuccess, fnError, bAsync) {
        var that = this, sUrl, sToken;
        // bAsync default is false ?!
         bAsync = bAsync === true;
        // trigger a read to the service url to fetch the token
        //sUrl = this._createRequestUrl("/");
        sUrl = this._createRequestUrl("/TicketCollection?$top=1");
        var oRequest = this._createRequest(sUrl, "GET", bAsync);




         oRequest.headers["x-csrf-token"] = "Fetch";

To create a new service request, you can use the following code snippet:

var serviceRequest = {};
serviceRequest.Type = "SRRQ";
serviceRequest.Description = "Fix machine 12121";
serviceRequest.CustomerID = "99999"; // Account/Customer Id, not the guid
serviceRequest.Priority = "1";
//etc. etc.

_modelBase.create("/TicketCollection", serviceRequest, { 
          success: function(odata,response){ 
               // handle results here 
           },
           error: function(error){ 
               //handle error here 
           },
           async: true
});

6. The final app I created

With the steps described above to get data from and to Cloud for Customer, I build a simple app that lists service request and has functionality to create a new one. Below are some screenshots of the final app I created. It's just a proof of concept that took me about 6 hours to build. I plan on expanding this app with more functionality, it might be a nice addition for our customers that are currently using Cloud for Customer.









8 comments:

  1. I am impressed, nice work there Pieter, and thanks also for the nice hint on the CSRF issue.

    Also impressive is that you made the whole app in 6 hours - less time than it took me this week to eventually realise that the sap.ui.model.odata.ODataModel class is the one to study in detail for doing an Update operation in my own demo app.

    Overall I am genuinely surprised just how well the SAPUI5-OData-GatewayBuilder framework hangs together both in DesignTime and Runtime, SAP have really put some effort into this area - makes even good ol' Webcuif suddenly seem quite wooden and staid by comparison. Hopefully SAP continue to provide more n more Odata Services in ERP and CRM, as this will reduce development effort for UI5 apps.

    ReplyDelete
  2. Or should that read: "thanks Arjan", rather than "thanks Pieter"... thanks in any case!

    ReplyDelete
  3. Thanks for the great blog! Would you please post to SCN: http://scn.sap.com/community/cloud-for-customer - or may we post a blog there that links to this blog? We have an active community there whom I'm sure would be interested in this.
    Regards
    Ginger.Gatling@sap.com

    ReplyDelete
  4. Feel free to copy with reference. :-)

    ReplyDelete
  5. Hello Sir,

    Great blog....!!!!!!!!!!!!

    Can you please help me how to connect SAPUI5 and Cloud For Customer?
    What are the steps we need to perform?

    Many Thanks,
    Mithun

    ReplyDelete
    Replies
    1. Hi Mithun,

      Can you share the steps to connect SAPUI5 and C4C if you have got the reply?


      Thanks,
      Srinivasan

      Delete
    2. Hi Mithun,

      Can you please share the steps to connect SAPUI5 an C4C?


      Thanks,
      Srinivasan

      Delete
  6. Hi Srinivas,

    The OData service url mentioned in the blog is deprecated now, but the steps to connect are still the same as described in the blog. SAP released a new OData service. To connect SAPUI5 to the new standard C4C REST/ODATA service you set up a ODataModel:

    var oModel = new sap.ui.model.odata.ODataModel(
    "https://.crm.ondemand.com/sap/c4c/odata/v1/c4codata/", true, "username", "password");

    After that you can read, create and/or update information using the standard ODataModel methods:

    For example, to read all accounts:

    oModel.read("/AccountCollection", {
    success: function(odata,response){
    // handle results here
    },
    error: function(error){
    //handle error here
    }
    });

    You can even build your own OData services now in C4C. In the silverlight client, navigate to Administrator > OData service explorer.

    You will see the OData services that SAP delivers by default in the list. To create your own, you can pick "Custom OData Services" in the dropdown list in the top left. Once that option is selected, you can create a new OData service by clicking "New".

    Regards,
    Arjan Nieuwenhuizen



    ReplyDelete