Financial Management Blogs by SAP
Get financial management insights from blog posts by SAP experts. Find and share tips on how to increase efficiency, reduce risk, and optimize working capital.
cancel
Showing results for 
Search instead for 
Did you mean: 
ThomasPeters
Product and Topic Expert
Product and Topic Expert
2,241

Introduction


A couple of days ago a customer came up with the following question:

Having all data in either SAP ERP Financials or SAP Contract and Lease Management on our SAP ERP system, the question is, how to transfer foreign currency leasing contracts from our old SAP ERP system having no foreign currency depreciation area to our new SAP S/4HANA system. And, in addition to that, how can we reconcile the migrated figures?

My initial idea was, why not use the valuation cashflow and transform it, so it looks like data that is coming from the standard SAP ERP database tables where fixed asset data is stored?

At first sight I thought this should be a no-brainer since all data is recorded somewhere and all what is left to do is some data transformation. However, as often things are different if you start having a closer look...

Assumption


From my experience the basis of any migration approach for fixed assets in SAP ERP is the relevant content of the according database tables, i.e. ANLC, ANEK, ANEP etc. To keep things simple, I solemnly focus on the aspect of leased assets and how to get the data out of the system, in a format that is alike to how data is recorded in the above mentioned database tables.

Since I want to focus on the principle of the data transformation I assume that there is only one depreciation area that needs to be considered.

Since there is no real-time integration between the cash flow in SAP Contract and Lease Management and the fixed assets in SAP ERP data, migrated figures might be not comparable and the possibility of retro-active changes in SAP Contract and Lease Management can make things even worse. On the other hand, the cash flow in SAP Contract and Lease Management is the best we have when it comes to foreign currency figures that are not posted in SAP ERP as part of fixed asset accounting.

In other words, what I present here is not a 100% solution but it is better than just using fixed asset data and performing a foreign currency migration on a defined key date.

Approach


Having a closer at the cashflow data from SAP Contract and Lease Management that generated in a valuation run it shows that despite of the deviating format nearly all necessary information is available to obtain an output similar to what is recorded e.g. in the tables ANLC, ANLP and ANEP in SAP ERP.

All cashflow items are recorded in database table VICECFPROCESS. However, it is much more convenient to use the function module API_RE_CE_GET_CASHFLOW to obtain the cashflow, since setting parameter IF_CFNEWEST to 'X' allows us to get the latest valid cashflow for a specific contract.

Having a closer look at the cashflow the relevant information for fixed assets,

  • APC changes and

  • depreciation,


could easily be identified using the transaction type from SAP Contract and Lease Management. However, the cashflow type, i.e. field CFTYPE, already classifies items as acquisition, i.e. CFTYPE 1, and depreciation, i.e. CFTYPE 2. Having a closer look to both acquisition items also include impairments whereas depreciation only include normal depreciation. The split between real acquisitions and impairments is also easily by using the reference flow type relation, i.e. REFFLOWREL.

Now, that all information is available to transform the cashflow into the structure of both tables ANLP and ANLC, we are set to perform a year-end data migration. To perform a mid-year migration, however, transactional values, i.e. ANEP records, are still to be generated in the required format.

Starting from the cash flow, the goal is to find the original transaction and enrich the according data.

The tricky part about the transactional data is the asset transaction type since in the cashflow we only have the according transaction type from the SAP Contract and Lease Management. Technical there are two options, either go through the logic that is processed when documents are posted in daily business, or try to identify the asset document. Since customizing is likely to change I decided to take the latter approach.

The steps are:

  1. Once an accounting document has been created for a valuation cashflow item from database table VICECFRULE

  2. the according identifier is recorded in this very item and

  3. the linked record in database table VIRADOCITEM can be identified.

  4. Using the reference document number from the header record from database table VIRADOC

  5. the corresponding record in database table ANEK can be looked up and

  6. finally the line item in ANEP with the asset transaction type is identified.


Solution


The import parameters are the company code, the fiscal year - normally the fiscal year of the migration -, the valuation rule and the pseudo-depreciaton area, that is used for the output, in combination with the requested currency.

For productive use the currency will be one where there is no according depreciation area in place, since this is what the whole function module is designed for. For testing purpose, however, I also used the function module in test-mode with the local currency. In this case the exported data should match with what is recorded in the database tables ANLC and ANEP.

So far I was able to test the functionality of the following code in only a few systems, so there might be some glitches left. Especially the impairment has not yet been well tested due to missing data. Beside adaptions on the migration programs are required on your side.
function Z_REFX_GET_ASSET_VALUES.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(IV_BUKRS) TYPE BUKRS
*" REFERENCE(IV_GJAHR) TYPE GJAHR OPTIONAL
*" REFERENCE(IV_CERULE) TYPE RECECERULE
*" REFERENCE(IV_AFABE) TYPE AFABE_D DEFAULT '99'
*" REFERENCE(IV_WAERS) TYPE WAERS
*" EXPORTING
*" REFERENCE(ET_ANLC) TYPE FAA_T_ANLC
*" REFERENCE(ET_ANLP) TYPE AA_T_ANLP
*" REFERENCE(ET_ANEP) TYPE FAA_T_ANEP
*" EXCEPTIONS
*" UNKNOWN_TRANSACTION
*"----------------------------------------------------------------------

data: LT_INTRENO type RE_T_INTRENO,
LT_CE_CASHFLOW type BAPI_RE_T_CE_CASHFLOW_INT,
LS_ANLC type ANLC,
LS_ANLP type ANLP,
LS_ANEP type ANEP,
LV_ASSETOBJ type RECEASOBJNR,
LV_DEPPOST type D,
LV_DETAILVALIDTO type RECADETAILVALIDTO,
LV_ANBTR type ANBTR.

clear: ET_ANLC, ET_ANLP, ET_ANEP.

*
* get relevant contracts
*
concatenate `AN` IV_BUKRS into LV_ASSETOBJ.

LV_ASSETOBJ+6(1) = '%'.

* after the latest update the currency is recorded in the cash flow items
select distinct INTRENO
from VICERULE
where ASSETOBJNR like @LV_ASSETOBJ
and RULECURR eq @IV_WAERS
union
* old valuation runs may have the currency not available in the cash flow
select distinct VICNCN~INTRENO
from VICERULE
inner join VICNCN
on VICERULE~INTRENO eq VICNCN~INTRENO
where VICERULE~ASSETOBJNR like @LV_ASSETOBJ
and VICERULE~RULECURR eq ''
and VICNCN~RECNCNCURR eq @IV_WAERS
order by INTRENO
into table @LT_INTRENO.

* any contract found
check sy-dbcnt gt 0.

* get date of last depreciation run
select AFBLGJ, AFBLPE up to 1 rows
from TABA
into @data(LS_TABA)
where BUKRS eq @IV_BUKRS
order by AFBLGJ descending, AFBLPE descending.

endselect.

concatenate LS_TABA-AFBLGJ LS_TABA-AFBLPE+1(2) '01' into LV_DEPPOST.

LV_DEPPOST = CL_RECA_DATE=>SET_TO_END_OF_MONTH( LV_DEPPOST ).

* get highest open year for asset postings
select single T093C~LGJAHR
from T093C
where BUKRS eq @IV_BUKRS
into @data(LV_LGJAHR).

if SY-SUBRC eq 0.
LV_DETAILVALIDTO(4) = LV_LGJAHR.
LV_DETAILVALIDTO+4(4) = '1231'.
else.
* if not defined select all available values
LV_DETAILVALIDTO = RECA0_DATE-MAX.
endif.

*
* loop through all relevant contracts
*
loop at LT_INTRENO into data(LV_INTRENO).

call function 'API_RE_CE_GET_CASHFLOW'
exporting
* ID_BUKRS =
* ID_RECNNR =
ID_INTRENO = LV_INTRENO
* IO_OBJECT =
* ID_DETAIL_DATA_FROM =
* ID_DETAIL_DATA_TO =
* ID_TERMNO =
ID_CERULE = IV_CERULE
* ID_CFTYPE =
* ID_CFSTATUS =
* IF_CFNEWEST = ABAP_TRUE
importing
ET_CE_CASHFLOW = LT_CE_CASHFLOW
exceptions
ERROR = 1
others = 2.

if SY-SUBRC ne 0.
continue.
endif.

* collect values for each year.
loop at LT_CE_CASHFLOW assigning field-symbol(<LS_CE_CASHFLOW>)
where ASSETOBJNR cp 'AN*'.

LS_ANLC = value #( BUKRS = <LS_CE_CASHFLOW>-ASSETOBJNR+2(4)
ANLN1 = <LS_CE_CASHFLOW>-ASSETOBJNR+6(12)
ANLN2 = <LS_CE_CASHFLOW>-ASSETOBJNR+18(4) ).

* use identifier for the pseudeo 'depreciation area' from import parameter
LS_ANLC-AFABE = IV_AFABE.

LS_ANLC-GJAHR = cond #( when <LS_CE_CASHFLOW>-POSTINGDATE is initial
then <LS_CE_CASHFLOW>-DFAELL(4)
else <LS_CE_CASHFLOW>-POSTINGDATE(4) ).

LV_ANBTR = cond #( when CL_RECDC_FLOW_TYPE=>GET_DETAIL( ID_FLOWTYPE = <LS_CE_CASHFLOW>-BOOK_FLOWTYPE )-SSOLHAB eq 'S'
then - <LS_CE_CASHFLOW>-BBWHR
else <LS_CE_CASHFLOW>-BBWHR ).

case <LS_CE_CASHFLOW>-CFTYPE.

when RECE2_CFTYPE-ACQUISITION.
if <LS_CE_CASHFLOW>-REFFLOWREL eq RECE3_REFFLOWREL-UNPLANNED_DEPRECIATION or
<LS_CE_CASHFLOW>-REFFLOWREL eq RECE3_REFFLOWREL-UNPLANNED_APPRECIATION.
* Impairment
LS_ANLP = corresponding #( LS_ANLC ).
LS_ANLP-AFABER = LS_ANLC-AFABE.
LS_ANLP-PERAF = <LS_CE_CASHFLOW>-DFAELL+4(2).

LS_ANLP-AAFAP = LV_ANBTR.
LS_ANLC-AAFAP = LV_ANBTR.
if <LS_CE_CASHFLOW>-DFAELL le LV_DEPPOST.
LS_ANLP-AAFAG = LS_ANLP-AAFAP.
LS_ANLC-AAFAG = LS_ANLC-AAFAP.
endif.

collect LS_ANLP into ET_ANLP. " collect periodic value changes

else.
* APC change
LS_ANLC-ANSWL = LV_ANBTR.
endif.

* Only transactions in the current are of any interest
if IV_GJAHR is initial or
IV_GJAHR eq <LS_CE_CASHFLOW>-DFAELL(4).

LS_ANEP = corresponding #( LS_ANLC ).
LS_ANEP-BZDAT = <LS_CE_CASHFLOW>-DFAELL.
LS_ANEP-ANBTR = LV_ANBTR.

* get original asset transaction type
select single ANEP~LNRAN, ANEP~BELNR, ANEP~BUZEI, ANEP~BZDAT, ANEP~BWASL
from ANEP inner join ANEK
on ANEP~BUKRS eq ANEK~BUKRS
and ANEP~ANLN1 eq ANEK~ANLN1
and ANEP~ANLN2 eq ANEK~ANLN2
and ANEP~LNRAN eq ANEK~LNRAN
inner join VIRADOC
on VIRADOC~PROCESSID eq ANEK~XBLNR
inner join VIRADOCITEM
on VIRADOC~DOCGUID eq VIRADOCITEM~DOCGUID
inner join TIVCERULECC
on TIVCERULECC~BUKRS eq ANEP~BUKRS
and TIVCERULECC~DEPRAREA eq ANEP~AFABE
where VIRADOCITEM~REFGUID eq @<LS_CE_CASHFLOW>-CFGUID
and ANEP~BUKRS eq @LS_ANLC-BUKRS
and ANEP~ANLN1 eq @LS_ANLC-ANLN1
and ANEP~ANLN2 eq @LS_ANLC-ANLN2
and VIRADOCITEM~OBJNR eq @<LS_CE_CASHFLOW>-ASSETOBJNR
and TIVCERULECC~CERULE eq @IV_CERULE
into ( @LS_ANEP-LNRAN, @LS_ANEP-BELNR, @LS_ANEP-BUZEI, @LS_ANEP-BZDAT, @LS_ANEP-BWASL ).

* skip if no transaction type was found
if SY-SUBRC ne 0.
CONTINUE.
endif.

append LS_ANEP to ET_ANEP.
endif.

when RECE2_CFTYPE-DEPRECIATION.
* Ordinary Depreciation
LS_ANLP = corresponding #( LS_ANLC ).
LS_ANLP-AFABER = LS_ANLC-AFABE.
LS_ANLP-PERAF = <LS_CE_CASHFLOW>-DFAELL+4(2).

LS_ANLP-NAFAP =
LS_ANLC-NAFAP = - LV_ANBTR.

if <LS_CE_CASHFLOW>-DFAELL le LV_DEPPOST.
LS_ANLP-NAFAG = LS_ANLP-NAFAP.
LS_ANLC-NAFAG = LS_ANLC-NAFAP.
endif.

collect LS_ANLP into ET_ANLP. " collect periodic value changes

when others.
* should never happen
raise UNKNOWN_TRANSACTION.
endcase.

collect LS_ANLC into ET_ANLC. " collect value changes

endloop.

endloop.

* ensure values are properly sorted for the periodic summarization
sort ET_ANLP by BUKRS ANLN1 ANLN2 AFABER GJAHR PERAF.

* calculate periodic values
loop at ET_ANLP into LS_ANLP.

loop at ET_ANLP assigning field-symbol(<LS_ANLP>)
where BUKRS eq LS_ANLP-BUKRS
and ANLN1 eq LS_ANLP-ANLN1
and ANLN2 eq LS_ANLP-ANLN2
and AFABER eq LS_ANLP-AFABER
and GJAHR eq LS_ANLP-GJAHR.

if <LS_ANLP>-PERAF gt LS_ANLP-PERAF.
add LS_ANLP-NAFAZ to -NAFAG.
endif.
add LS_ANLP-NAFAZ to <LS_ANLP>-NAFAP.
endloop.

endloop.

* calculate cumulated values
loop at ET_ANLC into LS_ANLC.

loop at ET_ANLC assigning field-symbol(<LS_ANLC>)
where BUKRS eq LS_ANLC-BUKRS
and ANLN1 eq LS_ANLC-ANLN1
and ANLN2 eq LS_ANLC-ANLN2
and AFABE eq LS_ANLC-AFABE
and GJAHR gt LS_ANLC-GJAHR.

add LS_ANLC-ANSWL to <LS_ANLC>-KANSW.
add LS_ANLC-NAFAP to <LS_ANLC>-KNAFA.
add LS_ANLC-AAFAP to <LS_ANLC>-KAAFA.

endloop.

endloop.

* restrict values to selected fiscal year
if IV_GJAHR is not initial.
delete ET_ANLC where GJAHR ne IV_GJAHR.
endif.

sort: ET_ANLC, ET_ANLP, ET_ANEP.

endfunction.

Conclusion


So, what do we get calling the above function module?

What we have to think of is how in general in fixed asset accounting transactional figures are migrated, i.e. extracting data from the database tables ANLC, ANLP and ANEP. All what there is to do is to call the above function module using correct import parameters, i.e. the company code, the fiscal year of the migrated figures, the name of the valuation rule, e.g. IFRS16, a currency - likely that of the controlling area, and a deprecation area that must not be part of the chart of depreciation.

The output is three tables, i.e. ANLC, ANLP and ANEP, that just needs to be merged to database extract of theses tables. Focusing on the existing migration programs the existing workaround to generated foreign currency values must be omitted for all fixed assets where there is data available from SAP Contract and Lease Management.

Since the assumption was to only have one depreciation area we are done and the migration does respect both,

  • local currency values that are - as before - extracted from the database tables ANLC, ANLP, ANEP, and some others, and

  • foreign currency values that - if available - are coming from the SAP Contract and Lease Management, or - as before - are determined elsewise.


I'm curious about your experience in the migration of foreign currency leasing contracts.