npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

money-calc

v1.3.1

Published

Helper class for calculating money amounts without rounding errors.

Downloads

11

Readme

Helper class for calculating money amounts without rounding errors.

Installation

npm install --save money-calc
# or
yarn install money-calc
# or
pnpm install money-calc

Example

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' }
}

Usage

MoneyAmount

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.

MoneyInput

A money input can be represented as:

  • A string matching the format of MoneyAmount.
  • The exact string 0, as a shortcut for 0.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().

Currency

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.

ComparisonResult

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

Money objects are immutable, and are designed to be used in a chainable sequence of operations.

new Money(amount: MoneyInput, currency?: Currency)

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.

add(...amounts: MoneyInput[]): Money

Returns an instance of Money with the result of adding the supplied amounts in sequence.

subtract(...amounts: MoneyInput[]): Money

Returns an instance of Money with the result of subtracting the supplied amounts in sequence.

mul(...amounts: MoneyInput[]): Money

Returns an instance of Money with the result of multiplying by the supplied amounts in sequence.

div(...amounts: MoneyInput[]): Money

Returns an instance of Money with the result of dividing by the supplied amounts in sequence.

mod(...amounts: MoneyInput[]): Money

Returns an instance of Money with the result of the modulus (division remainder) of the supplied amounts in sequence.

percent(amount: MoneyInput): Money

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.

negate(): Money

Returns an instance of Money with the amount negated - that is, a positive number becomes negative, and a negative number becomes positive.

cmp(amount: MoneyInput): ComparisonResult

Compares the amount with another amount, and returns the result of the comparison.

toString(): string

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.

toJSON(): { amount: MoneyAmount; currency: Currency }

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.

amount: string

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().

Credits

Developed by Chariz:

License

Licensed under the Apache License, version 2.0. Refer to LICENSE.md.