UNPKG

typescript-libraries

Version:
324 lines (323 loc) 10.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TSCurrencies = exports.TSMoney = void 0; var TSCurrencies_1 = require("./TSCurrencies"); Object.defineProperty(exports, "TSCurrencies", { enumerable: true, get: function () { return TSCurrencies_1.TSCurrencies; } }); var isInt = function (n) { return Number(n) === n && n % 1 === 0; }; var decimalPlaces = function (num) { var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); return !match ? 0 : Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0)); }; var assertSameCurrency = function (left, right) { if (left.currency !== right.currency) { throw new Error('Different currencies'); } }; var assertType = function (other) { if (!(other instanceof TSMoney)) { throw new TypeError('Instance of TSMoney required'); } }; var assertOperand = function (operand) { if (isNaN(parseFloat(operand)) && !isFinite(operand)) { throw new TypeError('Operand must be a number'); } }; var getCurrencyObject = function (currency) { var currencyObj = TSCurrencies_1.TSCurrencies[currency]; if (currencyObj) { return currencyObj; } else { for (var key in TSCurrencies_1.TSCurrencies) { if (key.toUpperCase() === currency.toUpperCase()) { return TSCurrencies_1.TSCurrencies[key]; } } } }; var TSMoney = /** @class */ (function () { /** * Creates a new TSMoney instance. The created TSMoney instances is a value object thus it is immutable. * * @param {Number} amount * @param {Object/String} currency * @returns {TSMoney} * @constructor */ function TSMoney(amount, currency) { if (typeof currency === 'string') { currency = getCurrencyObject(currency); } if (typeof currency !== 'object') { throw new TypeError('Invalid currency'); } if (!isInt(amount)) { throw new TypeError('Amount must be an integer'); } this.amount = amount; this.currency = currency.code; for (var c in TSCurrencies_1.TSCurrencies) { if (TSCurrencies_1.TSCurrencies.hasOwnProperty(c)) { this[c] = TSCurrencies_1.TSCurrencies[c]; } } Object.freeze(this); } TSMoney.fromInteger = function (amount, currency) { if (typeof amount === 'object') { if (amount.amount === undefined || amount.currency === undefined) { throw new TypeError('Missing required parameters amount,currency'); } currency = amount.currency; amount = amount.amount; } if (!isInt(amount)) { throw new TypeError('Amount must be an integer value'); } return new TSMoney(amount, currency); }; TSMoney.fromDecimal = function (amount, currency, rounder) { if (typeof amount === 'object') { if (amount.amount === undefined || amount.currency === undefined) { throw new TypeError('Missing required parameters amount,currency'); } rounder = currency; currency = amount.currency; amount = amount.amount; } if (typeof currency === 'string') { currency = getCurrencyObject(currency); } if (typeof currency !== 'object') { throw new TypeError('Invalid currency'); } if (rounder === undefined) { var decimals = decimalPlaces(amount); if (decimals > currency.decimal_digits) { throw new Error("The currency ".concat(currency.code, " supports only ").concat(currency.decimal_digits, " decimal digits")); } rounder = Math.round; } else { if (['round', 'floor', 'ceil'].indexOf(rounder) === -1 && typeof rounder !== 'function') { throw new TypeError('Invalid parameter rounder'); } if (typeof rounder === 'string') { rounder = Math[rounder]; } } var precisionMultiplier = Math.pow(10, currency.decimal_digits); var resultAmount = amount * precisionMultiplier; resultAmount = rounder(resultAmount); return new TSMoney(resultAmount, currency); }; /** * Returns true if the two instances of TSMoney are equal, false otherwise. * * @param {TSMoney} other * @returns {Boolean} */ TSMoney.prototype.equals = function (other) { assertType(other); return this.amount === other.amount && this.currency === other.currency; }; /** * Adds the two objects together creating a new TSMoney instance that holds the result of the operation. * * @param {TSMoney} other * @returns {TSMoney} */ TSMoney.prototype.add = function (other) { assertType(other); assertSameCurrency(this, other); return new TSMoney(this.amount + other.amount, this.currency); }; /** * Subtracts the two objects creating a new TSMoney instance that holds the result of the operation. * * @param {TSMoney} other * @returns {TSMoney} */ TSMoney.prototype.subtract = function (other) { assertType(other); assertSameCurrency(this, other); return new TSMoney(this.amount - other.amount, this.currency); }; /** * Multiplies the object by the multiplier returning a new TSMoney instance that holds the result of the operation. * * @param {Number} multiplier * @param {Function} [fn=Math.round] * @returns {TSMoney} */ TSMoney.prototype.multiply = function (multiplier, fn) { if (typeof fn !== 'function') { fn = Math.round; } assertOperand(multiplier); return new TSMoney(fn(this.amount * multiplier), this.currency); }; /** * Divides the object by the multiplier returning a new TSMoney instance that holds the result of the operation. * * @param {Number} divisor * @param {Function} [fn=Math.round] * @returns {TSMoney} */ TSMoney.prototype.divide = function (divisor, fn) { if (typeof fn !== 'function') { fn = Math.round; } assertOperand(divisor); return new TSMoney(fn(this.amount / divisor), this.currency); }; /** * Allocates fund bases on the ratios provided returing an array of objects as a product of the allocation. * * @param {Array} other * @returns {Array.TSMoney} */ TSMoney.prototype.allocate = function (ratios) { var _this = this; var remainder = this.amount; var results = []; var total = 0; ratios.forEach(function (ratio) { total += ratio; }); ratios.forEach(function (ratio) { var share = Math.floor(_this.amount * ratio / total); results.push(new TSMoney(share, _this.currency)); remainder -= share; }); for (var i = 0; remainder > 0; i++) { results[i] = new TSMoney(results[i].amount + 1, results[i].currency); remainder--; } return results; }; /** * Compares two instances of TSMoney. * * @param {TSMoney} other * @returns {Number} */ TSMoney.prototype.compare = function (other) { assertType(other); assertSameCurrency(this, other); return this.amount === other.amount ? 0 : (this.amount > other.amount ? 1 : -1); }; /** * Checks whether the value represented by this object is greater than the other. * * @param {TSMoney} other * @returns {boolean} */ TSMoney.prototype.greaterThan = function (other) { return 1 === this.compare(other); }; /** * Checks whether the value represented by this object is greater or equal to the other. * * @param {TSMoney} other * @returns {boolean} */ TSMoney.prototype.greaterThanOrEqual = function (other) { return 0 <= this.compare(other); }; /** * Checks whether the value represented by this object is less than the other. * * @param {TSMoney} other * @returns {boolean} */ TSMoney.prototype.lessThan = function (other) { return -1 === this.compare(other); }; /** * Checks whether the value represented by this object is less than or equal to the other. * * @param {TSMoney} other * @returns {boolean} */ TSMoney.prototype.lessThanOrEqual = function (other) { return 0 >= this.compare(other); }; /** * Returns true if the amount is zero. * * @returns {boolean} */ TSMoney.prototype.isZero = function () { return this.amount === 0; }; /** * Returns true if the amount is positive. * * @returns {boolean} */ TSMoney.prototype.isPositive = function () { return this.amount > 0; }; /** * Returns true if the amount is negative. * * @returns {boolean} */ TSMoney.prototype.isNegative = function () { return this.amount < 0; }; /** * Returns the decimal value as a float. * * @returns {number} */ TSMoney.prototype.toDecimal = function () { return Number(this.toString()); }; /** * Returns the decimal value as a string. * * @returns {string} */ TSMoney.prototype.toString = function () { var currency = getCurrencyObject(this.currency); return (this.amount / Math.pow(10, currency.decimal_digits)).toFixed(currency.decimal_digits); }; /** * Returns a serialised version of the instance. * * @returns {{amount: number, currency: string}} */ TSMoney.prototype.toJSON = function () { return { amount: this.amount, currency: this.currency }; }; /** * Returns the amount represented by this object. * * @returns {number} */ TSMoney.prototype.getAmount = function () { return this.amount; }; /** * Returns the currency represented by this object. * * @returns {string} */ TSMoney.prototype.getCurrency = function () { return this.currency; }; /** * Returns the full currency object */ TSMoney.prototype.getCurrencyInfo = function () { return getCurrencyObject(this.currency); }; return TSMoney; }()); exports.TSMoney = TSMoney; Object.assign(TSMoney, TSCurrencies_1.TSCurrencies);