ABAP Development for SAP S4HANA (SAP PRESS) (第5页)

第 109 页 / 共 465 页

3.4 Service Adaptation Description Language

Figure 3.16 Adding a New OData Service to the Service Catalog

3.4 Service Adaptation Description Language

One of the core technologies enabling the ABAP programing model for SAP Fiori is

the Service Adaptation Description Language (SADL). It provides two main function-

alities in this context:

(cid:2) At design time, SADL supports the model-based creation of an OData service based

on a CDS data model.

(cid:2) At runtime, the OData runtime delegates incoming requests for OData entities to

the SADL adapter, which dynamically generates SQL SELECT statements to select

the business data via CDS views or further delegates the requests to the transac-

tional BOPF runtime if write access is required.

With this, SADL supports two of the three phases required for developing an OData

service:

(cid:2) Data model definition (supported by SADL)

(cid:2) Service implementation (supported by SADL)

(cid:2) Service maintenance

109

第 110 页 / 共 465 页

3 ABAP Programing Model for SAP Fiori

3.4.1 Data Model Definition Phase

The aim of this OData service development phase is to provide potential clients of the

service with information about the service’s shape, for instance, the structure of its

entities, their relationships, and the supported operations. This information is pro-

vided in the form of a service metadata document in Extensible Markup Language

(XML). In the data model definition phase, SADL creates a mapping of CDS entities to

an OData Entity Data Model (EDM) and populates the MPC of the OData implementa-

tion with information derived from the CDS model structure. Additionally, CDS view

field data types are mapped to EDM primitive data types; for instance, the ABAP dic-

tionary built-in type DATS is mapped to the EDM.DateTime data type. Moreover, if trans-

actional processing is enabled for CDS entities via the creation of a BOPF business

object, BOPF actions will appear as OData function imports in the service metadata

document. Table 3.2 provides an overview of the mappings from CDS concepts to

OData concepts performed by SADL.

CDS OData

CDS view (DDL) EDM entity

CDS associations EDM association

CDS view field data type EDM primitive data type

BOPF actions Function import

Table 3.2 Mappings between CDS Data Model Concepts and OData EDM Concepts

Figure 3.17 shows how the service metadata document will look for the simple sce-

nario introduced in Chapter 1. As you remember, the purchase document CDS view

(Z_PurchasingDocumentDDL) had an association to the purchase document items view

(Z_PurchasingDocumentItemDDL). Both views now appear as OData entity types in the

OData service’s metadata document, including the information about the associa-

tion between the two entities and their cardinalities. Which operations an entity sup-

ports is indicated by the sap:creatable, sap:updatable, and sap:deletable attributes

of the EntitySet element. In the following example, you can see that the service

doesn’t support any write access at all, as we haven’t enabled the transactional run-

time for our CDS model by generating a BOPF business object. Thus, the service only

supports read access via HTTP GET entity requests. As already mentioned, the meta-

data file of an OData service can be requested using the $metadata path, /sap/opu/

odata/sap/<OData_service_name>/$metadata.

110

CDS OData
CDS view (DDL) EDM entity
CDS associations EDM association
CDS view field data type EDM primitive data type
BOPF actions Function import

第 111 页 / 共 465 页

3.4 Service Adaptation Description Language

Figure 3.17 XML Service Metadata Document of the Simple CDS Scenario from Chapter 1

Exposed as an OData Service

3.4.2 Service Implementation Phase

In the previous data model definition phase, SADL maps the CDS data model to an

OData EDM and creates a static service definition. At runtime, SADL also takes care of

processing the OData requests performed by clients. The OData runtime delegates

OData requests to the generic SADL query engine, which generates SQL SELECTS on

CDS views based on the request parameters ($select, $top, $filter, etc.) and the

requested OData entity.

An incoming OData request for the standard purchase order basic view entity might

look like Listing 3.2.

GET I_PurchaseOrderEntity?$select=

PurchaseOrder,PurchaseOrderType,PurchasingOrganization,PurchasingGroup,Purchas

eOrderDate&$top=10&$orderby=PurchaseOrderDate asc&$filter=

111

第 112 页 / 共 465 页

3 ABAP Programing Model for SAP Fiori

( PurchaseOrderDate ge datetime'2018-01-

01T00:00:00' and PurchaseOrderDate le datetime'2018-12-31T00:00:00')

Listing 3.2 OData GET Request for the I_PurchaseOrderEntity OData Entity

The SADL framework will then transparently transform this request into an SQL

SELECT statement on the I_PurchaseOrder CDS view (Listing 3.3).

SELECT

PurchaseOrder,

PurchaseOrderType,

PurchasingOrganization,

PurchasingGroup,

PurchaseOrderDate

FROM

I_PurchaseOrder

WHERE

PurchaseOrderDate GE '20180601'

AND PurchaseOrderDate LE '20180601'

ORDERBY

PurchaseOrderDate ASCENDING

UP TO 10 ROWS

Listing 3.3 Generated SQL SELECT for the OData GET Request

When you compare the OData request and the generated SQL statement, you can see

that OData queries can easily be pushed down to a relational database as OData

already resembles SQL, and all OData parameters can be mapped to a certain part of

the SQL SELECT statement. This property makes OData the perfect candidate for

exposing business entities over HTTP because easy transformation of HTTP requests

to SQL SELECT statements promotes the Code-to-Data paradigm of SAP HANA and

prevents unnecessary data processing on the ABAP server. Table 3.3 shows the map-

pings between OData parameters and SQL query parts.

OData Parameter SQL

$select SELECT

$top UP TO n ROWS

Table 3.3 Mapping between OData Parameters and Corresponding Parts of an SQL SELECT

Statement

112

OData Parameter SQL
$select SELECT
$top UP TO n ROWS

第 113 页 / 共 465 页

3.5 Business Object Processing Framework

OData Parameter SQL

$orderby ORDERBY

$filter WHERE

Table 3.3 Mapping between OData Parameters and Corresponding Parts of an SQL SELECT

Statement (Cont.)

3.5 Business Object Processing Framework

The Business Object Processing Framework (BOPF) is an ABAP framework that consti-

tutes the transactional runtime of an application in the ABAP Programming Model

for SAP Fiori. As soon as an application requires write actions such as CUD, a BOPF

business object must be generated from the CDS data model, which will take over the

transactional part of the app. Currently, four transactional scenarios are supported,

as discussed in the following subsections.

3.5.1 Read-Only Application with Quick Actions

In this case, you don’t want to enable full create, write, and delete access but only

enable a quick action, for instance, for changing the status of the business object. A

BOPF business object for this scenario can be generated by annotating the root view

of the CDS model with annotations on the header level as shown in Listing 3.4.

@ObjectModel: {

transactionalProcessingEnabled: true,

compositionRoot: true,

writeActivePersistence: '<SQL View>',

createEnabled: false,

updateEnabled: false,

deleteEnabled: false

}

Listing 3.4 Required Annotations for Generating a BOPF Business Object to Implement

Quick Actions

(Re)activation of the view will lead to the generation of a BOPF business object, and

Quick Actions can be implemented in ABAP for the respective BOPF node. We also

113

OData Parameter SQL
$orderby ORDERBY
$filter WHERE

第 114 页 / 共 465 页

3 ABAP Programing Model for SAP Fiori

must provide an active persistence using the writeActivePersistence annotation.

However, in this case, because we don’t allow standard (CUD) access, it will only be

used for field mappings between CDS and BOPF.

Note

When exposing a CDS view as an OData service using Auto-Exposure or the RDS sce-

nario, SADL takes the createEnabled, updateEnabled, and deleteEnabled CDS anno-

tations into account and maps them to OData entity set attributes. For instance, if

the CDS view doesn’t enable write access or doesn’t have a linked BOPF business

object at all, the respective OData entity set will have the attributes sap:creatable=

”false”, sap:updatable=”false”, and sap:deletable=”false”.

3.5.2 New Application without Draft

If we also want to enable standard generic CUD access for our application, we must

set the createEnabled, updateEnabled, and deleteEnabled annotations to true (Listing

3.5). Furthermore, we must provide the database table in which the data must be per-

sisted in using the writeActivePersistence annotation.

@ObjectModel: {

transactionalProcessingEnabled: true,

compositionRoot: true,

writeActivePersistence: '<ActivePersistenceName>',

createEnabled: true,

updateEnabled: true,

deleteEnabled: true

}

Listing 3.5 Required Annotations for Full CUD BOPF Support

In this case, BOPF will generically handle CUD operations. If we want to enhance the

standard generic transaction logic, we can provide BOPF actions, validations, or

determinations for the respective node of the BOPF business object. However, if we

want to reuse existing legacy ABAP CUD implementations containing complex busi-

ness logic, the next scenario is better suited.

114

Note When exposing a CDS view as an OData service using Auto-Exposure or the RDS sce- nario, SADL takes the createEnabled, updateEnabled, and deleteEnabled CDS anno- tations into account and maps them to OData entity set attributes. For instance, if the CDS view doesn’t enable write access or doesn’t have a linked BOPF business object at all, the respective OData entity set will have the attributes sap:creatable=
”false”, sap:updatable=”false”, and sap:deletable=”false”.

第 115 页 / 共 465 页

3.5 Business Object Processing Framework

3.5.3 Draft-Enabled Application

In this scenario, data isn’t immediately written to the standard active database tables

but is stored in a draft table. This scenario is very well suited for legacy applications

that already consist of database tables and ABAP CUD code, including complex busi-

ness logic. We can enable the old database tables for SAP HANA optimized read access

by providing CDS views on top of the legacy database tables and still reuse the legacy

ABAP code when activating a draft. Activating in this context means transferring the

data from the intermediary draft table to the actual table. To do this, the BOPF busi-

ness object root node will provide an adapter (/bobf/if_frw_draft~copy_draft_to_

active_entity) that must be implemented by the developer and maps the draft repre-

sentation of the data to the legacy signature of the ABAP code to write the data into

the legacy database tables. The required annotations for generating the draft infra-

structure are shown in Listing 3.6.

@ObjectModel: {

transactionalProcessingEnabled: true,

compositionRoot: true,

draftEnabled: true;

writeDraftPersistence: '<DraftPersistenceName>',

createEnabled: true,

updateEnabled: true,

deleteEnabled: true

}

Listing 3.6 Required Annotations for Generating the BOPF Draft Infrastructure for a Legacy

Application with an Existing Persistence

3.5.4 New Application with Draft

In this scenario, we provide new tables for draft and active entities (Listing 3.7). As in

the previous scenario, data will be stored in intermediary draft tables and only writ-

ten to the active persistence on explicit activation of the entity. However, in this sce-

nario, BOPF will completely take over the transactional processing. We can only

enhance the data processing by adding BOPF actions, validations, or determinations

to the respective nodes of the BOPF object. This scenario is only suited for new appli-

cations. If legacy tables and ABAP CUD code will be reused, this scenario isn’t the right

choice.

115

第 116 页 / 共 465 页

3 ABAP Programing Model for SAP Fiori

@ObjectModel: {

transactionalProcessingEnabled: true,

compositionRoot: true,

draftEnabled: true;

writeDraftPersistence: '<DraftPersistenceName>',

writeActivePersistence: '<ActivePersistenceName>'

createEnabled: true,

updateEnabled: true,

deleteEnabled: true

}

Listing 3.7 Required Annotations for Generating the BOPF Draft Infrastructure for a New

Application

3.6 SAP Fiori

The open access to backend business data via OData and SAP Gateway enables the use

of modern non-ABAP UI technologies for displaying and interacting with business

data. The UI of applications developed using the ABAP programming model for SAP

Fiori is therefore completely based on the SAPUI5 framework, which implements the

SAP Fiori design. The UI part of applications is usually implemented using the cloud-

based SAP Web IDE and is either based on SAP Fiori elements applications or freestyle

applications. SAP Fiori elements applications, for instance, the list report and object

page templates or floorplans, adapt their layouts based on the OData service’s meta-

data and UI annotations defined in CDS views or their respective metadata exten-

sions. Therefore, SAP Fiori elements templates significantly reduce the necessary

frontend SAPUI5 JavaScript code to a minimum and increase developer productivity

significantly by still providing flexibility using predefined extension points in the

frontend.

Additionally, transparent to the developer, the SAP Fiori elements applications

implement the necessary CRUD request handling for read-only, draft-enabled, and

non-draft-enabled applications, depending on which BOPF scenario has been anno-

tated, generated, and implemented in the backend. Freestyle applications, in contrast

to SAP Fiori elements, provide the frontend developer with full flexibility over the UI

design and logic but require a lot of effort in the development phase. The UI layout

and its controls must be declared manually by the developer, and the necessary

SAPUI5 JavaScript logic must be implemented. Therefore, it’s not recommended to

116

第 117 页 / 共 465 页

3.7 Summary

use complex draft-enabled BOPF scenarios with freestyle applications because the

orchestration of the necessary requests might become too complicated. Moreover,

another risk when developing freestyle applications is the violation of SAP Fiori

design guidelines. Consequently, only use freestyle applications when the required

UI design isn’t realizable using one of the SAP Fiori elements floorplans.

3.7 Summary

In this chapter, we gave you an overview of the ABAP programing model for SAP Fiori

and its associated technologies. We started with CDS, which are at the center of any

application development for SAP S/4HANA. They are the foundation for all applica-

tion types and can be configured for different application types using domain-spe-

cific UIs, analytics, search annotations, or transactional annotations. Next, we looked

at SAP Gateway and OData as the technologies enabling easy network-based access to

business data stored in SAP NetWeaver backend systems. Then we explored SADL

and how it supports providing model-based read and transactional access to CDS

entities via OData. The BOPF constitutes the transactional runtime of the ABAP pro-

gramming model for SAP Fiori and enables ABAP-based CUD operations for data

models based on CDS views. It provides several scenarios for different application

requirements, which we briefly listed and described.

117

第 118 页 / 共 465 页

第 119 页 / 共 465 页

PART II

Developing Applications for SAP S/4HANA

第 120 页 / 共 465 页

第 121 页 / 共 465 页

Chapter 4

Developing an SAP Fiori Elements

List Report and Object Page

In this chapter, you’ll learn to create your first SAP Fiori elements

applications: a list report and object page. We’ll illustrate the end-to-

end development process in detail with step-by-step instructions.

You’ll create database tables and Core Data Services (CDS) views, gen-

erate a Business Object Processing Framework (BOPF) object for trans-

actional processing, add user interface (UI) elements, and create an

OData service—building both the backend and the frontend of the

application.

We’ll use the business scenario and design developed in Chapter 2, Section 2.4.3, to

create an application for managing purchase documents. As a reminder, the applica-

tion design consisted of a list report displaying purchase documents in a table and an

object page providing detailed information for a purchase document, including its

individual purchase document items. Moreover, some purchase documents might

require approval, which can be granted using a quick action.

Using this business scenario, we’ll provide you with an end-to-end development

guide for developing list report and object page applications based on the ABAP pro-

gramming model for SAP Fiori.

4.1 Core Data Services Views

In this section, you’ll learn how to create a layered CDS data model according to the

SAP S/4HANA Virtual Data Model (VDM) modeling guidelines, including unit tests

for calculated field values using ABAP Unit and the CDS Test Double Framework.

Before we can start the development, we first must install the ABAP development

121

第 122 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

tools because Eclipse is the standard integrated development environment (IDE) for

developing CDS views and modern ABAP code. We then start the development of the

app from the bottom up by first introducing the data model and its database tables.

Based on this, we’ll create several layers of CDS views beginning with the basic inter-

face layer as a simple projection layer on top of the database tables. Using the basic

interface view layer as the basis, we’ll incrementally add more application-specific

views and calculations, including tests.

4.1.1 ABAP Development Tools in Eclipse

For developing state-of-the-art ABAP applications based on the ABAP programming

model for SAP Fiori, it’s no longer possible to use the classic ABAP Development

Workbench, accessible via Transaction SE80, because the development of CDS-based

data models isn’t supported with the old development tools anymore. Therefore,

developers must get a recent version of Eclipse, for instance, Eclipse Oxygen (IDE for

Java Developers) from the Eclipse Foundation’s website and subsequently install the

ABAP development tools frontend as an Eclipse plug-in. To do this, you must open

the Help menu of Eclipse and choose Install New Software (Figure 4.1).

Figure 4.1 Starting the ABAP Development Tools Installation Procedure in Eclipse

122

第 123 页 / 共 465 页

4.1 Core Data Services Views

This will open the Eclipse installation dialog. Next, you must add the ABAP develop-

ment tools update site as a new repository destination (Figure 4.2). The corresponding

ABAP development tools installation URL for the current Eclipse version is available

on the SAP Development Tools website at https://tools.hana.ondemand.com/#abap.

Figure 4.2 Adding the ABAP Development Tools in Eclipse Repository

To develop applications using the ABAP programming model for SAP Fiori, only the

ABAP development tools for SAP NetWeaver are required, so only select this software

package (Figure 4.3). Click Next, accept the terms of the license agreement, and click

on Finish. After the installation is done, Eclipse will require a restart.

123

第 124 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

Figure 4.3 Selecting the ABAP Development Tools for SAP NetWeaver

To connect to a SAP NetWeaver ABAP backend server, you first must open the now

available ABAP Perspective by clicking on Window (cid:2) Perspective (cid:2) Open Perspective (cid:2)

Other… (cid:2) ABAP. From there, you can create an ABAP project that will establish the con-

nection to the backend server. Figure 4.4 shows how the ABAP project creation pro-

cess can be started by clicking on File (cid:2) New (cid:2) ABAP Project in the Eclipse menu bar. A

new project can be created in one of the following ways:

(cid:2) From a predefined SAP Logon system connection

(cid:2) By defining a manual system connection

(cid:2) By duplicating an existing system connection

124

第 125 页 / 共 465 页

4.1 Core Data Services Views

Figure 4.4 Creating an ABAP Project from the ABAP Perspective in Eclipse

Note

To enable your ABAP backend for using the ABAP development tools in Eclipse, see

the “Configuring ABAP Back-end for ABAP Development Tools” guide provided by SAP

at https://archive.sap.com/documents/docs/DOC-62593.

4.1.2 Introduction to the Data Model

The first step in any app development is the creation of a data model followed by the

creation of actual database tables for persisting transactional or master data. In the

next sections, we’ll therefore introduce the underlying data model of the app and cre-

ate the necessary database tables.

Entity Relationship Model

The conceptual data model of the app in the form of an Entity Relationship Model

(ERM) is shown in Figure 4.5. It consists of a purchase document entity type and a pur-

chase document item entity type. Purchase documents have a 0 to n relationship

to items, and items have a 1 to 1 relationship to documents, which constitutes a

parent-child relationship with documents being the parent nodes and items the child

nodes.

The purchase document entity has several attributes, including the overall docu-

ment status and priority of the purchase, as well as the responsible purchasing orga-

nization. The primary key of a purchase document is based on a single purchase

document ID. The purchase document item entity represents the actual items of the

125

Note To enable your ABAP backend for using the ABAP development tools in Eclipse, see the “Configuring ABAP Back-end for ABAP Development Tools” guide provided by SAP
at https://archive.sap.com/documents/docs/DOC-62593.

第 126 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

purchase, including price and quantity. The primary key of a purchase document

item entity consists of an item ID and the purchase document ID, which references

the purchase document ID in the purchase document entity via a foreign key rela-

tionship.

Purchase …

Document

1 n Purchase

Purchase Document has

Document Item

Status Quantity

Purchase

Purchase

Purchasing Document Price

Priority … Document

Organization Item

Figure 4.5 Conceptual Data Model of the Application Depicted in the Form of an ERM

Database Tables

The foundation of any application in SAP S/4HANA is made up of the database tables

in which data is persisted in the SAP HANA database. New database tables can be cre-

ated in Eclipse using a source code editor available since SAP NetWeaver Application

Server for ABAP 7.52 SP 00 (SAP NetWeaver AS for ABAP). To persist the described pur-

chase document and purchase document item entities and their values on the data-

base, we need to create two separate database tables.

The following steps must be executed to create a transparent table in the ABAP Dic-

tionary:

1. Open the ABAP perspective in the ABAP development tools in Eclipse.

2. In the ABAP project, select the package node in which you want to create the table

via the Project Explorer view.

3. Open the context menu by right-clicking on the package, and select New (cid:2) Other

ABAP Repository Object (cid:2) Dictionary (cid:2) Database Table.

4. The database table creation wizard opens, and you must enter a Name and De-

scription (Figure 4.6). In our case, we’ll create a table for purchase documents called

ZPURCHDOCUMENT and a table for purchase document items called ZPURCHDOCITEM.

5. Finally, the database table source code editor opens, so you can now add fields to

the table and configure its properties.

126

第 127 页 / 共 465 页

4.1 Core Data Services Views

Figure 4.6 Database Table Creation Wizard

The programing language of the source code editor closely resembles the data defini-

tion language (DDL) of CDS. Metadata defined using annotations and technical prop-

erties, such as fields, is defined in an SQL-like syntax (Figure 4.7). On save or

activation, the actual persistence is updated. The source code displayed in the editor

isn’t a new transportable development object. All information is stored and retrieved

from the classic ABAP Dictionary. The source code definition of the database table for

persisting purchase documents is shown in Figure 4.7 and Listing 4.1.

Figure 4.7 The Table Editor Based on Source Code in Eclipse

127

第 128 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

Using the editor based on source code in Eclipse, we can define technical as well as

semantic attributes of the table with the help of annotations. For instance, with the

@EndUserText.label annotation, we can provide meaningful and translatable labels

and descriptions for objects and fields. For fields, this annotation will only be consid-

ered if the field has no data element assigned; otherwise, the field label is taken from

the data element. For simplicity, we’ve only created a data element for the purchase-

document field (zpurchasedocumentdtel) as this is required for later referencing the

field via a foreign key annotation in the purchase document items table. The other

fields are typed using built-in ABAP types, for instance, abap.char(4).

The technical @AbapCatalog.enhancementCategory: #EXTENSIBLE_ANY annotation in the

header part of the table definition specifies that all structure and database compo-

nents and their enhancements may contain components whose data type can be of

any category. The #TRANSPARENT table category is the default category for database

tables, and, on activation, it leads to the creation of a database table on the database

as well as to the creation of an identical variant in the classic ABAP Dictionary. Deliv-

ery class #A indicates that the table is an application table holding either transac-

tional or master data and is populated by application programs. The semantic data

maintenance #ALLOWED annotation makes the table editable using the data browser

Transaction SE16.

@EndUserText.label : 'Purchase Document'

@AbapCatalog.enhancementCategory : #EXTENSIBLE_ANY

@AbapCatalog.tableCategory : #TRANSPARENT

@AbapCatalog.deliveryClass : #A

@AbapCatalog.dataMaintenance : #ALLOWED

define table zpurchdocument {

key client : abap.clnt not null;

key purchasedocument : zpurchasedocumentdtel not null;

@EndUserText.label : 'Description'

description : abap.sstring(128);

@EndUserText.label : 'Approval Status'

status : abap.char(1);

@EndUserText.label : 'Priority'

priority : abap.char(1);

@EndUserText.label : 'Purchasing Organization'

purchasingorganization : abap.char(4);

@EndUserText.label : 'Purchase Document Image URL'

128

第 129 页 / 共 465 页

4.1 Core Data Services Views

purchasedocumentimageurl : abap.sstring(255);

include /bobf/s_lib_admin_data;

}

Listing 4.1 Database Table Definition for Purchase Documents

In addition to the actual table fields, we also include a predefined BOPF structure

for admin data (include /bobf/s_lib_admin_data;), which allows us to persist useful

information about who created or changed a table entry and when this took place.

We’ll also include this structure in the purchase document items table.

The database table definition for purchase document items is shown in Listing 4.2. In

contrast to the purchase documents table, it has a compound primary key consist-

ing of the purchasedocumentitem ID and the purchasedocument ID. The purchase docu-

ment items and the purchase documents tables are connected via a foreign key

relationship on the purchasedocument ID field. The table contains fields for the price

of an item and the quantity to purchase as well as fields for the corresponding cur-

rency and unit of measure. Those fields are connected using semantic annotations:

@Semantics.amount.currencyCode for monetary values, and @Semantics.quantity.unit-

OfMeasure for quantities.

@EndUserText.label : 'Purchase Document Item'

…

define table zpurchdocitem {

key client : abap.clnt not null;

@EndUserText.label : 'Purchase Document Item'

key purchasedocumentitem : abap.char(10) not null;

@AbapCatalog.foreignKey.keyType : #KEY

@AbapCatalog.foreignKey.screenCheck : true

key purchasedocument : zpurchasedocumentdtel not null

with foreign key [1..*,1] zpurchdocument

where client = zpurchdocitem.client

and purchasedocument = zpurchdocitem.purchasedocument;

@EndUserText.label : 'Description'

description : abap.sstring(128);

@EndUserText.label : 'Price'

@Semantics.amount.currencyCode : 'zpurchdocitem.currency'

price : abap.curr(13,2);

@EndUserText.label : 'Currency'

currency : abap.cuky;

129

第 130 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

@EndUserText.label : 'Quantity'

@Semantics.quantity.unitOfMeasure : 'zpurchdocitem.quantityunit'

quantity : abap.quan(13,2);

@EndUserText.label : 'Unit'

quantityunit : abap.unit(3);

@EndUserText.label : 'Vendor'

vendor : abap.sstring(32);

@EndUserText.label : 'Vendor Type'

vendortype : abap.sstring(32);

@EndUserText.label : 'Purchase Document Item Image URL'

purchasedocumentitemimageurl : abap.sstring(255);

include /bobf/s_lib_admin_data;

}

Listing 4.2 Database Table Definition for Purchase Document Items

Note

You can use the keyboard shortcut (Ctrl)+(Shift)+(A) to quickly open ABAP devel-

opment objects in Eclipse, such as packages, database tables, or CDS views.

4.1.3 Creating Basic Interface Core Data Services Views

In the previous section, we defined the data model and the underlying database

tables of our application to persist purchase documents and their items. In this sub-

section, we’ll put a semantic and reusable basic interface CDS layer on top of the pre-

viously created tables. We’ll adhere to the standard development guidelines of the

SAP S/4HANA VDM based on CDS views.

The basic interface layer is the foundation layer of CDS views directly deployed on

top of the database tables. As already described in Chapter 1, it isn’t supposed to do

any complex calculations or join already large sets of tables and data; instead, it sim-

ply does a projection of the fields provided by the underlying database tables to fos-

ter fine granular reuse of these views.

To create a CDS view using the ABAP development tools in Eclipse, follow these steps:

1. Open the ABAP perspective in the ABAP development tools in Eclipse.

2. In the ABAP project, select the package node in which you want to create the table

via the Project Explorer view.

130

Note You can use the keyboard shortcut (Ctrl)+(Shift)+(A) to quickly open ABAP devel-
opment objects in Eclipse, such as packages, database tables, or CDS views.

第 131 页 / 共 465 页

4.1 Core Data Services Views

3. Open the context menu by right-clicking on the package, and select New (cid:2) Other

ABAP Repository (cid:2) Core Data Services (cid:2) Data Definition.

4. In the CDS creation wizard that appears, enter a Name and Description. In our case,

we’ll call the purchase documents view Z_I_PurchaseDocument and the purchase

document items view Z_I_PurchaseDocumentItem.

5. Select one of the provided templates to create a skeleton CDS view, for instance,

Define View, which will create a simple projection view skeleton with one single

data source and without any associations or joins.

6. Click the Finish button in the wizard, and the source code editor will open so you

can add fields or associations to the view.

Note

You can use the shortcut (Ctrl)+(Space) inside the field selection part of the CDS

view source code editor to trigger the Eclipse content assist popover to easily select

fields of the underlying database table or CDS view (see Figure 4.8).

Figure 4.8 Triggering the Eclipse Content Assist for CDS Fields Using the Keyboard Shortcut

Listing 4.3 shows the basic interface view for purchase documents. It does a simple

projection on the purchase document table (table zpurchdocument) to expose all

table fields and provide camel case aliases for fields that are relevant to end users.

According to the naming convention of the SAP S/4HANA VDM development

guidelines for interface layer views, we name the views using the following pattern:

Z_I_<CDSViewName>. The Z_ indicates that this is a custom developed view in the cus-

tomer namespace, and the I_ indicates that this is an interface layer view. The view

131

Note You can use the shortcut (Ctrl)+(Space) inside the field selection part of the CDS view source code editor to trigger the Eclipse content assist popover to easily select
fields of the underlying database table or CDS view (see Figure 4.8).

第 132 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

is also annotated with the @VDM.viewType: #BASIC annotation that assigns the view to

the basic interface view layer of the VDM.

In addition to the persistent database fields, the view also contains several associa-

tions that are propagated to potential consumers of this view at the end of the field

selection list. By convention, associations start with an underscore, for instance, _Pur-

chaseDocumentItem. Usually, most of the (key) fields contained in a view will have

foreign key associations to other views because data is supposed to be stored in a nor-

malized and redundancy-free form. In some cases, we omit this for the sake of sim-

plicity, but, as an example, we’ve added associations to the Priority, Status, and

PurchasingOrganization views. In the purchase document table, only the Priority,

Status, and PurchasingOrganization keys will be stored; however, additional data, like

texts, can be read via the foreign key associations to these views.

Another important annotation is the authorization check @AccessControl.authoriza-

tionCheck: #CHECK, which enables the restricted access to a CDS view using a data con-

trol language (DCL) access control. We’ll discuss access restrictions for CDS views in

detail in Section 4.1.5.

The @ObjectModel.representativeKey annotation defines the field of the primary key

that is most specific for this view, and the @ObjectModel.semanticKey defines the pri-

mary key of this view. For the purchase document basic interface view, this is the Pur-

chaseDocument field in both cases. Fields containing descriptions or text should be

annotated with @Semantics.text: true. The main description field of the entity can be

linked to the entity key with the @ObjectModel.text.element: ['Description'] anno-

tation.

@AbapCatalog.sqlViewName: 'ZIPURCHDOC'

@EndUserText.label: 'Purchase Document'

@AccessControl.authorizationCheck: #CHECK

@VDM.viewType: #BASIC

@ObjectModel.representativeKey: 'PurchaseDocument'

@ObjectModel.semanticKey: ['PurchaseDocument']

define view Z_I_PurchaseDocument

as select from zpurchdocument

association [0..*] to Z_I_PurchaseDocumentItem as _

PurchaseDocumentItem on $projection.PurchaseDocument = _PurchaseDocumen-

tItem.PurchaseDocument

association [0..1] to Z_I_PurchaseDocumentPriority as _

Priority on $projection.Priority = _Priority.Priority

132

第 133 页 / 共 465 页

4.1 Core Data Services Views

association [0..1] to Z_I_PurchaseDocumentStatus as _

Status on $projection.Status = _Status.Status

association [0..1] to Z_I_PurchasingOrganization as _

PurchasingOrganization on $projection.PurchasingOrganization = _PurchasingOr-

ganization.PurchasingOrganization

{

@ObjectModel.text.element: ['Description']

key purchasedocument as PurchaseDocument,

@Semantics.text: true

description as Description,

@ObjectModel.foreignKey.association: '_Status'

status as Status,

@ObjectModel.foreignKey.association: '_Priority'

priority as Priority,

@ObjectModel.foreignKey.association: '_PurchasingOrganization'

purchasingorganization as PurchasingOrganization,

@Semantics.imageUrl: true

purchasedocumentimageurl as PurchaseDocumentImageURL,

// BOPF Admin Data

crea_date_time,

crea_uname,

lchg_date_time,

lchg_uname,

// Associations

_PurchaseDocumentItem,

_Priority,

_Status,

_PurchasingOrganization

}

Listing 4.3 Basic Interface View on Top of the Purchase Documents Table

(zpurchdocument)

The purchase document item basic interface view is shown in Listing 4.4. Its repre-

sentative key is the PurchaseDocumentItem field as this is the most specific part of its

133

第 134 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

primary key and defines this entity. The semantic key consists of the PurchaseDocu-

ment and PurchaseDocumentItem fields and reflects the primary key of the entity. It con-

tains a foreign key association to the purchase document view as well as to reuse

views for the currency (I_Currency) and the unit of measure (I_UnitOfMeasure) pro-

vided by the standard SAP S/4HANA basic interface view layer. As soon as views are

explicitly released by SAP, they can be used in your own developments without the

risk of introducing breaking changes in future releases. The semantic currency and

unit of measure annotations should be known from the table definition. We added

the @DefaultAggregation:#NONE annotation to the Price and Quantity fields because

all amount fields will be handled, by default, as measures and aggregated by SADL

or the Analytical Engine. However, in our case, we explicitly want to suppress this

default behavior.

@AbapCatalog.sqlViewName: 'ZIPURCHDOCITEM'

@EndUserText.label: 'Purchase Document Item'

@AccessControl.authorizationCheck: #NOT_REQUIRED

@VDM.viewType: #BASIC

@ObjectModel.representativeKey: 'PurchaseDocumentItem'

@ObjectModel.semanticKey: ['PurchaseDocumentItem','PurchaseDocument']

define view Z_I_PurchaseDocumentItem

as select from zpurchdocitem

association [1..1] to Z_I_PurchaseDocument as _

PurchaseDocument on $projection.PurchaseDocument = _

PurchaseDocument.PurchaseDocument

association [0..1] to I_UnitOfMeasure as _

QuantityUnitOfMeasure on $projection.QuantityUnit = _

QuantityUnitOfMeasure.UnitOfMeasure

association [0..1] to I_Currency as _

Currency on $projection.Currency = _Currency.Currency

{

@ObjectModel.text.element: ['Description']

key purchasedocumentitem as PurchaseDocumentItem,

@ObjectModel.foreignKey.association: '_PurchaseDocument'

key purchasedocument as PurchaseDocument,

134

第 135 页 / 共 465 页

4.1 Core Data Services Views

@Semantics.text: true

description as Description,

vendor as Vendor,

vendortype as VendorType,

@Semantics.amount.currencyCode: 'Currency'

@DefaultAggregation: #NONE

price as Price,

@Semantics.currencyCode: true

@ObjectModel.foreignKey.association: '_Currency'

currency as Currency,

@Semantics.quantity.unitOfMeasure: 'QuantityUnit'

@DefaultAggregation: #NONE

quantity as Quantity,

@Semantics.unitOfMeasure: true

@ObjectModel.foreignKey.association: '_QuantityUnitOfMeasure'

quantityunit as QuantityUnit,

@Semantics.imageUrl: true

purchasedocumentitemimageurl as PurchaseDocumentItemImageURL,

// BOPF Admin Data

crea_date_time,

crea_uname,

lchg_date_time,

lchg_uname,

// Associations

_PurchaseDocument,

_QuantityUnitOfMeasure,

_Currency

}

Listing 4.4 Basic Interface View on Top of the Purchase Document Items Table

(zpurchdocitem)

135

第 136 页 / 共 465 页

4 Developing an SAP Fiori Elements List Report and Object Page

4.1.4 Adding Calculated Fields

With the CDS DDL, it’s possible to dynamically calculate fields based on other per-

sistent fields already present in the database. In the past, such calculated values

might have been calculated on the application server or, in the worst case, were pre-

calculated and stored in redundant aggregate tables. However, with the launch of SAP

HANA, this has become obsolete as we can easily aggregate and calculate values on

the fly now, which potentially reduces the data footprint of the system and improves

the performance by pushing data-intensive calculations and aggregations to the

database layer. In the following, we’ll calculate several values that are of interest for

our application but don’t have to be stored on the database as they would introduce

redundancy and can be calculated dynamically using CDS views at runtime.

Calculating the Overall Item Price

One very simple example of a calculated value is the overall price of a purchase doc-

ument item. We’ve persisted the price of a single item and the requested quantity on

the database but not the overall price. To calculate the overall price, we can simply

multiply the requested quantity by the price of a single item and provide a new name

for the field using an alias. For example, with an item price of 50 and a quantity of 10,

the overall price of this item would be 50 ∙ 10 = 500. How this can be implemented in

the Z_I_PurchaseDoumentItem basic view is shown in the following listing. Though this

is a calculated field, we can also reference the already-persisted currency field.

…

@Semantics.amount.currencyCode: 'Currency'

@DefaultAggregation: #NONE

quantity * price as OverallItemPrice,

…

Calculating Overall Purchase Document Price by Introducing a Composite

Interface View and Using Test-Driven Development

Additionally, we’re also interested in the overall price of a purchase document. To cal-

culate the overall price, we’ll make use of the previously calculated overall item price

as the overall price of a purchase document can be calculated by summing up all

overall item prices of its assigned items. To do this, we must put an additional view

on top of the basic purchase document view, which we’ll name Z_I_PurchDocOver-

allPrice and assign to the composite interface layer of the VDM as it will contain a

136

返回ABAP参考资料列表