In this blog we will cover:
Introduction:
The CDS hierarchy in SAP ABAP is used to define recursive, tree-like relationships in data directly within Core Data Services (CDS) views. It allows structured, hierarchical data (like manager-employee, material categories, sales orgs, BOMs, etc.) to be represented and consumed easily in UI applications and analytics tools.
In the RAP (RESTful ABAP Programming Model), a Tree View is used to visualize hierarchical (recursive) data structures in the UI—typically in Fiori Elements apps such as List Reports with tree tables.
Tree View allows end users to navigate data in a parent-child format (e.g., managers → employees, sales org → region → country).
├── Region North America
│ ├── Country USA
│ └── Country Canada
└── Region Europe
├── Country Germany
└── Country France
To enable a Tree View in a RAP app:
Treeviews: Architecture Overview
The implementation of a treeview in the ABAP RESTful Application Programming Model (RAP) requires different entities depending on whether the treeview should be read-only or editable.
Architecture Overview: Read-Only Treeview
Architecture Overview: Read-Only Tree View in CDS
Architecture Overview: Editable Treeview with Draft
Editable Tree View with Draft Enablement – Architecture Overview
Database table:
CDS view Entities (Interface Views):
CDS Hierarchy:
Base CDS views:
Behaviour Definition for base views:
Projection views:
Projection behaviour definition:
Service Definition and Service Binding:
===========================================================================
Scenario for Tree view in RAP:
In large global companies, the Sales & Distribution (SD) module often reflects the company's organizational structure. Typically, Sales Organizations are arranged in a multi-level hierarchy like this:
This kind of structure helps companies manage sales performance, reporting, and operations more effectively.
However, many systems don’t provide a read-only, easy-to-use view of this hierarchy — especially in a tree or drill-down format that users can easily navigate.
In this blog, we’ll walk through how to model and expose this Sales Org hierarchy using CDS Hierarchies, and finally expose it through an OData service to be consumed in a Fiori UI.
Procedure:
Step 1: Define the Base Table - ZVS_DT_SALES
This transparent table stores the core sales organization data including parent-child relationships.
@EndUserText.label : 'Hierarchy: Read Only: Sales Organization'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zvs_dt_sales {
key client : abap.clnt not null;
key sales_org_id : abap.char(6) not null;
name : abap.char(50);
region : abap.char(20);
country : abap.char(3);
@Semantics.amount.currencyCode : 'zvs_dt_sales.currency'
revenue : abap.curr(21,2);
currency : /dmo/currency_code;
parent_sales_org : abap.char(6);
}
Note: parent_sales_org is a self-referencing field to represent the hierarchy.
This table contain some records:
Step 2: Interface View - ZVS_I_SALES
This CDS view represents the Sales Org data and defines a self-association to establish the parent-child link.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface View: Sales Organization'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity zvs_i_sales as select from zvs_dt_sales
association to zvs_i_sales as _Parent on
$projection.ParentSalesOrg = _Parent.SalesOrgId
{
key sales_org_id as SalesOrgId,
name as Name,
region as Region,
country as Country,
@Semantics.amount.currencyCode: 'Currency'
revenue as Revenue,
currency as Currency,
parent_sales_org as ParentSalesOrg,
_Parent
}
Step 3: Define Hierarchy - ZVS_I_SALES_HN
Using CDS hierarchy syntax, we now define a parent-child recursive hierarchy.
@EndUserText.label:'Sales Organization Hierarchy'
define hierarchy zvs_i_sales_hn
as parent child hierarchy (
source zvs_i_sales
child to parent association _Parent
start where ParentSalesOrg is initial
siblings order by SalesOrgId ascending
)
{
key SalesOrgId,
ParentSalesOrg
}
This is where the magic happens. This hierarchy enables a recursive structure that can be rendered in Fiori Tree controls.
Step 4: Projection View - ZVS_C_SALES
This is the final consumption layer that will be exposed as OData. The hierarchy is referenced using the @OData.hierarchy.recursiveHierarchy annotation.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Projection View: Sales Organization'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality:#X,
sizeCategory:#S,
dataClass:#MIXED
}
@Metadata.allowExtensions:true
@Search.searchable:true
@OData.hierarchy.recursiveHierarchy: [{ entity.name: 'zvs_i_sales_hn' }]
define view entity zvs_c_sales as select from zvs_i_sales
association of many to one zvs_c_sales as _Parent
on $projection.ParentSalesOrg = _Parent.SalesOrgId
{
key SalesOrgId,
@Search.defaultSearchElement: true
Name,
Region,
Country,
@Semantics.amount.currencyCode: 'Currency'
Revenue,
Currency,
ParentSalesOrg,
/* Associations */
_Parent
}
Screenshot:
Metadata extension:
@Metadata.layer: #CORE
annotate entity zvs_c_sales with
{
@UI: {lineItem: [{ label: 'Sales org ID', position: 10 }],
identification: [{ label: 'Sales org ID', position: 10 }]
}
SalesOrgId;
@UI: {lineItem: [{ label: 'Sales org Name', position: 20 }],
identification: [{ label: 'Sales org Name', position: 20 }]
}
Name;
@UI: {lineItem: [{ label: 'Region', position: 30 }],
identification: [{ label: 'Region', position: 30 }]
}
Region;
@UI: {lineItem: [{ label: 'Country', position: 40 }],
identification: [{ label: 'Country', position: 40 }]
}
Country;
@UI: {lineItem: [{ label: 'Revenue', position: 50 }],
identification: [{ label: 'Revenue', position: 50 }]
}
Revenue;
@UI: {lineItem: [{ label: 'Currency', position: 60 }],
identification: [{ label: 'Currency', position: 60 }]
}
Currency;
@UI: {lineItem: [{ label: 'Parent Sales org ID', position: 70 }],
identification: [{ label: 'Parent Sales org ID', position: 70 }]
}
ParentSalesOrg;
}
Step 6: Service Binding - ZVS_C_SALES_ORG_V4
If you will choose service binding type as V2, So you will get one error:
So select your Binding type as V4,
Now preview your application:
Conclusion:
Using CDS views and hierarchies in SAP S/4HANA is a simple and effective way to show the Sales Organization structure in a clear, tree-like format. It helps sales managers easily understand how different sales units are connected and how each one is performing. This setup is read-only, so the data stays safe, and it works well with Fiori apps for a smooth user experience.
Overall, this approach makes reporting and analysis easier without needing a lot of custom coding.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
8 | |
5 | |
4 | |
3 | |
3 | |
3 | |
3 | |
2 | |
2 | |
2 |