Helper class for calculating money amounts without rounding errors.
npm install --save money-calc
# or
yarn install money-calc
# or
pnpm install money-calc
import Money, { MoneyAmount } from "money-calc";
interface Product {
name: string;
manufacturer: string;
weightKg: MoneyAmount;
unitsPerPack: MoneyAmount;
price: MoneyAmount;
}
interface Discount {
percent: MoneyAmount;
}
let product: Product = {
name: "Mr Sparkle Dishwashing Detergent Powder, 2kg, 66 Washes",
manufacturer: "Matsumura Fishworks & Tamaribuchi Heavy Manufacturing Concern",
weightKg: "2.00",
unitsPerPack: "66.00",
price: {
amount: "19.99",
currency: "AUD"
},
shippingFee: {
amount: "4.18",
currency: "AUD"
}
};
let discount: Discount = {
percent: "20.00"
};
let discountRemainder = new Money("100.00")
.subtract(discount.percent);
let originalPrice = new Money(product.price);
let finalPrice = new Money(originalPrice)
.percent(discountRemainder)
.add(product.shippingFee);
let pricePerKg = new Money(finalPrice)
.div(product.weightKg);
let pricePerUnit = new Money(finalPrice)
.div(product.unitsPerPack);
console.log(`Was ${originalPrice}, now ${finalPrice} w/shipping!`);
console.log(`Price per kilogram: ${pricePerKg}`);
console.log(`Price per unit: ${pricePerUnit}`);
let response = {
product,
discount,
originalPrice,
finalPrice,
pricePerKg,
pricePerUnit
};
// Stringify and then parse the object back in, to simulate sending the data
// over the wire to an API client.
let jsonified = JSON.parse(JSON.stringify(response));
console.log("JSON response:");
console.log(jsonified);
Running this script produces the following output:
Was A$19.99, now A$20.17!
Price per kilogram: A$10.09
Price per unit: A$0.31
JSON response:
{
product: {
name: 'Mr Sparkle Dishwashing Detergent Powder, 2kg, 66 Washes',
manufacturer: 'Matsumura Fishworks & Tamaribuchi Heavy Manufacturing Concern',
weightKg: '2.00',
unitsPerPack: '66.00',
price: { amount: '19.99', currency: 'AUD' },
shippingFee: { amount: '4.18', currency: 'AUD' }
},
discount: { percent: '20.00' },
originalPrice: { amount: '19.99', currency: 'AUD' },
finalPrice: { amount: '20.17', currency: 'AUD' },
pricePerKg: { amount: '10.09', currency: 'AUD' },
pricePerUnit: { amount: '0.31', currency: 'AUD' }
}
A string of the format 1234.56
. Two decimal places must be provided. For example: 12.00
or 12.30
, rather than 12
, 12.0
, or 12.3
. Numbers only - no digit separators or currency symbols! The TypeScript type definition will help ensure your inputs are of the right format.
A money input can be represented as:
- A string matching the format of MoneyAmount.
- The exact string
0
, as a shortcut for0.00
. - An instance of js-big-decimal.
- An instance of the Decimal128 type, as exported by bson (the same type is also re-exported by the MongoDB driver). In MongoDB, this is called NumberDecimal, meaning you can store a NumberDecimal in a MongoDB document, then retrieve and pass it directly to Money.
- You can also pass another instance of Money, or the simplified object returned by
Money.toJSON()
.
Enumeration of all three-letter currency symbols that account for at least 1% of world trade, according to xe.com. Any other currency supported by ICU (the source of truth used by the Intl classes) will work, however.
An enumeration of possible outcomes from a numeric comparison:
ComparisonResult.Ascending = -1
: The first number is less than the second number.ComparisonResult.Same = 0
: The two numbers are equal.ComparisonResult.Descending = 1
: The first number is greater than the second number.
Money objects are immutable, and are designed to be used in a chainable sequence of operations.
Initialise a new Money instance with the supplied MoneyInput.
If a currency is not specified, and the amount isn’t an instance of Money, it will fall back to the default of USD.
Throws TypeError
if the input amount is invalid.
Returns an instance of Money with the result of adding the supplied amounts in sequence.
Returns an instance of Money with the result of subtracting the supplied amounts in sequence.
Returns an instance of Money with the result of multiplying by the supplied amounts in sequence.
Returns an instance of Money with the result of dividing by the supplied amounts in sequence.
Returns an instance of Money with the result of the modulus (division remainder) of the supplied amounts in sequence.
Returns an instance of Money with the result of multiplying by a percentage between 0.00
and 100.00
. This is effectively a shortcut for dividing the input amount by 100.00
before multiplying by that amount. If the percentage is between 0.00
and 1.00
, use mul()
instead.
Returns an instance of Money with the amount negated - that is, a positive number becomes negative, and a negative number becomes positive.
Compares the amount with another amount, and returns the result of the comparison.
Formats the money amount for display in a user interface. Includes the appropriate currency sign for the supplied currency, in addition to thousand separators. For a machine-readable string, use amount
.
Returns an object that can be used to represent the Money in a JSON object. You can then initialise an instance of Money on the client side by using this as a MoneyInput
, or directly pass these parameters to the number formatting mechanism for the platform.
toJSON()
is called by JSON.stringify()
to retrieve a variant of the object that can be represented in JSON. As such, you likely won’t need to call this directly.
The string value that can be stored in a database or serialized into a payload such as JSON. This amount is rounded to 2 decimal places, and is intended to be machine-readable. For a human-readable string, use toString()
.
Developed by Chariz:
Licensed under the Apache License, version 2.0. Refer to LICENSE.md.