Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
Bohdan
Active Contributor
7,852
Dear SAPers !

With this post, I'm starting a new series of blog posts on topic around enhancements in electronic bank statement processing. I hope it will be interesting for you.

Introduction


SAP offers a powerful solution for electronic bank statement processing. This solution includes three main components:

  • A range of standard programs for upload and processing of bank statements in various formats (MT940, Multicash, BAI, CAM053 etc.).

  • A variety of configuration options (account symbols, posting rules, transaction types, return processing rules etc.), which are used by these standard programs.

  • A range of enhancement options that can be implemented to further enhance parsing of raw bank statements, their processing / interpretation and posting.


In this blog post, I’ll focus on the use of BADI FIEB_CHANGE_BS_DATA. This BADI is triggered during interpretation of bank statement. It is called both – during upload and initial processing of bank statement as well as during post-processing (e.g., via GUI transaction FEB_BSPROC or Fiori App F1520Reprocess Bank Statement Items”).

I’ll explain the interface of the BADI, the possibilities provided by this enhancement spot and share some tips & recommendations based on my previous experience. These findings are applicable to both SAP ECC as well as SAP S/4 HANA systems (on-premises).

Overview of the BADI attributes


Let’s walk through the BADI attributes in transaction SE18. As you can see, BADI FIEB_CHANGE_BS_DATA is a single-use BADI i.e., it has no filter and is called only once. This has an important implication. In my practice, this BADI is used very often to address custom requirements across many countries & many banks. Therefore, proper architecture should be put into place to separate the implementation logic for various competing business requirements, simplify the maintenance of the logic, and minimize the regression impact.


This BADI implements the interface IF_EX_FIEB_CHANGE_BS_DATA, which has one method CHANGE_DATE:


Screenshot below shows the signature for this method i.e., the list of method parameters & their typing:


The meaning behind these parameters is as follows:

  • T_FEBRE – table with note to payee data (i.e., information about payment details & purpose).

  • C_FEBKO – header of bank statement.

  • C_FEBEP – line item of bank statement.

  • T_FEBCL – clearing details for line item of the bank statement.


These are four main parameters, which you can use to implement your custom logic. The data in these parameters corresponds to the data in standard SAP tables FEBRE, FEBKO, FEBEP and FEBCL. You can change all parameters except the table with note to payee. This is the only limitation within this BADI.

I’m not 100% sure what is the purpose behind parameter I_TESTRUN. I never had a chance or a need to use it before. You can use other parameters if you want to issue a custom error message during bank statement processing.

Use of the BADI


Before the program calls this BADI, the underlying program for bank statement processing (e.g., RFEKA400 for MT940) has already split the bank statement into lines, parsed them and saved the data into the tables listed above.

The tables are linked between themselves via the fields KUKEY and ESNUM that represent the internal key for bank statement header and line item respectively:


As I mentioned earlier, this BADI is called during interpretation stage of the bank statement. To be more exact, it is called before standard interpretation of line items in accordance with interpretation mechanisms begins. Standard interpretation mechanisms for bank statement are defined in transaction OT83 (table T028G). Standard interpretation and search string processing happens immediately after this BADI and in some cases might overwrite your logic.

Interpretation of line item is executed during upload / initial processing of bank statement (both via GUI Transaction FF_5 or Fiori App F1680Manage Incoming Payment Files”). The BADI is triggered during post-processing each time when you press the button “Scan” in the transaction FEB_BSPROC:


If you’re post-processing bank statement items via Fiori App F1520 “Reprocess Bank Statement Items”, BADI is triggered when you press the button “Allocate Open Items”:



Short historical perspective


You might also notice that there is another alternative for this BADI namely SMOD-enhancement FEB00001, which implements user exit EXIT_RFEBBU10_001, include ZXF01U01:


The screenshot below shows the interface of this user exit. As you can see, it is almost the same, which one difference: parameter T_FEBRE is defined as such that can be changed. As I already mentioned before, is not possible to change this parameter in BADI.


User exit EXIT_RFEBBU10_001 was the first enhancement point introduced by SAP that allowed the customers to implement their own logic before standard interpretation mechanisms kick-in. Later, SAP introduced the definition of BADI FIEB_CHANGE_BS_DATA as a more modern enhancement approach.

I worked with the user exit EXIT_RFEBBU10_001 on one of my previous projects. There were a lot of legacy enhancements in this spot. The company introduced separate includes per country to structure the code. But it was not overly reliable / efficient, because there were a lot of global objects and conflicts between different countries. So eventually, I had to define a global class which encapsulated all logic and called it from the EXIT_RFEBBU10_001.

My personal preference is to use BADI. The main benefit of the BADI is that we have much better control over the enhancement due to the object-oriented design of this enhancement spot.
Technically speaking you might have implementation for both enhancement spots in your system. If that’s the case, the processing sequence is as follows: BADI → SMOD User Exit.

Enhancement architecture


As I mentioned before BADI FIEB_CHANGE_BS_DATA is a single-use BADI, which is a certain limitation from development point of view. But if you care about the architecture & design of your solution, it is easy to overcome this limitation. My proposal is to use BADI implementing class for two main purposes implementing:

  • global logic – that can be used across countries / banks.

  • router logic – that can be used to re-route processing logic to other global classes responsible for the requirements for specific countries.


In my experience, country level is enough to separate the business logic, because business requirements for company codes in one country will be similar across banks. A simplified UML diagram below shows the relationship between BADI implementing class and global classes that implement the specific per country:


For the purposes of this post, I’ve created a BADI implementing class ZCL_IM_FIEB_CHANGE_BS_DATA and a global class ZCL_UA_FIEB_CHANGE_BS_DATA that implements logic for Ukraine.

As I hinted before, the global class might implement some business logic that is not dependent on a country or company code. For example, you might want to implement a custom configuration table, where you’ll maintain a mapping between specific text patterns and posting rules for bank statements. This mapping can be defined on the house bank account level, therefore it can be implemented globally and executed only once.

If you’re familiar with the functionality of search strings in SAP, you might ask, why do we need such a table? It is a valid question, and, in some cases, it would be easier to implement a search string. But the functionality of search strings has its own limitations with regards to REGEX-usage and in general is not very easy to implement / troubleshoot.

Another common requirement has a technical nature and deals with the way a note to payee is stored. It is stored in the table FEBRE and is split into several lines. One of the common ways to enhance the interpretation of bank statement is to analyze the text of note to payee and search for some patterns or details. Therefore, it is a good idea to transfer the table to a string. Along the way you can implement some additional logic e.g., remove some special characters, or covert the case (to uppercase or lowercase).

I provide a sample source code for a global class below. As you can see, it has two additional private methods: PREPARE_NOTE_TO_PAYEE and GET_COUNTRY_CODE. The first method transfers the note to payee from a table to a string-representation. The second method fetches the country code associated with the company code. Both methods are called from the standard method CHANGE_DATE. A case-statement is used as a router to call specific classes. In this case, global class will call country-specific logic for Ukraine i.e., ZCL_UA_FIEB_CHANGE_BS_DATA.
class zcl_im_fieb_change_bs_data definition
public
final
create public .

public section.

interfaces if_ex_fieb_change_bs_data .

protected section.
private section.

class-methods get_country_code
importing
!is_febko type febko
returning
value(rv_land) type land1 .

class-methods prepare_note_to_payee
importing
!it_febre type any table
returning
value(rv_note_to_payee) type string .

endclass.

class zcl_im_fieb_change_bs_data implementation.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_IM_FIEB_CHANGE_BS_DATA=>GET_COUNTRY_CODE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_FEBKO TYPE FEBKO
* | [<-()] RV_LAND TYPE LAND1
* +--------------------------------------------------------------------------------------</SIGNATURE>
method get_country_code.

select single land1
from t001
into rv_land
where bukrs = is_febko-bukrs.

endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_IM_FIEB_CHANGE_BS_DATA->IF_EX_FIEB_CHANGE_BS_DATA~CHANGE_DATA
* +-------------------------------------------------------------------------------------------------+
* | [--->] I_TESTRUN TYPE XFELD
* | [--->] T_FEBRE TYPE STANDARD TABLE
* | [<---] E_SUBRC TYPE SY-SUBRC
* | [<---] E_MSGID TYPE SY-MSGID
* | [<---] E_MSGTY TYPE SY-MSGTY
* | [<---] E_MSGNO TYPE SY-MSGNO
* | [<---] E_MSGV1 TYPE SY-MSGV1
* | [<---] E_MSGV2 TYPE SY-MSGV2
* | [<---] E_MSGV3 TYPE SY-MSGV3
* | [<---] E_MSGV4 TYPE SY-MSGV4
* | [<-->] C_FEBKO TYPE FEBKO
* | [<-->] C_FEBEP TYPE FEBEP
* | [<-->] T_FEBCL TYPE STANDARD TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
method if_ex_fieb_change_bs_data~change_data.

data lv_note_to_payee type string.
lv_note_to_payee = prepare_note_to_payee( t_febre ).

" Some global logic can be applied here
" Example: adjustment of posting rules based on Z-configuration table

data lv_country type land1.
lv_country = get_country_code( c_febko ).

" Initiate country specific logic
case lv_country.
when 'UA'.
zcl_ua_fieb_change_bs_data=>process_line(
exporting
iv_note_to_payee = lv_note_to_payee
changing
cs_febko = c_febko
cs_febep = c_febep
ct_febcl = t_febcl ).
when others.
" Do nothing
endcase.

endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_IM_FIEB_CHANGE_BS_DATA=>PREPARE_NOTE_TO_PAYEE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_FEBRE TYPE ANY TABLE
* | [<-()] RV_NOTE_TO_PAYEE TYPE STRING
* +--------------------------------------------------------------------------------------</SIGNATURE>
method prepare_note_to_payee.

field-symbols <line> type febre.

" Prepare string representation of note to payee
loop at it_febre assigning <line>.
if <line> is not assigned.
continue.
endif.
concatenate rv_note_to_payee <line>-vwezw into rv_note_to_payee.
endloop.

condense rv_note_to_payee.

" Additional logic can be added here
" Transfer to upper / lower case, removal of special characters etc.

endmethod.

endclass.

Design of the country specific class


I provide a sample source code for a country-specific class below. So far it is just a backbone of the global class that shows how it is defined and has several global constants. I’ll use this backbone and will provide additional details along the way.
class zcl_ua_fieb_change_bs_data definition
public
final
create public .

public section.

types:
tt_febcl type standard table of febcl with default key .

class-methods process_line
importing
!iv_note_to_payee type string
changing
!cs_febko type febko
!cs_febep type febep
!ct_febcl type standard table .

protected section.
private section.

constants:
begin of c_clear_by,
ref_number type febcl-selfd value 'XBLNR' ##NO_TEXT,
doc_number type febcl-selfd value 'BELNR' ##NO_TEXT,
paym_order type febcl-selfd value 'PYORD' ##NO_TEXT,
doc_amount type febcl-selfd value 'WRBTR' ##NO_TEXT,
end of c_clear_by.

constants:
begin of c_account_type,
customer type koart value 'D' ##NO_TEXT,
vendor type koart value 'K' ##NO_TEXT,
gl_account type koart value 'S' ##NO_TEXT,
end of c_account_type.

constants:
begin of c_operation_type,
inc_payment type shkzg value 'H' ##NO_TEXT,
out_payment type shkzg value 'S' ##NO_TEXT,
end of c_operation_type.

endclass.

class zcl_ua_fieb_change_bs_data implementation.

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_UA_FIEB_CHANGE_BS_DATA=>PROCESS_LINE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE_TO_PAYEE TYPE STRING
* | [<-->] CS_FEBKO TYPE FEBKO
* | [<-->] CS_FEBEP TYPE FEBEP
* | [<-->] CT_FEBCL TYPE STANDARD TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
method process_line.

endmethod.

endclass.

Typical use cases


There are several common use cases for this BADI. Let’s review them one by one.

Identification of business partner

Ideally speaking the purpose of the bank statement interpretation (especially for incoming payments) is to find an open item representing the sales invoice, for which the customer paid. If this reference is found, you do not really need to bother about the identification of the business partner. But what happens, if the system is not able to identify the open item or the business partner? In these cases, you can use this BADI to find a business partner.

There are several approaches: you can analyze the bank details of the business partner. Relevant fields in the parameter FEBEP are: PABKS, PABLZ, PASWI, PAKTO, PARTN & PIBAN.

Alternatively, you can analyze the content of the note to payee and check if there are any details that allow you to identify the business partner. In one case, I was working with the bank statement, where the bank provided the tax number of the business partner for each payment. My requirement was to identify this tax number and query the tables LFA1/KNA1 to identify the partner.

One more alternative is to search for a business partner based on the reference information provided in the note to payee (i.e., based on sales invoice or pro-forma invoice number).

Once a business partner is known, you can update it in the parameter FEBEP. Two fields are used for this purpose: AVKOA – account type, AVKON – account number. A sample source code below provides some hints on how to implement the logic:
" Definition of the methods

class-methods identify_business_partner
importing
iv_note type string
is_febko type febko
changing
cs_febep type febep.

class-methods is_bp_known
importing
is_febep type febep
returning
value(rv_yes) type abap_bool.

class-methods get_customer_number
importing
iv_note type string
is_febko type febko
is_febep type febep
returning
value(rv_kunnr) type kunnr .

class-methods get_vendor_number
importing
iv_note type string
is_febko type febko
is_febep type febep
returning
value(rv_lifnr) type lifnr .

" Implementation of the methods

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>GET_CUSTOMER_NUMBER
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE TYPE STRING
* | [--->] IS_FEBKO TYPE FEBKO
* | [--->] IS_FEBEP TYPE FEBEP
* | [<-()] RV_KUNNR TYPE KUNNR
* +--------------------------------------------------------------------------------------</SIGNATURE>
method get_customer_number.
" Your own logic here
endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>GET_VENDOR_NUMBER
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE TYPE STRING
* | [--->] IS_FEBKO TYPE FEBKO
* | [--->] IS_FEBEP TYPE FEBEP
* | [<-()] RV_LIFNR TYPE LIFNR
* +--------------------------------------------------------------------------------------</SIGNATURE>
method get_vendor_number.
" Your own logic here
endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>IDENTIFY_BUSINESS_PARTNER
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE TYPE STRING
* | [--->] IS_FEBKO TYPE FEBKO
* | [<-->] CS_FEBEP TYPE FEBEP
* +--------------------------------------------------------------------------------------</SIGNATURE>
method identify_business_partner.

if is_bp_known( cs_febep ) = abap_true.
return.
endif.

" Determination of business partner based on payment type
if cs_febep-epvoz = c_operation_type-inc_payment.

data lv_kunnr type kunnr.
lv_kunnr = get_customer_number(
iv_note = iv_note
is_febko = is_febko
is_febep = cs_febep ).
if lv_kunnr <> ''.
cs_febep-avkoa = c_account_type-customer.
cs_febep-avkon = lv_kunnr.
endif.

elseif cs_febep-epvoz = c_operation_type-out_payment.

data lv_lifnr type lifnr.
lv_lifnr = get_vendor_number(
iv_note = iv_note
is_febko = is_febko
is_febep = cs_febep ).
if lv_lifnr <> ''.
cs_febep-avkoa = c_account_type-vendor.
cs_febep-avkon = lv_lifnr.
endif.

else.
" Should not reach this stage
endif.

endmethod.

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>IS_BP_KNOWN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_FEBEP TYPE FEBEP
* | [<-()] RV_YES TYPE ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>
method is_bp_known.

if is_febep-avkon <> '' and is_febep-avkoa <> ''.
rv_yes = abap_true.
endif.

endmethod.

" Call of the method from the main method in local class

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_UA_FIEB_CHANGE_BS_DATA=>PROCESS_LINE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE_TO_PAYEE TYPE STRING
* | [<-->] CS_FEBKO TYPE FEBKO
* | [<-->] CS_FEBEP TYPE FEBEP
* | [<-->] CT_FEBCL TYPE STANDARD TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
method process_line.

identify_business_partner(
exporting
iv_note = iv_note_to_payee
is_febko = cs_febko
changing
cs_febep = cs_febep ).

endmethod.

I propose using a small utility method IS_BP_KNOWN to check if the business partner was already found before. This might be useful in post-processing mode because you no longer need to search for a business partner if it is already known.

Transactional details

You can use the BADI to update a range of attributes that will be passed down to accounting document level. The list of these details includes the following fields in the parameter FEBEP:

  • XBLNR – reference number.

  • ZUONR – assignment number.

  • KOSTL – cost center.

  • GSBER – business area.

  • PRCTR – profit center.

  • SGTXT – line-item text.


Change of the posting rule

Posting rule for a line item is stored in the field FEBEP-VGINT. You can use this field to adjust the determination of the posting rules depending on the business scenario. A typical business case from my practice. Incoming payments in Ukraine should be analyzed and processed differently depending on the fact if it is a down-payment or a post payment. Down-payments are posted with VAT on so called gross-basis and require assignment of the tax code and ideally speaking a reference to sales order or pro-forma invoice (i.e., local VAT requirements). Down-payments generate a new open item on the customer account and no clearing is required (i.e., because the invoice is not even posted yet). Whereas post payment should automatically clear the existing invoice. You can easily define two separate posting rules for these cases, but you can only assign one of them in the mapping, because the bank provides only one BTC-code for customer payments. So, what can you do in this case?

My solution is as follows: I’ve used the BADI to identify the customer, then I analyzed the list of open items associated with the customer via FM BAPI_AR_ACC_GETOPENITEMS. Depending on the current balance of these open items, I decided about the payment type and changed the posting rule accordingly.

I've provided more details on this subject in a dedicated blog post.

Parsing for reference numbers

Note to payee in the bank statement might contain a lot of useful information. Main problem is that sometimes it is not easy to extract this information due to various technical or business-related issues. Let’s suppose your company is issuing sales invoices with document numbers in the range of 9100000000-9199999999. Some customers might pay several invoices at a time and provide details as follows: “payment for invoices 9100900901, *900902 & *900903 from 01.01.2023”. In this case, there are three invoice numbers in the payment details, but standard SAP will be able to recognize one the first invoice number. I’ve encountered such a case on one of my previous projects, where many customers provided only the last 4-3 invoice numbers on a regular basis, and I managed to automate the search and assignment of open items for incoming payments of this kind.

Alternatively, reference numbers can be impacted by various technical issues i.e., they can be truncated or split into several lines during upload. For example, invoice number 9100900901 might be stored in the database table as 9100 900901. Extra space between the digits turns recognizable invoice number into two numbers that cannot be recognized.

Therefore, a common requirement is to implement custom logic that will search for these reference numbers more efficiently. Common references numbers are:

  • Accounting document numbers (BKPF-BELNR) – customer invoices or down-payment requests.

  • Reference numbers (BFKP-XBLNR) – most commonly billing document numbers for sales invoices.

  • Proforma invoice numbers (VBRK-VBELN of VBAK-VBELN) – based on billing documents or sales orders.

  • Sales contract numbers (VBAK-VBELN) – based on sales contract numbers.

  • Payment document numbers or payment orders (REGUH-PYORD) – for outgoing payments etc.


Update of clearing information

Once you interpreted the note to payee and extracted some useful reference numbers, you have to update the clearing details (if relevant for a posting rule). Clearing details are stored in the table FEBCL and can be updated via the parameter T_FEBCL.

Let’s return to our case with payment details “9100900901, *900902 & *900903”. If you managed to extract all three invoice numbers and you checked that these accounting document numbers exist in the system, you can fill the table T_FEBCL as described below. If the amount of the payment equals the total amount of open items across these three invoices, all three invoices will be automatically cleared.

Automatic clearing is also possible if payment amount is less than total amount of invoices, but it assumes that the difference is within tolerance limit (i.e., case of underpayment) or in line with the conditions for early payment discounts as defined in the payment terms.


What is of importance here:

  • CSNUM – is a counter that shows how many lines with clearing details are available.

  • KOART / AGKON – represent account type and account number.

  • SELFD – is a selection field that will be used as a criterion during selection of open items for clearing.

  • SELVON / SELBIS – store the values for the criteria in accordance with its type. You can indicate one value (SELVON) or a range of values (SELVON to SELBIS).


Special note: if you use clearing by accounting document numbers i.e., BELNR, you can provide a document number 9100900901 only or a full reference to a line item 91009009012023001 (concatenation of document number, fiscal year & line ID).

Additional notes below provide some recommendations about update of the clearing details.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_UA_FIEB_CHANGE_BS_DATA=>PROCESS_LINE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE_TO_PAYEE TYPE STRING
* | [<-->] CS_FEBKO TYPE FEBKO
* | [<-->] CS_FEBEP TYPE FEBEP
* | [<-->] CT_FEBCL TYPE STANDARD TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
method process_line.
" Sample code to update clearing details

data: lv_xblnr type xblnr.
data: lv_belnr type belnr.
data: lv_pyord type pyord.

data: lt_febcl type tt_febcl,
ls_febcl like line of lt_febcl.

" Fill common clearing parameters
ls_febcl-kukey = cs_febep-kukey.
ls_febcl-esnum = cs_febep-esnum.
ls_febcl-csnum = '1'.
ls_febcl-koart = cs_febep-avkoa.
ls_febcl-agkon = cs_febep-avkon.

" Optional parameter
ls_febcl-agums = 'X'. " SGL-indicator can be passed if you want to clear against SGL-items

" Specific parameters

" You can clear by reference numbers, or
ls_febcl-selfd = c_clear_by-ref_number.
ls_febcl-selvon = lv_xblnr.

" You can clear by accounting document numbers, or
ls_febcl-selfd = c_clear_by-doc_number.
ls_febcl-selvon = lv_belnr.

" You can clear by payment order number, or
ls_febcl-selfd = c_clear_by-paym_order.
ls_febcl-selvon = lv_pyord.

" You can clear by amount
ls_febcl-selfd = c_clear_by-doc_amount.
ls_febcl-selvon = cs_febep-kwbtr.

append ls_febcl to ct_febcl.

endmethod.

Other specific business cases

As part of this series, I plan to publish a couple of other follow-up blog posts, that will describe several other topics, which are related to this enhancement spot. As of now, I have at least a dozen of various topics in my action list. The details will be updated here. As of now the following posts are available:

  • Update of posting rules in BADI FIEB_CHANGE_BS_DATA (link).

  • Use of account modification in bank statement (link).

  • Advanced use of BADI FIEB_CHANGE_BS_DATA (link).

  • Troubleshooting tool for BADI FIEB_CHANGE_BS_DATA (link).


Concluding notes


I hope that this post provided some useful insights and it was not too boring. I did not provide a lot in terms of actual coding. The purpose of this post is not to solve specific issues, but rather to explain the enhancement spot, its purpose and potential use cases. On the other hand, this is an enhancement spot. As such it is should be used to implement customer-specific logic. So it would be up to you to decide what that should should be and how it should be implemented. I hope that this post would be a good guidance if you are looking to improve your processes around electronic bank statement processing.

I'm looking forward to your comments and questions. I would be happy to address / answer them.

Regards,

Bohdan

 
7 Comments
e_enginyilmaz
Participant
Very helpful indeed for the SAPers who especially work on bank reconciliations in multinational projects. Thanks for sharing.

Engin
Bohdan
Active Contributor
0 Kudos
Hi e.enginyilmaz,

Thank you for good feedback !

Regards,

Bohdan
Jack_Reynolds
Explorer
Great blog, thanks!

I have a couple of comments:

  • With note 3343362 it's possible to change FEBRE when using this BAdI.  The change is not physically stored in the FEBRE table but it's available for the search strings & interpretation algorithms. In other words, it works in a similar way to mapping into the "Payment Notes" in Search Strings.  3343362 - Bank statement: Change of note to payee in BAdI FIEB_CHANGE_BS_DATA.  The note is only applicable to S/4HANA and not ECC.


 

  • Do you have experience with BAdI FIEB_CHANGE_STATEMNT as well?  This BAdI is called much later on in the bank statement processing logic (after interpretation & search strings) so depending on what you want to adjust and when in the process, it may be a good option.


Br,

Jack
Bohdan
Active Contributor
0 Kudos
Hi jack1816,

Thank you for these extended / useful comments. Note 3343362 is a good one, I was not aware of this change, but on the other hand, I never had a requirement to actually change note to payee. Also, when it comes to BADI FIEB_CHANGE_BS_DATA: though we cannot change the note to payee and store the changes in DB, it is possible to change it internally and use it for various interpretation purposes. On one of my projects I was doing just the same and it was enough to enhance the interpretation.

With regards to BADI FIEB_CHANGE_STATEMNT: yes, I have worked with it BADI before, but I prefer to use FIEB_CHANGE_BS_DATA. In many cases, especial when it comes to the requirements I deal with very often (e.g. processing of customer down-payments), there is no added benefits in standard interpretation mechanisms. But I agree that in some cases, it might be very useful.

Regards,

Bohdan
nathalie_changra
Newcomer
0 Kudos
Hello,

Thank you for the fantastic post. It helps me a lot. However, I have a question. The accounting sales invoices have in Reference key 1 the number of the billing document. This data( number of the billing document)  is also in my "note to payee". So, now i need to do the clearing between customer invoices and its payments using the "billing document number". As far I understood, i can follow your instructions but i dont know how. Could you help me please?

Thank you!
Bohdan
Active Contributor
0 Kudos
Hi nathalie_changra,

Normally, whenever we speak about the integration between FI & SD, the reference to a billing document is stored in the Reference of accounting document (i.e. BKPF-XBLNR). If that the case, you actually do not need much in terms of enhancements. You can leverage standard interpretation mechanisms for bank statement, which are provided by SAP. That assumes of course that you have billing document in note to payee, which as far as I understand you have. Interpretation mechanism for this case is 001 "Standard algorithm". For that you need to configure posting rule for incoming payments with clearing of open items of the customer. Also, you need to make sure that the number ranges for references (i.e. XBLNR) are maintained properly on selection screen of FF_5. If you mean these criterias, SAP will take care of automatic clearing. You can use this enhancement optionally to increase the automatic rate of the interpretation.

If for some reason the reference to billing document is on line item level (BSEG-XREF1) only and there is nothing in the header (BKPF-XBLNR), you will need to use this enhancement point. You'll need to parse note to payee and try to find the billing document number based on the regular expression that takes into account possible number ranges for billing document. Once you have found this document number and verified that it exists in the database (i.e. VBRK-table), you can start looking for FI-document. If you have found the FI-document, you'll have to add it as a clearing criteria to FEBCL-table as I described in the post. The problem with references on line item level is, that any solution will be more performance heavy i.e. because you need to go down to line item level, instead of querying the headers of accounting documents. Therefore, if your client is not live yet, I suggest to reconsider the design and move the reference to billing document to its proper place. This is best practice for SD/FI integration.

I hope it should help you.

Regards,

Bohdan
Priya17
Discoverer
0 Kudos

Hello @Bohdan,

Good Day.

Thank you for the fantastic post. It helps me a lot. However, I have a question. We have requirement on bank clearing enhancement where the clearing is based on reference number or bank account number(search string) from bank statement. This data(reference number and bank account number)  is also in my "note to payee". So, now need to do the clearing between customer invoices and its payments using the "reference number or bank account number". As far I understood, can follow the instructions but don't know how. Could you help me please?

Labels in this area