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 typerefto cl_hrpa_message_list.
data lr_masterdata_bl typerefto if_hrpa_masterdata_bl.
data container typerefto if_hrpa_infty_container.
data old_container typerefto cl_hrpa_infotype_container.
data new_container typerefto if_hrpa_infty_container.
data new_infotype_container typerefto cl_hrpa_infotype_container.
data infotype_ref typereftodata.
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> typeany.
field-symbols<pskey> type pskey.
field-symbols<record> typeany.
field-symbols<pxxxx> typeany.
createobject lr_message_list.
callmethod cl_hrpa_masterdata_factory=>get_business_logic
importing
business_logic = lr_masterdata_bl.
check lr_masterdata_bl isbound.
callmethod 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.
describetable container_tab lines lv_count.
if lv_count gt1.
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.
callmethod 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 eq0.
lv_is_ok = abap_false.
message e009(pg)with iv_infty into lv_dummy.
move-corresponding sy to ls_msg.
callmethod lr_message_list->if_hrpa_message_handler~add_message
exporting
message = ls_msg
cause = lr_message_list->if_hrpa_message_handler~infotype_generic.
else.
readtable container_tab into container index1.
endif.
endif.
if lv_is_ok = abap_false.
callmethod lr_message_list->get_abend_list
importing
messages = et_messages.
if et_messages isinitial.
callmethod lr_message_list->get_error_list
importing
messages = et_messages.
endif.
return.
endif.
old_container ?= container.
try.
callmethod 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 ).
createdata 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'ofstructure<record>to<pskey>.
callmethod 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.
callmethod 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.
callmethod lr_message_list->get_abend_list
importing
messages = et_messages.
if et_messages[] isinitial.
callmethod lr_message_list->get_error_list
importing
messages = et_messages.
endif.
callmethod lr_masterdata_bl->if_hrpa_buffer_control~initialize.
else.
callmethod 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.
callmethod 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.