Thursday 12 July 2012

Most Used Tables in SAP CRM


Most Used Database Tables in SAP CRM

TableDescription
CRMD_ORDERADM_HContains the basic Header Information on Any Transaction created through CRMD_ORDER. This could be lead, opportunity, orders, quotations etc
CRMD_ORDERADM_IContains the basic item Information on Any Transaction created through CRMD_ORDER. This could be lead, opportunity, orders, quotations etc
BUT000 , BUT001Business Partner General Data
BUT100SAP CRM Business Partner Roles
BUT150SAP CRM BP Relationship
COMM_PRODUCTProduct Master
CRMD_ORDER_INDEXDescription
CRMD_PARTNEROrder partner Information
CRM_JESTOrder Status

GUID



What is GUID in SAP CRM ?

As we learnt in SD, a Transaction is uniquely idenfied in the database using a Transaction Number / Document Number. In SAP CRM this uniqueness is not driven by the document number, but by SAP GUID. An SAP GUID is a unique field generated by SAP which will essentially guarantee a big unique alpha-numeric numer that can act as a primary key for the database tables.
As you can see from the basic ORDER table – CRMD_ORDERADM_H, there are two leads with the same Lead Number of #476, but what differentiates the table rows is the GUID. GUIDs are created using the FM – GUID_CREATE.
What intrigues the folks from the core SAP ECC system is that over there there is no concept of GUID, whereas in SAP CRM this becomes the primary key. This was necessitated by a number of problems – Mostly related to the fact that CRM is generally not a master data system and also the fact that CRM is essentially built to interact with mobile clients as well which are not necessarily connected to the server. Let’s consider the following scenarios.
1. A mobile order (say Txn Type – ZTA) was taken by a field rep on his laptop and the laptop generated an order # 1234. This number was generated without consulting the Server and might not reflect the current number range scenarios for the Txn type ZTA. Now what happens when the fields sales rep connects to the server at the end of his day and tries to sync the data ? If the Order # was the only primary key, obviously you are in trouble – especially since its the primary field. So SAP CRM came up with the concept of GUID which uniquely identifes the transaction in the system no matter what.
2. Also, it is not always the case that all transactions need to be created in SAP CRM. For example, regular sales orders can be created in SAP SD whereas Service Orders, leads and opportunities could be created in SAP CRM. Since data needs to be synchronized between the two systems – this could lead to potential issues. Although there are mitigatory mechanisms for situations like this ( Like creating leading systems, making number ranges external in receiving system etc ) SAP has to plan for its own contingencies and GUID is the key for it.

Monday 9 July 2012

Adding Widgets

Click here to Download

Types of Business Objects in BOL

The business objects are subdivided into 6 kinds:
root objects, 
access objects, 
dependant objects, 
query objects, 
query result objects, 
dynamic query objects.


Root Object:
The root object is the only object within the hierarchy structure of a data model that is assigned as superior object to all the data objects. Each root object is also access data.
Access Object:
An access object is a special type of Business object, who’s ID can be accessed to determine both the attributes of the access object itself and those of its dependent objects.
It is also a root object but it handles transactional data.
Dependent Objects:
A dependent object is a special type of business object whose attributes cannot be determined solely from the business object ID. You can only determine its attributes by using the ID of the superior access object.

 For example: ONEORDER (BOL component set) 􀄺 BTOrder (Root Object) 􀄺 BTAdminH (Access Object) 􀄺BTCustomerH (Dependent Object)

Search Objects:

A Query Object is special type of BO, whose attributes are the parameters of search request.
It is like parameters

Dynamic Search Object:

A Query Object is special type of BO, whose attributes are the parameters of search request.  It is possible to create select options of the parameter.

It is like select-options.

Search Result Object:

The result object of a search request has a dictionary structure assigned and displays data from different BOs as a result last.  To link the search result object to the data model hierarchy the search object is associated with the root object of the same component.

After query, the output is there in the search result object like internal table.  Here the internal table has the same structure as the root objects.

BOL Programming - Dquery Objects

*Get the BOL Core instance
DATA: lr_core1 TYPE REF TO cl_crm_bol_core.
*Load the component set Or Component
lr_core1 = cl_crm_bol_core=>get_instance( ).
lr_core1->start_up( 'BP_APPL' ).

*Determine Dynamic Query Services Available
DATA:lv_obj_model  TYPE REF TO if_genil_obj_model.
lv_obj_model = cl_crm_genil_model_service=>get_runtime_model( ).

DATA:lt_query_names TYPE crmt_ext_obj_name_tab.
CALL METHOD lv_obj_model->get_object_list
  EXPORTING
    iv_object_kind     = if_genil_obj_model=>dquery_object
*    iv_ws_enabled_only = ABAP_FALSE
  IMPORTING
    et_object_list     = lt_query_names.


**Select Particular Query
DATA:lv_query_name TYPE crmt_ext_obj_name.
READ TABLE lt_query_names INTO lv_query_name INDEX 6. "'BuilContactAdvancedSearch '

*Create Query Service by passing the dynamic search object name
DATA:lv_query TYPE REF TO cl_crm_bol_dquery_service.
lv_query = cl_crm_bol_dquery_service=>get_instance( lv_query_name ).


*Set General Query parameters for maximum number of hits
DATA lt_parms TYPE crmt_name_value_pair_tab.
DATA ls_parms TYPE crmt_name_value_pair.

ls_parms-name = 'MAX_HITS'.
ls_parms-value = '5'.
APPEND ls_parms TO lt_parms.
lv_query->set_query_parameters( it_parameters = lt_parms ).

*Add Selection Criteria where BP number > 30
CALL METHOD lv_query->add_selection_param
  EXPORTING
    iv_attr_name = 'BP_NUMBER'
    iv_sign      = 'I'
    iv_option    = 'GT'
    iv_low       = '0000311966'
    iv_high      = ' '.


*Execute Query and Receive Result
DATA:lv_result_tab TYPE REF TO if_bol_entity_col.  "To Capture Multiple Records
lv_result_tab = lv_query->get_query_result( ).

*Use Iterator to acces entities in query result
DATA:lv_iterator TYPE REF TO if_bol_entity_col_iterator. "or IF_BOL_ENTITY_COL
lv_iterator = lv_result_tab->get_iterator( ).

*Get First Entity in the result list.
*Entity is contact person here.
DATA:lv_entity TYPE REF TO cl_crm_bol_entity.
lv_entity  = lv_iterator->get_first( ).


*..........Begin of Messages
*Acces Messages of Business Objects
*Use the Message Container Manager
DATA:lv_mcm TYPE REF TO cl_crm_genil_mess_cont_manager.
lv_mcm = lr_core1->get_message_cont_manager( ).

*To Obtain the Message Container for Relavent Object
DATA:lv_object_name TYPE crmt_ext_obj_name,
     lv_object_id TYPE crmt_genil_object_id.

lv_object_name = lv_entity->get_name( ).
lv_object_id   = lv_entity->get_key( ).

DATA:lv_mc TYPE REF TO if_genil_message_container.
lv_mc = lv_mcm->get_message_cont( iv_object_name = lv_object_name
                                  iv_object_id = lv_object_id ).
*Get Relavent messages..
DATA:lv_number_of_errors TYPE int4,
     lt_messages TYPE crmt_genil_message_tab.

*Get Number of Messages Count
lv_number_of_errors = lv_mc->get_number_of_messages( lv_mc->mt_error ).
IF lv_number_of_errors <> 0.
*Get List of Error messages
  lv_mc->get_messages( EXPORTING iv_message_type = lv_mc->mt_error
                       IMPORTING et_messages = lt_messages ).
ENDIF.
*..........End of Messages


*Loop through Further Entities....
WHILE lv_entity IS BOUND. "Means lv_entity is not initial..

*Access Attributes of the Business Objects Selected
  DATA:lv_bpnumber TYPE string,
       lv_contactbp  TYPE string.

  lv_bpnumber = lv_entity->get_property_as_string( 'BP_NUMBER' ).
  lv_contactbp  = lv_entity->get_property_as_string( 'CONP_NUMBER' ).

*Get 1:1 Related Entities of BP of BuilSalesEmployeeRel Child Cardinality 1
  DATA:lv_employee_responsible TYPE REF TO cl_crm_bol_entity. "Only one record
  lv_employee_responsible = lv_entity->get_related_entity( 'BuilSalesEmployeeRel' ).

  DATA:lv_empbp TYPE string.
  lv_empbp = lv_employee_responsible->get_property_as_string( 'SALESEMPLOYEE' ).

*Get 0:n Related Entities of BP of BuilContactPersonAddressRel Child Cardinality 0..n
  DATA:lv_address TYPE REF TO if_bol_entity_col.
  lv_address = lv_entity->get_related_entities( iv_relation_name = 'BuilContactPersonAddressRel' ).

*Use Iterator to acces entities in query result
  DATA:lv_iterator_add TYPE REF TO if_bol_entity_col_iterator. "or IF_BOL_ENTITY_COL
  lv_iterator_add = lv_address->get_iterator( ).

*Get First Entity in the result list.
*Entity is address of BP here.
  DATA:lv_entity_add TYPE REF TO cl_crm_bol_entity.
  lv_entity_add  = lv_iterator_add->get_first( ).
*Loop through all address of BP....
  WHILE lv_entity_add IS BOUND. "Means lv_entity is not initial..
    DATA:lv_stdardaddress  TYPE string.
    lv_stdardaddress = lv_entity_add->get_property_as_string( 'STANDARDADDRESS' ).

    WRITE:/ lv_bpnumber,        "Business Partner
          / lv_contactbp,       "Contact Person
          / lv_empbp,           "Sales Employee Responsible
          / lv_stdardaddress.   "Standard Address

    lv_entity_add = lv_iterator_add->get_next( ).
  ENDWHILE.
  lv_entity = lv_iterator->get_next( ).
ENDWHILE.

BOL Porgramming - Query Objects


*Get the BOL Core instance
DATA: lr_core1 TYPE REF TO cl_crm_bol_core.
*Load the component set Or Component
lr_core1 = cl_crm_bol_core=>get_instance( ).
lr_core1->start_up( 'BP_APPL' ).

*Determine Query Services Available
DATA:lv_obj_model  TYPE REF TO if_genil_obj_model.
lv_obj_model = cl_crm_genil_model_service=>get_runtime_model( ).

DATA:lt_query_names TYPE crmt_ext_obj_name_tab.
CALL METHOD lv_obj_model->get_object_list
  EXPORTING
    iv_object_kind     = if_genil_obj_model=>query_object
*    iv_ws_enabled_only = ABAP_FALSE
  IMPORTING
    et_object_list     = lt_query_names.


*Select Perticular Query
DATA:lv_query_name TYPE crmt_ext_obj_name.
READ TABLE lt_query_names INTO lv_query_name INDEX 6. "'BuilContactPersonSearch'

*Create Query Service by passing the search object name
DATA:lv_query TYPE REF TO cl_crm_bol_query_service.
lv_query = cl_crm_bol_query_service=>get_instance(
                  iv_query_name = lv_query_name ).

*Set Search Criteria
lv_query->set_property( iv_attr_name = 'BP_NUMBER'
                        iv_value = '0000311966' ).

*Read Search Criteria
DATA:lv_city TYPE string.
lv_city = lv_query->get_property_as_string( 'BP_NUMBER' ).

*Executer Query and Receive Result
DATA:lv_result_tab TYPE REF TO if_bol_entity_col.  "To Capture Multiple Records
lv_result_tab = lv_query->get_query_result( ).

WD_USAGE_INITIALIZE

Data Exchange between UI Components
Consider the Scenario where Component 'A'  is the Embedding Component & Component 'B' is the Embedded Component. (i.e B resides in A).
In Component B 
Goto the Runtime Repository Editor
Expand Component Interface
Under Interface Controller
Right click on the context and add the context node (Say 'PARTNER').
(We need to do this as we have to expose the context node( here say 'PARTNER' ) of the component controller of UI Component B to be used in Component A).
Save
*********************************************************************************
In Component A
Goto the Runtime Repository Editor
Goto Component Usage Right Click and add Component usage
(i.e Used Component = UI Component 'B' & Interface View = Main Window).
Save
*********************************************************************************
Now implement the 'WD_USAGE_INITIALIZE' method in the Component Controller of the Embedding Component i.e Component 'A'.

CASE iv_usage->usage_name.
When 'B.'   ................." Here the Component Usage 'B'.
    iv_usage->bind_context_node
    exporting
iv_controller_type =  cl_bsp_wd_controller=>co_type_component
iv_target_node_name = "PARTNER"
iv_node_2_bind = "PARTNER".

Note: You can also Bind the Interface Controller context node with the Custom Controller of an Embedding Component (i.e in our case it is UI Component 'A'). The above Scenario discusses the { Component Controller(A)<-->Component Controller(B) }Binding . Let us See the case
Custom Controller(A)<-->Component Controller(B)}



CASE iv_usage->usage_name.
When 'B.'   ................." Here the Component Usage 'B'.
    iv_usage->bind_context_node
    exporting
iv_controller_type =  cl_bsp_wd_controller=>co_type_custom
iv_target_node_name = "PARTNER"
iv_name =  'Name of the custom controller in component A'
iv_node_2_bind = "PARTNER".

----<<<<@@@@@There Ends the Binding@@@@@>>>>---------



     

Binding

Context Node  binding on custom controller


The prerequisite for the successful context node Binding is that the context nodes to be bound must have same attributes.
Binding the context node(CV1) of a view controller with the context node(CC1) of a Custom Controller cab be done using a wizard while creating a view in a component, However it can be done manually by retrospectively inserting the following code in the CREATE_(CONTEXT_NODE) method of the context (.CTXT extension) Class.

Owner-> do_context_node_binding ( iv_controller_type = cl_bsp_wd_controller =>co_type_custom
                                                          iv_name  =  'name of the custom controller'
                                                       iv_target_node_name =  'name of the target context node'  "Here CC1
                                                     iv_source_node_name =  name of the source context node ). "HereCV1

We can carry out the context node binding  from View Controller to the component controller

      In this case  replace the constant "cl_bsp_wd_controller=>co_type_custom" with                 "cl_bsp_wd_controller=>co_type_component" in the above method of the context class.

Controllers

Types of Controllers
1) Component Controller
2) Custom Controller
3) Interface Controller
4) Window Controller
5) View Controller

Each Controller type  fulfills its specific tasks.
Tasks of Controllers
1) View Controller
Controls the event handling wit in a view.
2) Custom Controller
Used to exchange the data between the views with in a Component.
3) Component Controller
Used to exchange data between the views of different Components.
4) Interface Controller
It manages the interface of the UI component to the outside.