Skip to Content
Author's profile photo Tim Chang

How to add custom BO facets to C4C Account 360 screen – Part 1

Our Cloud professional services team recently brought the customer live on Cloud for Customer project. The customer needed  to standardize their selling process and provide greater transparency to their pipeline. One key requirement was to provide visibility to sales history  from a disparate system  and to capture sales forecast all in one place. The customer had decided that they wanted to have custom data objects that could be placed into the C4C account  360 views.

The team explored the  capabilities  of using a Cloud Data Source within the Business Analytics work center;  however the customer required additional UI functionality as well as data validation rules.  Therefore, two custom objects were created.  One object was to capture Sales Actuals and the second captured Sales Budgets /Forecasts that were read only except for forecast column that could be edited.

Here is how we set out to provide this data to users –

We will describe how to develop and deploy this Sales History and Planned Sales in SAP C4C solution.

In summary, the steps are:

  1. Develop a new Work Center in C4C to manage each
    of the new business objects – Sales History BO and Planned Sales BO
  2. Develop a list UI component to display of BO in
    the Accounts Tab
  3. Implement the file input of each BO
  4. Configure the file input job in C4C

Since both the Sales History Bo and Planned Sales BOs are quite similar, our guide will focus on the steps for Sales History BO.

  1. Develop a new Work Center for Sales History.

In the SAP Cloud Applications Studio, we started with a new solution, and added a new BO.  We defined the Sales History BO as:

import AP.Common.GDT as apCommonGDT;
import AP.FO.BusinessPartner.Global;
import AP.PC.IdentityManagement.Global;
import AP.FO.ProductDataMaintenance.Global as apProdGlobal;

businessobject SalesHistory raises MsgProductErr, MsgSoldtoErr, MsgEndUserErr, MsgEmployeeErr,
                     MsgProductBlank, MsgSoldtoBlank, MsgEndUserBlank, MsgEmployeeBlank {

message MsgProductErr text “Product &1 does not exist” : ProductInternalID;
message MsgSoldtoErr  text “Sold To &1 does not exist” : BusinessPartnerInternalID;
message MsgEndUserErr text “End User &1 does not exist” : BusinessPartnerInternalID;
message MsgEmployeeErr text “SalesPerson ID &1 does not exist” : apCommonGDT:EmployeeID;

message MsgProductBlank text “Product must be filled for record &1” : ID;
message MsgSoldtoBlank text “Soldto must be filled for record &1” : ID;
message MsgEndUserBlank text “EndUser must be filled for record &1” : ID;
message MsgEmployeeBlank text “Employee must be filled for record &1” : ID;

  [Label (“Sales History Key”)]
  element SHkey : ID;
  [Label (“Fiscal Period”)]
  element fiscalper : YearMonth;
  [Label (“Calendar Period”)]
  element calendarper : YearMonth;
  [Label (“Sold To”)]
  element soldto  : BusinessPartnerInternalID ;
  [Label (“End User”)]
  element enduser  : BusinessPartnerInternalID ;
  [Label (“Product Family”)]
  element productfamily : ID ;
  [Label (“Product Category”)]
  element productcategory : ID ;
  [Label (“Product Type”)]
  element producttype  : ID ;
  [Label (“Product ID”)]
  element productID  : apCommonGDT:ProductInternalID ;
  [Label (“SalesPerson”)]
  element salesperson  : apCommonGDT:EmployeeID ;
  [Label (“Transaction Date”)]
  element transactiondate : Date;
  [Label (“Weight MT Actual”)]
  element weight_mt_act  : DecimalValue ;
  [Label (“Weight ST Actual “)]
  element weight_st_act  : DecimalValue ;
  [Label (“Revenue”)]
  element revenue_act   : Amount ;
  [Label (“Est. Avg EBITDA”)]
  element est_avg_ebitda  : Amount ;
  [Label (“Avg EBITDA”)]
  element avg_ebitda_percent  : Percent ;

    // for end-user only
  association ToEndUserCustomer to Customer;
  association ToMaterialSH to Material ;
  association ToRespEmployee [0,1] to Employee;
  association ToCustomerSH to Customer ;

  // action
  action DeleteSH ;

In the above ABSL code, we have defined the error messages needed for validation, the structure of the BO, the associations for related data in other master BOs, and an action to handle deletion of a row.

Once this BO is saved and activated, do a right-mouse click on the .BO and select Create Screens (see below).  We are using the automated screen creation to setup a full set of Work Center (WC), OWL, TT, TI and other screens with navigation fully linked and working.

The screen type we want is the Screen Scenario with Thing-Based Navigation:


Once the screens are created, be sure to activate the entire solution.

The newly created WC will provide the ability to update data in the BO, add rows and delete rows for administrative use only, especially if incorrect data was imported.   The user will not have access to this WC.

This is a good milepost to test the Sales History WC.  You can edit your user id, and add the WC.

2. Develop a list UI component to display of BO in the Accounts Tab

In the Accounts 360 screen, you can add a new facet (aka tab) by using available slots in the Studio on the Account TI screen object.  In this new facet, we can place a custom UI component – called embedded component (EC) – that displays a list of the Sales History rows.

Since the Account 360 screen is showing only 1 account, we will need to send current account ID as a parameter to theEC to retrieve only the Sales history for that account.


First, let’s build this EC, which is a list of the Sales history and will accept a parameter.

  • In the solution, we add a New Item from the Embedded Component type.


  • The object SalesHistoryEC.EC.uicomponent is added to the solution, and double-clicking on the .EC.uicomponent will bring up the UI Designer.
  • In the UI Designer, drag and drop the Advanced List Pane to the left side – into the UI box. The Advanced List Pane is available from the Toolbox.


Afterwards, it looks like this with 3 columns:

0318_3 columns.png

We update the 3 columns and add the remaining ones.

Click on the upper left corner of the list box – see below.

Click to go the Properties tab.


Click on ChildElements->ListColumns.  It brings up the Column editor – see below.


Let’s map the Column to one of the data elements in the BO.

Click on Data Information->Value->./Column – and it brings up the DependentProperty

0318 depprop.png

In the Select BO-Model prompt, select the Sales History BO.  Then select the field that this UI column maps to.

In this case, we will choose the field fiscalper which shows the fiscal period.

0318 fiscalper.png

It will prompt to use the associated Backend Text.  Click Yes.

Repeat the above association steps for the remaining 2 fields.

We will walk to add a new column and an example of showing the Product Description, available by association we defined in the BO, since the user may not be familiar with the Product ID.

Click the Addbutton.  It adds a generic named Column as shown below.

0318_more cols.png

0318_more cols.png

0318_more cols.png

Click on Data Information->Value->./Column – and it brings up the DependentProperty Editor

We look in the BO list of attributes – one of which is the ToMaterialSH, which is our gateway to the Material BO and the description text.  See below.

0318 desc.png

We continue to add the remaining fields of the BO to the EC.

As a last step, make sure all the columns are read-only by setting the Behavior->ReadOnly value to true, as shown here:

0318 readonly.png

In Part 2, we will cover how to create the query to retrieve the data list based on the customer ID – being shown in the C4C screen in context.

Please note – the associations will need some coding when each Sales record to maintain the relationship to the other master data BOs.  I leave this as an exercise for the reader.

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hi Tim,

      Great tutorial!

      Looking forward to part2 of this tutorial;-)

      Warm regards,


      Author's profile photo Tim Chang
      Tim Chang
      Blog Post Author

      Harry, thanks for your interest.

      I think I'll post it as a PDF doc.  What happens in the SCN blog authoring, is that I can't paste the diagrams so I have to export each screenshot, and re-import into the blog.  Quite tedious.

      Watch for the full document this week.

      Author's profile photo Tim Chang
      Tim Chang
      Blog Post Author
      Author's profile photo Former Member
      Former Member

      Hi Tim,

      one of the best posts I've seen so far in the scn blog which is mostly due to your english. Furthermore I really appreciated that you were trying to explain functionalities of the cloud studio application such as inport etc. That makes it a lot easier for beginners to follow your thoughts and understand the technical background of these functionalities.

      Best wishes,


      Author's profile photo Savita Arora
      Savita Arora

      Hi Tim,

      I have done the same way as you have mentioned in pdf.

      My requirement is to display current AccountID from Standard Account Screen to Custom EC. So for that in Eventhandler, before ExecuteDefaultSet I have added one more event "DataOperation" to assign datafield to ZAccountID.

      I am getting current AccountID in my custom field ZAccountID but when I click on Save, Getting Error "Save Failed".

      Can you suggest?

      Thanks in advance.



      Author's profile photo fan shuwei
      fan shuwei

      你好 张 先生

      我是国内的一名新人。手头资料特别少,想要学习SAP businessBYDesign的开发 。不知道如何学起,现在连发布都不清楚怎么实现。有没有什么可以推荐的文档或视频。现阶段想实现 标准业务的webservice的实现,希望得到你的帮助。万分感谢。