Introduction

I was surprised not to find any examples on how to modify the start and/or end dates of PA infotypes using the decoupled framework. Typically the start and end dates are part of the key identifying the record. Unless you know what you are doing, you will most likely get a CX_HRPA_INVALID_PARAMETER exception with the parameter PRIMARY_RECORD-PSKEY. Important here is to have the existing record, create a new one (with new values) and refer the old record when calling the MODIFY method.

Acknowledgements

All the code was copied and adapted from the standard function module HR_CONTROL_INFTY_OPERATION, the decoupled framework parts of it.

The Code

First the definition for method CHANGE_BEGDA_ENDDA

  class-methods CHANGE_BEGDA_ENDDA

    importing

      value(IV_TCLAS) type PSPAR-TCLAS default ‘A’

      value(IV_INFTY) type PRELP-INFTY

      value(IV_SUBTY) type P0001-SUBTY

      value(IV_OBJPS) type P0001-OBJPS

      value(IV_SPRPS) type P0001-SPRPS

      value(IV_SEQNR) type P0001-SEQNR default ‘000’

      value(IV_PERNR) type P0001-PERNR

      value(IV_BEGDA) type P0001-BEGDA

      value(IV_ENDDA) type P0001-ENDDA

      value(IV_BEGDA_NEW) type P0001-BEGDA

      value(IV_ENDDA_NEW) type P0001-ENDDA

      value(IV_TEST_MODE) type BOOLE_D default ‘ ‘

    exporting

      value(ET_MESSAGES) type HRPAD_MESSAGE_TAB

      value(EV_OK) type BOOLE_D .

Then the implementation of method CHANGE_BEGDA_ENDDA

method change_begda_endda.

  data lr_message_list          type ref to cl_hrpa_message_list.

  data lr_masterdata_bl         type ref to if_hrpa_masterdata_bl.

  data container                type ref to if_hrpa_infty_container.

  data old_container            type ref to cl_hrpa_infotype_container.

  data new_container            type ref to if_hrpa_infty_container.

  data new_infotype_container   type ref to cl_hrpa_infotype_container.

  data infotype_ref             type ref to data.

  data lv_is_ok                 type boole_d.

  data lv_dummy                 type string.

  data ls_msg                   type symsg.

  data container_tab            type hrpad_infty_container_tab.

  data container_if             type hrpad_infty_container_ref.

  data t777d                    type t777d.

  data lv_has_error             type boole_d.

  data lv_count                 type i.

  field-symbols <pshdr>         type pshdr.

  field-symbols <pnnnn>         type any.

  field-symbols <pskey>         type pskey.

  field-symbols <record>        type any.

  field-symbols <pxxxx>         type any.

  create object lr_message_list.

  call method cl_hrpa_masterdata_factory=>get_business_logic

    importing

      business_logic = lr_masterdata_bl.

  check lr_masterdata_bl is bound.

  call method lr_masterdata_bl->read

    exporting

      tclas          = iv_tclas

      pernr          = iv_pernr

      infty          = iv_infty

      subty          = iv_subty

      objps          = iv_objps

      sprps          = iv_sprps

      begda          = iv_begda

      endda          = iv_endda

      seqnr          = iv_seqnr

      mode           = if_hrpa_masterdata_bl=>exact_matching_record

      no_auth_check  = abap_true

      message_handler = lr_message_list

    importing

      container_tab  = container_tab

      is_ok          = lv_is_ok.

  if lv_is_ok eq abap_true.

    describe table container_tab lines lv_count.

    if lv_count gt 1.

      lv_is_ok = abap_false.

      message e016(pg) with ‘Multiple records found, limit to exactly one’ into lv_dummy.

      move-corresponding sy to ls_msg.

      call method lr_message_list->if_hrpa_message_handler~add_message

        exporting

          message = ls_msg

          cause  = lr_message_list->if_hrpa_message_handler~infotype_generic.

    elseif lv_count eq 0.

      lv_is_ok = abap_false.

      message e009(pg) with iv_infty into lv_dummy.

      move-corresponding sy to ls_msg.

      call method lr_message_list->if_hrpa_message_handler~add_message

        exporting

          message = ls_msg

          cause  = lr_message_list->if_hrpa_message_handler~infotype_generic.

    else.

      read table container_tab into container index 1.

    endif.

  endif.

  if lv_is_ok = abap_false.

    call method lr_message_list->get_abend_list

      importing

        messages = et_messages.

    if et_messages is initial.

      call method lr_message_list->get_error_list

        importing

          messages = et_messages.

    endif.

    return.

  endif.

  old_container ?= container.

  try.

      call method old_container->if_hrpa_infty_container_data~primary_record_ref

        importing

          pnnnn_ref = infotype_ref.

    catch cx_hrpa_violated_assertion .

  endtry.

  assign infotype_ref->* to <pxxxx>.

  t777d = cl_hr_t777d=>read( infty = iv_infty ).

  create data infotype_ref type (t777d-ppnnn).

  assign infotype_ref->* to <pnnnn> casting like <pxxxx>.

  <pnnnn> = <pxxxx>.

  assign <pnnnn> to <pshdr> casting.

  <pshdr>-infty = iv_infty.

  assign infotype_ref->* to <record> casting like <pxxxx>.

  assign component ‘PSKEY’ of structure <record> to <pskey>.

  call method lr_masterdata_bl->get_infty_container

    exporting

      tclas          = ‘A’

      pskey          = <pskey>

      no_auth_check  = abap_true

      message_handler = lr_message_list

    importing

      container      = container_if.

  new_infotype_container ?= container_if.

  <pskey>-endda = iv_endda_new.

  <pskey>-begda = iv_begda_new.

  new_infotype_container ?= new_infotype_container->modify_key( <pskey> ).

  new_infotype_container ?= new_infotype_container->modify_primary_record( <record> ).

  new_container ?= new_infotype_container.

  if iv_test_mode eq abap_false.

    call method lr_masterdata_bl->modify

      exporting

        old_container  = old_container

        message_handler = lr_message_list

      importing

        is_ok          = lv_is_ok

      changing

        container      = new_container.

    if lr_message_list->has_error( ) = abap_true or

       lr_message_list->has_abend( ) = abap_true.

      lv_has_error = abap_true.

    else.

      lv_has_error = abap_false.

    endif.

    if lv_has_error = abap_true.

      call method lr_message_list->get_abend_list

        importing

          messages = et_messages.

      if et_messages[] is initial.

        call method lr_message_list->get_error_list

          importing

            messages = et_messages.

      endif.

      call method lr_masterdata_bl->if_hrpa_buffer_control~initialize.

    else.

      call method lr_masterdata_bl->flush

        exporting

          no_commit = ‘ ‘.

    endif.

  endif.

endmethod.

To use it, you would simply call the method with all required parameters

  data lt_messages type hrpad_message_tab.

  data lv_ok type boole_d.

  call method change_begda_endda

    exporting

      iv_tclas    = ‘A’

      iv_infty    = ‘0002’

      iv_subty    =

      iv_objps    =

      iv_sprps    =

      iv_seqnr    = ‘000’

      iv_pernr    = ‘12345678’

      iv_begda    = ‘20001201’

      iv_endda    = ‘99991231’

      iv_begda_new = ‘20101201’

      iv_endda_new = ‘99991231’

      iv_test_mode = ‘ ‘

    importing

      et_messages = lt_messages

      ev_ok       = lv_ok.

This would change the start date of infotype 0002 for employee 12345678 from 12/01/2000 to 12/01/2010.

Limitations

I’m sure there are many situations where the code will break. For example, I didn’t bother with secondary records and the code handles only one record at a time. In addition the code should check that the decoupled framework can actually be used for the infotype in question. Nevertheless, I thought I’d share this as it may help folks out there.

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

Leave a Reply