METHOD operate_it.
DATA ls_return TYPE bapireturn1.
DATA key TYPE bapipakey.
CALL FUNCTION 'BAPI_EMPLOYEE_ENQUEUE'
EXPORTING
number = is_2002-pernr
IMPORTING
return = ls_return.
IF ls_return IS NOT INITIAL.
RAISE EXCEPTION TYPE zcx_xxx MESSAGE ID ls_return-id TYPE ls_return-type NUMBER ls_return-number.
ENDIF.
CALL FUNCTION 'HR_INFOTYPE_OPERATION'
EXPORTING
infty = '2002'
number = is_2002-pernr
subtype = is_2002-subty
objectid = is_2002-objps
lockindicator = is_2002-sprps
validityend = is_2002-endda
validitybegin = is_2002-begda
recordnumber = is_2002-seqnr
record = is_2002_chg
operation = iv_actio "MOD,INS,DEL
tclas = 'A'
dialog_mode = '0'
IMPORTING
return = ls_return
key = key.
IF ls_return IS NOT INITIAL.
RAISE EXCEPTION TYPE zcx_xxx MESSAGE ID ls_return-id TYPE ls_return-type NUMBER ls_return-number.
ENDIF.
CALL FUNCTION 'BAPI_EMPLOYEE_DEQUEUE'
EXPORTING
number = is_2002-pernr.
ENDMETHOD.
Category: ABAP
ABAP
[ABAP] BAPI_ACC_DOCUMENT_POST
How to handle BAPI_ACC_DOCUMENT_POST with a document split at position 980. The method create_document fills the necessary tables and calls post_document, if it reaches position 980, to post the current document. Then the method create_document calls itself recursiv for the next positions.
METHOD create_document.
DATA: lt_pos TYPE TABLE OF bapiacgl09,
lt_pos_amt TYPE TABLE OF bapiaccr09.
gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_info
iv_text = |Beginne Belegerstellung|
iv_alog = abap_true ).
"Belegkopf
DATA(ls_documentheader) = VALUE bapiache09( comp_code = gs_sel-p_bukrs
header_txt = |header text|
pstng_date = sy-datum
doc_date = sy-datum
fisc_year = sy-datum(4)
fis_period = sy-datum+4(2)
doc_type = gs_sel-p_blart
username = sy-uname ).
"Fülle Positionen
LOOP AT it_xxx ASSIGNING FIELD-SYMBOL(<ls_xxx>).
APPEND VALUE #( itemno_acc = lines( lt_pos ) + 1
gl_account = <ls_xxx>-hkont
stat_con = abap_false
acct_type = 'S' "Sachkonto
bus_area = '0030'
fis_period = sy-datum+4(2)
fisc_year = sy-datum(4)
pstng_date = sy-datum
value_date = sy-datum
item_text = |item text|
alloc_nmbr = <ls_xxx>-zuonr
doc_type = <ls_xxx>-blart
comp_code = <ls_xxx>-bukrs
func_area = '0030'
costcenter = <ls_xxx>-kostl
tax_code = <ls_xxx>-mwskz ) TO lt_pos.
APPEND VALUE #( itemno_acc = lines( lt_pos_amt ) + 1
curr_type = '00' "Belegwährung
currency = |EUR|
amt_doccur = <ls_xxx>-betrg ) TO lt_pos_amt.
"Belegsplit notwendig?
IF lines( lt_pos ) = 980.
gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_statistic
iv_text = |Belegsplit notwendig!|
iv_alog = abap_true ).
"Verbuche die aktuellen Positionen
post_document( is_documentheader = ls_documentheader
it_pos = lt_pos
it_pos_amt = lt_pos_amt ).
"Rekursiver Aufruf der Methode! Nur mit den Sätzen die noch nicht verarbeitet wurden
create_document( it_xxx = FILTER #( it_xxx USING KEY sort_key WHERE xxx = xxx ) ).
"Verlasse bei Rekursion hier
RETURN.
ENDIF.
ENDLOOP.
"Wenn alle Positionen hinzugefügt, lege den Beleg an
post_document( is_documentheader = ls_documentheader
it_pos = lt_pos
it_pos_amt = lt_pos_amt ).
ENDMETHOD.
Calling the BAPI:
METHOD post_document.
DATA lt_return TYPE STANDARD TABLE OF bapiret2.
IF gs_sel-p_test = abap_true.
gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_info
iv_text = |Testlauf: Keine Belegbuchung|
iv_alog = abap_true ).
RETURN. "Im Testlauf hier verlassen
ENDIF.
SET UPDATE TASK LOCAL.
CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
EXPORTING
documentheader = is_documentheader
TABLES
accountgl = it_pos
currencyamount = it_pos_amt
return = lt_return.
"Protokollzeilen mit BAPI Meldungen hinzufügen
LOOP AT lt_return ASSIGNING FIELD-SYMBOL(<ls_return>).
gr_listlog->append_log_entry( iv_type = <ls_return>-type
iv_text = CONV #( <ls_return>-message )
iv_alog = abap_true ).
ENDLOOP.
"Prüfen, ob eine Fehlermeldung vorliegt
IF line_exists( lt_return[ type = 'A' ] ) OR line_exists( lt_return[ type = 'E' ] ).
"Rollback
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
"Alles gut -> commit
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
"Protokollzeile mit der Erzeugten Belegnummer nochmal explizit ins Log
DATA(lv_documentnumber) = lt_return[ 1 ]-message_v2(10). "hier steht laut Doku die Belegnummer drin
gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_success
iv_text = |Belegnummer: { lv_documentnumber }|
iv_alog = abap_true ).
ENDIF.
ENDMETHOD.
[ABAP] Clean Code
DRY – Don’t repeat yourself
KISS – Keep it simple, stupid
YAGNI – You ain’t gonna need it
PEBKAC – Problem Exist Between Keyboard And Chair
SoC – Separation of concerns
Issues generally come in three forms:
- syntax errors that prevent a program from running
- runtime errors when code fails to execute or has unexpected behavior
- semantic (or logical) errors when code doesn’t do what it’s meant to
[ABAP] Read infotype records
* Read multiple infotype records
DATA: ls_p0001 TYPE p0001,
lt_p0001 TYPE TABLE OF p0001.
* Initialise Infotyp reader
cl_hrpa_read_infotype=>get_instance( IMPORTING infotype_reader = DATA(lr_infotype_reader) ).
* Read Infotyp 1
lr_infotype_reader->read( EXPORTING tclas = 'A'
pernr = 6
infty = '0001'
begda = '01011900'
endda = '31129999'
no_auth_check = abap_true
IMPORTING infotype_tab = DATA(lt_infotype)
data_exists = DATA(lv_data_exists) ).
LOOP AT lt_infotype INTO DATA(ls_infotype).
cl_hr_pnnnn_type_cast=>prelp_to_pnnnn( EXPORTING prelp = ls_infotype
IMPORTING pnnnn = ls_p0001 ).
APPEND ls_p0001 TO lt_p0001.
ENDLOOP.
cl_demo_output=>display( lt_p0001 ).
[ABAP] Idoc MBGMCR – Goods Movement
METHOD create_mbgmcr_idoc.
set_idoc_control( IMPORTING es_idoc_control = DATA(ls_idoc_control) ).
map_mbgmcr_data( EXPORTING is_data = is_data
IMPORTING es_kopf = DATA(ls_kopf)
es_head = DATA(ls_head)
es_code = DATA(ls_code)
et_item = DATA(lt_item) ).
set_idoc_data( EXPORTING is_kopf = ls_kopf
is_head = ls_head
is_code = ls_code
it_item = lt_item
IMPORTING et_idoc_data = DATA(lt_idoc_data) ).
idoc_inbound_write_to_db( IMPORTING ev_idoc_number = DATA(lv_docnum)
CHANGING ct_idoc_data = lt_idoc_data
cs_idoc_control = ls_idoc_control ).
idoc_start_inbound( EXPORTING it_idoc_data = lt_idoc_data
is_idoc_control = ls_idoc_control ).
get_idoc_status( EXPORTING iv_docnum = lv_docnum ).
ENDMETHOD.
Method set_idoc_control:
METHOD set_idoc_control.
CLEAR es_idoc_control.
" Lese Partnummer
SELECT SINGLE logsys FROM t000 INTO @DATA(lv_logsys)
WHERE mandt = @sy-mandt.
" IDOC Basisdaten
es_idoc_control-mandt = sy-mandt.
es_idoc_control-direct = '2'. "Richtung der IDoc-Übertragung: Eingang
es_idoc_control-idoctp = mc_idoctp. "MBGMCR03
es_idoc_control-mestyp = mc_mestyp. "MBGMCR
es_idoc_control-mescod = mc_mescod. "Logische Nachrichtenvariante
" Empfänger
es_idoc_control-rcvpor = |SAP{ sy-sysid }|. "Empfängerport (SAP-System, EDI-Subsystem)
es_idoc_control-rcvprt = mc_rcvprt. "Partnerart des Empfängers (LS)
es_idoc_control-rcvprn = lv_logsys. "Partnernummer des Empfängers
" Sender
es_idoc_control-sndpor = |SAP{ sy-sysid }|. "Absenderport (SAP-System, EDI-Subsystem)
es_idoc_control-sndprt = mc_rcvprt. "Partnerart des Absenders (LS)
es_idoc_control-sndprn = lv_logsys. "Partnernummer des Absenders
ENDMETHOD.
Method map_mbgmcr_data:
METHOD map_mbgmcr_data.
" Hinweis: Zum Füllen der Strukturen, siehe auch Dokumentation für BAPI_GOODSMVT_CREATE.
" Die möglichen Werte für gm_code findet man in der Tabelle T158G
CLEAR: es_kopf, es_head, es_code, et_item.
es_kopf = VALUE #( testrun = gs_sel-test ).
es_head = VALUE #( pstng_date = sy-datum
doc_date = sy-datum ).
es_code = VALUE #( gm_code = mc_gm_code_04 ). "Code 04: Umbuchung
et_item = VALUE #( ( is_data ...) ).
ENDMETHOD.
Method set_idoc_data:
METHOD set_idoc_data.
CLEAR et_idoc_data.
et_idoc_data = VALUE #( ( segnam = 'E1MBGMCR' sdata = is_kopf segnum = 1 psgnum = 1 hlevel = 1 )
( segnam = 'E1BP2017_GM_HEAD_01' sdata = is_head segnum = 2 psgnum = 2 hlevel = 2 )
( segnam = 'E1BP2017_GM_CODE' sdata = is_code segnum = 3 psgnum = 2 hlevel = 2 ) ).
DO lines( it_item ) TIMES.
APPEND VALUE #( segnam = 'E1BP2017_GM_ITEM_CREATE' sdata = it_item[ sy-index ] segnum = ( 3 + sy-index ) psgnum = 2 hlevel = 2 ) TO et_idoc_data.
ENDDO.
ENDMETHOD.
Method idoc_inbound_write_to_db :
METHOD idoc_inbound_write_to_db.
CLEAR : ev_idoc_number, ev_state, ev_inb_process_data.
CALL FUNCTION 'IDOC_INBOUND_WRITE_TO_DB'
EXPORTING
pi_do_handle_error = abap_true
pi_return_data_flag = abap_true
IMPORTING
pe_idoc_number = ev_idoc_number
pe_state_of_processing = ev_state
pe_inbound_process_data = ev_inb_process_data
TABLES
t_data_records = ct_idoc_data
CHANGING
pc_control_record = cs_idoc_control
EXCEPTIONS
idoc_not_saved = 1
OTHERS = 2.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_ecos_goods_movement
EXPORTING
textid = VALUE scx_t100key( msgid = sy-msgid
msgno = sy-msgno
attr1 = sy-msgv1
attr2 = sy-msgv2
attr3 = sy-msgv3
attr4 = sy-msgv4 ).
ENDIF.
gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_statistic
iv_text = |Idoc mit der Nummer { ev_idoc_number } angelegt.|
iv_alog = abap_true ).
ENDMETHOD.
Method idoc_start_inbound :
METHOD idoc_start_inbound.
DATA: lt_idoc_control TYPE TABLE OF edidc.
APPEND is_idoc_control TO lt_idoc_control.
CALL FUNCTION 'IDOC_START_INBOUND'
EXPORTING
pi_do_commit = abap_true
TABLES
t_control_records = lt_idoc_control
t_data_records = it_idoc_data
EXCEPTIONS
invalid_document_number = 1
error_before_call_application = 2
inbound_process_not_possible = 3
old_wf_start_failed = 4
wf_task_error = 5
serious_inbound_error = 6
OTHERS = 7.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_xxx
EXPORTING
textid = VALUE scx_t100key( msgid = sy-msgid
msgno = sy-msgno
attr1 = sy-msgv1
attr2 = sy-msgv2
attr3 = sy-msgv3
attr4 = sy-msgv4 ).
ENDIF.
ENDMETHOD.
Method get_idoc_status:
METHOD get_idoc_status.
SELECT SINGLE status FROM edidc INTO @DATA(lv_status) WHERE docnum = @iv_docnum.
gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_statistic
iv_text = |Idoc Status: { lv_status }|
iv_alog = abap_true ).
ENDMETHOD.