Outbound messaging > Real-time inventory quantities (ATP)

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Overview: real-time inventory for materials

Current material stock quantities (usually referred to as Available-to-promise or ATP stock) is widely required e.g. to present the current and orderable number of products in an online store. But ATP is not a static value within SAP systems, unfortunately. To determine current ATP quantities, SAP systems run an on-line calculation that considers reservations, inbound pipeline, planned shipment dates etc.

Therefore, sending real-time ATP stock per material requires the detection of all changes that can affect the stock quantity calculation, an actual calculation and the formatting to make it sendable as a message, with quantity per material, units etc.

ASAPIO provides that with its ATP extraction feature, including pre-delivered example function modules that can be adopted by customers.



Required configuration

SAP Business Objects that can be used and necessary BAdI/User Exit implementation.

Object name Object type Configuration
Sales Order BUS2032 Standard
Purchase Order BUS2012 Standard
Delivery LIKP Standard
Goods Movement BUS2017 BAdI (MB_DOCUMENT_UPDATE)
Material Reservation ZBUS2093 User Exit (MBCF0007)

Create Outbound ATP Configuration

Create Extracting Func. Module:

  • Transaction: SE37
  • Create function module: Z_ACI_EXTRACTOR_ATP

Example coding:

FUNCTION z_aci_extractor_atp .
*"*"Local Interface:
ls_bdcp      TYPE bdcp,
ls_csv_line  TYPE /asadev/aci_any_string,
lv_tmp_event TYPE string,
lv_tmp_key   TYPE string,
lv_keyname   TYPE /asadev/aci_head_attr_value,
ls_return    TYPE bapiret2. 

" ATP check
DATA:   lv_werks      TYPE                   werks,
lv_matnr      TYPE                   matnr,
lv_meins      TYPE                   meins,
lt_iwmdvsx    TYPE STANDARD TABLE OF bapiwmdvs,"TABLES PARAM
ls_iwmdvsx    LIKE LINE OF           lt_iwmdvsx ,
lt_iwmdvex    TYPE STANDARD TABLE OF bapiwmdve,"TABLES PARAM
ls_iwmdvex    LIKE LINE OF           lt_iwmdvex.

DATA:   lv_bdcnt           TYPE string,
lv_req_date        TYPE string,
lv_req_qty         TYPE string,
lv_com_date        TYPE string,
lv_com_qty         TYPE string,
lv_av_qty_plt      TYPE bapicm61v-wkbst,
lv_av_qty_plt_str  TYPE string,
lv_lines           TYPE i,
ls_return_bapi     TYPE bapireturn.

DATA:   lb_last_row TYPE abap_bool VALUE abap_false.

"populate fields of struture and append to itab
APPEND ls_iwmdvsx TO lt_iwmdvsx.
"populate fields of struture and append to itab
APPEND ls_iwmdvex TO lt_iwmdvex.

CONSTANTS:   lc_auth_obj_rc           TYPE xuobject                   VALUE '/ASADEV/RC', "Mod-001++
lc_auth_fld_rf           TYPE fieldname                  VALUE '/ASADEV/RF', "Mod-001++
lc_message_id            TYPE symsgid                    VALUE '/ASADEV/AMR_MESSAGE', "Mod-001++
lc_message_number        TYPE symsgno                    VALUE '077', "Mod-001++
lc_autch_check_data_proc TYPE /asadev/aci_rfc_auth_check VALUE 'DATA_PROC'."Data processing "Mod-001++

* Check if user can execute RFC
ID lc_auth_fld_rf
FIELD lc_autch_check_data_proc.

IF sy-subrc <> 0.
*   No authorization for user &1 to call ACI function!
ls_return-type = /asadev/cl_aci_helper=>mc_aci_error.
ls_return-id = lc_message_id.
ls_return-number = lc_message_number.
ls_return-message_v1 = sy-uname.
APPEND ls_return TO et_return.
CLEAR ls_return.

iv_instance  = iv_instance
iv_object    = iv_object
iv_attribute = /asadev/cl_aci_cloudev_helper=>mc_attr_em_key_name
rv_value     = lv_keyname

DESCRIBE TABLE it_bdcp_lines LINES lv_lines.

LOOP AT it_bdcp_lines INTO ls_bdcp.

"lv_tmp_event = ls_bdcp-tabkey(32).
"lv_tmp_key = ls_bdcp-tabkey+35(70).
lv_werks = ls_bdcp-tabkey+21(4).
lv_matnr = ls_bdcp-tabkey(18).
lv_meins = ls_bdcp-tabkey+18(3).

IF lv_lines = sy-tabix.
lb_last_row = abap_true.


plant              = lv_werks " Plant
material           = lv_matnr " Material number
unit               = lv_meins " Unit of measure for display
*       check_rule         =     " Checking rule
*       stge_loc           =     " Storage location
*       batch              =     " Batch
*       customer           =     " Customer number
*       doc_number         =     " Document number
*       itm_number         =     " Item number
*       wbs_elem           =     " WBS Element
*       stock_ind          =     " Special Stock Indicator
*       dec_for_rounding   =     " No. of decimal places to which rounding should be performed
*       dec_for_rounding_x =     " Updated information in related user data field
*       read_atp_lock      =     " Control indicator for availability check
*       read_atp_lock_x    =     " Updated information in related user data field
*       material_evg       =     " Updated information in related user data field
*       endleadtme         =     " End of replenishment lead time
av_qty_plt         = lv_av_qty_plt   " Quantity available at plant level
*       dialogflag         =     " Indicator (X = not available, N = no check)
return             = ls_return_bapi   " Indicator (X = not available, N = no check)
wmdvsx             = lt_iwmdvsx " Input table (date and quantity)
wmdvex             = lt_iwmdvex. " Output table (date and ATP quantity)
IF sy-subrc EQ 0.

lv_av_qty_plt_str = lv_av_qty_plt.

CONCATENATE ls_csv_line '{' '"objectType":"' ls_bdcp-tabname '", '
*             cl_abap_char_utilities=>newline ' "event":"' lv_tmp_event '", '
cl_abap_char_utilities=>newline ' "werks":"' lv_werks '", '
cl_abap_char_utilities=>newline ' "matnr":"' lv_matnr '", '
cl_abap_char_utilities=>newline ' "meins":"' lv_meins '", '
cl_abap_char_utilities=>newline ' "date":"' sy-datum '", '
cl_abap_char_utilities=>newline ' "quantity":"' lv_av_qty_plt_str '"}' INTO ls_csv_line.

CONCATENATE '{"records":[{"value":[' ls_csv_line INTO ls_csv_line.

IF lb_last_row = abap_false.
CONCATENATE ls_csv_line ',' INTO ls_csv_line.

CONCATENATE ls_csv_line ']}]}' INTO ls_csv_line.

APPEND ls_csv_line TO et_csv_lines.
CLEAR ls_csv_line.



Create an outbound object configuration:

  • Transaction: SPRO
  • Go to IMG > ASAPIO Cloud IntegratorConnection and Replication Object Customizing
  • Or go directly to transaction: /ASADEV/68000202
  • Select the created Connection
  • Go to section Outbound Objects
  • Add New Entry and specify:
      • Object: name of the outbound configuration
      • Extraction Func. Module: Z_ACI_EXTRACTOR_ATP
      • Load Type: Incremental Load
      • Trace: activate for testing purposes

Set-up Business Object Event Linkage

Implement BAdI inside /ASADEV/ACI_EVENTS_TRIGGER to recieve meins, werks and matnr that will be needed inside the cutom extractor:

  • Transaction: SE18
  • Filter Val.: Add your Instance and Object that shall use the BAdI implementation.
  • Add Implementation:

Example coding:

METHOD /asadev/trigger_if~set_bdcp_lines.

  DATA: lv_meins            TYPE meins,
        lv_werks            TYPE werks,
        lv_matnr            TYPE matnr,
        lv_len              TYPE i,
        lv_object_type      TYPE string,
        lv_mblnr            TYPE mblnr,
        lv_vbeln            TYPE vbeln,
        lv_ebeln            TYPE ebeln,
        lv_rsnum            TYPE rsnum.

* Definition of internal tables
  DATA: "ct_bdcp_lines       TYPE /asadev/aci_tt_bdcp,
        lt_marc             TYPE STANDARD TABLE OF marc,
        lt_vbap             TYPE STANDARD TABLE OF vbap,
        lt_ekpo             TYPE STANDARD TABLE OF ekpo,
        lt_mseg             TYPE STANDARD TABLE OF mseg,
        lt_resb             TYPE STANDARD TABLE OF resb,
        lt_lips             TYPE STANDARD TABLE OF lips.

  DATA: ls_bdcp_lines       TYPE bdcp.

                  TYPE vbap,
                  TYPE ekpo,
                  TYPE mseg,
                  TYPE resb,
                  TYPE lips.

  CLEAR ct_bdcp_lines.

  "Subobjects? Last 7 characters from iv_sender-typeid e.g. zzBUS1001
  IF strlen( iv_sender-typeid ) GT 7.
    lv_len = strlen( iv_sender-typeid ) - 7.
    lv_object_type = iv_sender-typeid+lv_len(7).
    lv_object_type = iv_sender-typeid.
  " Select material number, plant and units of messure.
  CASE lv_object_type.
    WHEN 'BUS1001'. " Material

      lv_matnr = iv_sender-instid.

      SELECT werks INTO CORRESPONDING FIELDS OF TABLE lt_marc FROM marc WHERE matnr = lv_matnr.
      SELECT SINGLE meins INTO lv_meins FROM mara WHERE matnr = lv_matnr.

      LOOP AT lt_marc ASSIGNING .
        CONCATENATE lv_matnr lv_meins -werks INTO ls_bdcp_lines-tabkey RESPECTING BLANKS.
        APPEND ls_bdcp_lines TO ct_bdcp_lines.
        " CLEAR ls_bdcp_lines.

    WHEN 'BUS2012'. " Purchase Order

      lv_ebeln = iv_sender-instid.

      SELECT matnr meins werks INTO CORRESPONDING FIELDS OF TABLE lt_ekpo FROM ekpo WHERE ebeln = lv_ebeln.

      LOOP AT lt_ekpo ASSIGNING .
        CONCATENATE -matnr -meins -werks INTO ls_bdcp_lines-tabkey RESPECTING BLANKS.
        APPEND ls_bdcp_lines TO ct_bdcp_lines.

    WHEN 'BUS2032'. " Sales Order

      lv_vbeln = iv_sender-instid.

      SELECT matnr meins werks INTO CORRESPONDING FIELDS OF TABLE lt_vbap FROM vbap WHERE vbeln = lv_vbeln.

      LOOP AT lt_vbap ASSIGNING .
        CONCATENATE -matnr -meins -werks INTO ls_bdcp_lines-tabkey RESPECTING BLANKS.
        APPEND ls_bdcp_lines TO ct_bdcp_lines.

    WHEN 'BUS2017'. " Goods Movement

      lv_mblnr = iv_sender-instid(10).

      SELECT matnr werks meins FROM mseg INTO CORRESPONDING FIELDS OF TABLE lt_mseg WHERE mblnr = lv_mblnr.

      LOOP AT lt_mseg ASSIGNING .
        CONCATENATE -matnr -meins -werks INTO ls_bdcp_lines-tabkey RESPECTING BLANKS.
        APPEND ls_bdcp_lines TO ct_bdcp_lines.

    WHEN 'BUS2093'. " Material Reservation

      lv_rsnum = iv_sender-instid.

      SELECT matnr werks meins FROM resb INTO CORRESPONDING FIELDS OF TABLE lt_resb WHERE rsnum = lv_rsnum.

      LOOP AT  lt_resb ASSIGNING .
        CONCATENATE -matnr -meins -werks INTO ls_bdcp_lines-tabkey RESPECTING BLANKS.
        APPEND ls_bdcp_lines TO ct_bdcp_lines.

    WHEN 'LIKP'. " Outbound Delivery

      lv_vbeln = iv_sender-instid.

      SELECT matnr werks meins FROM lips INTO CORRESPONDING FIELDS OF TABLE lt_lips WHERE vbeln = lv_vbeln.

      LOOP AT  lt_lips ASSIGNING .
        CONCATENATE -matnr -meins -werks INTO ls_bdcp_lines-tabkey RESPECTING BLANKS.
        APPEND ls_bdcp_lines TO ct_bdcp_lines.


  CLEAR ls_bdcp_lines.


Link the Business Objects that will trigger the ATP:

  • Go to section Event Linkage
  • Add New Entry and specify:
    • Object Category: BOR Object Type
    • Object Type: The Business Object Type sending the event
    • Event: Event to react to
    • Receiver Function Module: /ASADEV/ACI_EVENTS_TRIGGER
    • Type linkage active: tick the checkbox
Object name Object type Event TABLES Transaction
Sales Order BUS2032 Created, Changed VBAK, VBAP VA01, VA02
Purchase Order BUS2012 Created, Changed EKKO, EKPO ME21N, ME22n
Delivery LIKP Created, Changed LIKP, LIPS VL01, VL02
Goods Movement BUS2017 Created MKPF, MSEG MB11
Material Reservation ZBUS2093 Created, Changed RKPF, RESB MB21, MB22

Test example

With the available trigger inside the Add-on a notification of the ATP will be sent as a JSON-File.

Payload structure:

"value": [
"objectType": "BUS2012",
"werks": "1200",
"matnr": "DPC1002",
"meins": "ST",
"date": "20221011",
"quantity": "4216.000 "
"objectType": "BUS2012",
"werks": "1200",
"matnr": "DPC1003",
"meins": "ST",
"date": "20221011",
"quantity": "2063.000 "
"objectType": "BUS2012",
"werks": "1200",
"matnr": "DPC1004",
"meins": "ST",
"date": "20221011",
"quantity": "1385.000 "
"objectType": "BUS2012",
"werks": "1200",
"matnr": "DPC1005",
"meins": "ST",
"date": "20221011",
"quantity": "4886.000 "
Scroll to Top