aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-util/src/amounts.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-11-27 13:06:58 -0300
committerSebastian <sebasjm@gmail.com>2023-11-27 13:06:58 -0300
commit5cc00344e2ed7736887a718bf5ddb2b25d1dc357 (patch)
treec4e52c9a7074747a39377f46dfdd91400709f7f9 /packages/taler-util/src/amounts.ts
parentdc70723044b143bafa0f77cdc35381d82fe6f0cc (diff)
downloadwallet-core-5cc00344e2ed7736887a718bf5ddb2b25d1dc357.tar.xz
DD51 look for currency symbol and split between small and normal
Diffstat (limited to 'packages/taler-util/src/amounts.ts')
-rw-r--r--packages/taler-util/src/amounts.ts65
1 files changed, 63 insertions, 2 deletions
diff --git a/packages/taler-util/src/amounts.ts b/packages/taler-util/src/amounts.ts
index 5c6444b00..76ba3a0c5 100644
--- a/packages/taler-util/src/amounts.ts
+++ b/packages/taler-util/src/amounts.ts
@@ -30,6 +30,7 @@ import {
DecodingError,
renderContext,
} from "./codec.js";
+import { CurrencySpecification } from "./index.js";
import { AmountString } from "./taler-types.js";
/**
@@ -50,6 +51,11 @@ export const amountFractionalLength = 8;
export const amountMaxValue = 2 ** 52;
/**
+ * Separator character between interger and fractional
+ */
+export const FRAC_SEPARATOR = "."
+
+/**
* Non-negative financial amount. Fractional values are expressed as multiples
* of 1e-8.
*/
@@ -373,7 +379,7 @@ export class Amounts {
if (!res) {
return undefined;
}
- const tail = res[3] || ".0";
+ const tail = res[3] || (FRAC_SEPARATOR + "0");
if (tail.length > amountFractionalLength + 1) {
return undefined;
}
@@ -508,7 +514,7 @@ export class Amounts {
let s = av.toString();
if (af || minFractional) {
- s = s + ".";
+ s = s + FRAC_SEPARATOR;
let n = af;
for (let i = 0; i < amountFractionalLength; i++) {
if (!n && i >= minFractional) {
@@ -543,4 +549,59 @@ export class Amounts {
}
return amountFractionalLength - i + 1;
}
+
+
+ static stringifyValueWithSpec(value: AmountJson, spec: CurrencySpecification): { currency: string, normal: string, small?: string } {
+ const strValue = Amounts.stringifyValue(value)
+ const pos = strValue.indexOf(FRAC_SEPARATOR)
+ const originalPosition = pos < 0 ? strValue.length : pos;
+
+ let currency = value.currency
+ const names = Object.keys(spec.alt_unit_names)
+ let FRAC_POS_NEW_POSITION = originalPosition
+ //find symbol
+ //FIXME: this should be based on a cache to speed up
+ if (names.length > 0) {
+ let unitIndex: string = "0" //default entry by DD51
+ names.forEach(index => {
+ const i = Number.parseInt(index, 10)
+ if (Number.isNaN(i)) return; //skip
+ if (originalPosition - i <= 0) return; //too big
+ if (originalPosition - i < FRAC_POS_NEW_POSITION) {
+ FRAC_POS_NEW_POSITION = originalPosition - i;
+ unitIndex = index
+ }
+ })
+ currency = spec.alt_unit_names[unitIndex]
+ }
+
+ if (originalPosition === FRAC_POS_NEW_POSITION) {
+ const { normal, small } = splitNormalAndSmall(strValue, originalPosition, spec)
+ return { currency, normal, small }
+ }
+
+ const intPart = strValue.substring(0, originalPosition)
+ const fracPArt = strValue.substring(originalPosition + 1)
+ //indexSize is always smaller than originalPosition
+ const newValue = intPart.substring(0, FRAC_POS_NEW_POSITION) + FRAC_SEPARATOR + intPart.substring(FRAC_POS_NEW_POSITION) + fracPArt
+ const { normal, small } = splitNormalAndSmall(newValue, FRAC_POS_NEW_POSITION, spec)
+ return { currency, normal, small }
+ }
+
+
+}
+
+function splitNormalAndSmall(decimal: string, fracSeparatorIndex: number, spec: CurrencySpecification): { normal: string, small?: string } {
+ let normal: string;
+ let small: string | undefined;
+ if (decimal.length - fracSeparatorIndex - 1 > spec.num_fractional_normal_digits) {
+ const limit = fracSeparatorIndex + spec.num_fractional_normal_digits + 1
+ normal = decimal.substring(0, limit)
+ small = decimal.substring(limit)
+ } else {
+ normal = decimal
+ small = undefined
+ }
+ return { normal, small }
}
+