Thursday, 18 September 2025

Add Custom Fields AR01 Transaction Code in SAP ABAP

Add Custom File to Tcode AR01 in SAP ABAP

Add Custom File to Tcode AR01 in SAP ABAP

A step-by-step guide to extend AR01 functionality with custom fields and logic in SAP ABAP.

Introduction

In this tutorial, we will explore how to add a custom file in tcode AR01 by enhancing the program RABEST_ALV01. The approach involves using the main structure FIAA_SALVTAB_RABEST and the include structure CI_REPRABEST.

Main Structure and Include

  • Main Structure: FIAA_SALVTAB_RABEST
  • Include Structure: CI_REPRABEST

Custom Code Implementation

Below is the ABAP code snippet inserted into the program RABEST_ALV01 to fetch additional information such as cost center, profit center, asset class description, and long text:


FIELD-SYMBOLS: <ANLN1> TYPE ANY.
FIELD-SYMBOLS: <ANLKL> TYPE ANY.
FIELD-SYMBOLS: <KOSTL> TYPE ANY.
FIELD-SYMBOLS: <PRCTR> TYPE ANY.
FIELD-SYMBOLS: <LTEXT> TYPE ANY.
FIELD-SYMBOLS: <TXK50> TYPE ANY.

LOOP AT <itab_data>[] ASSIGNING FIELD-SYMBOL(<fs_csfield>).

  ASSIGN COMPONENT 'KOSTL' OF STRUCTURE <fs_csfield> TO <KOSTL>.
  ASSIGN COMPONENT 'PRCTR' OF STRUCTURE <fs_csfield> TO <PRCTR>.
  ASSIGN COMPONENT 'ANLKL' OF STRUCTURE <fs_csfield> TO <ANLKL>.
  ASSIGN COMPONENT 'TXK50' OF STRUCTURE <fs_csfield> TO <TXK50>.
  ASSIGN COMPONENT 'LTEXT' OF STRUCTURE <fs_csfield> TO <LTEXT>.

  SELECT SINGLE PRCTR FROM CSKS
    INTO <PRCTR> WHERE KOSTL = <KOSTL>.

  SELECT SINGLE LTEXT FROM CEPCT
    INTO <LTEXT> WHERE PRCTR = <PRCTR> AND SPRAS = sy-langu.

  SELECT SINGLE TXK50 FROM ANKT
    INTO <TXK50> WHERE SPRAS = sy-langu AND ANLKL = <ANLKL>.

ENDLOOP.
      

Conclusion

By adding the above logic into RABEST_ALV01, you can extend the AR01 report to include additional information like cost center descriptions, profit center texts, and asset class details. This approach provides flexibility for financial reporting in SAP.

Wednesday, 17 September 2025

How to Create a REST API in SAP ABAP — Step-by-step Guide

How to Create a REST API in SAP ABAP — Step-by-step Guide

Summary: This tutorial shows how to build a REST API in SAP ABAP by creating a handler class, configuring SICF service, registering endpoints with cl_rest_router, implementing endpoint logic (example GET method), and testing the API. Based on an internal implementation reference.

Why expose REST APIs from SAP?

REST APIs allow SAP systems to integrate with web, mobile, and external services using standard HTTP and JSON payloads. Implementing REST endpoints in ABAP provides secure, reusable, and maintainable integration points for modern applications.

Prerequisites

  • Access to an SAP system with authorization to create classes (SE24) and SICF services (SICF).
  • Familiarity with ABAP object-oriented concepts and basic SAP transaction codes.
  • ABAP classes CL_REST_RESOURCE, CL_REST_ROUTER and utilities like /UI2/CL_JSON.

High-level overview (4 steps)

  1. Create an API handler class (e.g. ZCL_API_HANDLER).
  2. Register endpoint templates using cl_rest_router.
  3. Create and activate an SICF service (e.g. /sap/bc/zapi01).
  4. Implement endpoint logic in endpoint classes and test the API.

Step 1 — Create the API handler class

Create class ZCL_API_HANDLER in SE24, implement CL_REST_HTTP_HANDLER, and register endpoints.


DATA(lo_router) = NEW cl_rest_router( ).
lo_router->attach(
  EXPORTING
    iv_template      = '/ZFLIGHTLIST'
    iv_handler_class = 'ZCL_FLIGHT01' ).
ro_root_handler = lo_router.

Step 2 — Create and configure the SICF service

In SICF, create a new service node (e.g. ZAPI01) and attach your handler class ZCL_API_HANDLER. Activate the service.

Step 3 — Create endpoint class

Make class ZCL_FLIGHT01 inheriting from CL_REST_RESOURCE. Redefine GET/POST methods.


METHOD if_rest_resource~get.
  " Parse JSON request
  DATA(lo_entity) = mo_request->get_entity( ).
  DATA(lv_data)   = lo_entity->get_string_data( ).
  DATA: ls_params TYPE ty_flight.

  /ui2/cl_json=>deserialize( json = lv_data changing data = ls_params ).

  " Read SFLIGHT
  IF ls_params IS NOT INITIAL.
    SELECT * FROM sflight INTO TABLE @DATA(lt_flight)
      WHERE carrid = @ls_params-carrid
        AND connid = @ls_params-connid.
  ELSE.
    SELECT * FROM sflight INTO TABLE @lt_flight.
  ENDIF.

  " Build JSON response
  IF lt_flight IS NOT INITIAL.
    /ui2/cl_json=>serialize( data = lt_flight RECEIVING r_json = lv_result ).
    lv_result = '{"Status":"OK","Message":"SUCCESS","Data":' && lv_result && '}'.
  ELSE.
    lv_result = '{"Status":"ERROR","Message":"DATA NOT FOUND"}'.
  ENDIF.

  lo_response->set_string_data( iv_data = lv_result ).
  lo_response->set_header_field(
    EXPORTING iv_name = 'CONTENT-TYPE'
              iv_value = 'APPLICATION/JSON' ).
ENDMETHOD.

Step 4 — Test the API

Test with Postman or cURL. Example:


curl -u username:password -X GET "https://your-sap-host/sap/bc/zapi01/ZFLIGHTLIST" \
-H "Content-Type: application/json" \
-d '{"carrid":"AA","connid":"0017"}'

Security & Best Practices

  • Always use HTTPS and proper authentication.
  • Validate and sanitize inputs.
  • Return correct HTTP status codes.
  • Use pagination for large datasets.
  • Log requests and errors responsibly.

FAQ

Where do I register endpoints?

Inside cl_rest_router in the handler class.

Which transaction creates the web service?

SICF is used to create and activate the service node.

Which ABAP class handles JSON?

/UI2/CL_JSON is commonly used for JSON serialization and deserialization.

Tuesday, 16 September 2025

Custom Agent Determination in SAP Flexible Workflow for Supplier Invoice Approval

Custom Agent Determination in SAP Flexible Workflow for Supplier Invoice Approval

Custom Agent Determination in SAP Flexible Workflow for Supplier Invoice Approval

In SAP MM, supplier invoice approval is often handled using the Flexible Workflow. However, standard configuration may not fully cover complex approval requirements. In such cases, Custom Agent Determination can be implemented using BAdI MRM_WORKFLOW_AGENTS.

This blog explains how to implement a custom approval workflow for supplier invoices (MIR7), including creating custom tables, CDS views, Fiori custom logic, and defining workflow conditions.

1. Create Custom Tables

Two custom tables are required:

a. Table for Mapping User Approval

Table: ZMMT007 (Supplier Invoice Approval Agent Assignment)

  • FUNCTION – Function key
  • FUNDESC – Function description
  • APP_LVL – Approval level
  • BUS_USR – Business user

b. Table for Mapping Condition Approval

Table: ZMMT008 (Invoice Release Strategy)

  • ZREL_GROUP – Release group
  • ZREL_STRAT – Release strategy
  • ZFUNCTION – Function
  • ZSIGN – Comparison sign
  • ZCURR – Currency
  • ZAMOUNT – Amount threshold

2. Create Custom CDS Views

CDS views are required for retrieving approval mapping data. Example definitions:

@AbapCatalog.sqlViewName: 'ZIWFINVOICE'
define view ZI_SUPP_INV_WF as select from zmmt007 {
  key function as Function,
  fundesc as FuncDesc,
  app_lvl as AppLvl,
  bus_usr as BusUser
}
      
@AbapCatalog.sqlViewName: 'ZIWFINVOICEREL'
define view ZI_SUPP_INV_REL_MAP as select from zmmt008 {
  key zrel_group,
  key zrel_strat,
  zfunction,
  zsign,
  zcurr,
  zamount
}
      

Make sure to release CDS Views for usage in custom logic by setting the API State to Use System-Internally (Contract C1).

3. Implement Custom Logic in Fiori

Navigate to Custom Logic app in Fiori and create a new implementation:

  • Business Context: Procurement: Flexible Workflow
  • BAdI: Determination of Workflow Agents for Supplier Invoice
  • Implementation ID: BADI MRM_WORKFLOW_AGENTS

Sample ABAP snippet for custom agent selection:

DATA: lt_wf TYPE TABLE OF ZI_SUPP_INV_WF,
      lt_wf_rel TYPE TABLE OF zi_supp_inv_rel_map,
      ls_wf_relx TYPE zi_supp_inv_rel_map.

SELECT * FROM I_SupplierInvoiceAPI01
  WHERE SupplierInvoice = @supplierinvoice
    AND FiscalYear = @FiscalYear
  INTO TABLE @DATA(lt_SupplierInv).

IF ls_invoice-companycode = 'JSB'
   AND ls_invoice-ACCOUNTINGDOCUMENTTYPE = 'RE'
   AND ls_invoice-INVOICEGROSSAMOUNT >= 1.

  SELECT * FROM zi_supp_inv_rel_map
    WHERE zrel_group = 'WPO-GEN-WF'
      AND zrel_strat = 'ALL'
    INTO TABLE @lt_wf_rel.

ENDIF.
      

In the Filter tab, set the filter: workflowscenario = WS00800303.

4. Define Flexible Workflow Conditions

In the Fiori app Manage Workflows for Supplier Invoices, configure the workflows according to business rules. For example:

a. Invoice With PO

  • Company code = JSB
  • Invoice is based on PO
  • Steps: Level-1 and Level-2 Agent Determination via BAdI

b. Invoice Without PO < 10 Million

  • Company code = JSB
  • Amount < 10,000,000 IDR
  • Steps: Level-1, Level-2, Level-3 Agent Determination

c. Invoice Without PO ≥ 10 Million

  • Company code = JSB
  • Amount ≥ 10,000,000 IDR
  • Steps: Level-1 to Level-4 Agent Determination

Conclusion

By combining custom tables, CDS views, and Fiori custom logic, businesses can implement robust and flexible approval workflows for supplier invoices in SAP. This approach ensures compliance, supports complex approval hierarchies, and automates the agent determination process.

👉 If you’re also interested in other SAP MM workflow enhancements, check out our related article on SAP Invoice Splitting.

How to Set Default Values in SAP Business Partner (BP)

How to Set Default Values in SAP Business Partner (BP)

How to Set Default Values in SAP Business Partner (BP)

In SAP Business Partner (BP) transactions, setting default values can help streamline data entry and ensure consistency across the system. For example, you may want to predefine a default language or tolerance group at the company level. SAP provides a standard way to handle this through the BUSDEFAULT structure and enhancement options.

This guide explains how to set default BP values using customer exits and the function module BUP_BUPA_FIELDVALUES_SET.

Understanding the BUSDEFAULT Structure

SAP provides a structure called BUSDEFAULT, which contains fields that can be configured with default values. You can explore it using transaction SE11.

Some of the key fields available in BUSDEFAULT include:

  • LANGU – Business partner language
  • COUNTRY – Country/Region key
  • POST_CODE1 – City postal code
  • MC_CITY1 – City name
  • TELNR – Telephone number
  • BPKIND – Business Partner Type
  • BU_SORT1 / BU_SORT2 – Search Terms

For a detailed reference, SAP Note 2992030 provides more insights into this feature.

Implementation Steps

Follow these steps to configure default values for SAP BP:

  1. Create a custom function module in the customer namespace.
  2. Within the function module, call BUP_BUPA_FIELDVALUES_SET to populate default values.
  3. Save and activate the function module.
  4. Run transaction BUS7.
  5. Open event ISDAT/ISSTA.
  6. Create a new entry to register your function module for application BUP.
  7. Save and ensure the Call indicator is set to X.

Sample ABAP Code


DATA i_busdefault TYPE busdefault.

CLEAR i_busdefault.
i_busdefault-langu = sy-langu.

CALL FUNCTION 'BUP_BUPA_FIELDVALUES_SET'
  EXPORTING
    i_busdefault = i_busdefault.
      

This example sets the default language (LANGU) based on the system language (sy-langu).

Registering the Function Module

In transaction BUS7, add a new entry to link the function module with the event:

  • Event: ISDAT (Read Data)
  • Function Module: Your custom module (e.g., Z_BUP_BUPA_DEFAULTS)
  • Call: Set to X

This ensures the default values are applied automatically whenever BP data is processed.

Conclusion

By leveraging the BUSDEFAULT structure and BUP_BUPA_FIELDVALUES_SET function module, you can automate the process of setting default values in SAP Business Partner (BP). This not only saves time but also improves data consistency and reduces manual errors.

For complex requirements, you can extend this approach by customizing additional fields within the BUSDEFAULT structure and linking them to events in BUS7.

SAP Badi Invoice Splitting Document

Mastering Invoice Splitting in SAP: A Complete Guide

Mastering Invoice Splitting in SAP: A Complete Guide

In SAP Financial Accounting (FI), managing invoices efficiently is critical for smooth financial operations. One of the most requested enhancements by businesses is invoice splitting, especially when dealing with complex procurement or billing scenarios. SAP provides flexibility through Business Add-Ins (BAdIs), allowing developers to customize invoice processing in both MIRO (Invoice Receipt) and VF01 (Billing Document Creation).

This article explains the process of invoice splitting in SAP using the relevant BAdIs:

  • FI_INVOICE_RECEIPT_SPLIT for MIRO
  • FI_BILL_ISSUE_SPLIT for VF01

By the end, you’ll have a clear understanding of how to implement and optimize invoice splitting to meet business needs.

What is Invoice Splitting in SAP?

Invoice splitting refers to dividing a single invoice into multiple accounting documents based on predefined criteria, such as:

  • Cost centers
  • Business areas
  • Profit centers
  • Tax codes
  • Vendor/customer requirements

This ensures accurate financial postings and better transparency for reporting and auditing.

BAdI for Invoice Splitting in MIRO

When processing supplier invoices in MIRO, SAP allows enhancement through the BAdI:

BAdI Name: FI_INVOICE_RECEIPT_SPLIT

Use Cases:

  • Splitting incoming vendor invoices by cost center.
  • Handling multiple tax codes within the same invoice.
  • Automating posting rules based on business area.

Benefits:

  • Improved accuracy in FI postings.
  • Reduced manual corrections.
  • Better compliance with local accounting rules.

BAdI for Invoice Splitting in VF01

For billing documents created in VF01, SAP provides another enhancement:

BAdI Name: FI_BILL_ISSUE_SPLIT

Use Cases:

  • Splitting customer invoices by profit center.
  • Generating separate accounting documents for different regions or entities.
  • Supporting complex revenue recognition requirements.

Benefits:

  • Streamlined revenue posting.
  • Enhanced transparency in customer billing.
  • More flexibility in financial reporting.

Step-by-Step Implementation (High-Level)

  1. Identify Business Requirement: Define the splitting logic (e.g., cost center, tax code, region).
  2. Implement the BAdI: Use transaction SE18/SE19 to locate and enhance the BAdI. Write custom ABAP logic for splitting criteria.
  3. Test in MIRO or VF01: Post invoices and check split accounting documents. Validate results against business rules.
  4. Move to Production: Ensure thorough testing in QA. Deploy and monitor results.

Best Practices for Invoice Splitting in SAP

  • Always document splitting logic for audit purposes.
  • Avoid hardcoding values; use configuration tables where possible.
  • Test with multiple business scenarios before go-live.
  • Monitor system performance to avoid posting delays.

Conclusion

Invoice splitting in SAP is a powerful way to enhance financial accuracy and reporting. By leveraging BAdIs such as FI_INVOICE_RECEIPT_SPLIT (for MIRO) and FI_BILL_ISSUE_SPLIT (for VF01), businesses can tailor invoice processing to match their financial and compliance needs.

Implementing these enhancements not only improves transparency but also saves significant manual effort, making financial operations more reliable and efficient.

👉 Looking to implement SAP invoice splitting in your system? Our step-by-step guide and best practices will help you streamline the process and achieve compliance with ease.

Monday, 15 September 2025

Enhance SAP FBL1N, FBL3N & FBL5N: Add Custom Fields in 3 Easy Steps (ABAP Guide)

Enhance SAP FBL1N, FBL3N & FBL5N: Add Custom Fields in 3 Easy Steps (ABAP Guide)

Enhance SAP FBL1N, FBL3N & FBL5N: Add Custom Fields in 3 Easy Steps (ABAP Guide)

In SAP Financial Accounting (FI), line item reports such as FBL1N (Vendor Line Items), FBL3N (G/L Account Line Items), and FBL5N (Customer Line Items) are heavily used. Business users often require custom fields in these reports. This guide explains how to add custom fields step by step with ABAP.

Step 1: Append Structure to RFPOSX

Extend the standard structure RFPOSX by appending your custom fields.

Step 2: Run Program RFPOSXEXTEND

Execute program RFPOSXEXTEND to regenerate the structure and make the appended fields available in the FBL reports.

Step 3: Implement BADI FI_ITEMS_CH_DATA

Implement BADI FI_ITEMS_CH_DATA and enhance method CHANGE_ITEMS to fill the new custom fields.

ABAP Code Example


METHOD if_ex_fi_items_ch_data~change_items.
  CONSTANTS : lc_fbl1n TYPE tcode VALUE 'FBL1N'.
  CONSTANTS : lc_fbl3n TYPE tcode VALUE 'FBL3N'.
  CONSTANTS : lc_fbl5n TYPE tcode VALUE 'FBL5N'.

  IF sy-tcode = lc_fbl1n.
    LOOP AT ct_items ASSIGNING FIELD-SYMBOL(<fs_items>).
      IF NOT <fs_items>-konto IS INITIAL.
        SELECT CONCAT( adrc~name1, adrc~name2 )
          FROM adrc
          INNER JOIN lfa1 ON adrc~addrnumber = lfa1~adrnr
          WHERE lfa1~lifnr = @<fs_items>-konto
          INTO @<fs_items>-zvend_name UP TO 1 ROWS.
        ENDSELECT.
      ENDIF.
      SELECT SINGLE txt50 FROM skat INTO <fs_items>-zhkontnm
        WHERE ktopl = '2000' AND saknr = <fs_items>-hkont AND spras = 'E'.
    ENDLOOP.
  ENDIF.

  IF sy-tcode = lc_fbl5n.
    LOOP AT ct_items ASSIGNING <fs_items>.
      IF NOT <fs_items>-konto IS INITIAL.
        SELECT CONCAT( adrc~name1, adrc~name2 )
          FROM adrc
          INNER JOIN kna1 ON adrc~addrnumber = kna1~adrnr
          WHERE kna1~kunnr = @<fs_items>-konto
          INTO @<fs_items>-zcust_name UP TO 1 ROWS.
        ENDSELECT.
      ENDIF.
      SELECT SINGLE txt50 FROM skat INTO <fs_items>-zhkontnm
        WHERE ktopl = '2000' AND saknr = <fs_items>-hkont AND spras = 'E'.
    ENDLOOP.
  ENDIF.

  IF sy-tcode = lc_fbl3n.
    LOOP AT ct_items ASSIGNING <fs_items>.
      SELECT SINGLE txt50 FROM skat INTO <fs_items>-zhkontnm
        WHERE ktopl = '2000' AND saknr = <fs_items>-hkont AND spras = 'E'.
      IF NOT <fs_items>-konto IS INITIAL.
        SELECT SINGLE txt50 FROM skat INTO <fs_items>-zsaknrnm
          WHERE ktopl = '2000' AND saknr = <fs_items>-konto AND spras = 'E'.
      ENDIF.
    ENDLOOP.
  ENDIF.
ENDMETHOD.
  

Best Practices

  • Always use append structure instead of modifying standard objects.
  • Run RFPOSXEXTEND after appending fields to regenerate structures.
  • Optimize SELECT queries to avoid performance bottlenecks.
  • Use SPRSL for language-dependent texts.

Conclusion

By appending structure RFPOSX, running program RFPOSXEXTEND, and implementing BADI FI_ITEMS_CH_DATA, you can successfully add custom fields to reports FBL1N, FBL3N, and FBL5N. This enhancement ensures upgrade safety, flexibility, and fulfills business requirements effectively.

Automatic Perform Posting GI After VLPOD Save in SAP

Automatic Posting GI After VLPOD Save in SAP

Automatic Posting GI After VLPOD Save in SAP

This guide explains how to enhance SAP to automatically perform Goods Issue (GI) with movement type Z55 after VLPOD (Proof of Delivery) is confirmed or canceled. The solution uses BADI implementation and custom function modules.

Business Requirement

After confirming or canceling POD in transaction VLPOD, the system should automatically trigger a MIGO Goods Issue (Z55) posting without requiring manual intervention.

Technical Design

BADI Implementations

  • LE_SHP_DELIVERY_PROC : ZIMPL_POD_TRANSFER
  • DELIVERY_PUBLISH : ZIM_DELIVERY_PUBLISH

Custom Function Modules

  • ZFG_VLPOD_POST_Z55 → To post Goods Issue
  • ZFG_VLPOD_CNCL_Z55 → To cancel Goods Issue

Enhancement Implementation

1. ZIMPL_POD_TRANSFER

METHOD if_ex_le_shp_delivery_proc~save_document_prepare.
  IF sy-tcode = 'VLPOD'.
    " Capture POD action and delivery data
    ...
  ENDIF.
ENDMETHOD.
  

2. ZIM_DELIVERY_PUBLISH

METHOD if_ex_delivery_publish~publish_after_save.
  IF sy-tcode = 'VLPOD' AND sy-ucomm = 'SICH_T'.
      DATA lt_lipsvb TYPE TABLE OF lipsvb.
      DATA:
        ct_xlikp   TYPE shp_likp_t,
        lv_pod_act TYPE char10.

      REFRESH : lt_lipsvb, ct_xlikp.

      IMPORT ct_xlikp  TO ct_xlikp  FROM MEMORY ID 'ZZ_VLPOD_HDR'.
      IMPORT lt_lipsvb TO lt_lipsvb FROM MEMORY ID 'ZZ_VLPOD_ITEM'.

      CLEAR lv_pod_act.
      IMPORT lv_pod_act TO lv_pod_act FROM MEMORY ID 'ZZ_VLPOD'.

      READ TABLE ct_xlikp INTO DATA(ls_likp) INDEX 1.

    CASE lv_pod_act.
      WHEN 'A'. " Confirm POD
        CALL FUNCTION 'ZFG_VLPOD_POST_Z55' IN UPDATE TASK.
        COMMIT WORK AND WAIT.
        WAIT UP TO 1 SECONDS.
      WHEN 'X'. " Cancel POD
        CALL FUNCTION 'ZFG_VLPOD_CNCL_Z55' IN UPDATE TASK.
        COMMIT WORK AND WAIT.
        WAIT UP TO 1 SECONDS.
    ENDCASE.
    
    FREE MEMORY ID 'ZZ_VLPOD_HDR'.
    FREE MEMORY ID 'ZZ_VLPOD_ITEM'.
    FREE MEMORY ID 'ZZ_VLPOD'.
  ENDIF.
ENDMETHOD.
  

Custom Function Modules

ZFG_VLPOD_POST_Z55

Posts the Goods Issue (Z55) by calling BAPI_GOODSMVT_CREATE with dynamically prepared items.


  FUNCTION zfg_vlpod_post_z55.
  	DATA:
          ls_header        TYPE bapi2017_gm_head_01,
          ls_code          TYPE bapi2017_gm_code,
          testrun          TYPE bapi2017_gm_gen-testrun,

          lv_matnr18       TYPE matnr18,

          goodsmvt_headret TYPE bapi2017_gm_head_ret,
          materialdocument TYPE bapi2017_gm_head_ret-mat_doc,
          matdocumentyear  TYPE bapi2017_gm_head_ret-doc_year,

          lt_smvt_item     TYPE TABLE OF bapi2017_gm_item_create,
          ls_smvt_item     TYPE bapi2017_gm_item_create,

          lt_return        TYPE TABLE OF  bapiret2,

          lt_tvpod         TYPE TABLE OF zcds_lips_tvpod,
          ct_xlikp         TYPE shp_likp_t,
          lv_pod_act       TYPE char10.

        DATA :
          ls_return TYPE bapiret2,
          ex_mblnr  TYPE mblnr,
          ex_mjahr  TYPE mjahr.

        CLEAR ct_xlikp.
        IMPORT ct_xlikp  TO ct_xlikp  FROM MEMORY ID 'ZZ_VLPOD_HDR'.

        READ TABLE ct_xlikp INTO DATA(ls_likp) INDEX 1.

        REFRESH lt_tvpod.
        SELECT * FROM zcds_lips_tvpod
          INTO TABLE @lt_tvpod
            WHERE vbeln = @ls_likp-vbeln AND lfimg_diff NE 0.

        ls_code = '03'.

        CLEAR: ls_header.
        ls_header-pstng_date = ls_likp-podat.
        ls_header-doc_date   = sy-datum.
        ls_header-header_txt = 'INTRANSIT'.

        REFRESH lt_smvt_item.
        LOOP AT lt_tvpod INTO DATA(ls_tvpod).
          CLEAR ls_smvt_item.
          CLEAR ls_smvt_item.
          CLEAR lv_matnr18.
          lv_matnr18 = |{ ls_tvpod-matnr ALPHA = IN }|.

          ls_smvt_item-material   = lv_matnr18.
          ls_smvt_item-plant      = ls_tvpod-werks.
          ls_smvt_item-batch      = ls_tvpod-charg.
          ls_smvt_item-move_type  = 'Z55'.
          ls_smvt_item-spec_stock = 'T'.
          ls_smvt_item-entry_qnt  = ls_tvpod-lfimg_diff.
          ls_smvt_item-entry_uom  = ls_tvpod-meins.
          ls_smvt_item-val_type   = ls_tvpod-bwtar.
          ls_smvt_item-costcenter = 'BMC0202'.
          ls_smvt_item-deliv_numb = ls_tvpod-vbeln.
          ls_smvt_item-deliv_item = ls_tvpod-posnr.

          APPEND ls_smvt_item TO lt_smvt_item.
          CLEAR ls_tvpod.
        ENDLOOP.

        CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
          EXPORTING
            goodsmvt_header  = ls_header
            goodsmvt_code    = ls_code
          IMPORTING
            materialdocument = ex_mblnr
            matdocumentyear  = ex_mjahr
          TABLES
            goodsmvt_item    = lt_smvt_item
            return           = lt_return.

      ENDFUNCTION.
    

ZFG_VLPOD_CNCL_Z55

Cancels the previously posted Goods Issue using BAPI_GOODSMVT_CANCEL.


    FUNCTION zfg_vlpod_cncl_z55.
*"----------------------------------------------------------------------
*"*"Update Function Module:
*"
*"*"Local Interface:
*"----------------------------------------------------------------------
  DATA:
    im_mblnr   TYPE mblnr,
    im_mjahr   TYPE mjahr,
    im_budat   TYPE budat,
    im_uname   TYPE uname,
    im_bktxt   TYPE bktxt,
    ct_xlikp   TYPE shp_likp_t,
    lv_pod_act TYPE char10.

  DATA :
    ex_headret TYPE bapi2017_gm_head_ret,
    lt_return  TYPE TABLE OF bapiret2,
    ls_return  TYPE bapiret2,
    ex_mblnr   TYPE mblnr,
    ex_mjahr   TYPE mjahr.

  CLEAR ct_xlikp.
  IMPORT ct_xlikp  TO ct_xlikp  FROM MEMORY ID 'ZZ_VLPOD_HDR'.

  READ TABLE ct_xlikp INTO DATA(ls_likp) INDEX 1.

  SELECT SINGLE mblnr, mjahr, budat, bktxt
    FROM matdoc
      INTO @DATA(ls_matdoc)
        WHERE vbeln_im = @ls_likp-vbeln AND
              cancelled = '' AND bwart = 'Z55'.

  IF ls_matdoc IS NOT INITIAL.
    REFRESH lt_return.
    CLEAR: im_mblnr, im_mjahr, im_budat, im_uname, im_bktxt.
    im_mblnr = ls_matdoc-mblnr.
    im_mjahr = ls_matdoc-mjahr.
    im_bktxt = ls_matdoc-bktxt.
    im_budat = ls_likp-podat.
    im_uname = sy-uname.

    CALL FUNCTION 'BAPI_GOODSMVT_CANCEL'
      EXPORTING
        materialdocument    = im_mblnr
        matdocumentyear     = im_mjahr
        goodsmvt_pstng_date = im_budat
        goodsmvt_pr_uname   = im_uname
        documentheader_text = im_bktxt
      IMPORTING
        goodsmvt_headret    = ex_headret
      TABLES
        return              = lt_return.
  ENDIF.

ENDFUNCTION.

Best Practices

  • Always use update tasks to ensure data consistency.
  • Free memory IDs after processing to avoid data conflicts.
  • Use WAIT UP TO carefully to synchronize update tasks.

Conclusion

By implementing BADI enhancements and custom function modules, SAP can automatically handle GI postings after VLPOD confirmation or cancellation. This ensures process efficiency and reduces manual errors in outbound logistics.

ABAP CDS View Part 10 : Authorization & DCL untuk ABAP CDS

Authorization & DCL di ABAP CDS | Panduan Lengkap (PFCG, @AccessControl, DCL) Authorization & DCL untuk ABAP CDS — Pandua...