Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

The part 1 explains, how to create generally persistent classes, basing on BAPIs. We have created a single persistent class on the example of SAP Business Partner. The objects of this persistent class can reading and saving updates of the partner central data.

In this part we have to model the partner central data in four persistent classes: the superclass Partner and its subclasses Person, Organization and Group. The functions of the classes are the same as in the part 1: read and save changes of the partner central data.

Persistent Classes for the Partner Central Data

Functional Class Model

The persistent subclasses CL_PERSON, CL_ORGANIZATION and CL_GROUP inherit primarly the mapping common attributes with their SET/GET methods from the superclass CL_PARTNER.

Persistent Class Model

The agent class of the superclass CL_PARTNER implements reading and saving logic for the partner central data. The agent class knows the subclasses of the superclass and creates the persistent objectes of them.

Public Methods of the Agent Class CA_PARTNER

  • GET_PARTNER_REF            - Get a Partner Persistent Object by the Partner Category
  • GET_DB_CENTRAL_DATA    - Get the Central Partner Data through BAPI
  • SAVE_DB_CENTRAL_DATA  - Save the Central Partner Data through BAPI

Implementation of the Persistent Classes

Mapping Structures (DDIC)

In addition to the main structure YSDN_BP_CENTRAL_DATA (see the part 1), each of the new persistent classes must have its own mapping structures:

  • Structure for the superclass Partner

    

  • Structure for the subclass Person

    

  • Structure for the subclass Organization

    

  • Structure for the subclass Group

    

Create the Persistent Classes

   1. Create the persistent superclass for the partner central data

   Map the structure YSDN_PARTNER_CENTRAL to the persistent class and define two fields PARTNER and VALID_FROM  as business key and read only.

   The others fields are to define as changeable value attributes.

   2. Create the persistent subclass for the person central data

   Map the structure YSDN_PERSON_CENTRAL to the persistent class, all fields of the structure are to define as changeable value attributes.

   3. Create the persistent subclass for the organization central data

   Map the structure YSDN_ORGANIZ_CENTRAL to the persistent class, all fields of the structure are to define as changeable value attributes.

   4. Create the persistent subclass for the group central data

   Map the structure YSDN_GROUP_CENTRAL to the persistent class, all fields of the structure are to define as changeable value attributes.

Extensions of the Agent Class (of the Super Class)

There are to define and to implement four new methods in the agent class:

  • Method GET_DB_CENTRAL_DATA


     Interface

         

     Code


METHOD get_db_central_data.

  DATA:

    ls_central_data TYPE ysdn_bp_central_data,

    lt_bapiret      TYPE STANDARD TABLE OF bapiret2.

  CALL FUNCTION 'BAPI_BUPA_CENTRAL_GETDETAIL'

    EXPORTING

      businesspartner         = i_partner

      valid_date              = i_valid_date

    IMPORTING

      centraldata             = ls_central_data-central

      centraldataperson       = ls_central_data-person

      centraldataorganization = ls_central_data-organiz

      centraldatagroup        = ls_central_data-group

      centraldatavalidity     = ls_central_data-validity

    TABLES

      return                  = lt_bapiret.

  IF ( lt_bapiret IS INITIAL ).

    ls_central_data-partner = i_partner.

    IF ( ls_central_data-person IS NOT INITIAL ).

      ls_central_data-category = '1'.

    ELSEIF ( ls_central_data-organiz IS NOT INITIAL ).

      ls_central_data-category = '2'.

    ELSEIF ( ls_central_data-group IS NOT INITIAL ).

      ls_central_data-category = '3'.

    ELSE.

      RETURN.

    ENDIF.

    MOVE-CORRESPONDING ls_central_data TO e_central_data.

  ENDIF.

ENDMETHOD.


  • Method SAVE_DB_CENTRAL_DATA


Interface


Code


METHOD save_db_central_data.

  TYPES BEGIN OF lty_partner_changes.

          INCLUDE TYPE bapibus1006_central_x        AS central.

          INCLUDE TYPE bapibus1006_central_person_x AS person.

          INCLUDE TYPE bapibus1006_central_organ_x  AS organiz.

          INCLUDE TYPE bapibus1006_central_group_x  AS group.

  TYPES END OF lty_partner_changes.

  DATA:

    lo_structdescr      TYPE REF TO cl_abap_structdescr,

    ls_central_data_old TYPE ysdn_bp_central_data,

    ls_central_data_new TYPE ysdn_bp_central_data,

    ls_partner_changes  TYPE lty_partner_changes,

    lt_bapiret          TYPE STANDARD TABLE OF bapiret2.

  FIELD-SYMBOLS:

    <lfs_new>       TYPE data,

    <lfs_old>       TYPE data,

    <lfs_change>    TYPE data,

    <lfs_component> TYPE abap_compdescr.

  lo_structdescr ?= cl_abap_structdescr=>describe_by_data( ls_partner_changes ).

  MOVE-CORRESPONDING i_central_data TO ls_central_data_new.

* get the old partner data

  yca_central_partner2=>agent->get_db_central_data(

    EXPORTING

      i_partner      = ls_central_data_new-partner

      i_valid_date   = ls_central_data_new-valid_from

    IMPORTING

      e_central_data = ls_central_data_old

  ).

* determine partner changes

  LOOP AT lo_structdescr->components ASSIGNING <lfs_component>.

    ASSIGN COMPONENT <lfs_component>-name OF STRUCTURE ls_central_data_new TO <lfs_new>.

    IF sy-subrc <> 0.

      CONTINUE.

    ENDIF.

    ASSIGN COMPONENT <lfs_component>-name OF STRUCTURE ls_central_data_old TO <lfs_old>.

    IF sy-subrc <> 0.

      CONTINUE.

    ENDIF.

    ASSIGN COMPONENT <lfs_component>-name OF STRUCTURE ls_partner_changes TO <lfs_change>.

    IF sy-subrc <> 0.

      CONTINUE.

    ENDIF.

    IF <lfs_new> NE <lfs_old>.

      <lfs_change> = abap_true.

    ENDIF.

  ENDLOOP.

* save the partner changes

  IF ( ls_partner_changes IS NOT INITIAL ).

    CALL FUNCTION 'BAPI_BUPA_CENTRAL_CHANGE'

      EXPORTING

        businesspartner           = ls_central_data_new-partner

        centraldata               = ls_central_data_new-central

        centraldataperson         = ls_central_data_new-person

        centraldataorganization   = ls_central_data_new-organiz

        centraldatagroup          = ls_central_data_new-group

        centraldata_x             = ls_partner_changes-central

        centraldataperson_x       = ls_partner_changes-person

        centraldataorganization_x = ls_partner_changes-organiz

        centraldatagroup_x        = ls_partner_changes-group

        valid_date                = ls_central_data_new-valid_from

      TABLES

        return                    = lt_bairet.

  ENDIF.

ENDMETHOD.


  • Method GET_PARTNER_REF


     Interface

    

     Code


METHOD get_partner_ref.

  DATA lv_partner_category TYPE bu_type.

  CALL METHOD me->get_partner_category

    EXPORTING

      i_partner          = i_partner

    RECEIVING

      r_partner_category = lv_partner_category

    EXCEPTIONS

      partner_not_found  = 1

      OTHERS             = 2.

  IF sy-subrc <> 0.

    RAISE EXCEPTION TYPE cx_os_object_not_found.

  ENDIF.

  CASE lv_partner_category.

    WHEN '1'.

      r_partner_ref = yca_central_person2=>agent->get_persistent(

          i_partner    = i_partner

          i_valid_from = i_valid_date

      ).

    WHEN '2'.

      r_partner_ref = yca_central_organiz2=>agent->get_persistent(

          i_partner    = i_partner

          i_valid_from = i_valid_date

      ).

    WHEN '3'.

      r_partner_ref = yca_central_group2=>agent->get_persistent(

          i_partner    = i_partner

          i_valid_from = i_valid_date

      ).

  ENDCASE.

ENDMETHOD.



  • Method GET_PARTNER_CATEGORY

     Interface

    

     Code

METHOD get_partner_category.


  DATA:

    ls_search_result TYPE bapibus1006_bp_addr,

    lf_person        TYPE bus000flds-char1,

    lf_organiz       TYPE bus000flds-char1,

    lf_group         TYPE bus000flds-char1.

  CALL FUNCTION 'BUP_PARTNER_TYPE_GET'

    EXPORTING

      i_partner         = i_partner

    IMPORTING

      e_xorganisation   = lf_organiz

      e_xperson         = lf_person

      e_xgroup          = lf_group

    EXCEPTIONS

      partner_not_found = 1

      wrong_type        = 2

      wrong_parameters  = 3

      OTHERS            = 4.


  IF ( sy-subrc = 0 ).

    CASE abap_true.

      WHEN lf_person.

        r_partner_category = '1'.

      WHEN lf_organiz.

        r_partner_category = '2'.

      WHEN lf_group.

        r_partner_category = '3'.

    ENDCASE.

  ENDIF.

  IF ( r_partner_category IS INITIAL ).

    RAISE partner_not_found.

  ENDIF.

ENDMETHOD.

Redefine the Agent Methods the of Subclasses

The two methods are to redefine (in the same way) in each of the agent classes of the subclasses:

1. Method MAP_LOAD_FROM_DATABASE_KEY

METHOD map_load_from_database_key.

  DATA:

    ls_result  LIKE LINE OF result,

    ls_err_msg TYPE string.

  FIELD-SYMBOLS <lfs_business_key> LIKE LINE OF i_business_key_tab.

  LOOP AT i_business_key_tab ASSIGNING <lfs_business_key>.

    yca_central_partner2=>agent->get_db_central_data(

      EXPORTING

        i_partner      = <lfs_business_key>-partner

        i_valid_date   = <lfs_business_key>-valid_from

      IMPORTING

        e_central_data = ls_result

    ).

    IF ( ls_result IS NOT INITIAL ).

      APPEND ls_result TO result.

    ELSE.

      ls_err_msg = |Partner | && <lfs_business_key>-partner && | not found|.

      RAISE EXCEPTION TYPE cx_os_db_select

        EXPORTING

          table  = 'CENTRAL_DATA'

          textid = cx_os_db_select=>by_bkeytab

          bkey   = ls_err_msg.

    ENDIF.

  ENDLOOP.

ENDMETHOD.

2. Method MAP_SAVE_TO_DATABASE

METHOD map_save_to_database.

  FIELD-SYMBOLS:

    <lfs_update> LIKE LINE OF i_updates.

* save the updates

  LOOP AT i_updates ASSIGNING <lfs_update>.

    yca_central_partner2=>agent->save_db_central_data( <lfs_update> ).

  ENDLOOP.

ENDMETHOD.

Test Report


*&---------------------------------------------------------------------*

*& Report  YSDN_CENTRAL_PARTNER_TEST2

*&

*&---------------------------------------------------------------------*

*&

*&

*&---------------------------------------------------------------------*

REPORT  ysdn_central_partner_test2.

TYPES oscon.

DATA:

  lo_partner   TYPE REF TO ycl_central_partner2,

  lo_person    TYPE REF TO ycl_central_person2,

  lo_organiz   TYPE REF TO ycl_central_organiz2,

  lo_group     TYPE REF TO ycl_central_group2,

  lv_partner   TYPE i,

  ls_text      TYPE string,

  lo_trans_mng TYPE REF TO if_os_transaction_manager,

  lo_trans     TYPE REF TO if_os_transaction.

PARAMETERS partner TYPE bu_partner.

LOAD-OF-PROGRAM.

* set the transaction mode

  cl_os_system=>init_and_set_modes(

      i_external_commit = oscon_false         " controll the LUWs by the local tranaction object

      i_update_mode     = oscon_dmode_direct  " perform database update immediately

  ).

START-OF-SELECTION.

  IF ( partner IS NOT INITIAL ).

    TRY.

        lo_partner ?= yca_central_partner2=>agent->get_partner_ref(

            i_partner    = partner

            i_valid_date = sy-datlo

        ).

        lo_trans_mng = cl_os_system=>get_transaction_manager( ).

        lo_trans     = lo_trans_mng->create_transaction( ).

        CASE lo_partner->get_category( ).

          WHEN '1'.

            lo_person ?= lo_partner.

            ls_text = lo_person->get_firstname( ).

            WRITE / ls_text.

            " start the transaction for partner changes

            lo_trans->start( ).

            lo_person->set_firstname( lo_person->get_firstname( ) && ' test' ).

            " end the transaction, the method END() calls the BAPI for partner change eventually

            lo_trans->end( ).

            ls_text = lo_person->get_firstname( ).

            WRITE / ls_text.

          WHEN '2'.

            lo_organiz ?= lo_partner.

            ls_text = lo_organiz->get_name1( ).

            WRITE / ls_text.

            lo_trans->start( ).

            lo_organiz->set_name1( lo_organiz->get_name1( ) && ' test' ).

            lo_trans->end( ).

            ls_text = lo_organiz->get_name1( ).

            WRITE / ls_text.

          WHEN '3'.

            lo_group ?= lo_partner.

            ls_text = lo_group->get_namegroup1( ).

            WRITE / ls_text.

            lo_trans->start( ).

            lo_group->set_namegroup1( lo_group->get_namegroup1( ) && ' test' ).

            lo_trans->end( ).

            ls_text = lo_group->get_namegroup1( ).

            WRITE / ls_text.

          WHEN OTHERS.

            WRITE 'The partner category is unknown'.

            RETURN.

        ENDCASE.

      CATCH cx_os_object_not_found.

        lv_partner = partner.

        ls_text = |{ lv_partner ZERO = NO }|.

        WRITE: 'The partner number ', ls_text , ' is not found'.

        RETURN.

    ENDTRY.

  ENDIF.