Generally we use F-02 to post accounting document and FB08 to reverse them.
And we will use BAPI "BAPI_ACC_DOCUMENT_POST" to post and "BAPI_ACC_DOCUMENT_REV_POST" to reverse.
If you check the parameter of "BAPI_ACC_DOCUMENT_POST", you will found some fields in BKPF/BSEG are missing, such as "BSCHL/XNEGP".
So we need to transport them to BAPI via extension2, and transport to document via BADI.
1. Create a strusture include the item number and the field you want to transport:
TCode: SE11
2. Implement the BADI "ACC_DOCUMENT"
TCode: SE19
Reference Transaction is "BKPFF"
Implement the method: CHANGE
Method if_ex_acc_document~change. data: wa_extension type bapiparex, ext_value(960) type c, wa_accit type accit, l_ref type ref to data. field-symbols: <l_struc> type any, <l_field> type any. sort c_extension2 by structure. loop at c_extension2 into wa_extension. at new structure. create data l_ref type (wa_extension-structure). assign l_ref->* to <l_struc>. endat. concatenate wa_extension-valuepart1 wa_extension-valuepart2 wa_extension-valuepart3 wa_extension-valuepart4 into ext_value. move ext_value to <l_struc>. assign component 'POSNR' of structure <l_struc> to <l_field>. if sy-subrc = 0. read table c_accit into wa_accit with key posnr = <l_field>. if sy-subrc = 0. move-corresponding <l_struc> to wa_accit. " Use corresponding so that the field's name in structure must be same with them in BSEG or BKPF modify c_accit from wa_accit index sy-tabix. endif. endif. endloop. endmethod.
3. Now we can prepare the parameters for BAPI
* clear the variables refresh: it_accountgl, it_accountreceivable, it_currencyamount, it_criteria, it_valuefield, it_extension2, it_return. clear: wa_documentheader, wa_obj. ********************************************************************** * Header ********************************************************************** * Document Date wa_documentheader-doc_date = wa_head-bldat. * Posting Date wa_documentheader-pstng_date = wa_head-budat. * Document Type wa_documentheader-doc_type = wa_head-blart. * Company Code wa_documentheader-comp_code = wa_head-bukrs. * Document Header Text wa_documentheader-header_txt = wa_head-bktxt. * Creator User name wa_documentheader-username = sy-uname. ********************************************************************** * Item ********************************************************************** loop at it_item into wa_item. if wa_item-bschl = '01' or wa_item-bschl = '11'. " Customer clear wa_accountreceivable. * Item number wa_accountreceivable-itemno_acc = wa_item-buzei. * General Ledger Account wa_accountreceivable-gl_account = wa_item-hkont. * Item Text wa_accountreceivable-item_text = wa_item-sgtxt. * Customer Number wa_accountreceivable-customer = wa_item-kunnr. * Terms of Payment Key wa_accountreceivable-pmnttrms = wa_item-zterm. * Baseline Date for Due Date Calculation wa_accountreceivable-bline_date = wa_item-zfbdt. append wa_accountreceivable to it_accountreceivable. clear wa_currencyamount. wa_currencyamount-itemno_acc = wa_item-buzei. * Currency wa_currencyamount-currency = wa_item-waers. * Amount in Document Currency wa_currencyamount-amt_doccur = wa_item-wrbtr. if wa_item-bschl = '11' or wa_item-bschl = '50'. wa_currencyamount-amt_doccur = - wa_currencyamount-amt_doccur. endif. append wa_currencyamount to it_currencyamount. " Posting Key & Indicator: Negative posting clear wa_extension2. clear wa_zaccdocuext. wa_zaccdocuext-posnr = wa_item-buzei. wa_zaccdocuext-bschl = wa_item-bschl. if wa_item-bschl = '11' or wa_item-bschl = '40'. wa_zaccdocuext-xnegp = 'X'. endif. wa_extension2-structure = 'ZACCDOCUEXT'. wa_extension2-valuepart1 = wa_zaccdocuext. append wa_extension2 to it_extension2. elseif wa_item-bschl = '40' or wa_item-bschl = '50'. " G/L account clear wa_accountgl. * Item number wa_accountgl-itemno_acc = wa_item-buzei. * General Ledger Account wa_accountgl-gl_account = wa_item-hkont. * Item Text wa_accountgl-item_text = wa_item-sgtxt. * Tax Code wa_accountgl-tax_code = wa_item-mwskz. append wa_accountgl to it_accountgl. clear wa_currencyamount. wa_currencyamount-itemno_acc = wa_item-buzei. * Currency wa_currencyamount-currency = wa_item-waers. * Amount in Document Currency wa_currencyamount-amt_doccur = wa_item-wrbtr. if wa_item-bschl = '11' or wa_item-bschl = '50'. wa_currencyamount-amt_doccur = - wa_currencyamount-amt_doccur. endif. append wa_currencyamount to it_currencyamount. " Posting Key & Indicator: Negative posting clear wa_extension2. clear wa_zaccdocuext. wa_zaccdocuext-posnr = wa_item-buzei. wa_zaccdocuext-bschl = wa_item-bschl. if wa_item-bschl = '11' or wa_item-bschl = '40'. wa_zaccdocuext-xnegp = 'X'. endif. wa_extension2-structure = 'ZACCDOCUEXT'. wa_extension2-valuepart1 = wa_zaccdocuext. append wa_extension2 to it_extension2. endif. clear l_katyp. select single katyp into l_katyp from cskb where kstar = wa_item-hkont. if l_katyp = '11'. " Profit Segment clear wa_criteria. wa_criteria-itemno_acc = wa_item-buzei. wa_criteria-fieldname = 'KAUFN'. " Sales Order wa_criteria-character = wa_item-vbeln. append wa_criteria to it_criteria. wa_criteria-fieldname = 'KDPOS'. " Sales Order Item wa_criteria-character = wa_item-posnr. append wa_criteria to it_criteria. wa_criteria-fieldname = 'KNDNR'. " Customer wa_criteria-character = wa_vbak-kunnr. append wa_criteria to it_criteria. wa_criteria-fieldname = 'ARTNR'. " Material wa_criteria-character = wa_item-matnr. append wa_criteria to it_criteria. endif. endloop.
4. Call BAPI at last
call function 'BAPI_ACC_DOCUMENT_POST' exporting documentheader = wa_documentheader * CUSTOMERCPD = * CONTRACTHEADER = importing obj_type = wa_obj-obj_type obj_key = wa_obj-obj_key obj_sys = wa_obj-obj_sys tables accountgl = it_accountgl accountreceivable = it_accountreceivable * ACCOUNTPAYABLE = * ACCOUNTTAX = currencyamount = it_currencyamount criteria = it_criteria valuefield = it_valuefield * EXTENSION1 = return = it_return * PAYMENTCARD = * CONTRACTITEM = extension2 = it_extension2 * REALESTATE = * ACCOUNTWT = . read table it_return into wa_return with key type = 'E'. if sy-subrc = 0. call function 'BAPI_TRANSACTION_ROLLBACK'. perform frm_message_display. else. call function 'BAPI_TRANSACTION_COMMIT' exporting wait = 'X'. " Return the Accounting Document Number and Fiscal Year p_belnr = wa_obj-obj_key(10). p_gjahr = wa_obj-obj_key+14(4). endif.
As for use "BAPI_ACC_DOCUMENT_REV_POST" to reverse document is more simpler:
Get the object type and object key of reverse document from table BKPF
wa_reversal-obj_type = wa_bkpf-awtyp. wa_reversal-obj_key = wa_bkpf-awkey. wa_reversal-obj_key_r = wa_bkpf-awkey. wa_reversal-reason_rev = '04'. " The reason code is required: wa_reversal-pstng_date = sy-datum. " The posting date is optional: call function 'BAPI_ACC_DOCUMENT_REV_POST' exporting reversal = wa_reversal bus_act = 'RFBU' importing obj_type = wa_obj-obj_type obj_key = wa_obj-obj_key obj_sys = wa_obj-obj_sys tables return = it_return. read table it_return into wa_return with key type = 'E'. if sy-subrc = 0. call function 'BAPI_TRANSACTION_ROLLBACK'. else. call function 'BAPI_TRANSACTION_COMMIT' exporting wait = 'X'. g_suc = 'X'. endif. loop at it_return into wa_return. * call function 'MESSAGE_TEXT_BUILD' * exporting * msgid = wa_return-id * msgnr = wa_return-number * msgv1 = wa_return-message_v1 * msgv2 = wa_return-message_v2 * msgv3 = wa_return-message_v3 * msgv4 = wa_return-message_v4 * importing * message_text_output = g_msg. * write: / g_msg. perform store_messages using wa_return-id wa_return-type wa_return-message_v1 wa_return-message_v2 wa_return-message_v3 wa_return-message_v4 wa_return-number. endloop.