ABAP Objects: Custom SAP ERP HCM Class Library – Example 1 – Class Instances
Eight months has pasted since SAP Community Network (SCN) published my blog ABAP Objects: Creating a Custom SAP ERP HCM Class Library. It is high time to publish some real life coding examples. In this blog, I will provide class instance coding examples based on a business scenario. Wikipedia (Dec 6, 2009) class instance definition: “A class is a construct that is used as a blueprint to create objects of that class. This blueprint describes the state and behavior that the objects of the class all share. An object of a given class is called an instance of the class.”
It was my intention from the very beginning that the custom library should be more than just another concept. From my perspective, the key success factor is that the custom class library is applied in running applications. Furthermore, it is important that the benefits described in the above mentioned blog are attained.
The custom class library is utilized. In fact, it has turned out applicable in many areas besides Human Capital Management (HCM), such as for example Financials (FI).
This is number 2 in a series of blogs on ABAP Objects in the context of a Custom SAP ERP HCM Class Library:
- ABAP Objects: Creating a Custom SAP ERP HCM Class Library
- ABAP Objects: Custom SAP ERP HCM Class Library – Example 1 – Class Instances
- ABAP Objects: Custom SAP ERP HCM Class Library – Example 2 – Utility Classes
- ABAP Objects: Custom SAP ERP HCM Class Library – Example 3 – Exceptions
In an HCM Processes & Forms process you want to display text information related to HCM objects, such as personnel area, cost center, position, and organizational unit of a manager. You create backend services for your custom form fields and need to implement functionality to derive the text information. Instead of rewriting code for text retrieval, the developer reuses the custom library.
Please note that the scenario could be any UI or business logic where you want to use text information.
In the following a manager class is instantiated. The instantiation opens up a multitude of possibilities to derive information related to the manager. Key parameters personnel number and effective date are only passed once. The main manager object ensures that all referred objects are using the same key parameters. In the coding below, all method calls can therefore be made without passing any parameters.
DATA lo_manager TYPE REF TO zcl_hr_mgr.
DATA lo_person TYPE REF TO zcl_hr_person.
DATA lo_position TYPE REF TO zcl_hr_position.
DATA lo_org_unit TYPE REF TO zcl_hr_org_unit.
DATA lo_cost_center TYPE REF TO zcl_co_cost_center.
* Create manager instance
CREATE OBJECT lo_manager
iv_otype = co_person
iv_objid = lv_pernr
iv_keydate = lv_effective_date.
IF lo_manager IS BOUND.
* Get person instance
lo_person = lo_manager->get_person( ).
* Get position instance
lo_position = lo_person->get_position( ).
* Get org. unit instance
lo_org_unit = lo_person->get_org_unit( ).
* Get cost center instance
lo_cost_center = lo_person->get_cost_center( ).
lv_full_name = lo_person->get_full_name( ).
lv_user = lo_person->get_usrid( ).
lv_first_name = lo_person->get_first_name( ).
lv_last_name = lo_person->get_last_name( ).
lv_position = lo_position->get_position( ).
lv_org_unit = lo_org_unit->get_org_unit( ).
lv_org_unit_txt = lo_org_unit->get_org_unit_text( ).
lv_org_key = lo_person->get_org_key( ).
lv_company_code = lo_person->get_company_code( ).
lv_company_code_txt = lo_person->get_company_code_text( ).
lv_cost_center = lo_cost_center->get_cost_center( ).
lv_cost_center_txt = lo_cost_center->get_cost_center_text( ).
lv_pers_area = lo_person->get_pers_area( ).
lv_pers_area_txt = lo_person->get_pers_area_text( ).
lv_pers_subarea = lo_person->get_pers_subarea( ).
lv_pers_subarea_txt = lo_person->get_pers_subarea_text( ).
Lets have a closer look at the class library. Starting point is the CONSTRUCTOR of the ZCL_HR_MGR class. The CONSTRUCTOR starts by calling the super class CONSTRUCTOR. The super class is ZCL_HR_EMP and its CONSTRUCTOR checks the validity of the provided personnel number. The ZCL_HR_MGR CONSTRUCTOR contains a manager validity check.
CALL METHOD super->constructor
iv_otype = iv_otype
iv_objid = iv_objid
iv_plvar = iv_plvar
iv_begda = iv_begda
iv_endda = iv_endda
iv_keydate = iv_keydate.
CALL METHOD zcl_util=>check_manager
iv_otype = iv_otype
iv_objid = lv_objid
iv_begda = iv_keydate
iv_endda = iv_keydate.
By instantiating the ZCL_HR_MGR object it is therefore ensured that the personnel number is valid and that the person in question is indeed a manager. Calling programs need not consider the usual checks when using the ZCL_HR_MGR object.
Next focus is method GET_COST_CENTER_TEXT of class ZCL_HR_ORG_UNIT. The implementation is rather basic and simply calls a standard function module RH_READ_OBJECT to retrieve the text.
CALL FUNCTION ‘RH_READ_OBJECT’
plvar = mv_plvar
otype = mv_otype
realo = mv_objid
begda = mv_keydate
endda = mv_keydate
display_text = rv_org_unit_text
not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Raise exception
Other methods, like for example GET_FULL_NAME of class ZCL_HR_PERSON are written using select statements.
DATA lv_full_name TYPE emnam.
SELECT SINGLE ename
WHERE pernr = mv_pernr AND
begda <= mv_begda AND
endda >= mv_endda.
IF sy-subrc = 0.
rv_full_name = lv_full_name.
As mentioned above, keeping track of the key parameters in both methods is provided when instantiating the manager class.
Mapping the advantages of using a custom class library to the coding above, I get the following result:
- Consistent business rules. It seems obvious to have consistent business rules before any coding can be done. However, experience has taught me that this is not always the case. Sometimes development specifications made in a hurry lead to irregularities in the business rules. Centralizing the coding will force business rules to be more consistent.
Yes, in many cases I would probably have forgotten to write a personnel number check and a manager check when trying to derive texts. There are often many text formats to choose from. By using the custom class library it is ensured that the correct text format is used.
- Onboarding cost reduction. Bundling custom functionality into a class library makes it easier and quicker for new employees to start coding.
Yes, whenever somebody needs to create a new method it is obvious where to put it. In many cases it is not necessary to create a class and there is less redundant classes floating around in the system.
- Authorization checks implemented centrally will keep developers from forgetting adding them.
No, not used in this example. However, it could have been possible to add the authorization checks within the methods.
- Maintenance costs decrease because problems can be fixed centrally and thereby avoid repeating changes in various places. Fewer issues through enhanced robustness achieved through reuse of code.
Yes, code has been reused and can therefore be fixed centrally.
- Division of labor. Experienced ABAP developers handle design questions and beginners implement simple code within predefined methods. SQL experts focus on optimizing wrapped select statements.
Yes, inexperienced developers start coding with the predefined methods, whereas experts consider how to optimize the interfaces and code within the class library methods.
- Faster development and more stable applications through reuse of code.
Yes, it was certainly much faster to write the calling program once the library was in place. I did not have to go through all the infotype screens to find out where to find the text of various fields.
- Better performance. Despite the technical overhead of OO programming, I think that performance can be improved by optimizing the code of the class library. Often programmers have little time to consider performance aspects. By reusing functionality from a class library performance optimization is given
No, the additional checks and instantiation of the classes will have a slightly negative impact on performance. Yes, select statements have been optimized.
The next blog in this series will provide a utility class coding examples.