According to the blog series (https://blogs.sap.com/2021/03/03/be-prepared-for-the-upgrade-2105-clean-up-your-rap-business-objects-to-adapt-them-to-the-upcoming-changes) which describes about cleaning up our RAP code before the update 2105 , I would like to point out some of my suggestions about the solutions described in the blog above (How I would tackle the same problem ).
NB: The solutions Mentioned in the post are not suggested for long run , but if you are affected by the recent update , you could use this solution as a temporary fix.
Using Data Type CURR :
It is clearly mentioned in the post that :
The decimal shift logic for currency amounts of data type
CURR only works in a consistent way
across different channels and consumption frameworks if the data type for currency amounts is
CURR with two decimals. That’s why, RAP only allows you to use the data type
it is defined with two decimals.
If you use this data type with another number of decimals, you will get an error on creating a
new service binding. If you already have an OData service that uses data type
CURR with more
or less than two decimals, you will now get a metadata error, and you will see an error message
in your service binding.
And the Solution was to :
Check if you can avoid using fields with data type
CURR that have more or less than two decimals in the data model for your RAP service. If there is no other way in your RAP Service than using the data type with a number of decimals unlike two, adjust the number of decimals in the CDS view that uses those data elements by casting the element to data type
- Cast an element Amount_m with data type
CURR(x,m)(where m > 2) to
CURR(x,2)with the following casting logic:
cast( cast( Amount_m as abap.dec(x,m) ) * 1000 as abap.curr(x,2) ) as CastAmount_m,
The data type has to be cast to type
abap.dec(x,m)(packed number) first, before it can be cast back to a currency amount type to avoid warnings for casting to an identical type. Once cast to
abap.dec, multiply the amount with a multiple of 10 (depending on the number of decimals of the original type) to get the amount with two decimals without losing digits.
Cast an element Amount_1 with data type
CURR(x,2) with the following casting logic:
cast( cast( division( cast( Amount_1 as abap.dec(16,1) ), 10, 1 ) as abap.dec(16,2) ) as abap.curr(16,2) ) as CastPrice1,
While I was using the same solution , ( I have a Curr(12,3) currency maintained at table and it is converted to Curr(12,2) using the above solution ) :
- The original value stored in the table is changed in the CDS due to the division and Multiplication in the CAST (), which is not acceptable in some cases since the exposed entity (CDS) may not be consumed in a Fiori App but used by other Entities ,May be a third party application consuming our service and obliviously they would have to convert the value back to the original value with more than 2 decimal places . So converting each currency field in the same Entity is not possible in case the third party app is already deployed and working (Revisiting 100+ services and converting each currency field is just not an option).
- Even though the Fiori could display the values with correct number of decimals using the cuky field used along the currency (Their decimal places are defined in database table TCURX), while the Fiori app sends the data to the backend the value will be having 2 decimal places. As the meta data states the field now has only 2 Decimal Places (Due to the CAST () statement) , while looking at the data maintained at the DB table and data returned from the Fiori app they wont match even if there is no change been done .So at the behavior implementation level I would have to convert it back. If you are having a 100+ CDS entity and having at least one currency field in each CDS ,Try imagining converting each currency field at the behavior class at create and update .
- For some functional requirement (an odd requirement) , each currency field should have 3 decimal places because it will be used in an external entity without considering the related cuky field .
Due to the above mentioned problems I was forced to keep my currency values with three decimal places , but update 2105 forces me to convert them to values with two decimal places .
and My solution was like :
cast( Amount_m as abap.dec(12,3) ) as Amount_m,
Making the currency field decimal and keeping the same name saved me from rewriting:
- Conversions to be done Fiori app.
- Conversions to be done at third party apps.
- Conversions at the behavior implementation.
Cross checked whether this change had any effect on the deployed and running code as well as the data flow , behavior implementation and tables , no data is being changed at any level and no conversion is to be done at any point.
NB: The solutions Mentioned in the post are not suggested for long run , but if you are affected by the recent update , you could use this solution as a temporary fix . The solution actually worked for me 🙂 .
Please Correct me in the comments , I have made any mistakes . Thanks in advance for the correction.