Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug - fromCents miscalculations in subsequent calculations #425

Open
jwarykowski opened this issue Dec 3, 2022 · 4 comments
Open

Bug - fromCents miscalculations in subsequent calculations #425

jwarykowski opened this issue Dec 3, 2022 · 4 comments
Labels

Comments

@jwarykowski
Copy link

jwarykowski commented Dec 3, 2022

Hi,

I noticed a weird problem when using a fromCents instance when performing further calculations down the line, please see the example below:

  const itemSubTotalFromCents = currency('800000', { fromCents: true, precision: 4 })
  const itemSubTotalWithoutFromCents = currency('80.00', { precision: 4 })
  
  const invoiceDiscount = currency('20.00', { precision: 4 })
  const invoiceSubTotal = currency('80.00', { precision: 4 })

  const resultWithFromCents = invoiceDiscount.multiply(itemSubTotalFromCents.divide(invoiceSubTotal))
  
  // returns { intValue: 20, value: 0.002, s: Object, p: 10000 }
  
  const resultWithoutFromCents = invoiceDiscount.multiply(itemSubTotalWithoutFromCents.divide(invoiceSubTotal))
  
  // returns { intValue: 200000, value: 20, s: Object, p: 10000 }

You can see that the first example which uses the fromCents looks incorrect, if you don't pass this option I get the expected result. If possible can you confirm whether this is a bug or not? I've only had a quick look at this but any insight would be greatly appreciated. I wouldn't expect the fromCents option to be carried forward in the returning instance.

In order to get round this problem I can just wrap with another instance of currency and this works:

const itemSubTotalFromCentsWithWorkAround = currency(currency('800000', { fromCents: true, precision: 4 }), { precision: 4 })
const resultWithWorkaround = invoiceDiscount.multiply(itemSubTotalFromCentsWithWorkAround.divide(invoiceSubTotal))

// returns { intValue: 200000, value: 20, s: Object, p: 10000 }

Note I use fromCents originally as the BE returns the value in centi cents

@scurker scurker added the bug label Dec 5, 2022
@scurker
Copy link
Owner

scurker commented Dec 5, 2022

That might be a bug, or at least I would probably flag that behavior is incorrect.

I need to look into this further, but I would think at a high level both of your results should return the same value.

@jwarykowski
Copy link
Author

Hey @scurker, thanks for your response. Agree, I'll try and take a look at this if I get a chance.

@paro-paro
Copy link

paro-paro commented Dec 12, 2022

Hi guys!

I ran into the exact same issue as @jwarykowski and used the same workaround for "fixing" it.

I believe the problem lies within the divide function that, as stated above, carries forward the fromCents property in the returned instance when (I think) it should not.

Using the same values as the example above...

let a, b, c, d

const numerator = currency('80.00', { precision: 4 })
const numeratorFromCents = currency('800000', { fromCents: true, precision: 4 })
const denominator = currency('80.00', { precision: 4 })

a = numerator.divide(denominator) // returns instance of currency(1, { fromCents: false, precision: 4 })
b = numeratorFromCents.divide(denominator) // returns instance of currency(1, { fromCents: true, precision: 4 })

console.log(a.value) // 1
console.log(b.value) // 0.0001

c = currency(1, { fromCents: false, precision: 4 })
d = currency(1, { fromCents: true, precision: 4 })

console.log(c.value) // which effectively should be 1
console.log(d.value) // which effectively should be 0.0001

Maybe the returned instance of the divide function should "always" have the fromCents property set to false (which is what the workaround actually does)?

Or at least when is the result of dividing two currency objects?

Thanks in advanced!

@cydside
Copy link

cydside commented Feb 14, 2024

Hi, here is a similar issue:

const EURO = value => currency(value, { fromCents: true, symbol: '€', decimal: ',', separator: '.' });

function myFunction() {
let tottax = EURO(3000);
let vatrate = EURO(2200);
let totvat = EURO(tottax.divide(100).multiply(vatrate.value).intValue);

console.log(`tottax.value: ${tottax.value}`);
console.log(`totvat.value: ${totvat.value}`);

let totamo = totvat.add(tottax.value);

console.log(`vatrate: ${vatrate.value}<br>tottax: ${tottax.value}<br>totvat: ${totvat.value}<br>totamo: ${totamo.value}`);
}

It's reporting totamo as 6.9 instead of 36.6 even if tottax and totvat are storing the correct values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants