ABAP in S4HANA - Mark Anderson
ABAP in S4HANA - Mark Anderson
By Mark Anderson
Table of Contents
Introduction
Structure of the Book
Conclusion
Chapter 1: ABAP in Eclipse
1. Installation
1.1 Download and Install Eclipse
1.2 Install the ABAP Development Tools for SAP NetWeaver (ADT)
1.3 Connecting Eclipse to a Backend SAP System
2. Features
2.1 Create Domains
2.2 Creating Data Elements
2.3 Creating Structures
2.4 Creating Classes
2.5 Deleting Unused Variables
2.6 Searching for Objects
2.7 Formatting ABAP Source Code
2.8 Using Where-used List
2.9 Navigating to SAP GUI
3. Summary
Chapter 2: New ABAP 7.4 and 7.5 Language Features
1. New Language Features
1.1 Inline Declarations
1.2 Internal Tables
1.3 String Processing
1.4 Calling functions
1.5 CONVersion Operator
1.6 CASTing Operator
1.7 VALUE Operator
1.8 FOR operator
1.9 Reduction operator REDUCE
1.10 Conditional operators COND
1.11 Conditional operators SWITCH
1.12 Corresponding Operator
2. Summary
Chapter 3: Core Data Services
1. What Is S/4 Hana?
2. ABAP Programming model in SAP S/4 HANA
2.1 Introduction
3. Code Pushdown
4. Core Data Services (CDS)
4.1 CDS Views: A Step-by-Step Approach
4.2 CDS Views
5. Summary
Chapter 4: ODATA
1. What is OData?
1.1 OData Architecture
2. Structure of an OData service
2.1 Service document
2.2 Service Metadata Document
3. OData Operations (CRUD)
3.1 Create
3.2 Read
3.3 Update
3.4 Delete
4. Gateway Service development
6. Summary
Chapter 5: Business Object Processing Framework
1. Introduction to BOPF
1.1 Business object Meta model
1.2 Nodes
1.3 BOPF Actions
1.4 BOPF Validations
1.5 BOPF Determinations
2. Creating BOPF Object from CDS views
3. Summary
Chapter 6: Exercise - Building a draft-enabled business object
1. Scenario
1.1 Create a Base table for BP header and Identification data
1.2 Create the Interface View for the base tables
1.3 Create the Transactional Processing View
1.4 Create the Consumption View for the User Interface
1.5 Create OData service
1.6 Transactional Processing
2. Summary
Conclusion
Introduction
Over the last four decades SAP technology has evolved at a great speed.
SAP systems now touch 77% of the world’s transactions and are the leading
source of operational data like financials, customer transactions, supply
chain, human resources, Insurance etc.
The first SAP Application was for Accounting (R/1 system), followed by
SAP R/2 system towards the end of 1970s, which was based on mainframe
computing.
In 1992, SAP developed the client/server application we all know as R/3.
Several PCs could be used to connect with the one or more application
instances which would process the data on one or more instances of the
database.
In the first three decades, SAP was primarily focused in building robust
Application software and used 3rd party databases e.g. Oracle, DB2 etc.
Furthermore, many customers wanted to use latest UI technology. Hence
SAP software found itself sandwiched between 3rd party software providing
UI and Database.
The journey of evolution continued, and SAP made great strides in the areas
of Development tools, User Interfaces, Business logic and Database
technology.
To maintain a lead in the market SAP then introduced S/4 Hana as its own
Database on 3rd February 2015 at the New York Stock Exchange. The event
introduced cloud and on-premise editions, and launched the on-premise
edition.
With the SAP technology changing so much over the years, the developers
across the world found it difficult to adapt to it.
Although all the SAP developers would love to use the new features but
most of the programmers who would benefit from it found it difficult to
understand and implement the new technologies in Client implementations.
The purpose of this book is to enable the inquisitive ABAP developers to
adapt to the new ABAP programming model. This book will help them be
aware of the SAP-delivered improvements and it also provides Exercises
which will guide them in a way that they can start implementing requirement
using the newer technologies.
Structure of the Book
https://tools.hana.ondemand.com/#abap
You could also install Eclipse directly from eclipse.org but it is best to
follow the detailed instructions in the provided link.
Confirm the license agreements and click Finish to start the installation
Once the Eclipse and ABAP Development Plug-ins are installed, we are
ready to connect to a SAP backend system. To connect, choose the menu
path - File –> New -> ABAP Project.
All the systems from your SAP Logon pad are listed in the next dialog box.
Choose and provide the credentials with the client information to login and
fetch the technical development objects.
Now the system is added on the left panel and this can now be expanded to
navigate to the development package. It is also possible to add the
development package as a Favorite package.
2. Features
In this section we will familiarize ourselves with the ABAP development in
Eclipse. Most of us would have extensive experience creating ABAP objects
in SE80, but it becomes important to be able to use Eclipse with equal ease.
With that in mind, we will go through the process of creation of a few
objects. The focus here is to understand how we can create the objects in
Eclipse rather than the artifact themselves.
This chapter also describes how we execute some simple tasks like
navigating to SAP GUI, Formatting the code etc.
Section 2.1 to 2.4 explains how you can create ABAP Artifacts using Eclipse
and Section 2.5 to 2.9 explain some frequently used features.
2.1 Create Domains
The next dialog provides a Form to fill the details of the Domain. It is
interesting to note that all the relevant fields are in one screen. Hence,
instead of navigating between different tabs (which often led to forgetting to
fill a few attributes) the user can fill all the required information in one
screen. This reduces the chance of missing out on entering important
attributes and the constant struggle of finding the correct attributes in the
different tabs is gone.
Figure 10: Enter Domain details
The Screen also provides more options on the right-top corner. The options
allow you to open the Documentation in SAP GUI, Share a link etc.
Once all the details of the Domain are filled, you can Save and Activate the
object. Once created, the object can also be viewed and changed in SE11.
Figure 11: View Domain in SAP GUI
The process for creating Data Elements is same as that for Domain.
However, let us go through one more example.
This time, let us use the context menu on the ‘Dictionary’ folder created for
the project.
Right click on the Dictionary folder and then click on New -> Data Element,
as shown in Figure 12.
Figure 12: Create Data Element
As you see, this time all the DDIC artifacts are already listed and need not be
searched. The system understands the context and provides the correct
options.
Select ‘Data Element’ option. A new dialog box opens where you can
specify the name and description of the Data Element.
Even for a first-time user, the UI is very intuitive and easy to use. In SE11,
you must navigate between different tabs to fill the relevant information. In
Eclipse all the necessary data can be filled in one screen and this eases the
creation of the object.
Once the relevant details are filled, you could save and active the object (just
like SE11).
Enter the name and Description of the structure and click on Finish (just like
the other DDIC objects).
It is interesting to note that this time the user is not presented with a Form to
fill out the structure components. Creating a DDIC structure in Eclipse is
like creating a TYPE in ABAP.
Now you can enter the different components of the structure in Curly
brackets.
@EndUserText.label : 'Business Partner address'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
define structure zbp_address {
city1 : ad_city1;
city_code : ad_citynum;
post_code1 : ad_pstcd1;
po_box_num : ad_pobxnum;
street : ad_street;
house_num1 : ad_hsnm1;
location : ad_lctn;
building : ad_bldng;
floor : ad_floor;
roomnumber : ad_roomnum;
country : land1;
Save and activate the structure. The structure is now created and can be
edited in SE11
Figure 17: View Structure in SAP GUI
Right now, you might be wondering that the ABAP dictionary provides the
options to provide ‘Input Help/Check’ and ‘Currency/quantity fields’. Hence
it should also be possible to add this in Eclipse. It wouldn’t make sense to
create the components in Eclipse and add other details via SAP GUI.
For our example, let us add an Input help for the field ‘CITY_CODE’.
As you can see from Fig 2.18, the help for city code is not available in SE11.
To create an ABAP class, use the menu option File -> New -> ABAP Class
Enter the name and description of the class and click on Finish.
Figure 21: Enter details of new Class
Here, you would notice that the generated code has blocks for both
Definition and Implementation. In SE24, the definition was Form-based, but
here the definition and implementation of the class is a big block of code
(something like an ABAP program).
Although it might seem complex for the old time ABAP programmers, it is
quite simple once you get used to it.
CLASS zbp_helper DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
This creates the method implementation. Now you can add Save and activate
the class.
Once successfully activated, we can Display / Edit the class in SAP GUI as
well.
Maintaining the quality of the code is very important to ensure its functional
correctness and maintainability. Hence before a code can be delivered, it is
important to clean up the code.
If you run an ATC or Extended checks, you can find the errors and warnings
in your program. One such check which keeps popping up is the ‘Deletion of
Unused variables’. In extended check, this comes as a Warning and requires
us to navigate back and forth to delete the unwanted variables. If the code is
big, then the context of the code is lost, and we might have to run the
Extended check again. This activity consumes a lot of time and can be done
very quickly in Eclipse.
To Delete the unused Variables, we can now use the menu path Source Code
-> Delete Unused variables.
This opens a dialog, where you could enter the search string to find the
object.
Figure 27: Open ABAP Development Object
You can get the Where-used list either by using the context menu or by using
the button on the Applicate toolbar.
Figure 2.29 shows the context menu option:
Figure 29: Where-used List
The Where used list is then displayed as shown in Fig 2.30. It is also
possible to navigate to the objects from the where-used list.
It is possible to navigate from Eclipse to SAP GUI with the buttons on the
menu bar.
With the above new feature, the complier already knows that it can and
needs to store the value of ‘Hello World’ in a String variable. Hence, there is
no explicit need to declare a variable of type String.
The above code does not only reduce the number of lines but is also easier to
understand.
Let us look at another example where we have to loop over an internal table
and assign a value to the work area.
Example 2: Loop over an internal table
Before release 7.40
DATA l_wa LIKE LINE OF i_tab.
LOOP AT i_tab INTO l_wa.
…
ENDLOOP.
Every time we need to loop over an internal table we need to declare a work
area. Many a times this work area is also not of any use once the loop
processing is complete.
Hence with inline declarations it makes it easy to declare it and use when it
is required.
Below are some more examples of inline declarations:
You would have noticed that you would have to put @ symbol in front of
your variables (or constants) used in select statements when using the new
features. This helps the complier in understanding that we are not referring
to the fields in the database but variables in the program.
Please note that when using new features, you also must put commas
between the fields you are retrieving from the database and put the INTO
statement at the end.
1.2 Internal Tables
In previous section we saw that it was possible to read the internal table into
a work area without having to declare the work area before the read
statement. This change would remove extra data declaration lines.
However, if you adopt the new features completely, you might never have to
use the read statement.
The above new language features come with a catch that if the value is not
found then an exception (CX_SY_ITAB_LINE_NOT_FOUND) is raised
and if the exception is not caught then there will be a short dump.
Therefore, SAP recommends that the value should be assigned to a field
symbol and then we could check the value using sy-subrc.
ASSIGN l_tab[ 1 ] to FIELD–SYMBOL(<ls_tab>).
IF sy–subrc = 0.
ENDIF.
String processing is very frequently used in ABAP code. The data from the
database often needs to be formatted before it is displayed to the user and
vice versa. E.g. if we have to display the sales order details on the screen,
then we might have to concatenate a text with the Sales order number and
then display it.
Following are some instances where string processing are required:
Convert Input data before using it in Database operations
Convert data from data base into a more human readable form.
lv_order = l_vbak-vbeln.
WRITE:/ lv_out.
CONCATENATE ABAP 7.4
lv_order = l_vbak-vbeln.
WRITE:/ lv_out.
As you would have noticed, ABAP now has a new concatenation operator,
&&.
String Templates
The purpose of a string template is to create a new character string out of
literal texts and embedded expressions. It largely replaces the use of the
WRITE TO statement.
A string template is defined by using the | (pipe) symbol at the beginning
and end of a template.
DATA: character_string TYPE string.
character_string = |This is a literal text.|.
This example has in fact the same result as:
character_string = `This is a literal text.`.
The added value of a string template becomes clear when combining literal
texts with embedded expressions and control characters. Embedded
expressions are defined within a string template with curly brackets {
expression }. Note that a space between bracket and expression is
obligatory.
An expression can be a data object (variable), a functional method, a
predefined function or a calculation expression. Some examples are:
character_string = |{ a_numeric_variable }|.
character_string = |This resulted in return code { sy–subrc }|.
character_string = |The length of text element 001 ({ text–001 }) is { strlen(text–001 ) }|.
Embedded expressions have a default output format, but also several
formatting options, comparable to the format options of the WRITE
statement.
Example:
DATA: comm_capital TYPE bzusage VALUE '1234567.123',
currency_field TYPE swhr,
lv_string TYPE string.
l_ordernum = '0000012345'.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
EXPORTING
input = l_ordernum
IMPORTING
OUTPUT = l_ordernum.
With Method chaining you can achieve the same results as follows:
lo_email->send_email( lo_bp->get_email( i_bp = l_bp ).
For Example, let us assume that a method expects a string, but you have the
data in a text field. As per the old syntax you would need to move the value
to a string variable and then pass this helper variable to the method call.
With CONV operator the helper variable is no more required.
helper = cust_name.
In the above code snippet, cust_name is a character of length 20. But the
method process_function expects a string. Hence in the old syntax it was
required to move the data to a variable which was type compatible with the
method parameters.
… CONV dtype|#( … ) …
If the value of the type can be derived (as in our example) then the data type
(‘dtype’) is not required. It is sufficient to use the ‘#’.
components = structdescr->components.
In the above code we first get the details of the structure in a helper variable
structdescr and then use this to get the components.
With the new syntax you do not need the helper variable structdescr.
Example 2: Create an internal table, where for each line a value can be
assigned.
TYPES: BEGIN OF t_struct,
col1 TYPE char10,
col2 TYPE char10,
END OF t_struct.
Example 3: Construct a ranges table and fills it with four rows while using
the short form for structured row types.
Before 7.4 we had to loop over the first table, assign the value to the work
area of the new table and then append the work area into the new table.
e.g.
lv_sales_no = <fs_sales>-vbeln.
CLEAR : lv_sales_no.
ENDLOOP.
In the new syntax the above operation can be done as shown below:
TYPES:
BEGIN OF ty_business_partner,
partner TYPE char10,
name TYPE char30,
city TYPE char30,
route TYPE char10,
END OF ty_business_partner.
DATA(t_BP) =
VALUE tt_bus_partner(
( partner = 'BP0001' name = 'PeterParker' city = 'NY' route = 'R0001' )
( partner = 'BP0002' name = 'Superman' city = 'LA' route = 'R0003' )
( partner = 'BP0003' name = 'Batman' city = 'DFW' route = 'R0001' )
( partner = 'BP0004' name = 'IronMan' city = 'CH' route = 'R0003' )
).
Reduce operator creates a result of specified data type after going through
iterations. In classical ABAP if we had to evaluate the data in an internal
table then we had to loop through the internal table, evaluate the condition
and then take appropriate action. This could be done in a much simpler way
with Reduce.
Syntax:
… REDUCE type(
INIT result = start_value
…
FOR for_exp1
FOR for_exp2
…
NEXT …
result = iterated_value
…)
Example 1: Count lines of table that meet a condition (field city contains
“LA”).
TYPES:
BEGIN OF ty_business_partner,
partner TYPE char10,
name TYPE char30,
city TYPE char30,
route TYPE char10,
END OF ty_business_partner.
DATA(t_BP) =
VALUE tt_bus_partner(
( partner = 'BP0001' name = 'PeterParker' city = 'NY' route = 'R0001' )
( partner = 'BP0002' name = 'Superman' city = 'LA' route = 'R0003' )
( partner = 'BP0003' name = 'Batman' city = 'DFW' route = 'R0001' )
( partner = 'BP0004' name = 'IronMan' city = 'LA' route = 'R0003' )
).
“ Before 7.40
DATA: lv_lines TYPE i.
LOOP AT t_bp INTO DATA(ls_bp) WHERE city = 'LA'.
lv_lines = lv_lines + 1.
ENDLOOP.
With the new syntax it is not required to loop through all the records to count
the number of matches.
The REDUCE operator can be used instead
..
ENDIF.
The above conditions are not possible by using Case statements as the
WHEN clause could only evaluate either the lv_prod_catg or the
lv_prodtype. This is where the new COND operator comes handy. COND
allows us to evaluate multiple variables.
Syntax:
Example 1:
TRY.
DATA(lv_text) =
COND #( WHEN lv_prod_catg = '10' AND lv_prodtype = 'A'
THEN 'Television'
WHEN lv_prod_catg ='20' AND lv_prodtype = 'B'
THEN 'Automatic Washing Machine'
WHEN lv_prod_catg ='20' AND lv_prodtype = 'C'
THEN 'Semi-Automatic Washing Machine'
ELSE THROW cx_exception( ) ).
CATCH cx_exception.
ENDTRY.
Syntax:
Example 1:
DATA(lv_status) = SWITCH #( lv_flag
WHEN 'X' THEN 'Completed'
ELSE 'In Process'
).
In the above example based on the value of the flag the value of the status is
assigned to the lb_status variable.
This operator allows the copy of data from one internal table to another
internal table (just like move-corresponding) but provides more options on
which columns are copied. With this new statement it is possible to not copy
the values of one column even it the same column exists in the target internal
table. It is also possible to copy data between columns which have different
names in the source and target internal tables.
Syntax:
… CORRESPONDING type( [BASE ( base )] struct|itab [mapping|except] )
Example:
Workareas contains the following data:
L_workarea1 = VALUE line1( col1 = 1 col2 = 2 ).
L_workarea2 = VALUE line2( col1 = 4 col2 = 5 col3 = 6 ).
Now the contents of the L_Workarea2 will have the following data:
L_workarea2 =( col1 = 1 col2 = 2 col3 = 0 ).
Example 2: This uses the existing contents of L_workarea2 as a base and
overwrites the matching columns from ls_line1.
This is exactly like MOVE-CORRESPONDING.
L_workarea2 = CORRESPONDING #( BASE ( L_workarea2) L_workarea1 ).
Now the contents of the Workarea2 will have the following data:
L_workarea2 =( col1 = 1 col2 = 2 col3 = 6 ).
Example 3: This creates a third and new structure (ls_line3) which is based
on ls_line2 but overwritten by matching columns of ls_line1
Example 3 has the same result as Example 2, but in Example 3 the data is
populated into a new structure L_workarea3.
2. Summary
This chapter covered some of the important and frequently used new
language features. This is only meant as a starting point for the more
inquisitee developer and should be explored further. As mentioned earlier
the new language features not only simply the code and reduces the number
of lines but is also easier to understand.
Chapter 3: Core Data Services
Core Data Services (CDS) is a new data modelling infrastructure. With CDS,
the data models are defined and consumed on the database rather than on the
Application server. Hence, this helps in the code push down and drastically
improves the performance.
This Chapter defines S/4 Hana and then goes on to explain what is Code
push down. Then in Section 3 we cover the details of Core data services. The
examples provided in this chapter are detailed and would help to get
introduced to the new programming model.
1. What Is S/4 Hana?
SAP S/4HANA stands for SAP Business Suite 4 SAP HANA. It is a new
product with a new code line for maximum leverage of SAP HANA. It is the
next generation business suite and is built on advanced in-memory platform,
SAP HANA, and offers a personalized user experience with SAP Fiori.
S/4HANA delivers massive simplifications (data model, user experience),
innovations and offers personalized user experience with SAP Fiori.
SAP S/4HANA simplifies IT landscape and reduce cost of ownership
(TCO), through:
Reducing your data footprint
Working with larger data sets in one system saving hardware
costs, operational costs, and time
2. ABAP Programming model in SAP S/4 HANA
2.1 Introduction
The new ABAP programming model has been introduced with the ABAP
release 7.50 SPS01, first only supporting the development of read-only Fiori
apps, and then successively enhanced and improved with the following
ABAP releases.
The new ABAP programming model is based on proven technologies such
as Core Data Services (CDS) for the data modelling and access, OData
protocol for the service exposure and the business object processing
framework for the transactional processing.
The picture below gives an overview of the end-2-end stack:
Figure 1: ABAP Programming Model for SAP Fiori
SAPUI5: this is the latest UI technology from SAP and provides Role based
access.
With the brand-new NW AS ABAP 7.4 SP5, SAP is adding new possibility
for ABAP Developers to leverage HANA capabilities.
Code pushdown means delegating data intense calculations to the database
layer. It does not mean push ALL calculations to the database, but only those
that make sense. An easy example is if you want to add the balances of a
customer’s saving account. You should not select all savings account
balances and add them in your application logic code. This can be easily
done by summing the account balances in the database and just return the
result.
In ABAP programming, Developers were always expected to have a layered
development approach i.e. keep the business logic separate from the data
base access layer. This lead to developers creating different Function Groups
/ Classes for Data base access and Application Logic. It might seem slightly
strange that with Code pushdown we want to now put some Business logic
in the database layer. But this is not new. Code pushdown was already being
done in many different ways like using Count (*) in Open SQL or by using
Stored Procedures.
4. Core Data Services (CDS)
With the availability of SAP HANA there has been a shift in the way
applications are developed. The idea is to push the code to the database layer
to get maximum performance.
Please note that traditional SE11 views were developed using forms which
had tabs for selecting various configuration settings, definition of fields etc.
In CDS based approach the view is created using code.
In the rest of the chapter we will create CDS views based on some of the
most used templates.
If the view were being created in a ABAP Package, then at this point in time
the system would have prompted to specify a Transport Request number.
The templates include placeholders for code that you fill in step by step. If
you later discover the need to change or extend the nature of your CDS view,
you can always change the source code directly in the DDL editor and freely
edit all parts of it as needed. This is particularly helpful if you want to copy
portions of the source code from example code, for instance.
Figure 7: Select CDS Template
For our scenario we will create the view using the ‘Define View with
Association’ template.
At this point let us understand the some of the frequently used templates.
Define View: This can be used to read data from one table. This is
like a select on a database table.
Define View with Join: This is used to read data from more than one
table. This is like a Select with Join to other tables. The table
provides a template to join 2 tables, but this can be extended for more
tables.
Define View with Parameters: CDS view can have parameters. The
parameter values could be passed from the ABAP programs using the
views.
Extend View: This template is used when the CDS view is delivered
by SAP and you want to extend the view with additional fields. E.g.
SAP would provide a CDS view to read Business partner data. But
this view could be extended with custom fields which you might
have appended to the business partner table (BUT000).
The code after having selected the Association template would look like as
shown in the below figure:
You would notice that there are various placeholders which needs to be
filled.
The first annotation requires us to specify the SQL view name. When we had
created the CDS view, we had specified the name of the view. But this was
the CDS view name.
Each DDL source has 2 names. The CDS view name and the SQL view
name. The SQL view name is the name which can be used to see the view
using SE11.
@AbapCatalog.sqlViewName: 'sql_view_name'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
Specifies the definition of the key fields in the CDS database view
of the CDS view.
@AccessControl.authorizationCheck: #CHECK
Defines implicit access control when Open SQL is used to access the
CDS view.
#CHECK:
If Open SQL is used to access the view, access control is performed
implicitly if a CDS role role is assigned to the view. If there is no
role for the view, a syntax check warning occurs.
#NOT_REQUIRED:
Like #CHECK, but there is no syntax check warning.
#NOT_ALLOWED:
No access control is performed. This produces a syntax check
warning in the DCL source code of a role for the view.
#PRIVILEGED_ONLY:
Privileged association (evaluated by SADL).
@EndUserText.label: 'Business Partner'
This is the description of the view which was specified when
entering the attributes of the view.
Now specify the target data source for the Business Partner basic data. The
underlying base table to be used as the target data source is named BUT000.
You can view the details of any of the syntactical elements that make up a
CDS view definition on the fly by pressing the F2 key. The tooltip pop-up
shows all the attributes, the corresponding data elements and types, and the
associations (relationships) between the element and other tables or views,
including their cardinality.
CDS view name: This is the CDS View name of the Second table i.e.
Default address table.
Now we should add the fields which for the view. E.g. We would like to
return the business partner key, first name, last name.
Once the code is complete, we need to activate the View (just like a SE16
view).
The Eclipse editor allows you to execute the CDS views and see the results.
The see the results, press the execute button
Figure 11: CDS - Execute
Inner Join: One row of the left table and one row of the right
table are always joined to a common result row - provided
that the JOIN condition is fulfilled
Left Outer join: One row of a table and one row of another
table are always connected to a common result row -
provided that the JOIN condition is fulfilled. In addition,
rows of the left table without matching row in the right table
are copied to the query result. The missing values (from the
right table) are filled with NULL values.
Right Outer join: One row of a table and one row of another
table are always connected to a common result row -
provided that the JOIN condition is fulfilled. In addition,
rows of the right table without matching row in the left table
are copied to the query result. The missing values (from the
left table) are filled with NULL value.
Full Outer Join: One row of a table and one row of another
table are always connected to a common result row -
provided that the JOIN condition is fulfilled. In addition,
rows of both tables without matching records are copied to
the query result. The missing values (from the other table) are
filled with NULL values.
Combination of results of several sub-queries (UNION)
UNION ALL vs. UNION
You can combine the result tables of multiple queries
using UNION [ALL]. The individual results tables must
have the same number of columns. The corresponding
result columns must have compatible data types.
If no name list specified, the column names of the
result sets must match.
Let us create another CDS View with Joins. This time we will Create a View
on the Business Partner table (BUT000) and Join it with Business Partner
Role.
A CDS view with Join can be created using the Join Template.
CDS views can be created with parameters which can be passed by the
ABAP Programs.
e.g. you have a report with Selection screen. The user enters parameters on
the screen and these parameters are directly passes to the CDS views to get
the results.
The parameters are provided as Comma-Separated list with Type. The Types
could be predefined type or Data elements.
These parameters could be used as ON conditions of JOINSs, Expressions in
WHERE or HAVING clauses etc.
In a traditional SE16 view, the parameters used in Select can only be used to
filter the result set, but here the parameters can be used anywhere in the CDS
code.
Let us create a View with parameters to understand this View in more detail.
Those who have already started working on S/4 Hana would have faced an
issue where they would have to access the F4 domain values to provide this
as a Combo box in UI. This can be simplified by create a View which takes
the Domain name as input, retrieves the domain values and returns the
results.
To create the CDS view create a new with and this time use the Template
with Parameters.
Figure 18: Select Parameter template
Now replace
the template code with the details.The final code should look like as shown
below:
In this DCL approach, the authorization checks are executed as part of the
view. Hence a CDS view is not only the DDL but it also includes DCL.
Let us assume that we want to create a DCL for the previously created CDS
View (the one which displays the BP data).
Guidelines
The DCL document must include the annotation @MappingRole:
true.
Only one mapping role definition per DCL source document is
allowed.
Other aspects than pfcg_auth shall not be used.
Only one mapping role per CDS view is allowed.
A DCL source document shall always include the mapping for one
CDS view exclusively.
CDS Views are used in the same way as the classical SE16 views. You could
use the views in Select statements.
SELECT * FROM zcds_businesspartner INTO TABLE @DATA(lt_bp).
5. Summary
This chapter introduced you to CDS View and explained some of the
commonly used Templates. With the details covered in this chapter you
should not be comfortable in creating different views and exposing the data
to the calling applications.
The next chapter would continue our journey and introduce you to SAP
Gateway, so that you understand how the data can be exposed to the external
world.
Chapter 4: ODATA
1. What is OData?
The beauty of OData services is that they are multi-channel and are designed
to serve many applications. You have one logical model that depicts how the
users perceive the model behind the UI. Each separate UI provides a
different view of the same logical model. Developers who know how to
extract data from SAP systems should be able to find a suitable model that
can be used by multiple application developers. Essentially, everything that
is possible with the UI becomes part of the API.
The Gateway sits between the User Access (Outside World) and the
Business Suite.
OData is an Open standard and can be consumed by any software that can
communicate with HTTP and parse an XML document.
The OData service provides sufficient information to the consumer in terms
of Metadata. Hence, it is not required for the consumer to understand the
details of how the data is accessed and provided by SAP.
At this point you might think that this is like RFCs and Enterprise Services.
But there is a difference. Other technologies used for communicating with
the outside world were SAP specific but OData is an Open standard with
wider reach. Hence it is easier to use and is understand more widely.
2. Structure of an OData service
Let us understand both the above documents in detail with the help of the
data model shown in the below figure:
The data model that we want to expose contains details of a business partner.
Business partner node contains details like Business Partner ID, BP
Role, Title, First name, Last name etc.
Identification data contains the various id details e.g. Passport,
Driving License.
2.1 Service document
The service document lists all of the top-level entity sets exposed by the
service. In our scenario this would be 2 entity sets (BP general data and BP
Identification data).
The URI of the service points to the service document itself.
/sap/opu/odata/tst/ZBP_SERV_SRV/?$format=xml
The service document as shown in the above figure displays all the
collections (Entity Sets) of the service.
For each collection, it also provides SAP-specific metadata e.g.
sap:updatable=’false’.
The annotations only show up if the values are set to a non-default value.
Default values for ‘creatable’, ‘updatable, ‘deletable’ is true and the default
value for ‘searchable’ is false.
By combining the base URI with the relative link (ZC_BUS_PART) it is
possible to retrieve the data of the entity sets.
e.g. /sap/opu/odata/test/ZBP_SERV_SRV/ZC_BUS_PART
The metadata document is a static resource that describes the data model and
type understood by that OData service.
The metadata document URI can be constructed by adding $metadata to the
root URI e.g. /sap/opu/odata/test/ZBP_SERV_SRV/$metadata
Metadata document provides the consumers of the OData with the
information about the structure of the service, the operations allowed and the
relationship between the resources.
The below figure shows a part of the meta document which describes the
data types of the ‘BP Identification’ entity type
As you can see from the above figure, each property is described by a Type
(‘ID number’ type is Edm.String). This helps the consumers of the service to
call the service with data in the correct format.
3. OData Operations (CRUD)
3.1 Create
The create operation is used to create data in the backend system. This is the
data which is created newly and did not exist in the system.
Create can be done by using the HTTP post method. Since the data is not
existing in the system, the data needs to be provided to the POST method as
payload. If the create operation is successful, then the system return HTTP
201 response code.
3.2 Read
Read operation is used to read existing data from the backend. This is done
by using the HTTP GET operation.
It is possible to read the complete data of an entity set or only single values.
For reading single values, the key of the data must be provided.
If the read is successful, then the system returns an HTTP 200 status code.
3.3 Update
Update operation is used to update existing data in the server. This is done
by using the HTTP PUT operation. For Update, the payload with the
changed data is provided as part of the request. Also, the URI must contain
the key of the data to be updated. If the update is successful, then the system
returns a HTTP 204 response.
3.4 Delete
Delete operation is used to delete existing data from the server. We use
HTTP DELETE operation to delete the data. For deleting data, the key fields
of the data need to be provided as part of the URI. If the operation is
successful, then the system returns an HTTP 204 response.
4. Gateway Service development
Step 2: Create the first entity by importing an RFC interface. For this right-
click on Data Model and choose Import -> RFC/BOR Interface
Enter the following values in the wizard and then choose Next:
Figure 9: Enter Data Source Attributes
Select the entire data by clicking on the Checkbox beside the RFC name
Now the basic definition of the Model is done. As a next step we can
generate the necessary runtime artifacts.
Now you would notice that run-time objects have been created, as shown in
Figure 12.
Click on the Register button to register the service as shown in Figure 14.
The next screen shows the ‘Add Service’ details where you could change the
Technical name and provide a Package.
We would use the default values and enter $tmp as the package and
choose Enter (Figure 15).
Verify that the service has been registered and activated successfully
Figure 18: Registration Status
Finally, select the service in the List and click on ‘Add selected services’
screen. This then takes you to the ‘Add Service’ pop-up. Add the necessary
details and click on ‘Ok’
This has the same effect as creating the service via SEGW but this step
requires you to search for the service before it can be registered.
Step 5: Execute the Service
To execute the service, execute the following steps.
The above figure shows that the meta data was retrieved successfully with
return code ‘200’. Hence the service has been created and registered
successfully.
Step 6: Add necessary ABAP code
Until now we have created the service and registered it. But we have not
added any ABAP code to read or write data into the database.
Let us know examine the DPC EXT class generated by the service.
Figure 22: Diplay DPC_EXT class
The class provided many methods which can be redefined to write the
CRUD logic.
For our example, let us write a logic to get the details of the Business Partner
in the GET_ENTITY method.
Write the below code in the Business Partner Get Entity method.
The input to the method is IT_KEY_TAB which contains a list of values
passed in the URI.
Since our Business partner field is the key field, we could get that into a
variable then then use this to get the business partner details from the BAPI.
Please note: The BP 131 used in the above URI should be replaced with a
valid Business partner number.
Execute the service.
As
you can see from the below Figure, the data of the BP is retrieved and
displayed in the Response.
Figure 23: Retrieve data
Similarly, you could now implement the Create, Update and Delete Entity
logic by redefining the methods.
6. Summary
This chapter introduced you to OData services and took you step-by-step
through the creation of a Service via RFC/BOR Interface. With this topic
covered you can now expose the SAP data to the outside world. This can
now be displayed in Browser, Mobile, or consumed by any other application
which can read OData. In Chapter 7 we will cover one more example where
we will create an OData service via CDS annotations.
The meta model defines elements that are used to describe a business object.
The most important ones are shown in the Figure 2.
Figure 2: BOPF Meta Model
Validations: Does not make any changes on the business object instance.
Queries: Search for business object instances that fulfill certain search
criteria.
These actions are not triggered by itself and must be invoked. These can be
invoked either by
by UI
by another business object
or by an action / determination.
Categories of Actions
In general, BOPF provides the following categories for actions:
BO-Specific Actions
BO-specific actions must be created explicitly for the node that
requires a specific service implementation.
Framework Actions
Framework actions provide each BO node with core-services for
which no implementation is required. They are automatically
generated by BOPF when a node of a business object is created and
are used internally by the framework itself.
A BOPF action could be added from the Eclipse by going to the Actions
from the ROOT node.
/BOBF/IF_FRW_ACTION~RETRIEVE_DEFAULT_PARAM: This
method is deprecated.
Validations are business logic entities that are triggered in certain situations
to check different aspects of a given set of node instances.
Validations, as the name suggests, is only used to check the data and not to
modify it. They return messages and the keys of failed node instances.
A validation can be added from the Eclipse by going to the Validations page
from the ROOT node.
Example:
Let us consider a Business Partner create function. It could be a requirement
to add the passport details of a BP whenever a new BP is created. Hence
whenever a new BP creation is invoked an initial line for identification with
the Identification type as Passport should be created.
/BOBF/IF_FRW_DETERMINATION~EXECUTE: This is a
mandatory method and should be implemented with the
determination logic.
2. Creating BOPF Object from CDS views
Traditionally BOPF objects were created from transaction BOBX. But with
the new Development paradigm, BOPF is integrated with CDS views.
If you were to create a new BOPF object manually, then ideally you would
have to create the nodes of the object (e.g. Business Partner General data,
and Business Partner Identifications – item table). Then you would have
created an association and generated the object.
But if you remember from Chapter 4, the table and CDS Views already have
this information. Hence there is no need to specify this again.
The BOPF object can be created directly from CDS views by adding the
annotation -@BUSINESS_OBJECT. This annotation is an instruction to the
system to create the BOPF object when the CDS view is activated.
3. Summary
In this chapter we saw how we can use BOPF for transactional processing in
S/4 Hana applications. It is not necessary to use BOPF along with CDS
Views. BOPF should be the Framework of choice for processing of real-
world objects.
With this chapter we have covered the key components of a S/4 Hana
architecture.
You should now be able to create end-to-end application successfully.
To further guide the developers, the next chapter provided a step-by-step
guide to create a Draft based business application.
UDEMY Course
https://www.udemy.com/course/abap-development-in-
s4hana/?referralCode=775BFA3941CBE1877341
Chapter 6: Exercise - Building a draft-
enabled business object
We have always come across situations where we accidently terminate our
session by closing the Browser or we lose data when the server crashes. The
result is same - the data entered in the screen is lost and the user must
manually input the lost data again!
Now consider a similar situation when working on a document (e.g. Word)
and the system crashes. The data entered between the last save and the
current version could have been lost if we did not have any recovery
mechanism.
Let us take the problem to an Enterprise application. The thought that the
data could be lost and must be entered again would already cause some
nervousness among the users. Creating a Contract in ERP requires entering
lots of data including sensitive data like amounts, quantities etc. These must
be verified and re-verified before the Contract is finalized. Hence loosing
this data before this is saved causes lot of rework. The solution to this
problem is to use Draft-Enabled Business Object.
A draft is an interim version of an entity that is not saved in the active
version of the data. Draft is an auto-save feature which saves the data in a
separate set of tables (called Draft tables) whenever the users adds or
changes information within a business entity.
In SAP Fiori, drafts data provides the following advantages:
To keep unsaved changes if an editing activity is interrupted,
allowing users to resume editing later.
To prevent data loss if an app terminates unexpectedly.
As a locking mechanism to prevent multiple users from editing the
same object concurrently.
Such an app must always be able to deal with two versions of data:
The active data that represents the state of the business entity that is
stored in the active persistence.
The draft data that represents the transient state of a business entity
until it is permanently stored in the persistence layer as active data.
Draft Types
There are different types of Draft which can be chosen based on the
scenario:
Exclusive Draft: Here the exclusive draft document is created by the
user who is the only processor. In this case, per business entity an
active document instance may have no or just one exclusive edit draft
document. Therefore, a non-expired edit draft document blocks other
users from editing the active document.
The exercise follows a bottom-up approach and starts with the creation of
the tables for storing the BP data. It then covers the creation of CDS views
followed by BOPF object and the OData service.
This exercise is designed in a way that it can be followed easily and gives an
overall view of how the concepts discussed in this book come together to
create a good application.
Please note that in a traditional database table, the keys of the table would be
the data which forms the Key. But in the BOPF world, the key is a GUID (32
Characters long).
The code in Eclipse editor for the table would be as shown below:
@EndUserText.label : 'Business Partner header'
@AbapCatalog.enhancementCategory : #NOT_CLASSIFIED
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table zbus_part {
key client : mandt not null;
key bpkey : /bobf/conf_key not null;
partner : bu_partner;
type : bu_type;
bpkind : bu_bpkind;
bu_group : bu_bpext;
name_last : bu_namep_l;
name_first : bu_namep_f;
Now let us create a table for Storing Business Partner Identification data –
ZBP_IDENTITY
Figure 3: Display Partner Identification table
The interface view is intended to expose the required fields of the table and
rename them (if required) to make them semantically more meaningful. In
this section we will create Basic and Interface views for the tables created in
Section 2.
Create a new data definition file (under Core data services)
Create a new data definition file (under core data services) for the Business
Partner Root data.
Please note that the name of the View ends with ‘TP’. This stands for
Transactional processing and helps in identifying the views easily. The
general guidance is to use the same name as the Basic view and end with a
Suffix ‘TP’.
Select the ‘Define View’ in the Template.
The generate code is as shown below:
@AbapCatalog.sqlViewName: 'sql_view_name'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Transactional processing view for BP'
define view ZI_BUS_PARTTP as select from data_source_name {
For a transactional view the data source would be the base view created in
the previous section
Also, the list of components will the fields exposed by the base view.
The code after making the above changes would be as follows:
@AbapCatalog.sqlViewName: 'ZI_BUSPTP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Transactional processing view for BP'
define view ZI_BUS_PARTTP
as select from ZI_BUS_PART
{
key bpkey,
partner,
type,
bpkind,
bu_group,
name_last,
name_first
Please note that till now we have just created another view which selects
from the base view. To make this view a Transactional processing view
which is draft enabled we must add a few more annotations.
VDM view type
@VDM.viewType: #TRANSACTIONAL
@ObjectModel.compositionRoot: true
@ObjectModel.usageType.dataClass: #TRANSACTIONAL
@ObjectModel.modelCategory: #BUSINESS_OBJECT
The Final code for this Transactional Processing view would be as follows:
@AbapCatalog.sqlViewName: 'ZI_BUSPTP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@VDM.viewType: #TRANSACTIONAL
@ObjectModel.transactionalProcessingEnabled: true
@ObjectModel.modelCategory: #BUSINESS_OBJECT
@ObjectModel.compositionRoot: true
@ObjectModel.writeDraftPersistence: 'ZIBUSPTPD'
@ObjectModel.writeActivePersistence:'ZBUS_PART'
@ObjectModel.draftEnabled:true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.usageType.dataClass: #TRANSACTIONAL
{
key bpkey,
partner,
type,
bpkind,
bu_group,
name_last,
name_first
}
Save and Activate the View.
The activation of the TP view generates the following 2 objects:
Draft table for storing the temporary data. This is the table name that
was specified as part of the Annotations.
BOPF object for the Business partner with the same as the
Transactional processing view.
This can either be displayed in Eclipse or in the BOBX transaction.
(you might have to refresh the View in the Eclipse to see the object)
Figure 7: Display Generated BOPF object
This object only has one node as the Identification View does not have any
association with the BP General data view.
Change the data source, provide a Sql View name and add the components.
The code at this stage would be as follows:
@AbapCatalog.sqlViewName: 'ZV_BP_IDTP'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'TP view for BP Identification'
@ObjectModel.writeDraftPersistence: ''
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.usageType.dataClass: #TRANSACTIONAL
Please note that for this view we will not add the below annotations.
@ObjectModel.compositionRoot: true
@ObjectModel.modelCategory: #BUSINESS_OBJECT
This is because the identification data is a sub node of the BP general data
node. The association to the BP TP View would be created in the next
section.
Save and Activate the TP View.
The final code after executing the above-mentioned steps is as follows:
@AbapCatalog.sqlViewName: 'ZV_BP_IDTP'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@ObjectModel.writeDraftPersistence: 'ZBPIDENTITD'
@ObjectModel.writeActivePersistence:'ZBP_IDENTITY'
@ObjectModel.draftEnabled: true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.usageType.dataClass: #TRANSACTIONAL
In the previous step we have created the Basic views and the
Transactional processing views. But these views are independent. In this
Step we will create an association between the views so that the
Identification data is created as a Sub-node of the BP data. This will also
regenerate the BOPF object.
ZI_BUS_PARTTP:
@AbapCatalog.sqlViewName: 'ZI_BUSPTP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@VDM.viewType: #TRANSACTIONAL
@ObjectModel.transactionalProcessingEnabled: true
@ObjectModel.modelCategory: #BUSINESS_OBJECT
@ObjectModel.compositionRoot: true
@ObjectModel.writeDraftPersistence: 'ZIBUSPTPD'
@ObjectModel.writeActivePersistence:'ZBUS_PART'
@ObjectModel.draftEnabled:true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.usageType.dataClass: #TRANSACTIONAL
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
_BPIdent
ZI_BP_IDENTITYTP:
@AbapCatalog.sqlViewName: 'ZV_BP_IDTP'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@VDM.viewType: #TRANSACTIONAL
@ObjectModel.transactionalProcessingEnabled: true
@ObjectModel.writeDraftPersistence: 'ZBPIDENTITD'
@ObjectModel.writeActivePersistence:'ZBP_IDENTITY'
@ObjectModel.draftEnabled: true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.usageType.dataClass: #TRANSACTIONAL
}
Now Activate both the TP views together.
After activation the BOPF object is regenerated. The object now has a Sub-
node for Identification data.
Check the data of the Draft and Active Partner table. This should be
empty as no data has been created
Figure 12: Display entires in Draft table
Execute the BOBT transaction and Create a new entry for the partner
data
Click on the Create New Entry button.
Figure 14: Create new BP
To Enter the details of the Identification for the BP data entered, Select
the BP data and click on ‘Execute Association’.
Figure 16: Execute Identification Assiciation
Let us now Execute the Save Action so that the data is copied from
the Draft to the Active table and the data in the Draft table entry is
deleted.
For this, we must execute 3 steps:
Preparation
Validation
Activation
Now check the data in the Draft and Active tables. The data in the Draft
table has been deleted and the data has been copied to the Active table.
The new UUIDs of the Active table were of course generated.
Like the previous steps, replace the SQL View, data source and add the
components.
Here the consumption view would select from the Transactional processing
view.
Add the following Annotations for the consumption view
@Metadata.allowExtensions: true
@VDM.viewType: #CONSUMPTION
@ObjectModel.createEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.draftEnabled: true
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingDelegated: true
@AbapCatalog.sqlViewName: 'ZC_BUSPTP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Partner Basic data Consumption view'
@Metadata.allowExtensions: true
@VDM.viewType: #CONSUMPTION
@ObjectModel.createEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.draftEnabled: true
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingDelegated: true
key bpkey,
partner,
type,
bpkind,
bu_group,
name_last,
name_first
@Metadata.allowExtensions: true
@VDM.viewType: #CONSUMPTION
@ObjectModel.createEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.draftEnabled: true
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingDelegated: true
key id_key,
parentkey,
type,
idnumber,
institute,
entry_date,
valid_date_from,
valid_date_to,
country,
region
}
@Metadata.allowExtensions: true
@VDM.viewType: #CONSUMPTION
@ObjectModel.createEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.draftEnabled: true
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingDelegated: true
key bpkey,
partner,
type,
bpkind,
bu_group,
name_last,
name_first,
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
_BPIdent
}
@AbapCatalog.sqlViewName: 'ZC_BP_IDTP'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'BP Identification data Consumption View'
@Metadata.allowExtensions: true
@VDM.viewType: #CONSUMPTION
@ObjectModel.createEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.draftEnabled: true
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingDelegated: true
key id_key,
parentkey,
type,
idnumber,
institute,
entry_date,
valid_date_from,
valid_date_to,
country,
region,
@ObjectModel.association.type:
[#TO_COMPOSITION_ROOT,#TO_COMPOSITION_PARENT]
_BPHeader
}
In the previous steps we create the Transactional View for CRUD operations
and Consumption view for displaying the data in the UI. But the Views can
only be consumed form outside world via oData service.
In this step we will generate the oData service for the views so that we can
Create and Display the data from UI5.
There are multiple ways to create OData service from CDS Views. Here, we
will cover 2 ways. But you would be required to follow only one of the
approaches mentioned below.
a) Odata via CDS views Annotation
b) Referenced Data source
The preferred approach is to use ‘Referenced Data source’ but the approach
via CDS Annotation is easy and works well for small projects / POCs.
To test the service, Select the service and go the SAP Gateway Client.
Select the URI option as ‘$metadata’ and check the service.
Now let us try to retrieve the data which was created. We had created an
entry for the BP General data and saved it in the active table via BOPF
transaction. It should now be possible to retrieve the data.
In the client enter the Request URI as below:
/sap/opu/odata/sap/ZC_BUS_PART_CDS/ZC_BUS_PART(bpkey=guid'047D7B8B-FE3F-1ED8-
B983-B6600DBE4A2B',IsActiveEntity=true)
Please note that you will have to replace the ‘bpkey’ value with the
value of the GUID in your table.
Execute the Request.
The data in the table is returned as shown below:
A new SEGW project will be created with empty data model like below.
Now right-click on the Data Model choose Reference and then Data Source.
Figure 36: Create Data Model using Referenced Data Sources
A new Reference Data Source wizard will open like below. Choose ABAP
CDS view using the F4 help and hit Next.
In the next wizard step check the information and hit Finish.
Figure 38: Select the CDS Entity Exposures
ABAP CDS entity will be successfully referenced in the SEGW project and
new folder Data Source References will be created under Data Model folder.
Figure 39: Display the Exposures via SADL structure
As you can see from above, the data is retrieved and displayed.
In the previous steps we have created all the backend building blocks
required to have the application running (Expect UI, as this is not the focus
of this book). But we are yet to add business logic.
We will now extend this application by adding various business logic.
Following are some examples of common requirements you might come
across in you project work
Create a Default Identification data in the Identification table as soon
as the BP basic data is entered.
This can be achieved by creating a Determination
Validate that correct value of Business Partner Group is entered when
creating the BP.
This can be done through a Validation
As you would have noticed, the system automatically proposes the name of
the class based on the name of the Determination. Click Finish and activate
the Object.
Once done, you would notice that the proposed class is already created with
no code.
Figure 44: Display Determination class
" IF the draftkeys are not initial then we proceed. This is because we
" want to create the Identification data only if the BP is being created
IF draftkeys IS NOT INITIAL.
TRY.
"Read the associations.
/bobf/cl_frw_factory=>get_configuration( iv_bo_key =
is_ctx-bo_key )->get_assoc_tab(
IMPORTING
et_assoc = DATA(assoctab)
).
CATCH /bobf/cx_frw.
RETURN.
ENDTRY.
" Get the BP Identification assiciation key
DATA(targetnodekey) = assoctab[ assoc_key =
zif_i_bus_parttp_c=>sc_association-zi_bus_parttp-_bpident ]-target_node_key.
" Get the BP identification data for the current BP. The identificaiton data should only be created i
f it is not
" existing. Hence only in the first call the value of bpidentifications will be empty
io_read->retrieve_by_association( EXPORTING
iv_node = is_ctx-node_key
it_key = draftkeys
iv_association = zif_i_bus_parttp_c=>sc_association-zi_bus_parttp-
_bpident
iv_fill_data = abap_true
IMPORTING
et_data = bpidentifications ).
" If no BP identification exists, then create a new identification
IF lines( bpidentifications ) EQ 0.
" Input the default values
bp_ident_create-type = 'FS0002'.
bp_ident_create-entry_date = sy-datum.
bp_ident_create-valid_date_from = sy-datum.
ENDIF.
ENDMETHOD.
You would notice that an entry for the BP Identification is already created
with the default data.
As you have seen from the above steps, the new programming model
simplifies the development and reduces the time to create an end-to-end
application. This helps the team in focusing on the complex real-world
business logic.
With this we come to the end of the exercise and hope it solves many of your
queries around building a new application from scratch.
UDEMY Course
https://www.udemy.com/course/abap-development-in-
s4hana/?referralCode=775BFA3941CBE1877341
Conclusion
The chapters covered in this book took you through the key components in
S/4 Hana.
Chapter 1 and 2 helped you get started with the Eclipse and New language
features. Chapter 3, 4 and 5 covered he essential information required to
develop applications, and finally Chapter 6 provided a detailed step-by-step
guide in building a complete draft-enabled application.
Whether you are a consultant or an application developer, this book should
have helped you in understanding the new programming model and will be
of help in your daily work.
Finally let me ‘thank you’ for reading this book.
Please feel free to provide your valuable feedback by writing to me at
[email protected] .
Also, if you need more course material or guidance then feel free to reach
me.
More books from Mark
SAP ABAP Core Data Services
This book
introduces ABAP
Core Data Services.
CDS is part of
SAP's new ABAP
development
paradigm. It is
important for all
SAP developers to
learn Core data
services and this
book aims to ease
the process of
learning CDS.The
book is divided into
five chapters. Each
chapter focuses on
a specific function
and provides
This book is available in both eBook
and Paperback formats. examples relating
to it.
Chapter 1:
Introduction to
Core Data Services
Chapter 2: CDS
Modelling concepts
and Syntax
Chapter 3: Access
Control
Chapter 4: CDS
View extension
Chapter 5: Create a
List Application
with CDS Views
eBook
https://www.amazon.com/dp/B07Y3KZ6SL
Paperback:
https://www.amazon.com/dp/1671824253
Chapter 1 and 2
introduces you to
Gateway and OData,
and Chapters 3 and 4
describe the process
of creating the OData
service in detail.
Following different
ways of Service
creation is covered as
part of this book:
•ABAP Code-based
implementation
•Service generation
via RFC/BOR
interface
•Service generation
through CDS
Consumption views
•Service generation
through CDS
Annotation
@Odata.publish
•Extending an existing
OData service
This book is available in both
eBook and Paperback formats.
eBook
https://www.amazon.com/dp/B07ZFW5KL9
Paperback:
https://www.amazon.com/SAP-Gateway-OData-Mark-
Anderson/dp/1701489546/ref=tmm_pap_swatch_0?
_encoding=UTF8&qid=&sr=
Comprehensive SAP ABAP Interview Questions
and Answers
Paperback:
https://www.amazon.com/dp/109687380X