In a previously blog I described how SAP Fiori Leave Requests can be brought into Microsoft Outlook to update your calendar. In this blog I want to highlight another scenario where SAP Fiori and Outlook complement each other perfectly – SAP Fiori My Contacts for SAP ERP.
Note: There is also My Contacts for CRM, but that is not the one used in this blog.
The SAP Fiori App lets you see and edit contact details:
Wouldn’t it be nice to see this information not only through SAP Fiori but also have it available as Outlook Contacts? I will discuss how you can utilize SAP NetWeaver Gateway productivity accelerator for Microsoft to create Microsoft Outlook Contacts based on the OData service behind the SAP Fiori App.
The OData service has external name SD_MYCONTACTS and the URL for the service should look like this: http://<host>:<port>/sap/opu/odata/sap/SD_MYCONTACTS/
The service follows a master-detail pattern and contains two entity sets that are of interest here:
- ContactSet: This can be used for querying the contacts. It contains only a small subset of 4 attributes (contact key, first and last name, customer name). As expected, create and update operations are not possible for this entity set.
- ContactDetailsSet: It contains all attributes (e.g. email address, mail address, …) but is not searchable. It allows for create and update operations.
To utilize the GWPAM generation tool I can use either entity set, but no matter which one I am choosing I have the possibility to adjust the generated .NET coding to accommodate the design of this service. I will choose the ContactsDetailsSet, as I get more coding generated by the wizard (e.g. the coding for create and update).
With that out of the way, I create a new project in Visual Studio and select the GWPAM Outlook 2010 Add-in template. The GWPAM wizard launches and here I provide a template name and chose Contact as the template type. I also select the ‘New Item’ checkbox, which will generate the .NET coding to allow the end user to create new contacts directly from Outlook.
On the Service Details tab, I enter the URL and in the Collection Name dropdown list I select the ContactDetailsSet entry (as discussed above). As for the mapping instructions I map some of the following:
|Service Properties||Outlook Properties|
You will notice that the list of Service Properties contains multiple entries with the same name, which makes mapping a bit tricky. I am not going to worry about this too much, as all this can be correct in the .NET coding later. I want to place all unmapped properties on a separate screen within the Outlook Contact. This I can easily do on the Custom Properties tab.
Before I can execute my application I need to do a couple of code changes related to the master-detail design of the service. Initially the GetAllData() method coding is based on the ContactDetailsSet, which does not offer a query operation. I quickly switch this against the ContactSet. Here my sample coding:
override internal void GetAllData()
var serviceresponse = serviceContext.ContactSet.Execute() as QueryOperationResponse<SD_MYCONTACTS.Contact>;
if (token != null)
Logger.Log(Severity.Info, Categories.Outlook_GetAll, “Executing next token query for ContactSet”);
serviceresponse = serviceContext.Execute<SD_MYCONTACTS.Contact>(token);
foreach (SD_MYCONTACTS.Contact contactEntity in serviceresponse)
ContactItem outlookItem = null;
UserProperties userProperties = null;
UserProperty userProperty = null;
string propertykey = “”;
// Read additional details (or alternatively use the $expand option for better performance)
string contactKey = contactEntity.ContactKey;
string relativeUrl = “ContactSet(‘” + contactKey + “‘)/ToContactDetails”;
SD_MYCONTACTS.ContactDetails entity = (serviceContext.Execute<SD_MYCONTACTS.ContactDetails>(new Uri(relativeUrl, UriKind.Relative))).FirstOrDefault();
Also since my mapping was a bit of a guess, I also clean up the mapping in method MapEntityToStandardFields(). Here my sample mapping:
private static void MapEntityToStandardFields(SD_MYCONTACTS.ContactDetails entity, ContactItem outlookItem)
Logger.Log(Severity.Verbose, Categories.Outlook_StarterKit, “Fiori_My_ContactsBusinessApplication::MapEntityToStandardFields()”);
outlookItem.MobileTelephoneNumber = entity.MobileMain;
outlookItem.MailingAddressState = entity.RegionMain;
outlookItem.LastName = entity.LastName;
outlookItem.JobTitle = entity.JobFunction;
outlookItem.FirstName = entity.FirstName;
outlookItem.Email1Address = entity.EmailMain;
outlookItem.Department = entity.Department;
outlookItem.CompanyName = entity.CustomerName;
outlookItem.BusinessTelephoneNumber = entity.PhoneMain;
outlookItem.BusinessFaxNumber = entity.FaxMain;
outlookItem.BusinessAddressStreet = entity.StreetMain;
outlookItem.BusinessAddressPostalCode = entity.PostalCodeMain;
outlookItem.BusinessAddressCountry = entity.CountryMain;
outlookItem.BusinessAddressCity = entity.CityMain;
With very little coding changes, now I am ready to fetch data from Outlook. I click on the GetAll button to trigger the query operation and for each entity in the result set I get a new Outlook Contact, containing information taken straight out of the ERP system.
These contacts correspond to the ones you see in the SAP Fiori App. The screenshot below shows a contact and all the mapped data coming from ERP. The unmapped information can be accessed via the Contact Details User Properties tab:
Create and Update
The underlying OData service also provides the capabilities to create and update contacts. The coding generated by the GWPAM wizard already contains much of the required .NET coding to facilitate create and update operations.
Nevertheless I have to do some more coding in order to get them to work properly. One of the tasks I have to accomplish is the formatting and validation of the data prior to submitting it to SAP. For example: Instead of submitting a department name, the OData service expects a department key. Fortunately the OData service provides additional entity sets that let me look up key values (e.g. for department or job function).
With a small development effort you will be able to provide a beautiful and easy to use Outlook Add-in offering similar functionality as the SAP Fiori App right from within Outlook. With the help of GWPAM, you will get a head-start into your development process by providing you with generated coding. GWPAM lets you focus on programming the business logic and shields you from low-level task like handling of authentication, logging and tracing.