Professional Documents
Culture Documents
Cookbook BOL App CRM2007 PDF
Cookbook BOL App CRM2007 PDF
®
SAP CRM 2007
Target Audience
System administrators
Technology consultants
JavaScript is a registered trademark of Sun Microsystems, Inc., used Documentation in the SAP Service Marketplace
under license for technology invented and implemented by Netscape. You can find this documentation at the following address:
http://service.sap.com/
<July 2008> 7
1 Business Object Layer
1.1.2 Introduction
Using the BOL and its uniform application programming interface (API) to access business
data offers considerable advantages compared to the various APIs typically available for
business objects:
The object-oriented BOL API is simple, uniform, and easy to use.
The built-in buffer accelerates your applications.
You can isolate your programs from any interface changes in the underlying business
object-specific APIs.
Development of SAP Customer Relationship Management (SAP CRM) applications is
easy since the BOL has been designed to work hand-in-hand with the UI parts of the
CRM WebClient UI framework.
It is possible to enhance the BOL to cover business data not yet supported. After the
corresponding business objects and query services have been modeled and implemented,
you can use them at runtime.
1.1.3 Overview
The BOL API consists of various interfaces and classes that you can use to access business
data:
CL_CRM_BOL_QUERY_SERVICE
You use this class to select business objects.
CL_CRM_BOL_ENTITY
You use this class for implementing business objects.
IF_BOL_TRANSACTION_CONTEXT
You use this interface to control transaction behavior.
IF_BOL_BO_COL
You use this interface to provide collections to hold business objects.
The lifetime of these objects lasts the entire session. The BOL API, however, provides you
with the ability to free used business objects and their memory.
8 <July 2008>
1 Business Object Layer
Important objects in the BOL Programming ABAP and their corresponding interfaces
and classes:
Objects
1..*
Transaction
Object Model
Context
1 1..*
1 1..*
1
*
BOL Core Entity
1
*
Entity Factory
*
Collection
Query Service for Business
Objects
1 0..n 1
1 1
CL_CRM_BOL_CORE CL_CRM_BOL_ENTITY
get_instance()
0..n
CL_CRM_BOL_ENTITY_FACTORY
0..n
<<Interface>>
IF_BOL_BO_COL
CL_CRM_BOL_QUERY_SERVICE
get_instance()
<July 2008> 9
1 Business Object Layer
Syntax
* Start BOL Core module
DATA: lv_bol_core TYPE REF TO cl_crm_bol_core.
lv_bol_core = cl_crm_bol_core=>get_instance( ).
lv_bol_core->start_up( ‘MY_COMPONENT_SET’ ).
The BOL core CL_CRM_BOL_CORE follows the singleton design pattern, so you can only
have one instance of it. The START_UP() method takes the name of the component set that
you want to start as input parameter and starts the BOL. Once this is completed, you can
load all services of the BOL and the component set.
The START_UP() method takes another optional parameter, IV_DISPLAY_MODE_SUPPORT,
which is set to ABAP_FALSE by default. This means that the BOL follows the optimistic
locking approach, making all of the objects appear changeable in the user interface even
without a lock. The lock is automatically requested on the first attempt to make a change to
an object.
If the parameter IV_DISPLAY_MODE_SUPPORT is set to ABAP_TRUE, the BOL follows the
strict locking approach where only locked objects appear as changeable. For more
information, see Display Mode Support [page 18].
10 <July 2008>
1 Business Object Layer
<July 2008> 11
1 Business Object Layer
Syntax
* Get advanced query
DATA: lv_advanced_query TYPE REF TO cl_crm_bol_dquery_service.
lv_advanced_query =
cl_crm_bol_dquery_service=>get_instance( 'AdvOrderQuery' ).
12 <July 2008>
1 Business Object Layer
Syntax
* Use iterator to access entities in query result
DATA:lv_iterator TYPE REF TO if_bol_entity_col_iterator.
<July 2008> 13
1 Business Object Layer
lv_iterator = lv_result->get_iterator.
DATA: lv_entity TYPE REF TO cl_crm_bol_entity.
lv_entity = lv_iterator->get_first( ). “Entity is business partner
here
WHILE lv_entity IS BOUND.
1.1.4.6 Transactions
One of the most important aspects of BOL programming is to know how to modify data. You
can create, modify, and delete entities in accordance with the BOL transaction model, which
supports several kinds of transaction contexts to handle entity operations consistently.
The global transaction context holds all modified root entities, whereas the fine granular
transaction context exists for each root object instance. The custom transaction context can
be used to handle special situations, where more than one (but not all) modified object forms
the transaction. This section discusses only the global context. For more information about
the fine granular transaction context, see Fine Granular Transaction Handling [page 24].
Syntax
* 1. Build parameters to create an entity:
* here an order entity with technical name ‘BTOrder’
14 <July 2008>
1 Business Object Layer
<July 2008> 15
1 Business Object Layer
The current locking granularity of the BOL is the root object instances, so the lock request for
an entity is always delegated to the corresponding root instance.
The following code shows how to lock an entity:
Syntax
* Lock BOL entity
DATA: lv_success TYPE crmt_boolean.
lv_success = lv_entity->lock( ).
If the lock was set, the return value LV_SUCCESS is true (ABAP_TRUE or
IF_GENIL_BOOLEAN => TRUE ).
Syntax
* 1. Lock and modify a property
* here order header entity with technical name ‘BTOrderHeader’
lv_order_header = lv_order->get_related_entity( ‘BTOrderHeader’
).
IF lv_order_header->lock( ) = if_genil_boolean=>true.
lv_order_header->set_property( iv_attr_name = ‘DESCRIPTION’
iv_value = ‘Changed
Description’ ).
ENDIF.
16 <July 2008>
1 Business Object Layer
For root object instances, the DELETE method call is sent directly to the API where the
complete aggregation hierarchy is deleted. The deletion is written to the database with an
internal COMMIT WORK.
Syntax
* Delete root entity
lv_order->delete( ).
In the case of a child object, the deletion is not automatically sent to the API. You have to
trigger this explicitly by calling the MODIFY method of the BOL core.
Syntax
* Delete child object
lv_order_header->delete( ).
lv_bol_core->modify( ).
<July 2008> 17
1 Business Object Layer
Syntax
* Start BOL core with display mode support
DATA: lv_bol_core TYPE REF TO cl_crm_bol_core.
lv_bol_core = cl_crm_bol_core=>get_instance( ).
lv_bol_core->start_up( iv_appl_name = ‘MY_COMPONENT_SET’
iv_display_mode_support = ABAP_TRUE ).
18 <July 2008>
1 Business Object Layer
<<interface>>
IF_BOL_BO_PROPERTY_ACCESS
CL_CRM_BOL_QUERY_SERVICE CL_CRM_BOL_ENTITY
The interface offers a standard means to work with BOL objects. Note that it is possible to
have an instance of IF_BOL_BO_PROPERTY_ACCESS for any BOL object.
Syntax
* Get search criterion of BOL query
DATA: lv_query TYPE REF TO cl_crm_bol_query_service, lv_city_type
string.
lv_query = cl_crm_bol_query_service=>get_instance( ‘QUERY_NAME’ ).
lv_city =
lv_query->if_bol_bo_property_access~get_property_as_string(
‘City’ ).
“Short form using alias
lv_city = lv_query->get_property_as_string( ‘City’ ).
<July 2008> 19
1 Business Object Layer
Syntax
* Get key code
DATA: lv_person TYPE REF TO cl_crm_bol_entity,
lv_sex type bu_sexid. “Defines values 1 = Female, 2 = Male
...
lv_sex = lv_person->get_property( ‘SEX’ ). “Key code
IF_BOL_BO_COL CL_CRM_BOL_BO_COL
IF_BOL_ENTITY_COL CL_CRM_BOL_ENTITY_COL
The collection interfaces offer a number of methods to work with collections, such as
INSERT, GET_FIRST, GET_NEXT, GET_CURRENT, SORT, CLEAR, MARK, and
UNMARK.
20 <July 2008>
1 Business Object Layer
If you want to iterate on the collection without moving the focus (and without triggering time-
consuming follow-up processes) you can use local iteration. To do so, request an iterator
object from the collection and use this to iterate.
Syntax
* Create collection
DATA: lv_collection TYPE REF TO cl_crm_bol_bo_collection,
lv_property_access TYPE REF TO if_bol_bo_property_access,
lv_query TYPE REF TO cl_crm_bol_query_service.
CREATE OBJECT lv_collection.
...
* Add item and make it current
lv_collection->if_bol_bo_col~insert( iv_bo = lv_query
Iv_index = 1
Iv_set_focus = ABAP_BOOL ).
* Global iteration
lv_property_access = lv_collection->get_next( ). “Global iteration
“ moves focus
* Local iteration
DATA: lv_iterator TYPE REF TO if_bol_bo_col_iterator.
lv_iterator = lv_collection->get_iterator( ).
lv_property_access = lv_iterator->get_first( )
WHILE lv_query_is_bound.
lv_property_access = lv_collection->get_next(). “Local iteration
does not
ENDWHILE. “ move focus
1.1.5.3.2 Searching
The collections provide the method FIND to search for a given business object in the
collection. If the business object is found, it is returned and the focus is set to this collection
entry.
You can search by index, business object instance, or object name and ID, but only one of
these parameters is used for the search at a time. The parameters are taken in the given
sequence. For example, if you provide an index and an instance, only the index is used.
The local iterator interface supports the search for a single property. This is provided by the
method FIND_BY_PROPERTY. The first object, whose property has the given value, is
returned. Neither the global nor the local collection pointer is influenced by this operation.
Syntax
* Find by property
DATA: lv_persons TYPE REF TO cl_crm_bol_entity_collection,
lv_male TYPE REF TO cl_crm_bol_entity,
lv_iterator TYPE REF TO if_bol_bo_col_iterator.
<July 2008> 21
1 Business Object Layer
lv_iterator = lv_persons->get_iterator( ).
lv_male = lv_iterator->find_by_property( iv_attr_name = ‘SEX’
iv_value = 2 ).
* Set collection focus on the entity found
lv_persons->find( iv_bo = lv_male ).
1.1.5.3.3 Sorting
Collections can be sorted with the SORT method and stay in the resulting sort order.
Note
You can not undo the sorting process.
The mandatory parameter IV_ATTR_NAME specifies the property that the collection is sorted
for. If you do not specify IV_SORT_ORDER, the sort order defaults as ascending.
Syntax
* Sorting
DATA: lv_persons TYPE REF TO cl_crm_bol_entity_collection,
lv_male TYPE REF TO cl_crm_bol_entity,
lv_iterator TYPE REF TO if_bol_bo_col_iterator.
lv_persons->sort( iv_attr_name = ‘SEX’
iv_sort_order = IF_BOL_BO_COL=>SORT_DESCENDING ).
The sorting is alphabetical and based on the string representation of the property. Since this
can lead to false results (for example, when working with dates) it is possible to control the
sorting by providing an instance of IF_BOL_COL_SORTING. During the sort process, the
method IS_A_GREATER_B is called whenever two values are compared. To modify the sort
order as needed, implement this method and provide the interface.
22 <July 2008>
1 Business Object Layer
Note
In single selection mode, the current or focus element is always defined, except
when the collection is empty. The methods of the interface
IF_BOL_BO_COL_MULTI_SEL are deactivated.
When multi selection mode has been activated, you may use the methods of the interface
IF_BOL_BO_COL_MULTI_SEL to mark and unmark entries, and to check which entries have
been marked (IF_BOL_BO_COL_MULTI_SEL~MARK, UNMARK, GET_MARKED).
In multi selection mode, the collection methods behave differently than in single selection
mode:
Method Result
IF_BOL_BO_COL~GET_CURRENT Returns the last selected element
IF_BOL_BO_COL~GET_CURRENT_INDEX Returns the index of the last selected
element
IF_BOL_BO_COL~PUBLISH_CURRENT Does nothing
IF_BOL_BO_COL~FIND Finds, eventually selects and returns an
element
IF_BOL_BO_COL~GET_NEXT Does nothing
IF_BOL_BO_COL~GET_PREVIOUS Does nothing
<July 2008> 23
1 Business Object Layer
Some collections need to protect their content, especially if they are essential for the further
operation of the application. You can use method
IF_BOL_BO_COL~SET_RESET_SURVIVAL_MODE to indicate that the root and access
entities are to be recreated after the BOL reset.
To receive notice at runtime of any collections that are not reset-compliant because they
contain dependent entities, you can activate the assertion group BOL_ASSERTS using
transaction SAAB (assertions, breakpoints and logpoints).
24 <July 2008>
1 Business Object Layer
<July 2008> 25
1 Business Object Layer
CL_CRM_COL_CORE
1
1
CL_CRM_GENIL_MESS_CONT_MANAGER
IF_GENIL_MESSAGE_CONTAINER
The message container manager can be reached using the core. The following code shows
how to access a particular message container:
Syntax
* Access messages of a business object
26 <July 2008>
1 Business Object Layer
Syntax
* 3) Access messages
DATA: lv_number_of_errors TYPE int4,
lt_error_messages TYPE crmt_genil_message_tab.
lv_number_of_errors = lv_mc->get_number_of_messages( lv_mc->mt_error
).
IF lv_number_of_errors <> 0.
lt_error_messages = lv_mc->get_messages( lv_mc->mt_error ).
ENDIF.
<July 2008> 27
1 Business Object Layer
28 <July 2008>
1 Business Object Layer
1.1.6.3 Entities
The class CL_CRM_BOL_ENTITY is a generic representation for business objects in the
BOL. Each instance is a unique representation for a specific business object. You can access
data using the IF_BOL_BO_PROPERTY_ACCESS interface. Entities are centrally managed
and cached.
<July 2008> 29
1 Business Object Layer
change entities in display mode is detected. You can activate this checkpoint group
in development and test systems to get early notice of problems related to the BOL
usage.
BOL_MODIFY_WATCH
This checkpoint group defines important break points, which can be used to track the
data transport from the business object to the Generic Interaction Layer (GenIL), the
merge back of data returned into the BOL buffer, ID adjustments for new entities, and
buffer invalidation of changed entities.
BOL_COLL_AUTOCLEAN
This checkpoint group activates the auto cleanup mode for collections as default.
This may lead to memory problems, so it should only be used for testing purposes or
compatiblility purposes with framework versions SAP CRM 5.0 and older.
30 <July 2008>
1 Business Object Layer
CL_CRM_BOL_ENTITY_MANAGER
entity_tab
0..n
CL_CRM_BOL_ENTITY
my_manager_entry
parent
1 #container_proxy
CL_CRM_GENIL_CONTAINER_OBJECT
data_ref
1.2.2 Collections
Various collections reference a set of BOL entities and offer convenient access to their
properties.
<July 2008> 31
1 Business Object Layer
<<Interface>>
IF_BOL_BO_COL
CL_CRM_BOL_BO_COL CL_CRM_ENTITY_COL
entity_list entity_list
1 1
0..n
<<Interface>>
IF_BOL_BO_PROPERTY_ACCESS
0..n
CL_CRM_BOL_QUERY_SERVICE CL_CRM_BOL_ENTITY
32 <July 2008>
1 Business Object Layer
CL_BSP_WD_CONTEXT_NODE
get_collection_wrapper()
set_collection_wrapper()
set_collection()
clear_collection()
1..n
-collection_wrapper
1
CL_BSP_WD_COLLECTION_WRAPPER
set_collection()
clear_collection()
<<event>>new_focus()
-collection
<<Interface>> <<Interface>>
IF_BOL_BO_COL IF_BOL_BO_COL
<July 2008> 33
1 Business Object Layer
CL_BSP_WD_CONTROLLER
+owner 1
+typed_context 1
CL_BSP_WD_CONTEXT
+<name> 1..n
CL_BSP_WD_CONTEXT_NODE
34 <July 2008>
1 Business Object Layer
Neither context nor context nodes are expected to be shared between controllers. The
underlying collections can be shared using the collection wrapper class by context
node binding.
+view <VIEW> 1
1
+controller 1
+<name> 1..n
CL_BSP_WD_CONTROLLER
CL_BSP_WD_CONTEXT_NODE
m_models
1 0..n
1..n +<name>
+owner 1
1 CL_BSP_WD_CONTEXT 1
+typed_context
<July 2008> 35
1 Business Object Layer
Sometimes it is necessary to display further entity-related attributes that are not part of the
underlying GenIL model and that are calculated at runtime. This is possible using mixed node
elements, which contain a regular BOL entity plus a value part with application-defined
attributes. The corresponding context node is referred to as a mixed node.
A mixed node element (represented by class CL_BSP_WD_MIXED_NODE) consists
of a model part referencing a regular BOL entity and a value part holding additional
application-defined data.
CL_BSP_WD_MIXED_NODE implements the IF_BOL_BO_PROPERTY_ACCESS
interface and does not inherit from CL_BSP_WD_CONTEXT_NODE.
When creating the element you hand over the BOL entity reference and a structure
with application-defined data.
You use the IF_BOL_BO_PROPERTY_ACCESS interface to access the element’s
properties. The mixed node automatically dispatches the request to either the model
or the value part.
You may also use
<IF_BSP_WD_EXT_PROPERTY_ACCESS>~GET_MODEL_NODE() to access the
underlying BOL entity.
Mixed node elements can be added to IF_BOL_BO_COL collections, which accept
objects implementing the IF_BOL_BO_PROPERTY_ACCESS interface.
It is easy to display mixed nodes on the UI, as context node binding proceeds as
normal.
To facilitate the application of mixed node elements, a specialization of the collection wrapper
CL_BSP WD_2COLLECTION_WRAPPER is available.
Assign CL_BSP_WD_2COLLECTION_WRAPPER to your mixed context node and
use its SET_VALUE_STRUCT method to declare the data structure with additional
application-defined attributes.
Add BOL entities to the node’s collection wrapper as usual. When its items are
accessed (for example, for UI display) a mixed node element with application-defined
attributes is automatically created and returned.
This technique saves memory because you only create the value part if it is needed.
The collection wrapper supports sorting by both model and value attributes.
CL_BSP WD_2COLLECTION_WRAPPER uses the built-in unifier manager, as shown in the
diagram below:
36 <July 2008>
1 Business Object Layer
CL_BSP_WD_COLLECTION_WRAPPER
CL_BSP_WD_2COLLECTION_WRAPPER LCL_UNIFIER_MANAGER
(from CL_BSP_WD_2COLLECTION_WRAPPER)
1 1
1 1
#collection 1 0..n
<<Interface>> <<Interface>>
IF_BOL_BO_COL IF_BOL_BO_PROPERTY_ACCESS
<<Interface>>
IF_BOL_BO_EXT_PROPERTY_ACCESS
CL_CRM_BOL_BO_COL
1 CL_BSP_WD_MIXED_NODE
1
1
1..n -model_node -value_node 1
<<Interface>> <<Interface>>
IF_BOL_BO_PROPERTY_ACCESS IF_BOL_BO_PROPERTY_ACCESS
1
CL_BSP_WD_VALUE_NODE
The CRM WebClient UI framework also supports value nodes, which contain value node
elements having an application-defined value part only.
A value node element is represented by class CL_BSP_WD_VALUE_NODE, which
accepts application-defined attributes in its constructor method.
You can use the IF_BOL_BO_PROPERTY_ACCESS interface to access its
attributes.
Value node elements can be added to IF_BOL_BO_COL collections.
Context node binding and the UI display work as normal.
<July 2008> 37