Tutorial Creating a Simple Business Object

48
Creating a Simple Business Object in BOPF 21.12.2009

Transcript of Tutorial Creating a Simple Business Object

Page 1: Tutorial Creating a Simple Business Object

Creating a Simple Business Object in BOPF

21.12.2009

Page 2: Tutorial Creating a Simple Business Object

2

Table of Contents

1. Authors ................................................................................................................................... 3

1. Scope of the Document ...................................................................................................... 4 2. Introduction to BOPF ......................................................................................................... 4

2.1. Business Object Processing Framework ...................................................................... 4 2.2. Implementation Considerations ................................................................................... 4 2.3. Business Object ........................................................................................................... 5

2.4. How to check the Business Object .............................................................................. 5 3. Creating a Simple BO ........................................................................................................ 5

3.1. BO Creation ................................................................................................................. 5

3.2. Maintaining BO Settings ............................................................................................. 6 3.3. Business Object Nodes ................................................................................................ 7 3.4. Creating and Generating the DDIC Elements ........................................................... 10

4. Adding a Sub Node to the BO .......................................................................................... 13

5. Query ................................................................................................................................ 15 5.1. Creation of a Query ................................................................................................... 15

6. Alternative Keys ............................................................................................................... 23 6.1. Creation of Alternative Keys ..................................................................................... 23

7. Validation ......................................................................................................................... 26 7.1. Creation of a Validation ............................................................................................ 26 7.2. Implementation of Validation .................................................................................... 30

8. Determination ................................................................................................................... 34

8.1. Creation of a Determination ...................................................................................... 34 8.2. Implementing a Determination .................................................................................. 38

9. Action ............................................................................................................................... 40

9.1. Creation of Action ..................................................................................................... 40 9.2. Implementing an Action ............................................................................................ 42

10. Associations .................................................................................................................. 43 10.1. Association to a Delegated node ............................................................................ 44 10.2. Creating Association to Dependent Object ............................................................ 44

11. Testing the Business Object .......................................................................................... 46

Page 3: Tutorial Creating a Simple Business Object

3

1. Authors

Role Name

Author Santosh Kumar Goud Laddipelly

Author Frank Mock

Reviewer DL Suite_V&C_Architecture Team

Page 4: Tutorial Creating a Simple Business Object

4

1. Scope of the Document This document should be a general help for people who want to do first steps with BOPF in

the Business Suite. It will cover the main steps that are needed to define a BO in the BOPF

framework. The main aim of this document is that it should be useful to everyone who is

using the BOPF for first time ever.

Here we are showing how to

Create a Business Object by name ZMY_CUSTOMER

Add nodes to the BO

Create the DDIC elements for a BO

Create a query for the BO

Create an Alternative Key for the BO

Create a Validation for the BO

Create a Determination for the BO

Create an Action for the BO

Create an Association for additional nodes

2. Introduction to BOPF

2.1. Business Object Processing Framework

The Business Object Processing Framework (BOPF) is a framework used to implement

Enterprise Services Oriented Architecture (eSOA)-compliant business objects. It provides

integrated functionality for business object implementation and leads to a common

programming model by design. BOPF controls the application businesses logic as well as the

data retrieval of the buffer and persistency layer. The main design principles are a clear

separation of the business logic and the buffering of data as well as a clear structuring of the

business logic in small parts with a clear separation of changing and checking business logic.

This framework offers an incremental and modular approach to your business object’s

implementation. You can quickly set up an initial, running prototype of your business object

with its most basic services already enabled (such as create, retrieve, updated, delete, save and

query). BOPF supports advanced enhancement and configuration options at every level, such

as defining the specific business logic and performance optimization attributes that are unique

to your business object.

2.2. Implementation Considerations

BOPF provides flexibility and adaptability while implementing your business object by

offering a complete overview of your business object’s internal structure, business logic and

behavior. The framework also offers convenient standardization and flexibility. You can

implement your business object using BOPF’s built-in buffers and data access classes (which

you can use via configuration), or implement your own. BOPF also integrates ABAP unit test

capabilities for an overall higher quality of your business object’s implementation.

The advantages of implementing BOPF are as follows:

Supports your business object implementation with multiple generic functions and full

ESOA-compliance

Gives you a complete overview of your internal business object structure, business

logic and behavior

Page 5: Tutorial Creating a Simple Business Object

5

Offers you the possibility to implement your Business Object in an incremental and

modular way

Leads to a high reuse of your business methods

Provides you with a running prototype in a very short time frame

Engineering approach for business object implementation; many parts are configured,

not implemented

Providing a common transaction model

Central user interface to configure your business object, which provides:

o Seamless integration with the ABAP development workbench

o Same look and feel as that of the backend systems

o Forward navigation support and creation of assigned classes, data structures

and database tables

o Versioning of the business object model and configuration

2.3. Business Object

Business Object represents

A view on a well defined & outlined business content

Well known in the business world (for example, in an international standard or

industry best practice)

A self-contained (capsule), independent business concept

Transaction to access BOPF in Business Suite is /BOBF/CONF_UI.

2.4. How to check the Business Object

There are some additional checks which can be utilized while creating the BO

Standard Check which contains only short-running configuration checks ( )

Extended Check which contains also long-running configuration checks

( )

Performance Check which checks the configuration of the BO (in the menu path

Business ObjectCheckPerformance Check)

Check & Correct which is able to automatically correct some minor errors of the

business object configuration. (in the menu path Business ObjectCheckCheck &

Correct). In contrast to it, the standard/ extended check does not change your business

objects’s configuration.

You can use these checks at any point of time during the creation of the Business Object. It is

strongly recommended to run the extended check at least before the transport of the Business

Object. The extended check indicates, if the execution of the Check & Correct function is

necessary.

3. Creating a Simple BO This chapter is about the creation of a new business object by the help of the BOBF

Configuration UI.

3.1. BO Creation

When you create a Business Object in a Business Suite have to create the BOPF BO model

manually via the BOPF Configuration UI tool.

Page 6: Tutorial Creating a Simple Business Object

6

1. Start the BOPF Configuration UI (transaction /BOBF/CONF_UI from your

development system)

2. Create a Business Object by clicking create icon or by pressing F5

3. Enter the Business Object’s name you want to create and press enter (leave the super

business object field empty). In our example it is named ZMY_CUSTOMER.

4. You will be entering into a BO level as shown in the figure below:

5. Give a small description about the BO e.g., “My first BOPF BO”

6. Maintain the BO prefix “ZMY”. The prefix is used when BOPF proposes names for

repository elements. This will be done later on. A Business Object must either have a

prefix or a namespace (or both) in order to clearly separate its BOPF and DDIC

entities from other Business Objects.

3.2. Maintaining BO Settings

Now we have to maintain the necessary settings required on the BO-level which can be done

by the following Menu path Extras Propose Repository Names which displays the image as

shown below. At this point in time we are proposing names for repository objects at the BO

level only, whereas the same procedure should be followed at the node level as well.

Here we only select the constant interface at the BO-level. The constant interface carries

constants for all the elements of the BO that are needed to access the BO (for e.g., constants

for node, keys, associations, etc.).

Page 7: Tutorial Creating a Simple Business Object

7

As buffer class and data access class we use the default implementations provided by BOPF

which are already maintained in the corresponding fields. Alternatively we could also

generate our own classes. If we would do so, we would propose the names for theses classes

as well.

After selecting the entry Constant Interface Name press ok.

Till now we have just named the constant interface. Now we have to generate the same by the

following menu path ExtrasGenerate Repository ObjectsGenerate Constant Interface.

As a result the interface is generated and activated.

3.3. Business Object Nodes

The root node is created by default for every BO. In order to configure it, double click on the

root in the navigation pane on the left hand side of the screen as shown in the figure

(highlighted in red) to enter into the root node:

Page 8: Tutorial Creating a Simple Business Object

8

Give a small description about the root node

You can also change the root node name depending on your convenience

We keep the flags Node Can Be Loaded Separately and Node Can Be Locked

Separately.

Now we propose the names for a couple of DDIC elements. For each node of the business

object BOPF needs these elements during the handling of the business object’s data and for

the persistency of this data. We propose the names by following the menu path Extras

Propose Repository Names:

Data Structure: DDIC structure which contains the persistent attributes (fields) of the

node

Transient Data Structure (Data Structure tr.): DDIC structure which contains the

transient attributes of the node. In contrast to the persistent attributes, transient

attributes are only stored in the working memory and not in the persistency (e.g.

database).

Combined Structure: DDIC structure which contains the technical key fields and the

Data Structure and the Transient Data Structure as include

Combined Table Type: internal table with Combined Structure as line type. The table

type is used by BOPF to hold the data in memory and during communication with a

consumer, e.g. UI

Database Table: The database table which contains the node data. In the tutorial we

use a simple 1:1 relationship between nodes and database tables, i.e. each node is

stored in its own database table. Alternative approaches are possible.

Page 9: Tutorial Creating a Simple Business Object

9

You can see the figure below which displaying all the names as selected.

Page 10: Tutorial Creating a Simple Business Object

10

Here you can also change the names of the data structures and database table based upon your

requirements before the generation of the DDIC Elements. For this tutorial we change the

proposed names in order to reflect the BO name in the structures. Thus change the names as

follows:

Combined Structure name to ZMY_S_CUST_ROOT

Combined Table Type name to ZMY_T_CUST_ROOT

Data Structure to ZMY_S_CUST_ROOT_D

Data Structure (tr.) to ZMY_S_CUST_ROOT_DT

Database Table to ZMY_D_CUST_ROOT

3.4. Creating and Generating the DDIC Elements

After proposing the names for the required data types they can be generated respectively

created manually. The Data Structure and the Transient Data Structure always have to be

created manually since they contain the application specific fields of a node. Thus the next

step is to create these DDIC structures.

1. Create Data Structure ZMY_S_CUST_ROOT_D

Create the Data Structure by double clicking the name ZMY_S_CUST_ROOT_D

Create the structure in the DDIC as shown in the following figure

Page 11: Tutorial Creating a Simple Business Object

11

2. Create Data Structure transient ZMY_S_CUST_ROOT_DT

Create the Data Structure by double clicking the name

ZMY_S_CUST_ROOT_DT

Create the structure in the DDIC as shown in the following figure

Don’t forget to activate the structures!

3. Now we can generate the remaining data structures using the BOPF generation feature

by following the menu path Extras Generate Repository Objects Generate

Dictionary Elements by which a window pops up to confirm the elements to be

generated.

Page 12: Tutorial Creating a Simple Business Object

12

Generate the data types by selecting Combined Data Structure, Combined Table Type

and Database Table in the popup as shown in the figure.

Now you can check whether the structures are generated properly by double clicking

them and navigating into the DDIC.

Note: You have to regenerate your constant interface after creating every new elements in

order to add the new or changed elements.

Your Business Object can be already used. You can just test it by the help of the generic

BOPF Test UI application - click on the execute button or press F8.

Page 13: Tutorial Creating a Simple Business Object

13

You can see the hierarchical tree of the Business Object created by you. Here double click the

root node click on create button in the right panel. Now you can create and save the data.

4. Adding a Sub Node to the BO You can enter additional nodes and sub nodes to your BO via the context menu in the

Business Object Detail Browser as shown in the figure below. Here you have to select the

Node Type

Standard Node for adding a “normal” Business Object Node

Delegated Node for adding a Dependent Object to your node structure

Business Object Representation Node for adding a cross BO reference to your BO

model

After this step there will be a pop up asking for the name of the sub node. Here enter the name

and the data model as shown below and press the Final button.

Page 14: Tutorial Creating a Simple Business Object

14

The Guided Procedure also allows to maintain an attribute mapping, but this is not required in

the Business Suite as we do not have any proxy Business Object. We also don’t maintain a

persistence mapping since the database table we use will have the same fields as the node’s

data structure.

Now you can see the sub node attached to the BO in the node structure in the Business Object

Detail Browser and you can create the data structure ZMY_S_BANK_DETAILS_D for the

Bank Details node as shown in the following figure. Double click structure name in the node

maintenance screen or go to SE11 and create the structure.

Page 15: Tutorial Creating a Simple Business Object

15

Afterwards repeat the steps from chapter 4 to generate the Combined Data Structure, the Data

Table and the Database Table.

5. Query

5.1. Creation of a Query

A query allows you to perform searches on business object nodes. For each node one or

several queries might be created. They provide the initial point of access to business objects.

Each query has an associated parameter structure. The result of the query can be

1. a set of all the node instance IDs or

2. a set of node instances including IDs and data or

3. a set of records in an internal table

that match the query criteria. Here in our example we are creating a query which is used to

select customer root nodes with using the data structure of the root node as query parameter

structure and the Combined Data Table as result table (option 3 from the list above). You can

create a query by accessing the tree on your left hand side as shown in the diagram.

Page 16: Tutorial Creating a Simple Business Object

16

After selecting the Create Query command a pop up comes up where you have to enter the

name of the query and the description. Fill the fields as shown in the figure below.

Page 17: Tutorial Creating a Simple Business Object

17

In the query we define a Query Result Type, i.e. the query implementation has to fill an

internal table that is type with Result Table Type. After query execution, BOPF directly

returns the table to the caller of the query. The result table is not buffered in BOPF. In

contrast, a query that does not specify a Result Table Type only returns the node IDs. Using

these node IDs BOPF then triggers internally the retrieve method in order to read the node

data if that is requested by the caller. As result, the BOPF buffer is filled with all node

instances corresponding to the queried node IDs. Thus the Result Table Type in a Query

should be used if the result must not be buffered in BOPF and you want to achieve the best

performance and memory consumption.

Now we create the query implementation: After you maintained the fields as shown in the

figure above press the finalize button. In the query details screen double click on the name of

the query class. Process the pop-ups to create the class, redefine the query method in the

Page 18: Tutorial Creating a Simple Business Object

18

created class and copy the code snippet listed below into it. Afterwards save and activate the

class.

METHOD /bobf/if_frw_query~query.

DATA:

ls_key TYPE /bobf/s_frw_key,

lt_selection TYPE /bobf/t_frw_query_selparam,

ls_selection TYPE REF TO /bobf/s_frw_query_selparam,

ls_sorting TYPE /bobf/s_frw_query_sorting,

lv_index TYPE i,

lv_max_rows TYPE i,

lv_where TYPE string,

lt_where TYPE STANDARD TABLE OF string,

lv_order TYPE string,

lt_order TYPE STANDARD TABLE OF string,

lt_range_key TYPE RANGE OF /bobf/conf_key,

ls_range_key LIKE LINE OF lt_range_key,

ls_comp TYPE cl_abap_structdescr=>component,

lt_comp TYPE cl_abap_structdescr=>component_table,

ls_range_r TYPE REF TO data,

lo_range TYPE REF TO cl_abap_structdescr,

lt_range TYPE RANGE OF string, "#EC NEEDED

ls_range LIKE LINE OF lt_range,

lt_result_db TYPE STANDARD TABLE OF zmy_d_cust_root,

ls_result TYPE zmy_s_cust_root,

lt_result TYPE zmy_t_cust_root,

lx_root TYPE REF TO cx_root.

FIELD-SYMBOLS:

<ls_result_db> TYPE zmy_d_cust_root,

<ls_range> TYPE any,

<lt_range> LIKE lt_range.

CLEAR:

et_key,

et_data,

es_query_info.

* build where condition for key filter

IF it_filter_key IS NOT INITIAL.

LOOP AT it_filter_key INTO ls_key.

ls_range_key-option = 'EQ'.

ls_range_key-sign = 'I'.

ls_range_key-low = ls_key-key.

INSERT ls_range_key INTO TABLE lt_range_key.

ENDLOOP.

lv_where = 'DB_KEY IN LT_RANGE_KEY'.

APPEND lv_where TO lt_where.

ENDIF.

* build where condition from selection

IF it_selection_parameters IS NOT INITIAL.

lt_selection = it_selection_parameters.

SORT lt_selection BY attribute_name.

LOOP AT lt_selection REFERENCE INTO ls_selection.

AT NEW attribute_name.

ls_comp-name = ls_selection->attribute_name.

ls_comp-type ?= cl_abap_typedescr=>describe_by_data( lt_range ).

APPEND ls_comp TO lt_comp.

ENDAT.

ENDLOOP.

Page 19: Tutorial Creating a Simple Business Object

19

lo_range = cl_abap_structdescr=>create( lt_comp ).

CREATE DATA ls_range_r TYPE HANDLE lo_range.

ASSIGN ls_range_r->* TO <ls_range>.

LOOP AT lt_selection REFERENCE INTO ls_selection.

AT NEW attribute_name.

IF lt_where IS NOT INITIAL.

lv_where = 'AND'.

APPEND lv_where TO lt_where.

ENDIF.

CONCATENATE '<LS_RANGE>-' ls_selection-

>attribute_name INTO lv_where.

ASSIGN (lv_where) TO <lt_range>.

ENDAT.

MOVE-CORRESPONDING ls_selection->* TO ls_range.

INSERT ls_range INTO TABLE <lt_range>.

AT END OF attribute_name.

IF ls_selection-

>attribute_name = /bobf/if_conf_c=>sc_attribute_name_key.

ls_selection->attribute_name = 'DB_KEY'.

ENDIF.

CONCATENATE ls_selection->attribute_name 'IN' lv_where

INTO lv_where SEPARATED BY space.

APPEND lv_where TO lt_where.

ENDAT.

ENDLOOP.

ENDIF.

* build order by table

LOOP AT is_query_options-sorting_options INTO ls_sorting.

IF ls_sorting-ascending = abap_true.

CONCATENATE ls_sorting-

attribute_name 'ASCENDING' INTO lv_order SEPARATED BY space.

ELSE.

CONCATENATE ls_sorting-

attribute_name 'DESCENDING' INTO lv_order SEPARATED BY space.

ENDIF.

APPEND lv_order TO lt_order.

ENDLOOP.

* default order if paging is active

IF sy-subrc <> 0 AND is_query_options-paging_options-

paging_active = abap_true.

lv_order = 'DB_KEY ASCENDING'.

APPEND lv_order TO lt_order.

ENDIF.

IF is_query_options-paging_options-paging_active = abap_true AND

is_query_options-paging_options-start_key IS NOT INITIAL.

IF lt_where IS NOT INITIAL.

lv_where = 'AND'.

APPEND lv_where TO lt_where.

ENDIF.

lv_where = 'DB_KEY GT IS_QUERY_OPTIONS-PAGING_OPTIONS-START_KEY'.

APPEND lv_where TO lt_where.

ENDIF.

IF is_query_options-maximum_rows > 0.

lv_max_rows = is_query_options-maximum_rows.

IF is_query_options-paging_options-paging_active = abap_true AND

Page 20: Tutorial Creating a Simple Business Object

20

is_query_options-paging_options-start_row IS NOT INITIAL.

lv_max_rows = 0.

ENDIF.

ENDIF.

TRY.

SELECT * FROM zmy_d_cust_root

UP TO lv_max_rows ROWS

INTO CORRESPONDING FIELDS OF TABLE lt_result_db

WHERE (lt_where)

ORDER BY (lt_order). "#EC CI_DYNTAB "#EC CI_DYNWHERE

es_query_info-count = sy-dbcnt.

LOOP AT lt_result_db ASSIGNING <ls_result_db>.

MOVE-CORRESPONDING <ls_result_db> TO ls_result.

ls_result-key = <ls_result_db>-db_key.

INSERT ls_result INTO TABLE lt_result.

ls_key-key = <ls_result_db>-db_key.

INSERT ls_key INTO TABLE et_key.

ENDLOOP.

CATCH cx_sy_sql_error INTO lx_root.

ASSERT ID /bobf/dac CONDITION 0 = 1.

RAISE EXCEPTION TYPE /bobf/cx_dac

EXPORTING

previous = lx_root

mv_node = is_ctx-node_key.

ENDTRY.

* fill export parameters

IF is_query_options-paging_options-paging_active = abap_true AND

is_query_options-paging_options-start_row IS NOT INITIAL.

IF is_query_options-paging_options-start_row > 1.

DELETE lt_result TO is_query_options-paging_options-start_row - 1.

ENDIF.

IF is_query_options-maximum_rows > 0.

lv_index = is_query_options-maximum_rows + 1.

DELETE et_key FROM lv_index.

ENDIF.

ENDIF.

et_data = lt_result.

ENDMETHOD.

Note: You have to regenerate your constant interface after creating every new object so as to

maintain the constants for all the elements.

Now you can test the query function using the BOPF test tool. Once the test tool has opened,

press enter and select the query as shown in the figure below. Double click the query,

maintain selection criteria as you want and execute it by press continue.

Page 21: Tutorial Creating a Simple Business Object

21

If you execute the query, you will recognize, that the results are only displayed in a popup

(see next picture).

At the time of writing this document it is not possible to take over the result of a query with a

Result Table Type into the main window. Thus we will quickly create an additional query,

which does not use the Result Table Type just to allow you to use the test tool. In order to

create the query go back into the BOPF Configuration UI and create a query again for the root

node with the settings shown in the figure below:

Page 22: Tutorial Creating a Simple Business Object

22

Please be aware of the difference between this query and the one with Result Table Type: The

new query does not specify an implementation class and remember the difference in the

buffer handling of the result: the results of this query are always buffered until the end of the

transaction (in most use cases this is not desirable). The query is executed by the data access

class of that node (/BOBF/CL_DAC_TABLE). This class has a generic query implementation,

which can be used when

1. The search parameters map to the node’s attributes and

2. No Result Table Type is used

In the future the data access class may also support the Result Table Type, but at the time of

writing that document it is not supported.

Now you can test the BO again as described above and using the newly created query.

Page 23: Tutorial Creating a Simple Business Object

23

6. Alternative Keys

6.1. Creation of Alternative Keys

An Alternative Key is a defined set of attributes of a business object node that identifies a

single (unique key) or a set of (non unique key) node instance. Alternative Keys are used

typically to model semantic keys of BO node.

From a definition point of view an Alternative Key is quite similar to a query. One major

difference is that a query searches by definition on the database only, whereas an Alternative

Key can search first within the transactional buffer and might afterwards also search on the

database if necessary. If the before image is requested it is identical to a query. The second

distinction is that an Alternative Key can be a key for the corresponding node. That means for

each combination of field values of the Alternative Key leads to exactly one result and

therefore to one Node ID. That information can be used to optimize the search in the

transactional buffer because as the search can be stopped if all requested node instances are

found. The third difference is that a query is defined as such over fields that can be located

everywhere within the BO Model. In some cases the query fields are even not part of the

Model at all. However the fields of an Alternative Key are all defined as fields of one node.

To create an Alternative Key we can use the tree on the left side of the screen as shown in the

figure below.

Maintain the name of the Alternative Key and provide a small description for your

understanding. In our example the name of the Alternative Key is CUSTOMER_ID. In

addition you maintain the Data Type, the Data Table Type and the Secondary Key.

Page 24: Tutorial Creating a Simple Business Object

24

In general Alternative Keys can be defined in two different ways

1) If an Alternative Key comprise several fields, you have to maintain a DDIC structure

in the Data Type field. In this case, each field in the structure has to map to a field in

the node’s Combined Data Table.

2) If an Alternative Key comprises a single field only, you can maintain a Data Element

in the Data Type field. In this case, the Name of the Alternative Key has to map to a

field in the node’s Data Type. Following this tutorial you define the Alternative Key in

this way. The Data Type field contains the Data Element

/BOBF/DEMO_CUSTOMER_ID and the name of the Alternative Key

CUSTOMER_ID maps to the field CUSOMTER_ID in structure

ZMY_S_CUST_ROOT_D. But you could also maintain a structure with a single field

here.

In the Data Table Type field you maintain an internal table which uses the type maintain in

the Data Type field as line type. In order to follow the example you need to maintain table

ZMY_T_CUSTOMER_ID that uses the data element /BOBF/DEMO_CUSTOMER_ID as line

type.

You also maintain a Secondary Key in order to achieve a good performance when using the

alternative key. The secondary key you maintain here refers to the node’s Combined Table

Type (not to the Data Table Type of the Alternative Key). Thus you have to maintain the

secondary key in the node’s Combined Data Table. BOPF takes over the secondary key

maintenance for you when you use the feature to generate DDIC Elements. You will do that

now: After you maintained the Alternative Key as shown in the figure above, generate the

relevant DDIC elements by following the menu path ExtrasGenerate Repository

ObjectsGenerate DDIC Elements. Maintain the settings in the popup as shown in the

picture below and click the generation button.

Page 25: Tutorial Creating a Simple Business Object

25

If you now look into the definition of the Combined Data Table Type of the node in the DDIC

you will see that a secondary key with the name CUSTOMER_ID and the component

CUSTOMER_ID was created.

Page 26: Tutorial Creating a Simple Business Object

26

Note: You have to regenerate your constant interface after creating every new object so as to

maintain the constants for all the elements

Now you can test the Alternative Key using the test tool. When you open the test tool by

pressing F8 you can find also the Alternative Key CUSTOMER_ID created by you in the

Meta Data and Instance Tree:

Double click the Alternative Key CUSTOMER_ID by which a pop up is opened

Click on the Append Row button and give a customer Id which is already existing in

the database

Click on continue to see the effect

7. Validation

7.1. Creation of a Validation

A Validation is an element of a business object node that describes some internal checking

business logic on the business object. There are two types of Validations

1. Action Validation to check if an action is allowed

2. Consistency Validation to check the consistency of the Business Object

Page 27: Tutorial Creating a Simple Business Object

27

An Action Validation is assigned to object-specific actions (e.g. Release) and to the

framework actions Create, Update, Delete and Save. An Action Validation is carried out

when an action is called but before it is performed.

A Consistency Validation can be used to check the consistency of a business object. They can

be triggered after a modification (Create, Update, Delete) of a node or during the execution of

the framework action check.

To create a validation you can use the Business Object Detail Browser. During the creation of

a validation you also have to decide if you want to create a Consistency Validation or an

Action Validation. In our example you create a Consistency Validation which is used to check

the uniqueness of the Customer ID after entering it.

In order to create the validation highlight the root node. In the context menu execute

command CreateCreate ValidationConsistency Validation. In the appearing popup enter

the name of the Validation you wish to create - in our case it is

CHECK_ROOT_CONSISTENCY

class name ZCL_CUST_V_CHECK_ROOT_CONS in field Class

Page 28: Tutorial Creating a Simple Business Object

28

In the next step mark the request nodes for the validation as shown in the following figure.

Request Nodes are the trigger for the execution of a validation. This means if a node instance

of the configured request nodes is changed the execution of the validation is triggered.

NOTE: Only Consistency Validation does have Request Nodes. Action Validation does not

have request nodes as the execution of Action Validations is triggered by the execution of the

action.

Page 29: Tutorial Creating a Simple Business Object

29

In the next step mark the Node Category for which the validation is executed. Each node

instance belongs to only one node category. Such a category allows you to group model

elements, like validations determination, into different configurations. At runtime BOPF

decides based on the node category of an instance which configuration needs to be applied

and executes the corresponding elements. In most cases you may have only one node category

– the default one - which is maintained automatically by BOPF. In these cases you will not

get in touch with it. However in this step you have to assign the validation to the node

category. For the example select the node category Root.

Page 30: Tutorial Creating a Simple Business Object

30

The Validation Sequence on the next step can’t be maintained sine you don’t have another

validation created yet, which could be executed before or after the current validation. Thus

processed with “Finalize Guided Procedure”.

7.2. Implementation of Validation

A validation has to implement the interface /BOBF/IF_FRW_VALIDATION. This interface

has got three methods: Check, Check Delta and Execute.

Method CHECK is used to adjust the set of node instances for which a validation

should be invoked. This is only a reduction of the instances, and therefore no new

instances must be added. Implementing this method is optional.

Method CHECK_DELTA inspects the delta between the old and the new state of a

node instance. It is intended to remove instances that do not need to be validated

because the relevant changes were not made. An inclusion of new node instances must

not be done. This check is intended to narrow down the instances to carry out a

validation since BOPF’s triggering of validation only acts on the node level and not on

the node attribute. Therefore, BOPF cannot determine if a change is relevant for a

validation. Implementing this method is optional.

Method EXECUTE is used to perform check of the conditions to be checked. Node

instances that are violating the conditions are reported back as failed and messages can

be created to report on the cause of the failing validation

In the example of this tutorial you reuse the existing validation implementation

/BOBF/CL_LIB_V_ALT_KEY. The class checks the uniqueness of alternative keys.

Remember that you have maintained the alternative key CUSTOMER_ID on the Root node

earlier. This alternative key maps to the CUSTOMER_ID field you now want to check for

uniqueness. Thus you can reuse the class.

Page 31: Tutorial Creating a Simple Business Object

31

You can find the class in the BOPF Library Browser. The BOPF Library Browser can be

reached via the entry screen of the BOPF Configuration UI as shown in the following figure.

Within the Library Browser open branch /BOBF/LIB_LIBRARY and double click on the class

name /BOBF/CL_LIB_V_ALT_KEY. Afterwards more details in the class are available.

Page 32: Tutorial Creating a Simple Business Object

32

As you can see there are many classes within the BOPF Library Browser which are all

provided for reuse. Thus make yourself familiar with them as you need.

Now let’s reuse the class. Thus go back into your business object and open the validation

CHECK_ROOT_CONSISTENCY you have created above.

Page 33: Tutorial Creating a Simple Business Object

33

In order to create the validation implementation double click on the class name

ZCL_CUST_V_CHECK_ROOT_CONS which you have named earlier during the creation of

the validation. Proceed the popups to create the validation. Once the validation has been

created, you have to change the Super Class of you created validation class. Switch the Super

Class of ZCL_CUST_V_CHECK_ROOT_CONS to /BOBF/CL_LIB_V_ALT_KEY. During the

switch you are asked to keep the redefinitions. Don’t keep them, discard them.

Page 34: Tutorial Creating a Simple Business Object

34

After the switch you can redefine the methods

/BOBF/CL_LIB_V_ALT_KEY~CREATE_MSG_DUP_KEY: is used to create (error)

messages for duplicate keys

/BOBF/CL_LIB_V_ALT_KEY~FILTER_RELEVANT_ALT_KEYS: is used to remove

alternative keys which shall not be checked by this implementation. Class

/BOBF/CL_LIB_V_ALT_KEY can perform uniqueness checks for all alternative keys

which are maintained on the node for which the class is executed and which are

configured as unique. If you want to execute the check not for each of these alternative

keys you can remove those alternative keys which are not relevant in this method

implementation.

In the example you implement in this tutorial you don’t need to redefine any method. For

simplicity reasons you can reuse the messages provided by the library class. Additionally you

have only one alternative key configured in your BO that you want to check. Thus after

switching the Super Class active your class and go back into the BOPF Configuration UI of

your BO.

Note: You have to regenerate your constant interface after creating every new object so as to

maintain the constants for all the elements. You can use the extended check for any errors and

also check and correct if recommended.

Now you can test the Validation using the test tool. Open the test tool by pressing F8,

maintain the Customer ID and see whether you get messages.

8. Determination

8.1. Creation of a Determination

A Determination is an element of a business object node that describes internal changing

business logic on the business object. It can be used to trigger business logic based on the

internal changes (in contrast to an action). A determination is mostly used to compute data

that can be derived from the values of other attributes.

There are two types of determinations: persistent and transient determinations. The category

indicates whether a determination alters persistent or only transient data.

Within this tutorial you will create a transient determination which calculates the age of the

customer after he/she was loaded from the database or the birthdate was changed.

To create a determination you have to select the option Create Determination in the Business

Object Detail Browser.

Page 35: Tutorial Creating a Simple Business Object

35

In the appearing popup provide:

A name for the determination you wish to create followed by a small description about

the determination. In our example it is CALCULATE_AGE

Choose the determination category. In our case it is a transient determination, because

only transient fields or nodes are affected by the determination

Choose the change mode: Use Only Read Mode for determinations with category

“Transient” and “Exclusive Write Mode” for determinations with category

“Persistent”. Thus for this determination you use Only Read Mode.

Give the class name which has to be implemented to maintain your determination. In

our example it is ZCL_CUST_D_CALCULATE_AGE

Page 36: Tutorial Creating a Simple Business Object

36

Proceed to the next step in the guided procedure and maintain the Request Nodes: Request

Nodes are the triggers for the execution of a determination. This means if a node instance of

the configured Request Nodes gets changed/ loaded the execution of the determination is

triggered. You also have to select which operation on the configured Request Nodes exactly

should trigger the execution. Possible operations are Create, Update, Delete, Load or

Determine. For this tutorial make your selection as shown in the figure below.

Optionally you could also select Read Nodes. The BOPF loads the configured Read Nodes

before executing the determination. If the implementation of the determination takes

advantage of the mass-enabeld core services, it does not make sense to maintain them (see

BOPF performance guideline for more information)

Page 37: Tutorial Creating a Simple Business Object

37

On the next step of the guided procedure you need to maintain the BOPF events at which the

determination is triggered. The determination for calculating the age shall be trigger after

customer root node instances are loaded from the database into the BOPF buffer or after a

consumer has changed the birthdate of a customer. Thus the triggering events After Loading

and After Modify need to be selected.

Page 38: Tutorial Creating a Simple Business Object

38

© SAP AG 2009. All rights reserved. / Page 20 Confidential

Business Logic

Determination Times & Trigger Conditions

Trigger condition

Determination Time

Create Update Delete Load1 Determine

Before Retrieve Only for transient nodes

After Loading X

After Modfiy X X X

During Check&Determine X

After Validation X X X

Before Save:

Before Consistency Check X X X

Finalize X X X

Draw numbers X (X)2 (X)2

During Save: Before Writing Data X X X

After Commit X X X

After Failed Save Attempt X X X

1) Trigger Condition „Load“ is only available, if at least one of the request nodes is a „transient“ one.

2) There is usually no need to take numbers during update or delete.

© SAP 2007 / Page 20

Only for

Transient

Determinations

Only for

Persistent

Determinations

Figure 1: Overview of triggering events for determinations

On the next step of the guided procedure you could maintain sequence dependencies between

determinations. Since you don’t have another determination that screen is empty and you

don’t need to maintain anything. Thus click the finalize button to complete the guided

procedure.

8.2. Implementing a Determination

To make the Determination effective we have to implement the class, so double click on the

class name ZCL_CUST_D_CALCULATE_AGE which you have named earlier during the

creation of the determination. Proceed the popups to create the class. A determination

implementation has to implement interface /BOBF/IF_FRW_DETERMINATION which

contains the following methods.

CHECK: checks if the execution of the determination is necessary. In contrast to the

check_delta method, this check take the semantic into account. Implementing this

method is optional.

CHECK_DELTA (analogous to validation): In this method you can compare the old

image of the data with the current image of the data and decide if the execution of the

validation is necessary or not dependend on the changed attribute values.

Implementing this method is optional.

EXECUTE: This method contain the real business logic of the determination.

For your example determination paste the following code into method EXECUTE.

METHOD /bobf/if_frw_determination~execute.

DATA:

Page 39: Tutorial Creating a Simple Business Object

39

lt_chg_fields TYPE /bobf/t_frw_name,

lr_root TYPE REF TO zmy_s_cust_root,

lt_root TYPE zmy_t_cust_root,

lv_age TYPE datum.

io_read->retrieve(

EXPORTING

iv_node = is_ctx-node_key

it_key = it_key

iv_fill_data = abap_true

IMPORTING

et_data = lt_root

).

APPEND 'AGE' TO lt_chg_fields.

LOOP AT lt_root REFERENCE INTO lr_root.

lv_age = sy-datum - lr_root->date_of_birth.

lr_root->age = lv_age+0(4) - 1.

io_modify->update(

EXPORTING

iv_node = is_ctx-node_key

iv_key = lr_root->key

is_data = lr_root

it_changed_fields = lt_chg_fields

).

ENDLOOP.

ENDMETHOD.

Method io_modify->update collects all updates internally without passing the changes

immediately to the BOPF buffer. The BOPF buffer is updated later, after the execute method

was finished. If you need an buffer update early you have to call io_modify->end_modify

which triggers the buffer update. However, BOPF automatically calls this method after the

execute method was finished.

The number of determinations you configure for a certain event can have a strong impact on

the performance of your BO. Especially the modifications that are done within a

determination have an impact on the performance. Thus, the more determinations you use

(and by that the more modifications) the slower may be the performance of your BO. Thus

from a performance perspective you may use only one determination for a triggering event.

Also explicit calls to method io_modify->end_modify within your determination

implementation may impact the performance of your BOs. On the other hand side the reuse

potential of a determination is higher, if the determination is very fine grained, e.g.

responsible for a single field update. Thus the recommendation for BOs with high

performance requirements is: For each relevant triggering event configure only one

determination. Avoid calling io_modify->end_modify explicitly if possible. Reuse is shifter

from the determination itself to classes which are called within the determination, i.e. within

the determination implementation delegate the responsibility to other classes which you

design for reuse. You can then reuse/call these classes within different determinations.

The example determination that you have implemented in this tutorial you use a fine grained

determination for simplicity reasons only. For a “real life” determination you may follow the

recommendations above.

Page 40: Tutorial Creating a Simple Business Object

40

Now you can test the Determination using the test tool. Open the test tool by pressing F8 and

set/change the birthdate of a customer. The field Age is automatically calculated.

9. Action

9.1. Creation of Action

An action is an element of a business object node that describes an operation performed on

that node. An action can be used to allow the external triggering of business logic (in contrast

to a determination). BOPF supports different actions cardinalities: static actions, single node

instance action or multiple node instance action. When you use single or multiple node

instance actions the consumer must specify the node instance keys on which the action is to

be performed. For static actions the node instances keys are not used.

The action execution can be influenced by action validations (see above). When a consumer

calls an action, BOPF checks whether action validations are configured for the called action.

If this is the case, these action validations are executed before the action implementation is

called. Within the action validation you can reduce the number of node instance keys that are

afterwards passed to the action implementation. In addition you can configure an action to get

executed only, if an corresponding action validation does not return a failed key. This

configuration is done in the action configuration screen. The example in this tutorial does not

use that option.

In the example here you will create an multiple instance action on the Bank Details nodes

which locks the given bank accounts.

To create a action we have to select the option Create Action from the Business Object Detail

Browser as shown in the figure below.

Page 41: Tutorial Creating a Simple Business Object

41

In the displayed popup provide the following information:

Give the name of the action you wish to create followed by a small description about

the action. In our example it is LOCK_BANK_ACCOUNT

Set the Action Cardinality to Multiple Node Instances.

Set the Change Mode to Exclusive Write Mode.

Maintain a class name which implements the action. In the example maintain

ZCL_CUST_A_LOCK_BANK_ACCOUNT.

Skip the next step of the guided procedure (you don’t need to maintain read or write nodes).

On the third step select the node category as shown in the figure below.

Page 42: Tutorial Creating a Simple Business Object

42

Afterwards finalize the guided procedure.

9.2. Implementing an Action

To make the Action effective you have to implement the class. Therefore double click on the

class ZCL_CUST_A_LOCK_BANK_ACCOUNT and follow the popups to create the class.

Actions have to implement interface /BOBF/IF_FRW_ACTION which contains the following

methods:

RETRIEVE_DEFAULT_PARAMETERS is used to get context dependent default

values for the parameters of an action.

PREPARE method is used to adjust the set of node instances the action is invoked on.

This includes removing and adding instances.

EXECUTE method implements the action.

In this tutorial you create an action to set the lifecycle status to locked, the coding we have

used is as shown in the figure

METHOD /bobf/if_frw_action~execute.

DATA:

lt_bank_details TYPE zmy_t_cust_bank_details,

lt_chg_fields TYPE /bobf/t_frw_name,

lr_bank_details TYPE REF TO zmy_s_cust_bank_details.

io_read->retrieve(

EXPORTING

iv_node = is_ctx-node_key

it_key = it_key

iv_fill_data = abap_true

IMPORTING

et_data = lt_bank_details

).

APPEND zif_cust_zmy_customer_c=>sc_node_attribute-bank_details-

lc_status TO lt_chg_fields.

LOOP AT lt_bank_details REFERENCE INTO lr_bank_details.

lr_bank_details->lc_status = '01'. " locked

io_modify->update(

EXPORTING

iv_node = is_ctx-node_key

iv_key = lr_bank_details->key

is_data = lr_bank_details

it_changed_fields = lt_chg_fields

).

ENDLOOP.

ENDMETHOD.

Now you can test the action using the test tool. Open the test tool by pressing F8. Select a

customer, navigate to the customer’s bank detail node and execute the action.

Page 43: Tutorial Creating a Simple Business Object

43

10. Associations BO nodes are linked by associations. BOPF supports different association types. The most

important one is the Composition association by which the BO node hierarchy is defined.

When you create a child node BOPF automatically creates a composition association between

the parent and the child node. In addition it creates two further associations: one from the

child node to the parent node (TO_PARENT) and one up to root node (TO_ROOT). The

composite association by default gets the name of the created node. Besides composition

associations BOPF supports:

Foreign Key associations: The key of the target node instance is contained in an

attribute of the source node.

Reverse Foreign Key associations: The key of the source node is contained in an

attribute of the target node. A Reverse Foreign Key association determines the keys of

those target nodes which contain the source node key as foreign key. The BOPF

composition association belongs to this type.

Specialization associations: A Specialization is a “filtered composition”. It filters the

“composition” by some constant values (e.g. role code). At runtime the check is

performed against a field in the target node.

Reverse Specialization associations: Is a kind of filtered Foreign Key association.

The target node key is contained in a specialized source node. This association

determines the target node key contained in the specialized source node.

Cross-BO associations: The target node of a Cross-BO-Association is located on

another BO then the source node.

Composition to Delegated Node: The composition to the delegated node is a special

composition.

BOPF uses Association Binding in order to resolve associations. This means no

implementation is needed when Association Binding is used. During the binding you maintain

those attributes which need to be evaluated in order to identify the target node keys. The

following association types support Association Binding: Composite, Association to parent,

Association to root, Specializations, Reverse Specializations, Foreign Key Associations,

Reverse Foreign Key Associations, Cross-BO-Assoications.

Each association has a cardinality. BOPF supports the following cardinalities [1:0..1], [1:1],

[1:0..n] and [1:1..n]. BOPF does not checked automatically whether a node meets the

cardinality constraints maintained in BOPF. The BO implementation has to implement this

Page 44: Tutorial Creating a Simple Business Object

44

check. However, for mandatory child nodes – cardinalities: [1:1] or [1:1..n] – you can reuse

the library validation /BOPF/CL_LIB_V_MANDATORY_NODES (out of the BOPF library).

More informations about associations can be found in the following document:

https://wiki.wdf.sap.corp/wiki/download/attachments/223184988/How+to+implement+a+BO

PF+Business+Object+in+the+Business+Suite.doc?version=1

10.1. Association to a Delegated node

BOPF distinguishes between Business Objects and so called Dependent Object (DO). A

Dependent Object is something different than a Business Object. It has its own model but it

can only be used by embedding it into a Business Object. You can’t instantiate a Dependent

Object outside of a Business Object. A couple of reusable Dependent Objects are available in

software component BS_FND: Text Collection, Attachment Folder and Address.

When you embed a Dependent Object into a Business Object (=Host Business Object) the

Dependent Object’s model gets part of the Business Object’s model. Thus the Business

Object consumer accesses the nodes of the Dependent Object through the hosting Business

Object. However, BOPF only merges the model of the Dependent Object into the model of

the Business Object at runtime. At design time in the BOPF Configuration UI the models are

not merged. This process is called the Blackbox Delegation, that is, the model information for

the Dependent Objects are only known at runtime and not during design time of the host

object.

In order to embed a Dependent Object into a Business Object you have to create a Delegated

Node in the Business Object. During runtime, BOPF replaces the Delegated Node with the

complete subset of the Dependent Object’s. At runtime, BOPF delegates the calls to the

Dependent Objects node to the Dependent Object.

In this tutorial you will embed the Text Collection Dependent Object into the Customer.

10.2. Creating Association to Dependent Object

Within this section you will embed the Dependent Object /BOBF/TEXT_COLLECTION into

you Customer BO. Thus open your Customer BO in BOPF and select the root node in the

Business Object Detail Browser. From the context menu select the entry as shown in the

following figure.

Page 45: Tutorial Creating a Simple Business Object

45

This command will create a Delegated Node directly underneath the root node. In the details

screen for the Delegated Node maintain the following fields:

Node Name: Names of the Delegated Node. Use the name Note.

Node Prefix: The node prefix is used by BOPF at runtime in order to identify the

Dependent Object which is called by a consumer. Example: The Collection used here

could additionally be embedded underneath the Bank Details node. Let’s assume this

for a while. When you access the embedded Text Collection via the BOPF APIs you

need to tell BOPF which embedded Text Collection you want to access – the one

underneath the Root node or the one underneath the Bank Details node. You use the

Delegated Node to provide BOPF this information. Thus both embeddings of the Text

Collection need to have a Node Prefix, to be more precise a different Node Prefix.

Description: Maintain “Customer note”

Referenced Business Object: Select /BOBF/TEXT_COLLECTION

When you create the Delegated Node as described above BOPF automatically creates the

required association to the root node of the Dependent Object. This is possible since the Text

Collection Dependent Object supports a standard linkage to a hosting Business Object. The

standard linkage is supported for each Dependent Object that fulfills the following

requirement: The embedded Dependent Object must have an alternative key on its root node

that uses /BOBF/S_LIB_K_DELEGATION as DATA_TYPE and

/BOBF/T_LIB_K_DELEGATION as DATA_TABLE_TYPE. Furthermore this alternative

key must be set to "Not-unique" to enable one-to-many usages of it.

Further details about the delegation concept can be found here:

https://wiki.wdf.sap.corp/wiki/display/BOPF/BS+BOPF+FAQ+and+Features#BSBOPFFAQa

ndFeatures-Delegation

Note: Don’t forget to regenerate the BOPF constant interface every time when you add or

delete something in the BO.

Afterwards you can test the embedded Dependent Object in the Test Tool. For this purpose

open the Test Tool (F8) for the Customer and create a new customer or select an existing one.

Navigate to node Root Note and press the Create Button. This will create the root node of

Page 46: Tutorial Creating a Simple Business Object

46

the Text Collection (you don’t have to maintain anything here). Subsequently navigate to the

content node and maintain a text.

11. Testing the Business Object There are two methods of testing the Business Object in the BOPF

1. Using the test tool

2. Using reports

You can test the Business Object using the test tool by pressing F8 in the Business Object

Configuration UI by which a separate SAP GUI window is opened showing the test tool

(transaction /BOBF/TEST_UI). This method was used several time trough out the tutorial.

The other method is using a manually written report. The report accesses the Business Object

via the Service Manager and the Transaction Manager. They provide the APIs you need to

access a Business Object from any consumer to trigger queries, to retrieve data, to modify

data and to execute actions. By triggering these operations, the determinations created in the

design time will get executed.

The first report performs a query on the Customer Root node and retrieves the Bank Details

for each Root node in the result set.

* Data declaration

DATA:

lo_customer TYPE REF TO /bobf/if_tra_service_manager,

lt_root_key TYPE /bobf/t_frw_key,

lt_root TYPE zmy_t_cust_root,

lt_bank_detail TYPE zmy_t_cust_bank_details.

* Get Service Manager for Customer BO

* - use the constant interface maintained in the BO

lo_customer = /bobf/cl_tra_serv_mgr_factory=>get_service_manager(

iv_bo_key = zif_cust_zmy_customer_c=>sc_bo_key

).

* Trigger the query on the root node

lo_customer->query(

EXPORTING

iv_query_key = zif_cust_zmy_customer_c=>sc_query-root-

select_by_elements

iv_fill_data = abap_true

IMPORTING

et_key = lt_root_key

et_data = lt_root

).

* Retrieve Bank Details node belonging to the queried root nodes

lo_customer->retrieve_by_association(

EXPORTING

iv_node_key = zif_cust_zmy_customer_c=>sc_node-root

iv_association = zif_cust_zmy_customer_c=>sc_association-root-

bank_details

it_key = lt_root_key

iv_fill_data = abap_true

IMPORTING

et_data = lt_bank_detail

).

Page 47: Tutorial Creating a Simple Business Object

47

The next report creates a Customer Root Node.

* data declaration

DATA:

lo_transaction_mgr TYPE REF TO /bobf/if_tra_transaction_mgr,

lo_customer TYPE REF TO /bobf/if_tra_service_manager,

lt_root TYPE zmy_t_cust_root,

ls_root TYPE zmy_s_cust_root,

lr_root TYPE REF TO zmy_s_cust_root,

lt_mod TYPE /bobf/t_frw_modification,

ls_mod TYPE /bobf/s_frw_modification.

* Set customer data

ls_root-customer_id = '4711'.

ls_root-first_name = 'Max'.

ls_root-last_name = 'Mustermann'.

GET REFERENCE OF ls_root INTO lr_root.

* Fill modification structure

ls_mod-key = /bobf/cl_frw_factory=>get_new_key( ).

ls_mod-node = zif_cust_zmy_customer_c=>sc_node-root.

ls_mod-change_mode = /bobf/if_frw_c=>sc_modify_create.

ls_mod-data = lr_root.

APPEND ls_mod TO lt_mod.

* Get Service Manager for Customer BO

* - use the constant interface maintained in the BO

lo_customer = /bobf/cl_tra_serv_mgr_factory=>get_service_manager(

iv_bo_key = zif_cust_zmy_customer_c=>sc_bo_key

).

* Call the Service Manager to create the customer

lo_customer->modify(

EXPORTING

it_modification = lt_mod

).

* Get the Transaction Manager to save the changes

lo_transaction_mgr = /bobf/cl_tra_trans_mgr_factory=>get_transaction_manage

r( ).

* Save the changes

lo_transaction_mgr->save( ).

The last report calls the action LOCK_BANK_ACCOUNT on all Bank Detail nodes

belonging to queried root nodes.

* Data declaration

DATA:

lo_customer TYPE REF TO /bobf/if_tra_service_manager,

lt_root_key TYPE /bobf/t_frw_key,

lt_bank_detail_key TYPE /bobf/t_frw_key.

* Get Service Manager for Customer BO

* - use the constant interface maintained in the BO

lo_customer = /bobf/cl_tra_serv_mgr_factory=>get_service_manager(

iv_bo_key = zif_cust_zmy_customer_c=>sc_bo_key

).

* Trigger the query on the root node

Page 48: Tutorial Creating a Simple Business Object

48

lo_customer->query(

EXPORTING

iv_query_key = zif_cust_zmy_customer_c=>sc_query-root-

select_by_elements

IMPORTING

et_key = lt_root_key

).

* Retrieve Bank Details node belonging to the queried root nodes

lo_customer->retrieve_by_association(

EXPORTING

iv_node_key = zif_cust_zmy_customer_c=>sc_node-root

iv_association = zif_cust_zmy_customer_c=>sc_association-root-

bank_details

it_key = lt_root_key

IMPORTING

et_target_key = lt_bank_detail_key

).

* Executing the action

lo_customer->do_action(

EXPORTING

iv_act_key = zif_cust_zmy_customer_c=>sc_action-bank_details-

lock_bank_account

it_key = lt_bank_detail_key

).