Advanced use of BADI FIEB_CHANGE_BS_DATA
2023-12-3 23:2:20 Author: blogs.sap.com(查看原文) 阅读量:10 收藏

Dear SAPers!

With my blog post “Enhancements in EBS – BADI FIEB_CHANGE_BS_DATA” I’ve started a series of posts around enhancements in electronic bank statement processing. This post is a continuation of this series. Please check out my previous post, because this post relies on the logic to split the implementation into two classes, which was described earlier.

I’ve described in my original post how to use this BADI to update some of the attributes for accounting documents e.g., Reference (XBLNR), Assignment (ZUONR), Cost center (KOSTL), Business area (GSBER), Profit center (PRCTR) and Line text (SGTXT). These attributes are included into the parameter C_FEBEP of the BADI interface and you can easily change them. The question is: can we use this BADI to adjust other attributes of accounting documents? The short answer is yes. My explanation is specific to Ukrainian legal specifics across, but the solution in essence is universal and can be used for any other country.

Description of the business scenario

Let’s return to my original example with incoming down-payment. Down-payments in Ukraine should be 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). Standard SAP solution (i.e., add-of for Ukraine) allows the references to be maintained in the fields BSEG-VBEL2 for sales order or BSEG-XREF2 for proforma invoices. Both fields are not available in the BADI interface. Let’s see how we can fill them automatically based on the details from note to payee.
I’ve prepared the following bank statement for the purpose of this blog post. As you can see, there is a reference to a pro-forma invoice 90000475 in the bank statement’s note to payee:

I use standard billing type F5 to generate a proforma invoice. This billing type does not generate any accounting postings but can be used to generate a print form i.e., preliminary invoice that is used to request the down-payment from the customer. The requirement is to save this number into the field BSEG-XREF2 for a customer down-payment posting.

Note: I’m working on another blog post that explores how to automate handling of incoming down-payments based on down-payment requests. I’ll update the link here upon completion.

Overview of the solution

The interface of the BADI allows you to fill in and pass into an accounting document up to three fields. I’m not sure what is the official name for this, but let me call it “BDC-approach“. I’ve stumbled on this idea when I was exploring various capabilities of the search string functionality. I’m attaching the screenshot of the standard SAP documentation for a search string that provides some explanation on this topic.

The idea is simple. If you want to fill some field, you should specify the following three attributes:

  • BDC Field Value (FEBEP-FVALX) – the value of the attribute.
  • BDC Field Name (FEBEP-FNAMX) – the name of the field.
  • BDC Field Type (FEBEP-FKOAX) – the type of field.

Type of the field is essentially a specification which says which posting area is impacted and which line should be updated. X refers to the ID of these fields. As I mentioned you can pass up to three different fields, therefore X is just a sequential number 1, 2 or 3.

Overview of the enhancement logic

For the purposes of this post, I’ve added a couple of additional methods into the BADI implementing class. I also added a class attribute C_BDC to store constant values for the BDC field types.

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_bdc,
        first_line_1st_area  type febep-fkoa1 value '0',
        first_line_2nd_area  type febep-fkoa1 value '1',
        second_line_1st_area type febep-fkoa1 value '2',
        second_line_2nd_area type febep-fkoa1 value '3',
      end of c_bdc.

    class-methods handle_inc_down_payment
      importing
        iv_note type string
      changing
        cs_febep type febep.

    class-methods get_pro_forma_invoice_nr
      importing
        iv_note type string
      returning
        value(rv_vbeln) type vbeln_vf.

    class-methods is_valid_vbeln
      importing
        iv_vbeln type vbeln
      returning
        value(rv_yes) type abap_bool.

    class-methods get_default_tax_code
      returning
        value(rv_mwskz) type mwskz.

endclass.

Now let’s come to the implementation details. The logic is triggered from the main method PROCESS_LINE. First, I call a method that caches a default posting rule for down-payment posting. Please check my previous post “Update of posting rules in BADI FIEB_CHANGE_BS_DATA” for more details on this method. Next, I call a dedicated method HANDLE_INC_DOWN_PAYMENT to update the attributes for incoming down-payment:

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

    cache_default_posting_rules( cs_febko ).

    handle_inc_down_payment(
      exporting
        iv_note = iv_note_to_payee
      changing
        cs_febep = cs_febep ).

  endmethod.

Method HANDLE_INC_DOWN_PAYMENT handles the update of the posting rule and updates three attributes for the accounting document: reference to proforma invoice (BSEG-XREF2), default tax code (BSEG-MWSKZ) and a flag “Calculate tax” (BKPF-XMWST). Source code below provides an example how to use these fields:

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>HANDLE_INC_DOWN_PAYMENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE                        TYPE        STRING
* | [<-->] CS_FEBEP                       TYPE        FEBEP
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method handle_inc_down_payment.

    " Adjust the posting rule
    cs_febep-vgint = ms_default_posting_rules-inc_down_payment.

    " Extract the reference to proforma invoice number
    data lv_vbeln type vbeln.
    lv_vbeln = get_pro_forma_invoice_nr( iv_note ).

    " Fill the reference to proforma invoice number
    if lv_vbeln <> ''.
      cs_febep-fnam1 = 'BSEG-XREF2'.
      cs_febep-fval1 = lv_vbeln.
      cs_febep-fkoa1 = c_bdc-second_line_2nd_area.
    else.
      return.
    endif.

    " Get tax code for a down-payment posting
    data lv_tax_code type mwskz.
    lv_tax_code = get_default_tax_code( ).

    " Fill tax code & the flag "Calculate tax"
    if lv_tax_code <> ''.
      cs_febep-fnam2 = 'BSEG-MWSKZ'.
      cs_febep-fval2 = lv_tax_code.
      cs_febep-fkoa2 = c_bdc-second_line_2nd_area.

      cs_febep-fnam3 = 'BKPF-XMWST'.
      cs_febep-fval3 = 'X'.
      cs_febep-fkoa3 = c_bdc-second_line_2nd_area.
    endif.

  endmethod.

The logic to retrieve proforma invoice number is implemented in a separate method GET_PRO_FORMA_INVOICE_NR. This method relies on the regular expression to recognize the proforma invoice number as the following pattern: 8-digit number that starts with 90, where numbers might be separated by a space. Once the number is found, the additional utility method IS_VALID_VBELN is triggered to check if this proforma invoice exists in the database.

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>GET_PRO_FORMA_INVOICE_NR
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_NOTE                        TYPE        STRING
* | [<-()] RV_VBELN                       TYPE        VBELN_VF
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method get_pro_forma_invoice_nr.
  " Utility method to extract proforma invoice number
  " Proforma invoice numbers begin with 90, have 8 digits and might be separated by space

    constants: lc_proforma_pattern type string value '(?=90)((\s?\d\s?){8})'.

    " Find numbers that might be proforma numbers
    data lv_proforma_nr type string.
    find regex lc_proforma_pattern in iv_note
      ignoring case
      submatches lv_proforma_nr.
    if sy-subrc is not initial.
      return.
    else.
      condense lv_proforma_nr no-gaps.   " Remove all spaces
      unpack lv_proforma_nr to rv_vbeln. " Add leading zeros i.e. padding
    endif.

    " Check if proforma number exists in the system
    if is_valid_vbeln( rv_vbeln ) = abap_false.
      clear: rv_vbeln.
    endif.

  endmethod.

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>IS_VALID_VBELN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_VBELN                       TYPE        VBELN
* | [<-()] RV_YES                         TYPE        ABAP_BOOL
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method is_valid_vbeln.

    data lv_vbeln type vbeln.

    select single vbeln
      from vbrk
      into lv_vbeln
      where vbeln = iv_vbeln.

    if sy-subrc = 0.
      rv_yes = abap_true.
    endif.

  endmethod.

Retrieval of default tax codes

Method GET_DEFAULT_TAX_CODE retrieves the default output tax code for incoming down-payment. An important note here: this example is quite simple, and it assumes that the company’s business operations are subject to one tax rate only. In some cases that might be true, while in others you might need more complicated logic. The source code for the method is as follows:

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_UA_FIEB_CHANGE_BS_DATA=>GET_DEFAULT_TAX_CODE
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RV_MWSKZ                       TYPE        MWSKZ
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method get_default_tax_code.

    constants: lc_country       type land1         value 'UA'.
    constants: lc_group_version type t007k-version value 'EBS'.

    " Select the tax code from the grouping version EBS
    select single mwskz
      from t007k
      into rv_mwskz
      where land1 = lc_country
        and version = lc_group_version.

  endmethod.

What is behind this code? Where do we store this default tax code? My proposal is to use the transaction OBCG. This transaction allows you to maintain custom tax grouping version for a variety of purposes. There are some pre-defined tax grouping versions for various country-specific VAT reports, but you are free to define your own versions. I’ve defined a tax grouping version EBS:

In the configuration I added one tax code with a transaction key MWS and a grouping number 1. For the purposes of the bank statement enhancement, neither the transaction key, nor the grouping number play any role. You can define them freely.

You are essentially using the benefits of configurable constants i.e., you define tax grouping version as a local constant in the enhancement (e.g. EBS), but the actual value (i.e., tax code I2) is configurable.

Definition of the posting rules

For the purposes of this post, I’m using the posting rule Z+DP for incoming down-payments. Posting rule Z+CP is a posting for customer’s post payment. We’re trying to update the second line of the accounting posting in the second posting area. It corresponds to the credit posting to the customer.

Test results

Screenshot below shows the posting log for bank statement upload:

Accounting document for the down-payment looks as follows. The tax code as well as the reference to proforma invoice were filled automatically by the BADI:

Screenshot below shows how the values were updated in the bank statement:

Concluding notes

I have used this approach many times to update various attributes in the accounting postings associated with the bank statement. The main drawback of this solution is that it allows you to adjust only three other fields in addition to those that are available in the definition of the attribute C_FEBEP. If you need to update more fields or introduce more complicated logic e.g. to split the posting into several lines, you will have to explore other enhancement spots in particular BADI FEB_BADI. I also plan another big blog post on this BADI, so stay tuned 🙂

Also, you have to be careful about this mechanism. This approach works and is in general quite reliable. But I encountered situations, where I properly filled the BDC-variables in the enhancement, but for some reason they were not passed to accounting interface. So before you commit to a full scale development, please implement a simple proof-of-concept to ensure that your intended solution works properly.

I hope that this post was useful and you have a better understanding of this enhancement mechanism.

Regards,

Bohdan


文章来源: https://blogs.sap.com/2023/12/03/advanced-use-of-badi-fieb_change_bs_data/
如有侵权请联系:admin#unsafe.sh