Skip to Content
Author's profile photo Bjørn-Henrik Zink

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:

  1. ABAP Objects: Creating a Custom SAP ERP HCM Class Library
  2. ABAP Objects: Custom SAP ERP HCM Class Library – Example 1 – Class Instances
  3. ABAP Objects: Custom SAP ERP HCM Class Library – Example 2 – Utility Classes
  4. ABAP Objects: Custom SAP ERP HCM Class Library – Example 3 – Exceptions

Business Scenario

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.

Coding Example

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. 

*
* Objects

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
  EXPORTING
    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( ).

ENDIF.


Class Library

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.

METHOD constructor.

  CALL METHOD super->constructor
    EXPORTING
      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
    EXPORTING
      iv_otype            = iv_otype
      iv_objid            = lv_objid
      iv_begda            = iv_keydate
      iv_endda            = iv_keydate.

ENDMETHOD.

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.

METHOD get_org_unit_text.

CLEAR rv_org_unit_text.

CALL FUNCTION ‘RH_READ_OBJECT’
   EXPORTING
     plvar = mv_plvar
     otype = mv_otype
     realo = mv_objid
     begda = mv_keydate
     endda = mv_keydate
   IMPORTING
     display_text = rv_org_unit_text
   EXCEPTIONS
     not_found = 1
     OTHERS = 2.

IF sy-subrc <> 0.
* Raise exception

ENDIF.

ENDMETHOD.

Other methods, like for example GET_FULL_NAME of class ZCL_HR_PERSON are written using select statements.

METHOD get_org_key.

  DATA lv_full_name TYPE emnam.

  CLEAR rv_full_name.

  SELECT SINGLE ename
    INTO lv_full_name
        FROM pa0001
    WHERE pernr = mv_pernr AND
          begda <= mv_begda AND
          endda >= mv_endda.

  IF sy-subrc = 0.
    rv_full_name = lv_full_name.
  ENDIF.

ENDMETHOD.

As mentioned above, keeping track of the key parameters in both methods is provided when instantiating the manager class.

Benefits

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.

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.