Extractor Report

Report ZFI_BILENDO_EXPORT_V2 for extracting data from SAP to Bilendo.

Overview

PropertyValue
ReportZFI_BILENDO_EXPORT_V2
SAP moduleFI-AR
Version2.1
FunctionExtracts customer master data, open items, and cleared items from SAP and writes TXT files to the application server
IncludesZFI_BILENDO_EXPORT_V2_D01 (data declaration), ZFI_BILENDO_EXPORT_V2_F01 (processing logic)
DependencyZCL_FI_BILENDO_ASSIST_V2 (→ 03 - Assist Class)

Selection Screen

The report offers the following selection parameters:

Block 1: Customer Master Data

ParameterFieldTypeDefaultDescription
P_KNA1–CheckboxXExtract customer master data
S_CUSDTBKPF-CPUDTSelect option–Customer master record creation date

Block 2: Transaction Data

ParameterFieldTypeDefaultDescription
P_BSEG–Checkbox–All items (complete BSEG)
P_BSID–CheckboxXOpen items
P_BSAD–CheckboxXCleared items
S_BUDATBKPF-BUDATSelect option–Posting date
S_AUGDTBSEG-AUGDTSelect option–Clearing date
S_CPUDTBKPF-CPUDTSelect option–Entry date
S_CPUTMBKPF-CPUTMSelect option–Entry time

Block 3: Load Mode

ParameterTypeDefaultDescription
P_ALLRadio button–Full load (initial) – all data without time restriction
P_DELTARadio buttonXDelta load – only data within the selection period

Additional

ParameterFieldTypeDescription
S_BUKRSBKPF-BUKRSSelect optionCompany code (restriction)
S_AUGBLBSEG-AUGBLSelect optionClearing document (for items cleared via document)
P_F_KNA1–Text255File name of customer master (populated automatically)
P_F_BSEG–Text255File name of all items (populated automatically)
P_F_BSID–Text255File name of open items (populated automatically)
P_F_BSAD–Text255File name of cleared items (populated automatically)

Source Code

Main Report – ZFI_BILENDO_EXPORT_V2

*&---------------------------------------------------------------------*
*& Report  ZFI_BILENDO_EXPORT_V2
*& Owner         : Bilendo GmbH
*& Module        : SAP A/R Module
*& Description   : Report to extract Customer Master, Open Item,
*&                 Cleared Items and create .txt files & place it in
*&                 application server
*& Version       : 2.1
*&---------------------------------------------------------------------*

REPORT ZFI_BILENDO_EXPORT_V2.

INCLUDE ZFI_BILENDO_EXPORT_V2_D01.
INCLUDE ZFI_BILENDO_EXPORT_V2_F01.

INITIALIZATION.
  PERFORM sub_initial.

AT SELECTION-SCREEN OUTPUT.

START-OF-SELECTION.
  PERFORM get_filenames USING 'Customers' CHANGING p_f_kna1.
  PERFORM get_filenames USING 'all'       CHANGING p_f_bseg.
  PERFORM get_filenames USING 'open'      CHANGING p_f_bsid.
  PERFORM get_filenames USING 'cleared'   CHANGING p_f_bsad.
  PERFORM sub_getscreendata.
  PERFORM sub_processing.

END-OF-SELECTION.

Include D01 – Data Declaration and Selection Screen

⚠️ Customization required: The constants gc_dir_hed, gc_dir_heq, gc_dir_hep and the WHEN branches in get_filenames (F01) must be adapted to your specific system landscape.

*&---------------------------------------------------------------------*
*&  Include           ZFI_BILENDO_EXPORT_V2_D01
*&---------------------------------------------------------------------*

TABLES: bkpf, bseg.

DATA: gt_seltab     TYPE TABLE OF rsparams,
      gt_seltab_255 TYPE TABLE OF rsparamsl_255,
      gf_file       TYPE string,
      gf_file_kna1  TYPE string,
      gf_file_bseg  TYPE string,
      gf_file_bsid  TYPE string,
      gf_file_bsad  TYPE string,
      go_bilendo    TYPE REF TO zcl_fi_bilendo_assist_v2,
      gf_msg        TYPE string,
      gt_t001       TYPE TABLE OF t001,
      gs_t001       TYPE t001.

CONSTANTS: gc_dir_hed TYPE string VALUE '/.....',   " ← Adjust DEV path
           gc_dir_heq TYPE string VALUE '/.....',   " ← Adjust QA path
           gc_dir_hep TYPE string VALUE '/.....'.   " ← Adjust PRD path


SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-006 .
  PARAMETERS: p_kna1 TYPE xfeld AS CHECKBOX DEFAULT 'X'.
  SELECT-OPTIONS: s_cusdt FOR bkpf-cpudt.
SELECTION-SCREEN END OF BLOCK b1 .

SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-007 .
  PARAMETERS: p_bseg TYPE xfeld AS CHECKBOX,
              p_bsid TYPE xfeld AS CHECKBOX DEFAULT 'X',
              p_bsad TYPE xfeld AS CHECKBOX DEFAULT 'X'.
  SELECT-OPTIONS: s_budat FOR bkpf-budat,
                  s_augdt FOR bseg-augdt.
  SELECT-OPTIONS: s_cpudt FOR bkpf-cpudt,
                  s_cputm FOR bkpf-cputm.
SELECTION-SCREEN END OF BLOCK b2 .

SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE text-008 .
  PARAMETERS: p_all   TYPE char1 RADIOBUTTON GROUP 01,
              p_delta TYPE char1 RADIOBUTTON GROUP 01 DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK b3 .

SELECTION-SCREEN ULINE.

SELECT-OPTIONS: s_bukrs FOR bkpf-bukrs,
                s_augbl FOR bseg-augbl.

SELECTION-SCREEN ULINE.

SELECTION-SCREEN COMMENT /1(83) text-005.

PARAMETERS: p_f_kna1 TYPE text255,
            p_f_bseg TYPE text255,
            p_f_bsid TYPE text255,
            p_f_bsad TYPE text255.

Include F01 – Processing Logic

*&---------------------------------------------------------------------*
*&  Include           ZFI_BILENDO_EXPORT_V2_F01
*&---------------------------------------------------------------------*

*----------------------------------------------------------------------*
* FORM sub_initial
* Initialization: Reset variables and internal tables
*----------------------------------------------------------------------*
FORM sub_initial.
  CLEAR: gf_file.
  REFRESH: gt_seltab, gt_seltab_255.
ENDFORM.

*----------------------------------------------------------------------*
* FORM get_filenames
* Builds the file name, including the path, based on data type, date,
* and system ID.
* Pattern: <path>/CC_<type>_<DD-MM-YYYY>_[INITIAL_]V2.txt
*----------------------------------------------------------------------*
FORM get_filenames USING    pf_table TYPE tabname
                   CHANGING pf_file  TYPE text255.

  IF pf_file IS NOT INITIAL.
    EXIT.
  ENDIF.

  CONCATENATE sy-datum+6(2) sy-datum+4(2) sy-datum(4)
    INTO gf_file SEPARATED BY '-'.
  CONCATENATE pf_table gf_file INTO pf_file SEPARATED BY '_'.
  CONCATENATE 'CC' pf_file INTO pf_file SEPARATED BY '_'.

  IF p_all = 'X'.
    CONCATENATE pf_file 'INITIAL' INTO pf_file SEPARATED BY '_'.
  ENDIF.

  CONCATENATE pf_file 'V2' INTO pf_file SEPARATED BY '_'.
  CONCATENATE pf_file '.txt' INTO pf_file.
  CONDENSE pf_file.

  CASE sy-sysid.
    WHEN 'C01'.                          " ← Adjust system ID for DEV
      CONCATENATE gc_dir_hed pf_file INTO pf_file.
    WHEN 'Q01'.                          " ← Adjust system ID for QA
      CONCATENATE gc_dir_heq pf_file INTO pf_file.
    WHEN 'P01'.                          " ← Adjust system ID for PRD
      CONCATENATE gc_dir_hep pf_file INTO pf_file.
    WHEN OTHERS.
  ENDCASE.
ENDFORM.

*----------------------------------------------------------------------*
* FORM sub_getscreendata
* Reads the current selection parameters and instantiates the
* assist class.
*----------------------------------------------------------------------*
FORM sub_getscreendata.
  CALL FUNCTION 'RS_REFRESH_FROM_SELECTOPTIONS'
    EXPORTING
      curr_report         = sy-repid
    TABLES
      selection_table     = gt_seltab
      selection_table_255 = gt_seltab_255.

  CREATE OBJECT go_bilendo
    EXPORTING
      it_seltab = gt_seltab_255.
ENDFORM.

*----------------------------------------------------------------------*
* FORM sub_processing
* Main processing: Iterates over all company codes and, depending on
* the selection, calls the extraction and file export.
*----------------------------------------------------------------------*
FORM sub_processing.

  SELECT bukrs FROM t001 INTO CORRESPONDING FIELDS OF TABLE gt_t001
    WHERE bukrs IN s_bukrs
      AND rcomp <> ''.

  LOOP AT gt_t001 INTO gs_t001.

    go_bilendo->clear( ).
    go_bilendo->set_bukrs( gs_t001-bukrs ).

    " === Customer master data ===
    IF p_kna1 = 'X'.
      go_bilendo->get_kna1( ).
      IF go_bilendo->at_kna1 IS INITIAL.
        gf_msg = text-001.
        REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
        WRITE:/ gf_msg.
        CLEAR gf_msg.
      ELSE.
        WRITE:/ gf_msg.
        go_bilendo->kna1_file_to_server(
          IMPORTING ef_msg = gf_msg ).
        WRITE:/ gf_msg.
        CLEAR gf_msg.
        CLEAR go_bilendo->at_kna1.
      ENDIF.
    ENDIF.

    " === All items (BSEG complete) ===
    IF p_bseg = 'X'.
      go_bilendo->get_bseg( ).
      go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bseg ).
      IF go_bilendo->at_bseg IS INITIAL.
        gf_msg = text-002.
        REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
        WRITE:/ gf_msg.
        CLEAR gf_msg.
      ELSE.
        go_bilendo->bseg_file_to_server(
          EXPORTING
            it_bseg    = go_bilendo->at_bseg
            if_dataset = go_bilendo->af_dataset_bseg
          IMPORTING
            ef_msg     = gf_msg ).
        WRITE:/ gf_msg.
        CLEAR gf_msg.
        CLEAR go_bilendo->at_bseg.
      ENDIF.
    ENDIF.

    " === Open items (BSID) ===
    IF p_bsid = 'X'.
      go_bilendo->get_bsid( ).
      go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsid ).
      IF go_bilendo->at_bsid IS INITIAL.
        gf_msg = text-003.
        REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
        WRITE:/ gf_msg.
        CLEAR gf_msg.
      ELSE.
        go_bilendo->bseg_file_to_server(
          EXPORTING
            it_bseg    = go_bilendo->at_bsid
            if_dataset = go_bilendo->af_dataset_bsid
          IMPORTING
            ef_msg     = gf_msg ).
        WRITE:/ gf_msg.
        CLEAR gf_msg.
        CLEAR go_bilendo->at_bsid.
      ENDIF.
    ENDIF.

    " === Cleared items (BSAD) ===
    IF p_bsad = 'X'.
      go_bilendo->get_bsad( ).
      go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsad ).
      IF go_bilendo->at_bsad IS INITIAL.
        gf_msg = text-004.
        REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
        WRITE:/ gf_msg.
        CLEAR gf_msg.
      ELSE.
        go_bilendo->bseg_file_to_server(
          EXPORTING
            it_bseg    = go_bilendo->at_bsad
            if_dataset = go_bilendo->af_dataset_bsad
          IMPORTING
            ef_msg     = gf_msg ).
        WRITE:/ gf_msg.
        CLEAR gf_msg.
        CLEAR go_bilendo->at_bsid.  " Note: the original uses at_bsid instead of at_bsad
      ENDIF.
    ENDIF.

  ENDLOOP.
ENDFORM.

Text Elements

The report uses text elements for messages and block titles. These must be maintained in the report (SE38 → Text Elements):

Text IDUsageSuggestion
text-001Message: no master data for BUKRSNo customer master data for company code &1
text-002Message: no documents (BSEG) for BUKRSNo documents for company code &1
text-003Message: no open items for BUKRSNo open items for company code &1
text-004Message: no cleared items for BUKRSNo cleared items for company code &1
text-005Comment below selection screenBilendo SAP Extractor v2.1 – Files are named automatically
text-006Block title: Customer masterCustomer master data
text-007Block title: Transaction dataTransaction data
text-008Block title: Load modeLademodus

Filename Generation

The get_filenames method builds the filename according to the following pattern:

<Pfad>/<Präfix>_<Typ>_<TT-MM-JJJJ>_[INITIAL_]V2.txt
ComponentValueSource
Path/usr/sap/P01/Bilendo_OUT/gc_dir_hep (per system)
PrefixCCHard-coded
TypeCustomers, all, open, clearedParameter in PERFORM get_filenames
Date01-04-2026sy-datum (current date, format DD-MM-YYYY)
INITIALonly when p_all = 'X'Full load mode
VersionV2Hard-coded

Examples:

CC_Customers_09-04-2026_V2.txt          ← Master data (delta)
CC_open_09-04-2026_V2.txt               ← Open items (delta)
CC_cleared_09-04-2026_V2.txt            ← Cleared items (delta)
CC_all_09-04-2026_INITIAL_V2.txt        ← All items (initial/full)

Known Notes

  1. Bug in the original: In sub_processing, in the cleared items block, go_bilendo->at_bsid is cleared at the end instead of go_bilendo->at_bsad. This has no functional impact because at_bsid has already been processed at this point, but it should be corrected during refactoring.

  2. T001 selection: The condition rcomp <> '' filters for company codes that are assigned to a group company. If a company code has no RCOMP, it is ignored. This is intentional but not always obvious.

  3. OPAMT: The OPAMT field (open amount for intercompany balance clearing) is not implemented in v2.1. For an extension → see 02 - DDIC Structures (structure extension) and 03 - Assist Class (method extension get_bsid/get_bsad).


Improved Delta Logic: Two-Stage Selection

Problem with Simple Delta Selection

The delta logic implemented in v2.1 selects open and cleared items primarily by the entry date (CPUDT) or posting date (BUDAT) from BKPF. With a typical 7-day window, the following problem arises:

Day 1:  Document 100000001 is posted (CPUDT = Day 1)
         → Document is in BSID (open)
         → Delta selection: CPUDT IN [Day 1 - 7 ... Day 1] → hit ✓

Day 8:  Document 100000001 is cleared (AUGDT = Day 8)
         → Document moves from BSID to BSAD
         → Delta selection BSID: CPUDT IN [Day 2 ... Day 8] → no hit ✗
            (CPUDT = Day 1, falls outside the window)
         → Delta selection BSAD with CPUDT: also no hit ✗
         → Bilendo does not learn that the document was cleared

The result: Items whose entry date falls outside the delta window and that are cleared afterward are never recognized by Bilendo as "cleared." The existing AUGDT-based selection in get_bsad partially addresses this, but it requires a correct variant configuration and does not cover all scenarios.

Solution Approach: Two-Stage Delta

The improved delta logic separates the selection into two stages:

Stage 1 – Identify clearing events (BSAD → AUGDT) Select from BSAD all items whose clearing date (AUGDT) falls within the delta window. This returns the clearing document numbers (AUGBL/AUGGJ), regardless of the original entry date.

Stage 2 – Reload complete document groups (BSAD → AUGBL) Select from BSAD all items that belong to the clearing transactions identified in Stage 1. This ensures that Bilendo receives all document line items of a clearing transaction, not just those that were recently cleared.

Additionally: BSID via BKPF For open items, BKPF is used to determine which documents were created or changed within the delta window. The associated open items are then selected from BSID.

flowchart LR
    subgraph "Stage 1"
        BSAD1["BSAD\nAUGDT >= yesterday"]
        BSAD1 -->|"DISTINCT AUGBL, AUGGJ"| AUGBL["Clearing documents"]
    end
    subgraph "Stage 2"
        AUGBL -->|"FOR ALL ENTRIES"| BSAD2["BSAD\nAUGBL = match"]
        BSAD2 --> RESULT["at_bsad\n(complete)"]
    end
    subgraph "Additionally: BSID"
        BKPF["BKPF\nCPUDT >= last 6h\nOR AEDAT >= last 6h"]
        BKPF -->|"FOR ALL ENTRIES"| BSID["BSID\nBELNR = match"]
        BSID --> RESULT2["at_bsid\n(currently open)"]
    end

Advantages over simple delta selection

CriterionSimple delta selection (v2.1)Two-stage selection
Clearings of old documentsAre missed if CPUDT is outside the windowAre reliably detected via AUGDT
Selection criterion BSADCPUDT or AUGDT (variant-dependent)Always AUGDT → robust against misconfiguration
CompletenessDepends on correct variant maintenanceEnsured systemically
PerformanceBKPF JOIN over a large time windowTargeted AUGDT selection → smaller result set
Recommended frequencyDaily (with 7-day overlap)Every 6 hours (with 24-hour overlap)

ABAP Code: GET_CLEARED_DELTA Method

This method replaces the BSAD selection in delta mode. It is added to the ZCL_FI_BILENDO_ASSIST_V2 class.

Class definition – addition:

    "! Two-stage delta for cleared items
    "! Stage 1: AUGDT-based selection of clearing transactions
    "! Stage 2: FOR ALL ENTRIES for complete document groups
    METHODS get_cleared_delta
      IMPORTING
        iv_hours TYPE i DEFAULT 24.    " Delta window in hours

Implementation:

METHOD get_cleared_delta.
*----------------------------------------------------------------------*
* Two-stage delta selection for cleared items
*
* Background:
*   Simple delta selection via CPUDT/BUDAT misses
*   clearing events on documents whose entry date
*   lies outside the selection window.
*
* Stage 1: Determine all clearing transactions of the last N hours
*          via the clearing date (AUGDT) in BSAD.
*          → Result: List of AUGBL/AUGGJ (clearing documents)
*
* Stage 2: Select all BSAD items that belong to these
*          clearing transactions (via AUGBL/AUGGJ).
*          In addition: Also the clearing documents themselves (via
*          BELNR/GJAHR), if they appear as original documents in BSAD
*          (e.g., payment documents).
*
* Parameters:
*   IV_HOURS  Size of the delta window in hours (default: 24)
*             For a run every 6 hours: iv_hours = 24 for 4x overlap
*----------------------------------------------------------------------*

  TYPES: BEGIN OF ty_augbl,
           bukrs TYPE bukrs,
           augbl TYPE augbl,
           auggj TYPE gjahr,
         END OF ty_augbl.

  DATA: lt_augbl     TYPE TABLE OF ty_augbl,
        lv_augdt_low TYPE sy-datum,
        lv_days      TYPE i.

  " Calculate delta window: hours → days (rounded up)
  lv_days = ( iv_hours + 23 ) / 24.  " ceil(hours/24)
  lv_augdt_low = sy-datum - lv_days.

  " === STAGE 1 ===
  " Identify all clearing transactions in the delta window.
  " AUGDT is the SAP clearing date – it is set at clearing,
  " regardless of when the original document was posted.
  SELECT DISTINCT bukrs augbl auggj
    FROM bsad
    INTO TABLE lt_augbl
    WHERE bukrs = af_bukrs
      AND augdt >= lv_augdt_low
      AND augbl <> space
      AND umskz IN ('B', 'E', 'L', 'G', 'W', '5', '').

  IF lt_augbl IS INITIAL.
    " No clearings in the time window → at_bsad remains empty
    RETURN.
  ENDIF.

  " === STAGE 2a ===
  " Select all items that were cleared by the identified
  " clearing documents.
  " Condition: AUGBL + AUGGJ match the stage 1 hits
  SELECT bukrs kunnr umskz augdt augbl zuonr gjahr belnr buzei xblnr
         blart auggj sgtxt budat bldat dmbtr waers wrbtr shkzg zterm
         zfbdt cpudt gsber xref1 xref2 rstgr mansp manst madat zbd1t
         zbd2t zbd3t zlsch maber kkber vbeln aufnr bschl hkont AS akont
    FROM bsad
    INTO CORRESPONDING FIELDS OF TABLE at_bsad
    FOR ALL ENTRIES IN lt_augbl
    WHERE bukrs = af_bukrs
      AND auggj = lt_augbl-auggj
      AND augbl = lt_augbl-augbl
      AND umskz IN ('B', 'E', 'L', 'G', 'W', '5', '')
      AND xcpdd = ''.

  " === STAGE 2b ===
  " Also select the clearing documents themselves.
  " Reason: The clearing document (e.g., an incoming payment) appears
  " as a separate item in BSAD. Its BELNR corresponds to
  " the AUGBL of the cleared items.
  SELECT bukrs kunnr umskz augdt augbl zuonr gjahr belnr buzei xblnr
         blart auggj sgtxt budat bldat dmbtr waers wrbtr shkzg zterm
         zfbdt cpudt gsber xref1 xref2 rstgr mansp manst madat zbd1t
         zbd2t zbd3t zlsch maber kkber vbeln aufnr bschl hkont AS akont
    FROM bsad
    APPENDING CORRESPONDING FIELDS OF TABLE at_bsad
    FOR ALL ENTRIES IN lt_augbl
    WHERE bukrs = af_bukrs
      AND gjahr = lt_augbl-auggj
      AND belnr = lt_augbl-augbl
      AND umskz IN ('B', 'E', 'L', 'G', 'W', '5', '')
      AND xcpdd = ''.

  " Remove duplicates (stages 2a and 2b may overlap)
  SORT at_bsad.
  DELETE ADJACENT DUPLICATES FROM at_bsad COMPARING ALL FIELDS.

ENDMETHOD.

ABAP Code: GET_OPEN_DELTA Method

Supplementary method for open items. It selects via BKPF (entry/change date) and then retrieves the associated open items from BSID.

Class definition – addition:

    "! Two-stage delta for open items
    "! Stage 1: BKPF-based identification of new/changed documents
    "! Stage 2: FOR ALL ENTRIES against BSID
    METHODS get_open_delta
      IMPORTING
        iv_hours TYPE i DEFAULT 6.    " Delta window in hours

Implementation:

METHOD get_open_delta.
*----------------------------------------------------------------------*
* Two-stage delta selection for open items
*
* Background:
*   BSID contains only currently open items. New postings or
*   changes to existing open items are identified via BKPF
*   (CPUDT/CPUTM/AEDAT).
*
* Stage 1: Determine from BKPF all documents that were created
*          (CPUDT/CPUTM) or changed (AEDAT) within the delta window.
*
* Stage 2: Select from BSID all open items for these
*          document numbers. Only items that are still in BSID
*          (that is, still open) are returned.
*
* Parameters:
*   IV_HOURS  Size of the delta window in hours (default: 6)
*----------------------------------------------------------------------*

  DATA: lt_bkpf      TYPE TABLE OF ty_bkpf,
        lv_cpudt_low TYPE sy-datum,
        lv_cputm_low TYPE sy-uzeit,
        lv_seconds   TYPE i.

  " Calculate delta window
  lv_seconds = iv_hours * 3600.
  lv_cputm_low = sy-uzeit - lv_seconds.
  lv_cpudt_low = sy-datum.

  " Check for underflow: if the calculated time > current time,
  " a day change has occurred
  IF lv_cputm_low > sy-uzeit.
    lv_cpudt_low = sy-datum - 1.
  ENDIF.

  " === STAGE 1 ===
  " BKPF: All document headers in the delta window
  " Criteria:
  "   - CPUDT/CPUTM: Time the document was entered
  "   - AEDAT: Change date (captures subsequent changes)
  SELECT bukrs belnr gjahr cpudt cputm aedat
    FROM bkpf
    INTO TABLE lt_bkpf
    WHERE bukrs = af_bukrs
      AND ( ( cpudt = lv_cpudt_low AND cputm >= lv_cputm_low )
         OR ( cpudt > lv_cpudt_low )
         OR ( aedat >= lv_cpudt_low ) ).

  IF lt_bkpf IS INITIAL.
    RETURN.
  ENDIF.

  " === STAGE 2 ===
  " BSID: Open items for the identified documents.
  " Only items that are still in BSID are selected –
  " items that have already been cleared are in BSAD and are
  " covered by GET_CLEARED_DELTA.
  SELECT i~bukrs
         i~kkber
         i~kunnr
         i~gjahr
         i~belnr
         i~buzei
         i~xblnr
         i~zuonr
         i~blart
         i~sgtxt
         i~budat
         i~bldat
         i~dmbtr
         i~wrbtr
         i~waers
         i~shkzg
         i~zfbdt
         i~cpudt
         i~gsber
         i~xref1
         i~xref2
         i~rstgr
         i~aufnr
         i~mansp
         i~manst
         i~maber
         i~madat
         i~zterm
         i~augbl
         i~auggj
         i~augdt
         i~zbd1t
         i~zbd2t
         i~zbd3t
         i~zlsch
         i~vbeln
         i~umskz
         i~bschl
         i~hkont AS akont
    FROM bsid AS i
    INTO CORRESPONDING FIELDS OF TABLE at_bsid
    FOR ALL ENTRIES IN lt_bkpf
    WHERE i~bukrs = af_bukrs
      AND i~gjahr = lt_bkpf-gjahr
      AND i~belnr = lt_bkpf-belnr
      AND i~umskz IN ('B', 'E', 'L', 'G', 'W', '5', '')
      AND i~xcpdd = ''.

  SORT at_bsid BY bukrs kunnr umskz augdt augbl zuonr gjahr belnr buzei.
  DELETE ADJACENT DUPLICATES FROM at_bsid COMPARING ALL FIELDS.

ENDMETHOD.

Changes to the Extractor Report (sub_processing)

To use the two-stage methods in the report, extend sub_processing as follows. The existing code is retained for full-load mode (p_all = 'X'); in delta mode, the new methods are called:

*----------------------------------------------------------------------*
* FORM sub_processing (extended for two-stage delta)
*----------------------------------------------------------------------*
FORM sub_processing.

  SELECT bukrs FROM t001 INTO CORRESPONDING FIELDS OF TABLE gt_t001
    WHERE bukrs IN s_bukrs
      AND rcomp <> ''.

  LOOP AT gt_t001 INTO gs_t001.

    go_bilendo->clear( ).
    go_bilendo->set_bukrs( gs_t001-bukrs ).

    " === Customer master data ===
    IF p_kna1 = 'X'.
      go_bilendo->get_kna1( ).
      IF go_bilendo->at_kna1 IS NOT INITIAL.
        go_bilendo->kna1_file_to_server(
          IMPORTING ef_msg = gf_msg ).
        WRITE:/ gf_msg.
        CLEAR: gf_msg, go_bilendo->at_kna1.
      ELSE.
        gf_msg = text-001.
        REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
        WRITE:/ gf_msg.
        CLEAR gf_msg.
      ENDIF.
    ENDIF.

    " === Open items (BSID) ===
    IF p_bsid = 'X'.
      IF p_delta = 'X'.
        " Two-stage delta: via BKPF → BSID
        go_bilendo->get_open_delta( iv_hours = 6 ).
      ELSE.
        " Full load: all open items
        go_bilendo->get_bsid( ).
      ENDIF.
      go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsid ).
      IF go_bilendo->at_bsid IS NOT INITIAL.
        go_bilendo->bseg_file_to_server(
          EXPORTING
            it_bseg    = go_bilendo->at_bsid
            if_dataset = go_bilendo->af_dataset_bsid
          IMPORTING
            ef_msg     = gf_msg ).
        WRITE:/ gf_msg.
        CLEAR: gf_msg, go_bilendo->at_bsid.
      ELSE.
        gf_msg = text-003.
        REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
        WRITE:/ gf_msg.
        CLEAR gf_msg.
      ENDIF.
    ENDIF.

    " === Cleared items (BSAD) ===
    IF p_bsad = 'X'.
      IF p_delta = 'X'.
        " Two-stage delta: AUGDT → AUGBL → complete document groups
        go_bilendo->get_cleared_delta( iv_hours = 24 ).
      ELSE.
        " Full load: all cleared items
        go_bilendo->get_bsad( ).
      ENDIF.
      go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsad ).
      IF go_bilendo->at_bsad IS NOT INITIAL.
        go_bilendo->bseg_file_to_server(
          EXPORTING
            it_bseg    = go_bilendo->at_bsad
            if_dataset = go_bilendo->af_dataset_bsad
          IMPORTING
            ef_msg     = gf_msg ).
        WRITE:/ gf_msg.
        CLEAR: gf_msg, go_bilendo->at_bsad.
      ELSE.
        gf_msg = text-004.
        REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
        WRITE:/ gf_msg.
        CLEAR gf_msg.
      ENDIF.
    ENDIF.

  ENDLOOP.
ENDFORM.

Job Scheduling for Two-Stage Delta

When you use two-stage selection, the export job is scheduled every 6 hours instead of daily. The selection variant no longer needs dynamic date fields. The delta windows are calculated programmatically in the methods.

Variant: BILENDO_DELTA_6H

ParameterValueNote
P_KNA1XCustomer master (once a day is sufficient, optional)
P_BSIDXOpen items
P_BSADXCleared items
P_DELTAXDelta mode (activates two-stage methods)
S_BUKRSAll relevant BUKRSAs before
S_CPUDTemptyCalculated internally by get_open_delta
S_AUGDTemptyCalculated internally by get_cleared_delta

SM36 job:

Job: BILENDO_EXPORT_6H
  Step 1: ZFI_BILENDO_EXPORT_V2 / Variant: BILENDO_DELTA_6H
  Start condition: Periodic, every 6 hours
    → Start time: 00:00, 06:00, 12:00, 18:00

important: > The two-stage methods (get_cleared_delta, get_open_delta) use their own time window calculations. The selection variables S_CPUDT and S_AUGDT are ignored in delta mode when the new methods are used. The old methods (get_bsid, get_bsad) are retained for full load mode and for backward compatibility.

For details on job scheduling → 07 - Variants & Job Scheduling.