Вы находитесь на странице: 1из 14

Saturday, May 26, 2018 8:11 AM

An efficient search is one of the most important feature required in an application. This is what
allows us to find objects that we want to work on.

In this 2-part blog, me and my colleague Rajesh Khatwa would like to share our experience of
implementing search functionality for a custom object built on top of S/4HANA. We used tools
and technologies provided out of the box in S/4HANA to minimize the development effort.

Pre-requisite :
Basic knowledge of Odata and CDS .

Requirement:
Before getting all technical, let's see what was the motive behind designing the search this way.

A new custom master data object is developed with numerous attributes - both at header level
as well as item level. In addition, it is linked to another custom master data object using foreign
key relationship.

The requirement is that the application should be able to perform the search and list the results
in a list.
The search should support below capability:
1. Ability to specify filter criteria on any number of object attributes
2. Ability to specify sort criteria on any number of object attributes
3. Ability to specify group criteria to show the results in list in a tree like format supporting
multi-level grouping
4. Ability to select attributes which should be displayed in result list
5. Ability to further filter result list using a free text search string (without specifying a
particular object attribute)

Filter Area Sort Criteria Group Criteria Select Attributes Search List area with free text search box

Search Implementation:
A typical S/4HANA application is built with SAP Fiori as user interface with REST based APIs (in
our case OData) calls to backend server to get /post required information.

Since the UI was built as per mock-ups using standard and custom Fiori controls, we will focus
more on how the ODATA was design and implemented to provide required results to UI layer.

Development Summary:
A search is essentially a SELECT statement on database.
To enable this, we would create S/4HANA Virtual Data Model (VDM) for our custom object.
Essentially, these will be ABAP Core Data Services that will select the data from required
database tables. We would then create a ODATA Service and map its implementation directly to
a CDS. This Service Implementation would be implemented using standard layer called SADL
(Service Adaption Definition Language). This layer will automatically take the filter/sort criteria
from ODATA parameters and convert them to corresponding SQL statement.

One important aspect here is that UI would be implemented in a such a manner that only those
object attributes which are selected to be displayed in Search List, would be passed to ODATA
parameters. This essentially means that only these fields will be selected using SQL from
database and returned to UI. This greatly improves the performance.

Let's have a look at these steps in detail.

Step 1: Creating VDM for custom object

The first step is to create a Virtual Data Model for your custom object.
This includes creating a CDS view for each of your database tables and create required
associations between them. If you are using standard master data in your object like Company
Code or Unit of Measurement, create associations with standard CDS provided by SAP as well.

Example:
Let's assume that we have below Database tables in which object data is stored:
• ZOBJHDR (Header table)

Blog Page 1
• ZOBJITM (Item table)

`
A typical VDM for above database would involves creating CDS as below:
1. An interface CDS ZI_ObjHeader on top of table ZOBJHDR with associations to other CDS
(like Text Associations or associations with foreign key relationships to objects like
Company Code, Sales Organization).

Blog Page 2
2. An interface CDS ZI_ObjItem on top of table ZOBJITM with foreign key association to
ZI_ObjHeader

3. An interface CDS ZI_Object on top of CDS ZI_ObjHeader with exposed associations to


ZI_ObjItem and ZI_ObjHeader

Blog Page 3
Step 2a: Create List CDS

Once we have a VDM created for our custom object, we next move to create a CDS specific for
object search.

Create a new Consumption CDS ZC_ObjList on top of CDS ZI_Object with all fields in field section
of ZI_Object and any exposed associations. Furthermore, based on need, additional fields can be
added to this CDS as needed on Search List UI. For e.g. In our implementation, we added Date
fields by converting them from Timestamp fields.

Blog Page 4
Step 2b: Create Expanded CDS

All the CDS created till now have exposed associations so that data is selected from associated
CDS only when fields are actually required from them. These will be basis of our selection from
database (more on that later). However, we still need a structure which has all the possible
object attributes which can possibly be part of Search List (or can have Filter, Sort, or Group on
them). These can be either directly from header or from item/subitem or from other objects
linked using foreign key associations.
To do so, create a new Consumption CDS ZC_ObjListExpanded on top of CDS ZC_ObjList. Include
all possible fields, either coming directly from ZC_ObjList or from exposed associations. There
would be no exposed associations in this CDS.

Blog Page 5
Step 3: Create a SAP Gateway project having OData Entity using the Expanded CDS

Create a new SAP Gateway project 'Z_OBJECTS' . Right click on Data Model->Import->DDIC
Structure . Create the Entity ' ObjectList' and Entity Set 'ObjectListSet' using the DDIC Structure
'ZV_OBJ_EXP'.
'ZV_OBJ_EXP' is the SQL view generated from the CDS 'ZC_ObjListExpanded'.

Blog Page 6
Click Next , Select all the properties and Finish.
Thus, our ODATA Entity would now have all possible object attributes.
Adjust the Entity Labels or Description as needed.

GeneratedId : In order to support Group By feature, OData service must provide a dedicated key
since the natural keys of the business entity are not usable in aggregated results.
Use of GeneratedId is explained in Mark the Properties as Dimension
For now , in the Entity Type 'ObjectList' add a property for the unique identifier of the returning
results. The name of the property can be freely chosen. The type of the property must be
Edm.String and this property needs to carry the ABAP field name ‘GENERATED_ID’. This should
be the only Key property in the OData entity.

You will receive an error on activation.

We need to add this field in our CDS view 'ZC_ObjListExpanded' and mark it as Key Field.

Activate the Gateway Project.

Step 4: Map the Service Implementation of OData Entity to List CDS

In your SAP Gateway project, expand node Service Implementation -> ObjectListSet. Right-click
on entity set and choose "Map to Data Source".

Choose Type 4 Business Entity and press F4 in the field 'Name'. Choose SADL Model Type CDS
and SADL Model : ZC_ObjList.
Please note that for the creation of the Odata properties, we had used the SQL view generated
from the CDS ZC_ObjListExpanded but while mapping the data source we are using CDS
ZC_ObjList.

ZC_ObjListExpanded was used for Odata properties creation, since we want all the fields from
Header as well as Item , to be shown in a single table on UI.

Drag and drop the elements of the mapped Business Entity ZC_ObjList to the mapping table.

Blog Page 7
Drag and drop the elements of the mapped Business Entity ZC_ObjList to the mapping table.
The property 'Genereatedid' does not need any mapping information. Leave the mapping
element empty.

Register the service 'Z_OBJECTS_SRV' generated using Transaction Code :


/IWFND/MAINT_SERVICE.

Step 5: Enhance the OData Metadata in MPC_EXT class

To enhance the metadata of the entity , redefine the method , 'Define' of the class
ZCL_Z_OBJECTS_MPC_EXT. To determine the classes generated for the entity, check the
Runtime artifacts node in the Entity .

Mark the properties as Hidden :

The CDS Annotation to mark the property as hidden is @Consumption.hidden: true.

Redefine the "Define" method of the Class ZCL_Z_OBJECTS_MPC_EXT, and read all the fields
from the corresponding CDS which are annotated as @Consumption.hidden: true and the set
those property as Invisible by marking the property as "Technical".
In our example, we have marked fields GeneratedId & DBKey as hidden in CDS
ZC_ObjListExpanded,

Redefine the method "Define" as shown :

Blog Page 8
Read all the Annotations of the CDS ZC_ObjListExpanded by calling method GET_ANNOS for the
class CL_DD_DDL_ANNOTATION_SERVICE.
Delete the annotations which are not @Consumption.hidden or if @Consumption.hidden then
the value is not equal to "true".

Get all the properties of the entity "ObjectList" and then mark all the properties, which are
marked as @Consumption.hidden = true in the CDS as invisible in the Odata by calling method
IS_TECHNICAL of the class CL_FIS_FILTER_ANNOTATION.

The metadata generated will have properties "Generatedid" and "Dbkey" annotated with
sap:visible ="false".

Mark the Properties as Non-Negative:


There is no Edm Core type for NUMC. The properties needs to be defined as Edm.String for
NUMC type properties also . For Example, for Objectid property the Edm type is Edm.String.

On Fiori screen, any string data can be entered in Objectid field. In order to allow only non-
negative numeric values in Objectid, can use the annotation .

In the "Define" method , set the display-format as "NonNegative". "NonNegative" indicates that
only non-negative numeric values are provided and persisted, other input will lead to errors.
Intended for Edm.String fields that are internally stored as NUMC.

The metadata generated will have property "Objectid" annotated with sap:display-
format="NonNegative".

Blog Page 9
Mark the Properties as Date:

The Edm core type for Date fields is "Edm.DateTime". The same core type is used for the
timestamps also . In order to distinguish TimeStamp type properties with "Date" type
properties , we need to annotate the property with sap:display-format="Date". “Date” indicates
that only the date part of an Edm.DateTime value is relevant

The Edm Core Type for properties "Validfromdate" and "Validtodate" is "Edm.DateTime".

Enhance the Define method for the properties "Validfromdate" and "Validtodate" as shown .

The metadata generated will have properties annotated with sap:display-format="Date".

Mark the Properties as Dimension :


In order to support Group By feature , we must have :
1. "Generatedid" field as a key property.
2. Maintain the analytical role for the entity types that carry aggregation information, and
also maintain this role for their dimensions and measures.

Enhance the Define method to set aggregation role at the Entity Level and at the Property Level.
All the properties except "Volume" would be set as Dimension and "Volume" would be set as
"Measure".

Blog Page 10
In the metadata, aggregation role is set at the Entity level .

Aggregation role for Property "Volume" is set as "Measure".

Maintain Value-Helps:

In order to link value-help with the "Object Type" field in the entity "ObjectList" , we need
to create two tables :
ZOBJ_TYPE : Master table for Object types

ZOBJ_TYPE_TEXT : Text table for Object types.

Blog Page 11
Create Interface CDS Views "ZI_ObjectTypes" and "ZI_ObjectTypesTexts" on top of the
database tables ZOBJ_TYPE,ZOBJ_TYPE_TEXT .

Create consumption view "ZC_ObjectTypes" on top of Interface view "ZI_ObjectTypes" .

In the Odata gateway project "Z_OBJECTS" , select the node "Data Model" and right click and
select

Enter the Consumption CDS "ZC_ObjectTypes" created for the value help for Object Types.

Blog Page 12
Click Next and Finish.

New Data Source Reference would be created in the Gateway Project.

We need to link "Objecttype" field of the entity "ObjectList" with the Value list entity set
"ZC_ObjectTypes" that we have just created .

We need to enhance the "Define" method to link the value-list with the property.

The metadata generated will have the information to denote that value-list for the property
"Objecttype" is ZC_ObjectTypes.

a.) The entity type "ZC_ObjectTypesType" is marked as value-list using the


annotation ,sap:value-list="true".

b.) The entity Set "ZC_ObjectTypes" is set as the value-list for the property "Objectype".

c.) The property "Objecttype" is annotated as ,sap:value-list="standard" to denote that it has


value-help associated with it.

If we want the property "Objecttype" as Drop-down instead of F4, then we need to enhance
"Define" method .

Blog Page 13
The property "Objecttype" is annotated as ,sap:value-list="fixed-values" to denote that it has
drop-down associated with it.

_______________________________________________________________________________
_______________________________________________________________________________
_______________________________________________________________________________
___

PART 2 start from here

Step 6: Enhance the OData Implementation in DPC_EXT class

Interesting Finds:

Blog Page 14

Вам также может понравиться