BAPI_ACC_DOCUMENT_POST – Vendor Down payment: Update Purchase order info and PO history
There usually is a requirement to post accounting documents in S/4HANA through an interface, program or an enhancement. Irrespective of the trigger point, BAPI ‘BAPI_ACC_DOCUMENT_POST’ does its job well and used extensively in custom developments.
Recently, we got a requirement to post vendor down payments through an interface, which can be done with above mentioned BAPI except that vendor table (ACCOUNTPAYABLE) in BAPI interface doesn’t have a ‘Purchase Order’ field. If you post the vendor down payment through FB01 transaction, you have an option to enter PO number and item number, which gets saved in BSEG table as well. Also, when you enter PO number in FB01 transaction, PO history is updated with generated document number, which doesn’t happen using BAPI. Mostly, having PO information and PO history update is an important requirement to achieve for customer for various reasons and above BAPI doesn’t provide for this requirement.
In this blog post, I am going to explain the solution we implemented to achieve above requirement.
Update Purchase Order Info
To have purchase order information in generated accounting document, we will make use of substitutions. There is lot of information available over the internet regarding substitutions. So, I will keep steps short:
Transaction GGB1 –> Financial Accounting -> Line Item (since we want to substitute a line item level information) -> Create a substitution using menu Substitution -> create or edit the one already existing -> Add a new step(Edit -> Insert Step) -> Choose the particular field that you want to substitute or just use option as ‘Exit’ as shown below:
Define an exit number starting with 9. You have the option to set some prerequisites as well e.g. if you want to trigger the substitution for a particular document type. While you make all above settings and save, system doesn’t ask for any transport request.
To transport these substitution settings, choose your substitution and use menu Substitution -> Transport. On the next screen, uncheck ‘Logical Rules’ and execute thus save your settings in a TR.
Form Routine Implementation
U901 defined in above setting is actually a subroutine name which we will implement. Copy program RGGBS000 to a customer defined name ZRGGBS000 (or any other name). Maintain this custom defined program at below SPRO path:
and update below entry:
These settings will make substitutions trigger your custom program, instead of standard program RGGBS000.
In program ZRGGBS000, implement the custom subroutine appending to already defined form routines.
FORM U901. *Write your code here ENDFORM.
In this subroutine, we check the fields ESRRE and ESRNR from BSEG and accordingly populate the EBELN and EBELP fields. You may include other pre-conditions here as well before updating these fields. BSEG and BKPF tables contain runtime data.
IF bseg-umsks = 'A' AND bseg-ebeln IS INITIAL AND bseg-ebelp IS INITIAL. bseg-ebeln = COND #( WHEN strlen( bseg-esrre ) GT 10 THEN bseg-esrre+17(10) WHEN strlen( bseg-esrre ) LE 10 THEN bseg-esrre ). bseg-ebelp = COND #( WHEN strlen( bseg-esrnr ) GT 5 THEN bseg-esrnr+6(5) WHEN strlen( bseg-esrnr ) LE 5 THEN bseg-esrnr ). ENDIF.
Above code should update the Purchase order and line item number for a generated document.
It is also possible that even after writing above logic, required information is not updated. Then, check below information:
- Go to SM30 and Open maintenance view ‘VWTYGB01’. Check for BSEG- EBELN and BSEG-EBELP entries: If ‘Exclude’ checkbox is ticked, please uncheck it and save the entries, in a transport.
- Execute program ‘RGUGBR00’ to regenerate the substitutions. You should run this program in each system also after TR movements.
Above 2 steps should solve the problem.
You can use above steps to update any other field as well, just do the required coding in routine and make sure fields are not excluded from substitutions.
PO History Update
To update the PO history, we have to implement a BTE:
This BTE gets triggered just before posting the document and system has completed all its checks. It is important not to change any field value in this BTE as there won’t be any further system checks and an undesired value can get updated in the database.
We will just read the purchase order information and update the PO history. Implement the BTE and in the BTE function module, mention below code (make sure that code is triggering only for your interface using any document value or memory id, we don’t want standard transaction executing our code):
*-- Update the PO Number & PO Item Number to BSEG table LOOP AT t_bseg ASSIGNING FIELD-SYMBOL(<lfs_bseg>) WHERE umsks = 'A' AND ebeln IS INITIAL. IF <lfs_bseg>-esrre IS NOT INITIAL AND <lfs_bseg>-esrnr IS NOT INITIAL. <lfs_bseg>-ebeln = COND #( WHEN strlen( <lfs_bseg>-esrre ) GT 10 THEN <lfs_bseg>-esrre+17(10) WHEN strlen( <lfs_bseg>-esrre ) LE 10 THEN <lfs_bseg>-esrre ). <lfs_bseg>-ebelp = COND #( WHEN strlen( <lfs_bseg>-esrnr ) GT 5 THEN <lfs_bseg>-esrnr+6(5) WHEN strlen( <lfs_bseg>-esrnr ) LE 5 THEN <lfs_bseg>-esrnr ). *-- We are updating this local table to track if we have updated any value in T_BSEG so that we can *-- reverse the same after updating PO History. APPEND INITIAL LINE TO lt_bseg ASSIGNING FIELD-SYMBOL(<lfs_bseg_elm>). <lfs_bseg_elm> = CORRESPONDING #( <lfs_bseg> ). ENDIF. ENDLOOP. *-- Call FM Update Purchasing Document CALL FUNCTION 'ME_CREATE_HISTORY_FINANCE' TABLES t_bkpf = t_bkpf t_bseg = t_bseg EXCEPTIONS error_message = 9. IF sy-subrc EQ 9. “ Important to have a abend message here MESSAGE ID sy-msgid TYPE 'A' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. *-- Clear the Po Number and Po Item - If we have updated above, Keeping T_BSEG same as it was received LOOP AT lt_bseg ASSIGNING <lfs_bseg_elm>. READ TABLE t_bseg ASSIGNING <lfs_bseg> WITH KEY bukrs = <lfs_bseg_elm>-bukrs belnr = <lfs_bseg_elm>-belnr gjahr = <lfs_bseg_elm>-gjahr buzei = <lfs_bseg_elm>-buzei. IF sy-subrc IS INITIAL. CLEAR: <lfs_bseg>-ebeln, <lfs_bseg>-ebelp. ENDIF. ENDLOOP.
To conclude, above solutions help us address some BAPI limitations regarding update of some particular field values. Same solution can be used for other fields as well.