Spend Management Blogs by Members
Check out community member blog posts about spend management and SAP Ariba, SAP Fieldglass, and SAP Concur solutions. Post or comment about your experiences.
cancel
Showing results for 
Search instead for 
Did you mean: 
wagener-mark
Contributor
This Blog is inspired by BSAO – Mapping – Adding Tax Details on PO items by joe.dutra (thanks very much for sharing it and for your offer of assistance).

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

This development was done for German tax scenario. Error handling could be further enhanced (exception handling of standard methods). It is not tested for service lines and all other scenarios. Moreover standard SAP FM are used for convesion of currency amount (string) to decimal. Please be aware that these FM could de deleted by SAP during upgrades.

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 Vendors –> Define Mapping Settings for Billing Documents –> MAP SAP ERP SD Tax Code to cXML Tax Category


Development


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

Method
method invc_itm_map_tax_code.

types: begin of ty_condition,
knumv type konv-knumv,
kposn type konv-kposn,
kschl type konv-kschl,
kawrt type konv-kawrt,
kbetr type konv-kbetr,
waers type konv-waers,
mwsk1 type konv-mwsk1,
kwert type konv-kwert,
end of ty_condition.

data t_condition type table of ty_condition.
field-symbols <fs_condition> type ty_condition.

field-symbols <fs_item> type line of arberp_xinvc_t_dtl_item.

data mo_config_instance type ref to if_arberp_config_access.
data mo_helper_out_instance type ref to if_arberp_helper_int_out.

data ls_ext_tax_category type arberp_s_taxc_sd.
data ls_taxdetail type line of arberp_xinvc_t_tax_detail.
data lf_tax_rate type msatz_f05l.
data ls_t001 type t001.
data lc_tax_desc type text1_007s.
data lv_tax_rate_decimals type i.
data ls_kposn type konv-kposn.
data ls_gross_amount type konv-kwert.
data ls_net_amount type konv-kwert.

data: ls_content type string,
ls_xml_lang type string.

"Initialize helpers
mo_config_instance = cl_arberp_config_factory=>get_instance( ).

call method cl_arberp_helper_factory_int=>get_instance_helper_int_out
importing
eo_instance = mo_helper_out_instance.

"get tax conditions
select knumv
kposn
kschl
kawrt
kbetr
waers
mwsk1
kwert
from konv
into corresponding fields of table t_condition
where knumv = pi_condition_no
and kschl = 'MWST'.

if sy-subrc is not initial.
" error handling here
if 1 = 2. message e021(zov_ariba). endif. "#EC MG_MISSING "for where-used-list
zov_cl_utilities=>add_message_static_bapi( exporting pi_id = 'ZOV_ARIBA'
pi_number = '021'
pi_type = 'E'
pi_message_v1 = pi_condition_no
changing pie_t_message = pie_t_messages ).
pie_skip_sending = abap_true.
endif.

" Get Company Country
call function 'FI_COMPANY_CODE_DATA'
exporting
i_bukrs = pi_company_code
importing
e_t001 = ls_t001
exceptions
system_error = 1.

if sy-subrc is not initial.
" error handling here
if 1 = 2. message e022(zov_ariba). endif. "#EC MG_MISSING "for where-used-list
zov_cl_utilities=>add_message_static_bapi( exporting pi_id = 'ZOV_ARIBA'
pi_number = '022'
pi_type = 'E'
pi_message_v1 = pi_company_code
changing pie_t_message = pie_t_messages ).
pie_skip_sending = abap_true.
endif.

"create <TAX> for each item
loop at pie_item_detail assigning <fs_item>.
"use filled reference field
clear ls_kposn.
ls_kposn = <fs_item>-invoice_detail_item_reference-line_number. "<fs_item>-invoice_detail_item_reference-line_number has no "real" initial value,
"therefore "if <fs_item>-invoice_detail_item_reference-line_number is initial" did not work
if ls_kposn is initial.
ls_kposn = <fs_item>-invoice_line_number.
endif.

"get corresponding tax condition record for this item
read table t_condition
assigning <fs_condition>
with key kposn = ls_kposn.

if sy-subrc = 0.
"Get the Tax category from the configuration -> see CL_ARBERP_VBRK_INVC_OUT-map_invc_summary
"lines 11139 - 1155
mo_config_instance->get_sd_invc_tax_category(
exporting
iv_customer_id = pi_payer "KUNRG
iv_tax_code = <fs_condition>-mwsk1
iv_country_code = pi_country
importing
es_ext_tax_category = ls_ext_tax_category
).

if ls_ext_tax_category is initial.
"error
if 1 = 2. message e102(arberp_map_sd). endif. "#EC MG_MISSING "for where-used-list
zov_cl_utilities=>add_message_static_bapi( exporting pi_id = if_arberp_t100_map_sd_c=>gc_msg_class_name
pi_message_v1 = <fs_condition>-mwsk1
pi_number = if_arberp_t100_map_sd_c=>gc_msgno_102
pi_type = 'E'
changing pie_t_message = pie_t_messages ).
pie_skip_sending = abap_true.
endif.

if <fs_condition>-waers is initial.
"take it from pi_currency
<fs_condition>-waers = pi_currency.
endif.

"Set tax-rate and adjust decimals if necessary
lf_tax_rate = <fs_condition>-kbetr.

" IDOC logic: currently wrong amount of decimals, work-around and change from 2 to 3 decimal places
" adopted from see CL_ARBERP_VBRK_INVC_OUT-map_invc_summary lines 1160 - 1164
describe field <fs_condition>-kbetr decimals lv_tax_rate_decimals.
if lv_tax_rate_decimals eq 2.
divide lf_tax_rate by 10.
endif.

"Get Tax description -> adopted from see CL_ARBERP_VBRK_INVC_OUT-map_invc_summary lines 1211 - 1219
call method mo_helper_out_instance->get_tax_description
exporting
iv_comp_code = pi_company_code
iv_tax_code = <fs_condition>-mwsk1
iv_langu = pi_salesorg_lang
importing
ev_tax_code_description = ls_content
ev_tax_code_xml_lang = ls_xml_lang.

"*--------------------------------------------------------------------*
"* Map the tax rate and category to the cxml
"*--------------------------------------------------------------------*
clear ls_taxdetail.
" Tax Amount
<fs_item>-tax-money-currency = <fs_condition>-waers.
<fs_item>-tax-money-content = <fs_condition>-kwert.

"convert gross_amount (string) to currency
call function 'HRCM_STRING_TO_AMOUNT_CONVERT'
exporting
string = <fs_item>-gross_amount-money-content
decimal_separator = '.'
importing
betrg = ls_gross_amount
exceptions
convert_error = 1
others = 2.
if sy-subrc <> 0.
if 1 = 2. message e000(zov_ariba). endif. "#EC MG_MISSING "for where-used-list
zov_cl_utilities=>add_message_static_bapi( exporting pi_id = 'ZOV_ARIBA'
pi_message_v1 = sy-msgid
pi_message_v2 = sy-msgno
pi_message_v3 = sy-msgv1
pi_message_v4 = sy-msgv2
pi_number = '000'
pi_type = sy-msgty
changing pie_t_message = pie_t_messages ).
pie_skip_sending = abap_true.
endif.

"convert net_amount (string) to currency
call function 'HRCM_STRING_TO_AMOUNT_CONVERT'
exporting
string = <fs_item>-net_amount-money-content
decimal_separator = '.'
importing
betrg = ls_net_amount
exceptions
convert_error = 1
others = 2.
if sy-subrc <> 0.
if 1 = 2. message e000(zov_ariba). endif. "#EC MG_MISSING "for where-used-list
zov_cl_utilities=>add_message_static_bapi( exporting pi_id = 'ZOV_ARIBA'
pi_message_v1 = sy-msgid
pi_message_v2 = sy-msgno
pi_message_v3 = sy-msgv1
pi_message_v4 = sy-msgv2
pi_number = '000'
pi_type = sy-msgty
changing pie_t_message = pie_t_messages ).
pie_skip_sending = abap_true.
endif.

add <fs_condition>-kwert to ls_gross_amount.
<fs_item>-gross_amount-money-content = ls_gross_amount. "also add tax-amount to gross-amount
add <fs_condition>-kwert to ls_net_amount.
<fs_item>-net_amount-money-content = ls_net_amount. "also add tax-amount to net-amount

if pi_purpose = 'lineLevelCreditMemo'. "set negative-sign as this is a Credit Memo
multiply <fs_item>-tax-money-content by -1.
endif.
" SAP Tax Code
<fs_item>-tax-description-xml_lang = ls_xml_lang.
<fs_item>-tax-description-content = <fs_condition>-mwsk1.
" Category and rate
ls_taxdetail-category = ls_ext_tax_category-ext_tax_type.
ls_taxdetail-percentage_rate = lf_tax_rate.
"TaxPointDate
"TaxPointDate is mandatory when tax is VAT. The date when the VAT becomes due.
"Ariba checks only the presence, so you can use the invoice date.
"create timestamp, use invoice date
mo_helper_out_instance->convert_date_to_iso8601(
exporting iv_date = pi_invoice_date
* iv_time = sy-timlo "no need to provide time, system uses default time
importing ev_date_iso = ls_taxdetail-tax_point_date ).
" Taxable Amount
if lf_tax_rate <> 0.
ls_taxdetail-taxable_amount-money-content = <fs_condition>-kawrt.
if pi_purpose = 'lineLevelCreditMemo'. "set negative-sign as this is a Credit Memo
multiply ls_taxdetail-taxable_amount-money-content by -1.
endif.
endif.
ls_taxdetail-taxable_amount-money-currency = <fs_condition>-waers.
" Tax Amount
ls_taxdetail-tax_amount-money-content = <fs_condition>-kwert.
if pi_purpose = 'lineLevelCreditMemo'. "set negative-sign as this is a Credit Memo
multiply ls_taxdetail-tax_amount-money-content by -1.
endif.
ls_taxdetail-tax_amount-money-currency = <fs_condition>-waers.
" 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 = ls_xml_lang.

" description
call function 'TAX_CODE_TEXT_GET'
exporting
i_langu = ls_t001-spras
i_bukrs = pi_company_code
i_mwskz = <fs_condition>-mwsk1
importing
e_text1 = lc_tax_desc
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 = ls_xml_lang.
else.
" error handling here
if 1 = 2. message e024(zov_ariba). endif. "#EC MG_MISSING "for where-used-list
zov_cl_utilities=>add_message_static_bapi( exporting pi_id = 'ZOV_ARIBA'
pi_message_v1 = ls_t001-spras
pi_message_v2 = pi_company_code
pi_message_v3 = <fs_condition>-mwsk1
pi_number = '024'
pi_type = 'E'
changing pie_t_message = pie_t_messages ).
pie_skip_sending = abap_true.
endif.
"add tax information to item
append ls_taxdetail to <fs_item>-tax-tax_detail.
"--------------------------------------------------------------------*
else.
"error -> could not create tax for this item, as no tax condition record was
"found for this item
if 1 = 2. message e023(zov_ariba). endif. "#EC MG_MISSING "for where-used-list
zov_cl_utilities=>add_message_static_bapi( exporting pi_id = 'ZOV_ARIBA'
pi_message_v1 = ls_kposn
pi_message_v2 = pi_condition_no
pi_number = '023'
pi_type = 'E'
changing pie_t_message = pie_t_messages ).
pie_skip_sending = abap_true.
endif.
endloop.
endmethod.

 

Signature
 methods invc_itm_map_tax_code
importing pi_invoice_no type vbeln
pi_invoice_date type vbrk-fkdat
pi_purpose type string
pi_payer type kunrg
pi_condition_no type knumv
pi_country type landtx
pi_currency type waerk
pi_company_code type bukrs
pi_salesorg_lang type spras
changing pie_item_detail type arberp_xinvc_t_dtl_item
pie_t_messages type bapirettab
pie_skip_sending type xfeld.

For the missing method  ADD_MESSAGE_STATIC_BAPI of class ZOV_CL_UTILITIES you can use:
method ADD_MESSAGE_STATIC_BAPI.
data wa_message type line of BAPIRETTAB.

clear wa_message.

wa_message-id = pi_id.
wa_message-type = pi_type.
wa_message-number = pi_number.
wa_message-message_v1 = pi_message_v1.
wa_message-message_v2 = pi_message_v2.
wa_message-message_v3 = pi_message_v3.
wa_message-message_v4 = pi_message_v4.

append wa_message to pie_t_message.
endmethod.

Result


Here is the cXML output for an Invoice with Tax data:
<Tax>
<Money currency="EUR">475.00 </Money>
<Description xml:lang="de">A1</Description>
<TaxDetail category="vat" percentageRate="19.000 " taxPointDate="2018-01-25T12:00:00+01:00">
<TaxableAmount>
<Money currency="EUR">2500.00 </Money>
</TaxableAmount>
<TaxAmount>
<Money currency="EUR">475.00 </Money>
</TaxAmount>
<Description xml:lang="de">Ausgangssteuer 19%</Description>
</TaxDetail>
</Tax>

Make sure to also set
<InvoiceDetailLineIndicator isTaxInLine="yes"/>

on <InvoiceDetailRequestHeader> level!
1 Comment