Enterprise Resource Planning Blogs by SAP
Get insights and updates about cloud ERP and RISE with SAP, SAP S/4HANA and SAP S/4HANA Cloud, and more enterprise management capabilities with SAP blog posts.
cancel
Showing results for 
Search instead for 
Did you mean: 
Hongjun_Qian
Product and Topic Expert
Product and Topic Expert
0 Kudos
[Updated on 2023 October]

Please be aware that this post applies for S/4HANA OP2021 version Only.

For S/4 HANA OP2022 or higher, you don't need such BAdI implementation because the standard logic already covers this part. What you need to do is use maintence view V_FCLM_FB2_LP to enable the old LP logic for specified company code.




 

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 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 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.

 
5 Comments