The Function module in SAP - FAGL_ACCOUNT_ITEMS_GL_API output's the data in 2 decimal places.
In Muscat (Oman) client uses 3 places after decimal to view amount.
How to achieve this here?
Thanks and Regards
CA. Nilesh Zambhuria
SAP always stores the posting amounts with two decimals. If the posting currency has three decimal places (you can check in table TCURX, field CURRDEC or in transaction OY04) it will be like this:
posting amount: 1.234
but in the database will be stored like: 12.34
Similiarly if a currency has no decimal places (like HUF for example), than:
posting amount: 100
in the database: 1.00
SAP will handle this inside SAP (standard transactions, ALV lists, etc.) properly (as long as the number of decimal places was set up correctly - it is not possible to change it in a live SAP system!).
In your case the function module will give back values with two decimal places, like 12.34 But in case the currency has three decimal playes (like OMR), you have to understand it like 1.234.
Related
Why is Power BI doing this to my values? (see video below) It is setting them to 1.00 in the visualization even though they are 99.61, 99.74, etc. in the query table. What is happening? I have tried setting the type to percentage, decimal, and fixed decimal and the same thing always happens. Also the values are set to "don't summarize" in the visualization table.
https://www.youtube.com/watch?v=bNHzelJTW7g&feature=youtu.be
See video to understand what I'm talking about.
Here are a couple screenshots from the video:
In your query editor you have the following values:
99.79%, 99.91%, 99.74%, 99.82%, 99.74%, 99.61%
These are in percent format as is clear by the "%" symbol next to your column name.
When you close and load, you put in in a table which is not formatted as a percent and shows only two decimal places. When rounded to two decimal places the value rounds up to 1.00 for all of these. (Note that your total rounds to 5.99 though.)
If you want them formatted as percentages, use the modeling tab to set the format for the column. (The format you set in the query editor doesn't necessarily carry through to your visualizations.)
Click on your visual, then, in Format visual, go to call-out value and change display units to none and change Value decimal places to the amount of decimals you need.
I am working on authorize.net php API and I found a problem there. I am sending $45.347 as amount value but it is rounding off to 2 decimal points($45.35). Is there any way to show the 3 decimal value?
According to the documentation for the advanced integration method (AIM) section on page 22 for the x_amount field only two decimal places are supported.
You must round your amount before submitting the transaction.
x_amount Value: Amount of the transaction.
Format: 15 digit-maximum, with a decimal point (no dollar symbol). For
example, 8.95.
Notes: This is the total amount and must include tax, shipping, and any
other charges.
Seems like Money type is discouraged as described here.
My application needs to store currency, which datatype shall I be using? Numeric, Money or FLOAT?
Your source is in no way official. It dates to 2011 and I don't even recognize the authors. If the money type was officially "discouraged" PostgreSQL would say so in the manual - which it doesn't.
For a more official source, read this thread in pgsql-general (from just this week!), with statements from core developers including D'Arcy J.M. Cain (original author of the money type) and Tom Lane:
Related answer (and comments!) about improvements in recent releases:
Jasper Report: unable to get value for field 'x' of class 'org.postgresql.util.PGmoney'
Basically, money has its (very limited) uses. The Postgres Wiki suggests to largely avoid it, except for those narrowly defined cases. The advantage over numeric is performance.
decimal is just an alias for numeric in Postgres, and widely used for monetary data, being an "arbitrary precision" type. The manual:
The type numeric can store numbers with a very large number of digits.
It is especially recommended for storing monetary amounts and other
quantities where exactness is required.
Personally, I like to store currency as integer representing Cents if fractional Cents never occur (basically where money makes sense). That's more efficient than any other of the mentioned options.
Numeric with forced 2 units precision. Never use float or float like datatype to represent currency because if you do, people are going to be unhappy when the financial report's bottom line figure is incorrect by + or - a few dollars.
The money type is just left in for historical reasons as far as I can tell.
Take this as an example: 1 Iranian Rial equals 0.000030 United States Dollars. If you use fewer than 5 fractional digits then 1 IRR will be rounded to 0 USD after conversion. I know we're splitting rials here, but I think that when dealing with money you can never be too safe.
Your choices are:
bigint : store the amount in cents. This is what EFTPOS transactions use.
decimal(12,2) : store the amount with exactly two decimal places. This what most general ledger software uses.
float : terrible idea - inadequate accuracy. This is what naive developers use.
Option 2 is the most common and easiest to work with. Make the precision (12 in my example, meaning 12 digits in all) as large or small as works best for you.
Note that if you are aggregating multiple transactions that were the result of a calculation (eg involving an exchange rate) into a single value that has business meaning, the precision should be higher to provide a accurate macro value; consider using something like decimal(18, 8) so the sum is accurate and the individual values can be rounded to cent precision for display.
Use a 64-bit integer stored as bigint
Store in the small currency unit (cents) or use a big multiplier to create larger integers if cents are not granular enough. I recommend something like micro-dollars where dollars are divided by 1 million.
For example: $5,123.56 can be stored as 5123560000 microdollars.
Simple to use and compatible with every language.
Enough precision to handle fractions of a cent.
Works for very small per-unit pricing (like ad impressions or API charges).
Smaller data size for storage than strings or numerics.
Easy to maintain accuracy through calculations and apply rounding at the final output.
I keep all of my monetary fields as:
numeric(15,6)
It seems excessive to have that many decimal places, but if there's even the slightest chance you will have to deal with multiple currencies you'll need that much precision for converting. No matter what I'm presenting a user, I always store to US Dollar. In that way I can readily convert to any other currency, given the conversion rate for the day involved.
If you never do anything but one currency, the worst thing here is that you wasted a bit of space to store some zeroes.
Use BigInt to store currency as a positive integer representing the monetary value in the smallest currency unit (e.g., 100 cents to store $1.00 or 100 to store ¥100 (Japanese yen, a zero-decimal currency). This is what Stripe does--one the most important financial service companies for global ecommerce.
Source: see "Zero-decimal currencies" at https://stripe.com/docs/currencies
This is not a direct answer, but an example of why float is not the best data type for currency.
Because of the way floating point is represented internally, it is more susceptible to round off errors.
In our own decimal system, you’ll get round off errors whenever you divide by anything other than 2 or 5, which are the factors of 10. In binary, it’s only 2 and not 5, so even “clean” decimals, such as 0.2 (1/5) are at risk.
You can see this if you try the following:
select
0.1::float + 0.2::float as floats, -- 0.30000000000000004
0.1::numeric + 0.2::numeric as numerics --- 0.3
;
That’s the sort of thing that drives auditors round the bend.
My personal recommendation is decimal with the precision according to your needs. Decimal with precision = 0 can be the option if you want to store the integer number of currency minor units (e.g. cents) and you have troubles handling decimals in your programming language.
To find out the needed precision you need to consider the following:
Types of currencies you support (they can have different number of decimals). Cryptocurrencies have up to 18 decimals (ETH). The number of decimals can change over time due to inflation.
Storing prices of small units of goods (probably as a result of conversion from another currency) or having accumulators (accumulate 10% fee from 1 cent transactions until the sum reaches 1 cent) can require using more decimals than are defined for a currency
Storing integer number of minimal units can lead to the need of rescaling values in the future if you need to change the precision. If you use decimals, it's much easier.
Note, that you also need to find the corresponding data type in the programming language you use.
More details and caveats in the article.
I need to store currency exchange rate data in the SQL 2008 database.
I would like to keep rate as a decimal data type in the database.
One thing I am not sure about, is how many decimal places to give (e.g. decimal(18, ?)).
Since, I will be using this service as a source: http://openexchangerates.org/latest.json. There, it seems that the highest number of decimal places used is '6'.
Is that the right number, or there possibly can be rates with more than 6 decimal places?
I once worked on an international financial C# based package, which had to support numerous currencies, and we supported 6 decimal places. We had a couple of very experienced designers who told us that would be sufficient.
Nowadays, to support the unlikely exchange rate of XBT/VND, you'll need 10 to 14 decimal places
As of 2017-11-20,
1 XBT = 185,416,429.63 VND
1 VND = 0.00000000539327 XBT
There is not an easy answer on that. The question is what you want to store:
is it the final currency amount of an invoice?
or is it maybe the line amount of an document line (e.g. the line amount of an invoice line)?
Final currency amount
I only know currencies with 2 decimal places but according to this doc from Oracle the ISO standard says 3 decimal places are allowed in a currency. (I couldn't find the ISO document Oracle is mentioning here).
Interesting: SQL Server has a data type money and smallmoney which supports 4 decimal places. Don't know how they came up with that, maybe because of rounding issues (see below).
Line amount of an document line
You might want to make sure that you don't run into rounding issues and therefore use more than 3 decimal places where you have a 'sub-amount' of the total amount of a document (e.g. invoice).
Example:
Line
Qty
Price
Discount
Line Amount
Line Amount rounded 2 decimal places
Item A
5
79.99
3%
387.9515
387.95
Item B
2
56.12
3%
108.8728
108.87
Item C
1
12.19
3%
11.8243
11.82
Total
508.65
508.64
We end up having 1 cent rounding difference when we round the line amount to two decimal places. You can play this game with other numbers where you run into differences with more than three decimal places.
The most systems I worked with use different approaches:
use 5 or more decimal places in the line amount. With 5 decimal places, most if these rounding issues should be soved. I saw ERP systems with 10 decimal places, but I saw this more like an bad application design.
'enforce' rounding in the line amount to the currency amount max. decimal places. This makes sence when you want to print the 'Line amount' in the invoice and you don't want to make printed invoices where the rounded line amount does not match up with the total
make it configurable for the application how many decimal places shall be used.
adding a 'rouding' line to a document to discount the rounding in case the rounding issues would be to the disadventage of the customer.
warn the application user when rounding issues occur and ask for how the system shall handle them
It is up to your application design how you want to deal with rounding issues in document lines.
I'm using a decimal column to store money values on a database, and today I was wondering what precision and scale to use.
Since supposedly char columns of a fixed width are more efficient, I was thinking the same could be true for decimal columns. Is it?
And what precision and scale should I use? I was thinking precision 24/8. Is that overkill, not enough or ok?
This is what I've decided to do:
Store the conversion rates (when applicable) in the transaction table itself, as a float
Store the currency in the account table
The transaction amount will be a DECIMAL(19,4)
All calculations using a conversion rate will be handled by my application so I keep control of rounding issues
I don't think a float for the conversion rate is an issue, since it's mostly for reference, and I'll be casting it to a decimal anyway.
Thank you all for your valuable input.
If you are looking for a one-size-fits-all, I'd suggest DECIMAL(19, 4) is a popular choice (a quick Google bears this out). I think this originates from the old VBA/Access/Jet Currency data type, being the first fixed point decimal type in the language; Decimal only came in 'version 1.0' style (i.e. not fully implemented) in VB6/VBA6/Jet 4.0.
The rule of thumb for storage of fixed point decimal values is to store at least one more decimal place than you actually require to allow for rounding. One of the reasons for mapping the old Currency type in the front end to DECIMAL(19, 4) type in the back end was that Currency exhibited bankers' rounding by nature, whereas DECIMAL(p, s) rounded by truncation.
An extra decimal place in storage for DECIMAL allows a custom rounding algorithm to be implemented rather than taking the vendor's default (and bankers' rounding is alarming, to say the least, for a designer expecting all values ending in .5 to round away from zero).
Yes, DECIMAL(24, 8) sounds like overkill to me. Most currencies are quoted to four or five decimal places. I know of situations where a decimal scale of 8 (or more) is required but this is where a 'normal' monetary amount (say four decimal places) has been pro rata'd, implying the decimal precision should be reduced accordingly (also consider a floating point type in such circumstances). And no one has that much money nowadays to require a decimal precision of 24 :)
However, rather than a one-size-fits-all approach, some research may be in order. Ask your designer or domain expert about accounting rules which may be applicable: GAAP, EU, etc. I vaguely recall some EU intra-state transfers with explicit rules for rounding to five decimal places, therefore using DECIMAL(p, 6) for storage. Accountants generally seem to favour four decimal places.
PS Avoid SQL Server's MONEY data type because it has serious issues with accuracy when rounding, among other considerations such as portability etc. See Aaron Bertrand's blog.
Microsoft and language designers chose banker's rounding because hardware designers chose it [citation?]. It is enshrined in the Institute of Electrical and Electronics Engineers (IEEE) standards, for example. And hardware designers chose it because mathematicians prefer it. See Wikipedia; to paraphrase: The 1906 edition of Probability and Theory of Errors called this 'the computer's rule' ("computers" meaning humans who perform computations).
We recently implemented a system that needs to handle values in multiple currencies and convert between them, and figured out a few things the hard way.
NEVER USE FLOATING POINT NUMBERS FOR MONEY
Floating point arithmetic introduces inaccuracies that may not be noticed until they've screwed something up. All values should be stored as either integers or fixed-decimal types, and if you choose to use a fixed-decimal type then make sure you understand exactly what that type does under the hood (ie, does it internally use an integer or floating point type).
When you do need to do calculations or conversions:
Convert values to floating point
Calculate new value
Round the number and convert it back to an integer
When converting a floating point number back to an integer in step 3, don't just cast it - use a math function to round it first. This will usually be round, though in special cases it could be floor or ceil. Know the difference and choose carefully.
Store the type of a number alongside the value
This may not be as important for you if you're only handling one currency, but it was important for us in handling multiple currencies. We used the 3-character code for a currency, such as USD, GBP, JPY, EUR, etc.
Depending on the situation, it may also be helpful to store:
Whether the number is before or after tax (and what the tax rate was)
Whether the number is the result of a conversion (and what it was converted from)
Know the accuracy bounds of the numbers you're dealing with
For real values, you want to be as precise as the smallest unit of the currency. This means you have no values smaller than a cent, a penny, a yen, a fen, etc. Don't store values with higher accuracy than that for no reason.
Internally, you may choose to deal with smaller values, in which case that's a different type of currency value. Make sure your code knows which is which and doesn't get them mixed up. Avoid using floating point values even here.
Adding all those rules together, we decided on the following rules. In running code, currencies are stored using an integer for the smallest unit.
class Currency {
String code; // eg "USD"
int value; // eg 2500
boolean converted;
}
class Price {
Currency grossValue;
Currency netValue;
Tax taxRate;
}
In the database, the values are stored as a string in the following format:
USD:2500
That stores the value of $25.00. We were able to do that only because the code that deals with currencies doesn't need to be within the database layer itself, so all values can be converted into memory first. Other situations will no doubt lend themselves to other solutions.
And in case I didn't make it clear earlier, don't use float!
When handling money in MySQL, use DECIMAL(13,2) if you know the precision of your money values or use DOUBLE if you just want a quick good-enough approximate value.
So if your application needs to handle money values up to a trillion dollars (or euros or pounds), then this should work:
DECIMAL(13, 2)
Or, if you need to comply with GAAP then use:
DECIMAL(13, 4)
The money datatype on SQL Server has four digits after the decimal.
From SQL Server 2000 Books Online:
Monetary data represents positive or negative amounts of money. In Microsoft® SQL Server™ 2000, monetary data is stored using the money and smallmoney data types. Monetary data can be stored to an accuracy of four decimal places. Use the money data type to store values in the range from -922,337,203,685,477.5808 through +922,337,203,685,477.5807 (requires 8 bytes to store a value). Use the smallmoney data type to store values in the range from -214,748.3648 through 214,748.3647 (requires 4 bytes to store a value). If a greater number of decimal places are required, use the decimal data type instead.
4 decimal places would give you the accuracy to store the world's smallest currency sub-units. You can take it down further if you need micropayment (nanopayment?!) accuracy.
I too prefer DECIMAL to DBMS-specific money types, you're safer keeping that kind of logic in the application IMO. Another approach along the same lines is simply to use a [long] integer, with formatting into ¤unit.subunit for human readability (¤ = currency symbol) done at the application level.
If you were using IBM Informix Dynamic Server, you would have a MONEY type which is a minor variant on the DECIMAL or NUMERIC type. It is always a fixed-point type (whereas DECIMAL can be a floating point type). You can specify a scale from 1 to 32, and a precision from 0 to 32 (defaulting to a scale of 16 and a precision of 2). So, depending on what you need to store, you might use DECIMAL(16,2) - still big enough to hold the US Federal Deficit, to the nearest cent - or you might use a smaller range, or more decimal places.
Sometimes you will need to go to less than a cent and there are international currencies that use very large demoniations. For example, you might charge your customers 0.088 cents per transaction. In my Oracle database the columns are defined as NUMBER(20,4)
If you're going to be doing any sort of arithmetic operations in the DB (multiplying out billing rates and so on), you'll probably want a lot more precision than people here are suggesting, for the same reasons that you'd never want to use anything less than a double-precision floating point value in application code.
I would think that for a large part your or your client's requirements should dictate what precision and scale to use. For example, for the e-commerce website I am working on that deals with money in GBP only, I have been required to keep it to Decimal( 6, 2 ).
A late answer here, but I've used
DECIMAL(13,2)
which I'm right in thinking should allow upto 99,999,999,999.99.