Skip to Content
Personal Insights
Author's profile photo Hongjun Qian

Flow Builder Plus: Go through document chain like Liquidity Planner

Flow Builder Plus, a.k.a. Flow Builder 2.0, is one of the kernel programs in SAP Cash Management, which target to generate cash flows from accounting documents as well as material documents.

As Flow Builder Plus now adopted the concept ‘Classification of G/L Account’ in Liquidity Planner, that is, when analyzing the document chain, the chain will stop when ‘Info Account’ reached in the chain.

Besides the standard logic that document chain shall stop at ‘Info Account’, there are business needs existed since Liquidity Planner era, that is, sometimes the document chain has to go further even the ‘Info Account’ are reached for an accurate liquidity item. For instance, normally there is no meaningful ‘Liquidity Item’ on GR/IR document and GR/IR account normally treated as ‘Info Account’, but it may have meaningful liquidity item information if the document chain can continue even the Info Account (GR/IR account in this case) reached. To support this, Liquidity Planner using the ‘FURTHER’ flag to enforce the document chain won’t been stopped.

To make the Flow Builder Plus go through the document chain like Liquidity Planner by supporting both ‘Info Account’ and support the ‘FURTHER’ flag, we need leverage the extensibility which offered by Flow Builder Plus.

Here comes the list of the steps.

Firstly, let’s take a look at BAdI methods which could help us on that part:

BAdI ‘FCLM_FB2_EXT’ was introduced to handle the document chain related logic. And among the methods of that BADI, method ‘FINAL_DECISION_EXT’ play the key role here for the requirement, within this method, the ‘FINAL’ flag controls whether the document chain reaches its final (the end) or not. Besides method ‘FINAL_DECISION_EXT’, metho ‘DOC_FKONT_EXT’ is also contribute on that part by set the FKONT value.

BAdI%20interface

BAdI interface

 

Secondly, we also understand what’s Flow Builder Plus’s default logic.

Flow Builder Plus, to keep the compatibility as Flow Builder 1.0, provide a default BAdI implementation for BADI ‘FCLM_FB2_EXT’:

Default%20Implementation

Default Implementation

Within its default implementation, the default logic will treat the GL account which defined in table FLQACC_INFO_APP. with the ‘FURTHER’ set to ‘X’ as the stopper despite the FKONT value the GL account could be.

 

Then, it is the time to make the decision to how deal with your situation. Normally there are two approaches:

  • For customers who coming from Liquidity Planner, their system used to treat GL account defined in table FLQACC_INFO_APP as Info Account while ‘FURTHER’ flag is the switch to let the document chain continues. In this way, you may need create an implement which follows the LP way and overwrite Flow Builder Plus’s default implementation.
  • For customers who running with Flow Builder 1.0 and get familiar with its logic already, you may need create an implementation to let Flow Builder Plus when to continues. For instance, whitelist the GL accounts though it is Info Account, but it shall not stop the document chain tracing.

 

Here comes the sample code to make Flow Builder Plus work as Classical LP:

CLASS zcl_fclm_fb2_ext_CLASSICLP DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_badi_interface .
    INTERFACES if_fclm_fb2_ext .
    methods constructor.

  PROTECTED SECTION.
  PRIVATE SECTION.
    data mo_default_impl type ref to cl_fclm_fb2_ext_default.
ENDCLASS.



CLASS zcl_fclm_fb2_ext_CLASSICLP IMPLEMENTATION.

  METHOD constructor.
    mo_default_impl = new #(  ).
  endmethod.

  METHOD if_fclm_fb2_ext~adjust_chain_step.
    CV_CHAIN_STEP = 6. " For CLASSICLP.
  ENDMETHOD.


  METHOD if_fclm_fb2_ext~clr_fkont_ext.
    if mo_default_impl IS NOT INITIAL.
      mo_default_impl->if_fclm_fb2_ext~clr_fkont_ext(
        CHANGING
          ct_item_fkont = ct_item_fkont
      ).
    endif.
  ENDMETHOD.

  METHOD if_fclm_fb2_ext~clr_lr_ext.
    if mo_default_impl IS NOT INITIAL.
      mo_default_impl->if_fclm_fb2_ext~clr_lr_ext(
        CHANGING
          ct_item_lr = ct_item_lr
      ).
    endif.
  ENDMETHOD.


  METHOD if_fclm_fb2_ext~doc_fkont_ext.
    TYPES: BEGIN OF ts_further,
             bukrs      TYPE bukrs,
             hkont_from TYPE hkont,
             hkont_to   TYPE hkont,
             further    TYPE flqfurther,
           END OF ts_further,
           BEGIN OF ts_hkont,
             bukrs TYPE bukrs,
             belnr TYPE belnr_d,
             gjahr TYPE gjahr,
             buzei TYPE buzei,
             hkont TYPE hkont,
           END OF ts_hkont.
    DATA: lt_item_tbd TYPE if_fclm_fb2_ext~tt_doc_item_fkont,
          lt_further_no_bukrs TYPE TABLE OF ts_further,
          lt_further_bukrs TYPE TABLE OF ts_further,
          lt_further_hkont TYPE TABLE OF ts_further,
          lt_hkont TYPE STANDARD TABLE OF ts_hkont WITH KEY bukrs belnr gjahr buzei,
          lv_further TYPE flqfurther.

    LOOP AT ct_item_fkont INTO DATA(ls_item).
      IF ls_item-item_fkont EQ 0 OR ls_item-item_fkont EQ 3 OR ls_item-item_fkont EQ 4.
        APPEND ls_item TO lt_item_tbd.
        DELETE ct_item_fkont.
      ENDIF.
    ENDLOOP.

    CHECK lt_item_tbd IS NOT INITIAL.

    SELECT DISTINCT b~bukrs, b~belnr, b~gjahr, b~buzei, b~hkont FROM @lt_item_tbd AS a
      INNER JOIN bseg AS b
      ON a~item_bukrs = b~bukrs AND a~item_belnr = b~belnr AND a~item_gjahr = b~gjahr AND a~item_buzei = b~buzei
    INTO TABLE @lt_hkont.

" Read FLQACC_INFO_APP for entries without company code
    SELECT bukrs, saknr_v AS hkont_from, saknr_b AS hkont_to, further
      FROM fclm_lqitem_further WITH PRIVILEGED ACCESS
      WHERE bukrs IS INITIAL
    INTO TABLE @lt_further_no_bukrs.

    LOOP AT lt_item_tbd INTO DATA(wa) GROUP BY ( bukrs = wa-item_bukrs ) INTO DATA(key).
      CLEAR: lt_further_bukrs[].

" Read FLQACC_INFO_APP for entries with company code
      SELECT bukrs, saknr_v AS hkont_from, saknr_b AS hkont_to, further
        FROM fclm_lqitem_further WITH PRIVILEGED ACCESS
        WHERE bukrs = @key-bukrs
      INTO TABLE @lt_further_bukrs.

      LOOP AT GROUP key ASSIGNING FIELD-SYMBOL(<fs_item>).
        CLEAR: lv_further.
        READ TABLE lt_hkont WITH TABLE KEY
          bukrs = <fs_item>-item_bukrs belnr = <fs_item>-item_belnr gjahr = <fs_item>-item_gjahr buzei = <fs_item>-item_buzei
          INTO DATA(ls_hkont).
        IF sy-subrc NE 0. CONTINUE. ENDIF.
        SELECT * FROM @lt_further_bukrs AS a
          WHERE bukrs = @ls_hkont-bukrs
            AND ( hkont_from <= @ls_hkont-hkont AND hkont_to >= @ls_hkont-hkont OR hkont_from = @ls_hkont-hkont )
          INTO TABLE @lt_further_hkont.
        READ TABLE lt_further_hkont INDEX 1 INTO DATA(ls_further).
        IF sy-subrc EQ 0.
          lv_further = ls_further-further.
        ELSE.
          SELECT * FROM @lt_further_no_bukrs AS a
            WHERE hkont_from <= @ls_hkont-hkont AND hkont_to >= @ls_hkont-hkont OR hkont_from = @ls_hkont-hkont
            INTO TABLE @lt_further_hkont.
          READ TABLE lt_further_hkont INDEX 1 INTO ls_further.
          IF sy-subrc EQ 0.
            lv_further = ls_further-further.
          ENDIF.
        ENDIF.

        IF lv_further EQ 'X'.
          IF <fs_item>-item_fkont EQ 3.
            <fs_item>-item_fkont = 4.
          ELSE.
            <fs_item>-item_fkont = 3.
          ENDIF.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

    APPEND LINES OF lt_item_tbd TO ct_item_fkont.
    SORT ct_item_fkont BY bukrs gjahr belnr item_bukrs item_gjahr item_belnr item_buzei.

  ENDMETHOD.


  METHOD if_fclm_fb2_ext~doc_lr_ext.
    if mo_default_impl IS NOT INITIAL.
      mo_default_impl->if_fclm_fb2_ext~doc_lr_ext(
        CHANGING
          ct_item_lr = ct_item_lr
      ).
    endif.
  ENDMETHOD.


  METHOD if_fclm_fb2_ext~final_decision_ext.
  ENDMETHOD.

ENDCLASS.

 

Hope this post helps.

 

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.