Predict Tax Classification Layout on Master Data Screens

Jimbo's picture

The ability to predict what fields will appear on what screens during batch input prevents the batch from failing when it stops to force the user to populate a mandatory field or errors out in background processing because an expected field isn't on the screen. Tax Classifications are some of these fields and predicting how they will appear on the billing document tab in XD01 or on the Sales Org 1 tab of MM01 is easier than one might think.

Failing to correctly predict the country codes that will appear while processing the batch will cause the transaction to throw a "Check tax classification; maintenance is incomplete Message no. F2269" error. This error can occur when updating a Master Data record that was fully maintained previously, but is now incomplete due to a configuration change.

It is not recommended to update tax information with recording, but predicting the order of the countries is very easy. It appears to be alphabetical based on the ISO code.

SAP maintains a link between Plants and Sales Org/Distribution channels in the TVKWZ table. When preparing the tax screens for Customer Master and Material Master, the system takes the Sales Org and Distribution Channel combinations and uses that information to find all of the Plants (distribution points) that can be used. The list of countries comes from those plants which are maintained in the T001W table.

The simplest way to predict what ALAND values will be in the list is to step through a join of TVKWZ and T001W filtered by VKORG and VTWEG ordered and grouped by LAND1. The example below is from an LSMW ojbect calling the XD01 transaction to copy Sales Org data from one duplicate Customer Master (the victim) to another Customer Master (the survivor).

Proportional Unit of MeasureCorrection
The red source code below was written for a client with customized tax software so that there was just a singular Tax Category (TATYP) associated with each Country Code and every Sales Area was associated with the same five Country Codes. It is overly simple and worked, but is incomplete because the XD02 transaction shows all of the Country Codes associated with all of the Sales Areas associated with the Customer Master and most SAP implementations have multiple Tax Categories.

The green code below was written for a client that restricted access to the RFBIDE00 program, but allowed for Batch Input Recording. It uses a list of Tax Classification fields to apply new values specifically to Customer Masters according to Country Code and Tax Category.


data: lTVKWZ like TVKWZ, lT001W like T001W, lTSTL like TSTL,
      lKNVV like KNVV, lKNVI like KNVI, lKNA1 like KNA1.
data: nCount type i, nRow type i, lALAND like KNVI-ALAND.

nCount = 0.
nRow = 0.
select T001W~LAND1 into lALAND
 from TVKWZ join T001W on ( TVKWZ~WERKS eq T001W~WERKS )
 join KNVV
  on ( TVKWZ~VKORG eq KNVV~VKORG and TVKWZ~VTWEG eq KNVV~VTWEG )
 where KNVV~KUNNR eq XD02T-KUNNR
 group by T001W~LAND1
 order by T001W~LAND1.

  select * from TSTL into lTSTL
   where TALND eq lALAND
   order by LFDNR.
    add 1 to nCount.
    if lTSTL-TALND eq XD02S-ALAND and lTSTL-TATYP eq XD02S-TATYP.
      "Found the line where this value will be.
      nRow = nCount.
    endif.
  endselect.
endselect.

case nRow.
  when 0.
    write: / XD02S-KUNNR, XD02S-ALAND, XD02S-TATYP,
     'Did not find this combination for Customer Master.'.
    skip_transaction.
  when 1. XD02T-TAXKD_01 = XD02S-TAXKD.
  when 2. XD02T-TAXKD_02 = XD02S-TAXKD.
  when 3. XD02T-TAXKD_03 = XD02S-TAXKD.
  when 4. XD02T-TAXKD_04 = XD02S-TAXKD.
  when 5. XD02T-TAXKD_05 = XD02S-TAXKD.
  when 6. XD02T-TAXKD_06 = XD02S-TAXKD.
  when 7. XD02T-TAXKD_07 = XD02S-TAXKD.
  when 8. XD02T-TAXKD_08 = XD02S-TAXKD.
  when 9. XD02T-TAXKD_09 = XD02S-TAXKD.
  when 10. XD02T-TAXKD_10 = XD02S-TAXKD.
  when 11. XD02T-TAXKD_11 = XD02S-TAXKD.
  when 12. XD02T-TAXKD_12 = XD02S-TAXKD.
  when 13. XD02T-TAXKD_13 = XD02S-TAXKD.
  when 14. XD02T-TAXKD_14 = XD02S-TAXKD.
  when 15. XD02T-TAXKD_15 = XD02S-TAXKD.
  when 16. XD02T-TAXKD_16 = XD02S-TAXKD.
  when 17. XD02T-TAXKD_17 = XD02S-TAXKD.
  when 18. XD02T-TAXKD_18 = XD02S-TAXKD.
  when 19. XD02T-TAXKD_19 = XD02S-TAXKD.
  when 20. XD02T-TAXKD_20 = XD02S-TAXKD.
endcase.

"Ensure that the Customer Master isn't already up-to-date.
select * from KNVI into lKNVI
 where KUNNR eq XD02S-KUNNR
   and ALAND eq XD02S-ALAND
   and TATYP eq XD02S-TATYP
   and TAXKD eq XD02S-TAXKD.
  if p_verbos eq 'X'.
    write: / XD02S-KUNNR, XD02S-ALAND, XD02S-TATYP, XD02S-TAXKD,
     'Customer Master already up-to-date.'.
  endif.
  skip_transaction.
endselect.

select * from KNA1 into lKNA1 where KUNNR eq XD02S-KUNNR.
  if lKNA1-KTOKD eq '0002'.  "No taxes on ship-to's.
    write: / XD02S-KUNNR, XD02S-ALAND, XD02S-TATYP, XD02S-TAXKD,
     'Ship-to Customer Masters get no Tax Classification data.'.
    skip_transaction.
  endif.
endselect.


"What countries are the plants assocated with this VKORG/VTWEG?
select T001W~LAND1 into BKNVI-ALAND
 from TVKWZ join T001W on ( TVKWZ~WERKS eq T001W~WERKS )
 where TVKWZ~VKORG eq BKN00-VKORG
   and TVKWZ~VTWEG eq BKN00-VTWEG
 group by T001W~LAND1
 order by T001W~LAND1.
  select single TATYP TAXKD from KNVI
   into corresponding fields of BKNVI
   where KUNNR eq p_Surviv
     and ALAND eq BKNVI-ALAND.
  if sy-subrc eq 0. "The Customer Master already has this.
    "Do nothing--the Customer Master already has a record
    "for this country.
  else.
    "The victim should have a record for this country.
    select single TATYP TAXKD from KNVI
     into corresponding fields of BKNVI
     where KUNNR eq p_Victim
       and ALAND eq BKNVI-ALAND.
    if sy-subrc ne 0. "Not from the survivor either.
      "Predict the tax category that SAP will expect . . .
      select single TATYP from TSTL into BKNVI-TATYP
       where TALND eq BKNVI-ALAND.
      "Use the most popular value based on combination of
      "country codes for Customer Master and Distribution Point.
      loop at it_taxOccur
       where LAND1 eq sKNA1-LAND1 "Survivor and victim's country.
         and ALAND eq BKNVI-ALAND
         and TATYP eq BKNVI-TATYP.
        BKNVI-TATYP = it_taxOccur-TATYP.
        BKNVI-TAXKD = it_taxOccur-TAXKD.
      endloop.
    endif.
    transfer_record.
  endif.
endselect.

In this example, the combination of Sales Org 1008 and Distribution Channel 99 is associated with Plants in five different countries including the US, but Customer Master 0009053912 already has a tax category value for country code US. The program does not provide a value for this field as the batch does not need it.

In the end, the Customer Master is extended to Sales Org 1008, Distribution Channel 99 without error. Automating the prediction of these tax fields eliminates the need to retool the LSMW object as the configuration changes and allows for it to be recycled over many projects.

Note: It is essential to get the values that will be used to populate these fields from the functional group responsible, or to at least get some rules that can be used to populate these fields. In this example, the finance group was fine with intuiting the values to be populated in the TAXKD fields based on what values are most commonly used in Customer Masters that already exist in the system.

A custom internal table is filled using a joined select and then sorted to find the most popular values in the system based on the combination of Customer Master country code and the Distribution Point country code. The loop at it_taxOccur code above causes the TAXKD field to be populated with the most common value for the combination of country codes.

data: begin of it_taxOccur occurs 0,
        LAND1 like KNA1-LAND1,
        ALAND like KNVI-ALAND,
        TATYP like KNVI-TATYP,
        TAXKD like KNVI-TAXKD,
        Occurs type i,
      end of it_taxOccur.

select KNA1~LAND1 KNVI~ALAND KNVI~TATYP KNVI~TAXKD count(*)
 into table it_taxOccur
 from KNA1 join KNVI on ( KNA1~KUNNR eq KNVI~KUNNR )
 group by KNA1~LAND1 KNVI~ALAND KNVI~TATYP KNVI~TAXKD.
sort it_taxOccur by Occurs. "Most popular values are last.

Material Masters

The same trick to populate an internal table with most popular values can be used when extending materials to new combinations of Sales Org and Distribution Channel. The code is very similar to the same code for Customer Masters.

Insert this short delcaration in the GLOBAL_DATA section of the LSMW. This table will be used to hold values for combinations of Material Type and Country code.

data: lMVKE like MVKE, lKNVI like KNVI, lMARA like MARA.
data: begin of it_taxOccur occurs 0,
        MTART like MARA-MTART,
        ALAND like MLAN-ALAND,
        TAXM1 like MLAN-TAXM1,
        Occurs type i,
      end of it_taxOccur.

In the BEGIN_OF_PROCESSING section add this snippet of code. It takes a few seconds to fill the internal table with the most popular values for combinations of Material Type and Country Code.

select MARA~MTART MLAN~ALAND MLAN~TAXM1 count(*)
 into table it_taxOccur
 from MARA join MLAN on ( MARA~MATNR eq MLAN~MATNR )
 where TAXM1 ne ''
 group by MARA~MTART MLAN~ALAND MLAN~TAXM1.
sort it_taxOccur by Occurs.  "Higest values are last.

Finally, insert this code in the BMMH2 section of the LSMW object for Material Master. It is important that the source data be related to the BMMH2 Material Master: Country Data for Batch Input (from 2nd Cty) structure for the RMDATIND program (Object 0020, Method 0000 in a Standard Batch/Direct Input LSMW object).

select T001W~LAND1 into BMMH2-ALAND
 from TVKWZ join T001W on ( TVKWZ~WERKS eq T001W~WERKS )
 where TVKWZ~VKORG eq BMM00-VKORG
   and TVKWZ~VTWEG eq BMM00-VTWEG
 group by T001W~LAND1
 order by T001W~LAND1.
  select single TAXM1 from MLAN into BMMH2-TAXM1
   where MATNR eq BMM00-MATNR
     and ALAND eq BMMH2-ALAND.
  if sy-subrc ne 0.
    BMMH2-TAXM1 = '1'.  "Default.
    select single TATYP from TSTL into BMMH2-TATY1
     where TALND eq BMMH2-ALAND.
    loop at it_taxOccur
     where MTART eq lMARA-MTART
       and ALAND eq BMMH2-ALAND.
      BMMH2-TAXM1 = it_taxOccur-TAXM1.
    endloop.
    transfer_record.
  endif.
endselect.
skip_record. "Don't transfer anything after this.

That's all there is to populating missing tax codes while extending or creating Material Masters. The rest is just regular mapping and conversion.

Dilbert tax

Programming Language: 
ABAP