Skip to Content

This is a code snippet to demonstrate how to get the tax information from SAP and map it to the cXML PO document, so it is transmitter to Suppliers over the Ariba Network.

This development was done for US tax scenario without tax jurisdiction calculation and error handling needs to be further enhanced. It also does not support Service lines.

We will map the following fields with the tax details from the ECC PO.

 

Configuration

We will share the CC Invoice configuration, maintaining the SAP Tax code to cXML Classification relationship at the SPRO activity:

Integration with Other SAP Components –> SAP Business Suite Integration Component for Ariba –> Application-Specific Settings –> SAP ERP Integration Component for Ariba –> Integration for Buyers –> Define Mapping Settings for Invoices –> CC Invoice: Map Tax Category for Ariba Network Invoice

Example:

 

Development

Use the BAdI ARBERP_OUTBOUND_MAPPING, method MAP_BUS2012_TO_ORDR_OUT to map the Tax details fields. In the example bellow, the method PO_ITM_MAP_TAX_CODE was created to encapsulate all the Tax Details relevant changes.

method PO_ITM_MAP_TAX_CODE.

  DATA: lt_po_item    TYPE TABLE OF BAPIMEPOITEM,
        ls_po_item    TYPE BAPIMEPOITEM,
        ls_po_header  TYPE BAPIMEPOHEADER,
        lc_po         TYPE EBELN,
        ls_taxdetail  TYPE ARBERP_XORDR_S_TAX_DETAIL,
        ls_t001       TYPE t001,
        lv_tax_category        TYPE arberp_tax_category_long,
        lt_messages            TYPE ARBFND_T_BAPIRET2_MSG,
        lv_message_v1          TYPE symsgv,
        lt_mwdat               TYPE STANDARD TABLE OF rtax1u15,
        lv_msatz               TYPE msatz_f05l,
        lf_tax_rate            type MSATZ_F05L,
        lf_net_amount          type WRBTR,
        lc_tax_desc   TYPE TEXT1_007S,
        mo_helper_out_instance TYPE REF TO IF_ARBERP_HELPER_INT_OUT.

  FIELD-SYMBOLS: <fs_item> TYPE ARBERP_XORDR_S_ITEM_OUT,
                 <fs_mwdat>                TYPE rtax1u15.

* Initialize helper
  CALL METHOD cl_arberp_helper_factory_int=>get_instance_helper_int_out
    IMPORTING
      eo_instance = mo_helper_out_instance.

  lc_po = IV_OBJECT_KEY.
* Get the PO data
  CALL FUNCTION 'BAPI_PO_GETDETAIL1'
    EXPORTING
      PURCHASEORDER    = lc_po
      DELIVERY_ADDRESS = 'X'
    IMPORTING
      POHEADER         = ls_po_header
    TABLES
      POITEM           = lt_po_item.

* Get Company Country
  CALL FUNCTION 'FI_COMPANY_CODE_DATA'
    EXPORTING
      i_bukrs      = ls_po_header-COMP_CODE
    IMPORTING
      e_t001       = ls_t001
    EXCEPTIONS
      SYSTEM_ERROR = 1.
  IF sy-subrc IS NOT INITIAL.
* error handling here
  ENDIF.

* Get to the Item element.
  LOOP AT CS_ORDR-REQUEST-ORDER_REQUEST-ITEM_OUT ASSIGNING <fs_item>.
    CLEAR: lf_net_amount, lv_tax_category, ls_po_item, lt_messages[], lv_message_v1, lt_mwdat[], lf_tax_rate, lc_tax_desc.
    READ TABLE lt_po_item INTO ls_po_item WITH KEY PO_ITEM = <fs_item>-LINE_NUMBER.
    IF sy-subrc IS INITIAL.
      CHECK ls_po_item-TAX_CODE IS NOT INITIAL.
*--------------------------------------------------------------------*
*      Get the Tax category from the configuration
*--------------------------------------------------------------------*
      CALL METHOD mo_helper_out_instance->map_tax_category
        EXPORTING
          iv_vendor_id        = ls_po_header-VENDOR
          iv_tax_code         = ls_po_item-TAX_CODE
          iv_country_code     = ls_t001-land1
        IMPORTING
          ev_ext_tax_category = lv_tax_category
        CHANGING
          ct_info_messages    = lt_messages.

      IF lv_tax_category IS INITIAL. " category is mandatory, can not continue
        lv_message_v1 = ls_po_item-TAX_CODE.
        RAISE EXCEPTION TYPE cx_arbfnd_appl
          EXPORTING
            message_id     = if_arberp_t100_map_c=>gc_msg_class_name
            message_number = if_arberp_t100_map_c=>gc_msgno_257
            message_v1     = lv_message_v1.
      ENDIF.
*--------------------------------------------------------------------*



*--------------------------------------------------------------------*
*        Calculate the tax rate
*--------------------------------------------------------------------*
* Calculate item ammount
      lf_net_amount = ls_po_item-NET_PRICE * ( ls_po_item-QUANTITY / ls_po_item-PRICE_UNIT ) * ( ls_po_item-CONV_NUM1 / ls_po_item-CONV_DEN1 ).
* Get tax rete
      CALL FUNCTION 'CALCULATE_TAX_FROM_NET_AMOUNT'
        EXPORTING
          i_bukrs           = ls_po_header-COMP_CODE
          i_mwskz           = ls_po_item-TAX_CODE
*         i_txjcd           =
          i_waers           = ls_po_header-CURRENCY
          i_wrbtr           = lf_net_amount
        TABLES
          t_mwdat           = lt_mwdat
        EXCEPTIONS
          bukrs_not_found   = 1
          country_not_found = 2
          mwskz_not_defined = 3
          mwskz_not_valid   = 4
          ktosl_not_found   = 5
          kalsm_not_found   = 6
          parameter_error   = 7
          knumh_not_found   = 8
          kschl_not_found   = 9
          unknown_error     = 10
          account_not_found = 11
          txjcd_not_valid   = 12
          OTHERS            = 13.
      IF sy-subrc <> 0. " calculation failed, rate will be 0.00
*    CLEAR ls_info_message.
*    lv_message_v1              = is_incinv_rbtx-mwskz.
*    lv_message_v2              = is_incinv_headerdata-comp_code.
*    ls_info_message-message_v1 = lv_message_v1.
*    ls_info_message-message_v2 = lv_message_v2.
*    ls_info_message-type       = if_arberp_t100_map_c=>gc_warning.
*    ls_info_message-id         = if_arberp_t100_map_c=>gc_msg_class_name.
*    ls_info_message-number     = if_arberp_t100_map_c=>gc_msgno_253.
*    APPEND ls_info_message TO ct_info_messages.
*    RETURN. " from method
      ENDIF.
* Calculate tax rate
      CLEAR: lv_msatz.
      LOOP AT lt_mwdat ASSIGNING <fs_mwdat>
        WHERE msatz <> 0.
        lv_msatz = lv_msatz + <fs_mwdat>-msatz.
      ENDLOOP.
* Return rate
      lf_tax_rate = lv_msatz.
*--------------------------------------------------------------------*



*--------------------------------------------------------------------*
*       Map the tax rate and category to the cxml
*--------------------------------------------------------------------*
      CLEAR ls_taxdetail.
* Tax Amount
      <fs_item>-tax-money-currency = ls_po_header-CURRENCY_ISO.
      <fs_item>-tax-money-content = ( lf_net_amount  * lf_tax_rate ) / 100 .
* SAP Tax Code
      <fs_item>-tax-description-xml_lang = me->CC_DEF_LANG.
      <fs_item>-tax-description-CONTENT = ls_po_item-TAX_CODE.
* Category and rate
      ls_taxdetail-category = lv_tax_category.
      ls_taxdetail-percentage_rate = lf_tax_rate.
* Taxable Amount
      IF lf_tax_rate <> 0.
        ls_taxdetail-TAXABLE_AMOUNT-MONEY-CONTENT = lf_net_amount.
      ENDIF.
      ls_taxdetail-TAXABLE_AMOUNT-MONEY-CURRENCY = ls_po_header-CURRENCY_ISO.
* Tax Amount
      ls_taxdetail-TAX_AMOUNT-MONEY-CONTENT = ( lf_net_amount * lf_tax_rate ) / 100 .
      ls_taxdetail-TAX_AMOUNT-MONEY-CURRENCY = ls_po_header-CURRENCY_ISO.
* exemptDetail
      IF lf_tax_rate = 0.
        LS_TAXDETAIL-EXEMPT_DETAIL = 'exempt'.              "#EC NOTEXT
      ENDIF.
* TaxLocation = Tax Jurisdiction
      LS_TAXDETAIL-TAX_LOCATION-CONTENT = ls_po_item-TAXJURCODE.
      LS_TAXDETAIL-TAX_LOCATION-XML_LANG = me->CC_DEF_LANG.

* description
      CALL FUNCTION 'TAX_CODE_TEXT_GET'
        EXPORTING
          I_LANGU               = ls_t001-SPRAS
          I_BUKRS               = ls_po_header-COMP_CODE
          I_MWSKZ               = ls_po_item-TAX_CODE
        IMPORTING
          E_TEXT1               = lc_tax_desc
* TABLES
*         T_C_ERRORS            =
        EXCEPTIONS
          TEXT_NOT_FOUND        = 1
          COMPANY_NOT_FOUND     = 2
          COUNTRY_NOT_FOUND     = 3
          TAX_PROCEDURE_MISSING = 4
          OTHERS                = 5.
      IF SY-SUBRC is INITIAL.
        LS_TAXDETAIL-DESCRIPTION-CONTENT = lc_tax_desc.
        LS_TAXDETAIL-DESCRIPTION-XML_LANG = me->CC_DEF_LANG.
      ELSE.
* error handling here
      ENDIF.


      APPEND ls_taxdetail TO  <fs_item>-tax-tax_detail.
*--------------------------------------------------------------------*

    ENDIF.
  ENDLOOP.

endmethod.

This is a graphical view of the logic implemented on the above code

 

Output on Ariba Network

Here is how the Tax Details will be displayed on the Ariba Network.

 

Here is the cXML output for a PO with Tax data:

<Tax>
	<Money currency="USD">7192.8 </Money>
	<Description xml:lang="en-US">I1</Description>
	<TaxDetail category="sales" percentageRate="6.000 ">
		<TaxableAmount>
			<Money currency="USD">119880.00 </Money>
		</TaxableAmount>
		<TaxAmount>
			<Money currency="USD">7192.8 </Money>
		</TaxAmount>
		<TaxLocation xml:lang="en-US">3306120101</TaxLocation>
		<Description xml:lang="en-US">A/P sales tax, 6%State 1%County 1%City distributed</Description>
	</TaxDetail>
</Tax>

 

Here is the cXML output for a PO with Tax exempt data:

<Tax>
	<Money currency="USD">0 </Money>
	<Description xml:lang="en-US">I0</Description>
	<TaxDetail category="sales" exemptDetail="exempt" percentageRate="0.000 ">
		<TaxableAmount>
			<Money currency="USD">119640.00 </Money>
		</TaxableAmount>
		<TaxAmount>
			<Money currency="USD">0 </Money>
		</TaxAmount>
		<TaxLocation xml:lang="en-US">3306120101</TaxLocation>
		<Description xml:lang="en-US">A/P sales tax, 0%</Description>
	</TaxDetail>
</Tax>

 

 

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply