Add money.ts as first linted .ts file

This commit is contained in:
Eric 2020-06-26 18:19:08 -05:00 committed by Eric Schultz
parent dbfb2f1b68
commit 6554861627

View file

@ -1,19 +1,19 @@
// License: LGPL-3.0-or-later // License: LGPL-3.0-or-later
// based upon https://github.com/davidkalosi/js-money // based upon https://github.com/davidkalosi/js-money
import isFunction from 'lodash/isFunction' import isFunction from 'lodash/isFunction';
const assertSameCurrency = function (left: any, right: any) { const assertSameCurrency = function (left: Money, right: Money) {
if (left.currency !== right.currency) if (left.currency !== right.currency)
throw new Error('Different currencies'); throw new Error('Different currencies');
}; };
const assertType = function (other: any) { const assertType = function (other: unknown) {
if (!(other instanceof Money)) if (!(other instanceof Money))
throw new TypeError('Instance of Money required'); throw new TypeError('Instance of Money required');
}; };
const assertOperand = function (operand: any) { const assertOperand = function (operand: unknown) {
if (isNaN(parseFloat(operand)) && !isFinite(operand)) if (typeof operand !== 'number' || isNaN(operand) && !isFinite(operand))
throw new TypeError('Operand must be a number'); throw new TypeError('Operand must be a number');
}; };
@ -31,12 +31,12 @@ export class Money {
readonly currency:string readonly currency:string
protected constructor(readonly amount: number, currency: string) { protected constructor(readonly amount: number, currency: string) {
this.currency = currency.toLowerCase() this.currency = currency.toLowerCase();
const methodsToBind = [this.equals, this.add, this.subtract, this.multiply, this.divide, this.allocate, const methodsToBind = [this.equals, this.add, this.subtract, this.multiply, this.divide, this.allocate,
this.compare, this.greaterThan, this.greaterThanOrEqual, this.lessThan, this.compare, this.greaterThan, this.greaterThanOrEqual, this.lessThan,
this.lessThanOrEqual, this.isZero, this.isPositive, this.isNegative, this.lessThanOrEqual, this.isZero, this.isPositive, this.isNegative,
this.toJSON] this.toJSON];
methodsToBind.forEach((func:Function) => Object.bind(func)) methodsToBind.forEach((func) => Object.bind(func));
Object.freeze(this); Object.freeze(this);
} }
@ -60,7 +60,7 @@ export class Money {
if (amount instanceof Money) if (amount instanceof Money)
return new Money(amount.amount, amount.currency); return new Money(amount.amount, amount.currency);
else else
return new Money(amount.amount, amount.currency) return new Money(amount.amount, amount.currency);
} }
@ -78,12 +78,12 @@ export class Money {
* @returns {Boolean} * @returns {Boolean}
*/ */
equals(other: Money): boolean { equals(other: Money): boolean {
var self = this;
assertType(other); assertType(other);
return self.amount === other.amount && return this.amount === other.amount &&
self.currency === other.currency; this.currency === other.currency;
}; }
/** /**
* Adds the two objects together creating a new Money instance that holds the result of the operation. * Adds the two objects together creating a new Money instance that holds the result of the operation.
@ -92,12 +92,12 @@ export class Money {
* @returns {Money} * @returns {Money}
*/ */
add(other: Money): Money { add(other: Money): Money {
var self = this;
assertType(other);
assertSameCurrency(self, other);
return new Money(self.amount + other.amount, self.currency); assertType(other);
}; assertSameCurrency(this, other);
return new Money(this.amount + other.amount, this.currency);
}
/** /**
* Subtracts the two objects creating a new Money instance that holds the result of the operation. * Subtracts the two objects creating a new Money instance that holds the result of the operation.
@ -106,29 +106,29 @@ export class Money {
* @returns {Money} * @returns {Money}
*/ */
subtract(other: Money): Money { subtract(other: Money): Money {
var self = this;
assertType(other);
assertSameCurrency(self, other);
return new Money(self.amount - other.amount, self.currency); assertType(other);
}; assertSameCurrency(this, other);
return new Money(this.amount - other.amount, this.currency);
}
/** /**
* Multiplies the object by the multiplier returning a new Money instance that holds the result of the operation. * Multiplies the object by the multiplier returning a new Money instance that holds the result of the operation.
* *
* @param {Number} multiplier * @param {number} multiplier
* @param {(x:number) => number} [fn=Math.round] * @param {(x:number) => number} [fn=Math.round]
* @returns {Money} * @returns {Money}
*/ */
multiply(multiplier: number, fn?: Function): Money { multiply(multiplier: number, roundingFunction: (x:number) => number): Money {
if (!isFunction(fn)) if (!isFunction(roundingFunction))
fn = Math.round; roundingFunction = Math.round;
assertOperand(multiplier); assertOperand(multiplier);
var amount = fn(this.amount * multiplier); const amount = roundingFunction(this.amount * multiplier);
return new Money(amount, this.currency); return new Money(amount, this.currency);
}; }
/** /**
* Divides the object by the multiplier returning a new Money instance that holds the result of the operation. * Divides the object by the multiplier returning a new Money instance that holds the result of the operation.
@ -142,10 +142,10 @@ export class Money {
fn = Math.round; fn = Math.round;
assertOperand(divisor); assertOperand(divisor);
var amount = fn(this.amount / divisor); const amount = fn(this.amount / divisor);
return new Money(amount, this.currency); return new Money(amount, this.currency);
}; }
/** /**
* Allocates fund bases on the ratios provided returing an array of objects as a product of the allocation. * Allocates fund bases on the ratios provided returing an array of objects as a product of the allocation.
@ -154,28 +154,28 @@ export class Money {
* @param {Money[]} * @param {Money[]}
*/ */
allocate(ratios: number[]): Money[] { allocate(ratios: number[]): Money[] {
var self = this;
var remainder = self.amount; let remainder = this.amount;
var results: Money[] = []; const results: Money[] = [];
var total = 0; let total = 0;
ratios.forEach(function (ratio) { ratios.forEach(function (ratio) {
total += ratio; total += ratio;
}); });
ratios.forEach(function (ratio) { ratios.forEach(function (ratio) {
var share = Math.floor(self.amount * ratio / total) const share = Math.floor(this.amount * ratio / total);
results.push(new Money(share, self.currency)); results.push(new Money(share, this.currency));
remainder -= share; remainder -= share;
}); });
for (var i = 0; remainder > 0; i++) { for (let i = 0; remainder > 0; i++) {
results[i] = new Money(results[i].amount + 1, results[i].currency); results[i] = new Money(results[i].amount + 1, results[i].currency);
remainder--; remainder--;
} }
return results; return results;
}; }
/** /**
* Compares two instances of Money. * Compares two instances of Money.
@ -184,16 +184,16 @@ export class Money {
* @returns {Number} * @returns {Number}
*/ */
compare(other: Money): number { compare(other: Money): number {
var self = this;
assertType(other); assertType(other);
assertSameCurrency(self, other); assertSameCurrency(this, other);
if (self.amount === other.amount) if (this.amount === other.amount)
return 0; return 0;
return self.amount > other.amount ? 1 : -1; return this.amount > other.amount ? 1 : -1;
}; }
/** /**
* Checks whether the value represented by this object is greater than the other. * Checks whether the value represented by this object is greater than the other.
@ -203,7 +203,7 @@ export class Money {
*/ */
greaterThan(other: Money): boolean { greaterThan(other: Money): boolean {
return 1 === this.compare(other); return 1 === this.compare(other);
}; }
/** /**
* Checks whether the value represented by this object is greater or equal to the other. * Checks whether the value represented by this object is greater or equal to the other.
@ -213,7 +213,7 @@ export class Money {
*/ */
greaterThanOrEqual(other: Money): boolean { greaterThanOrEqual(other: Money): boolean {
return 0 <= this.compare(other); return 0 <= this.compare(other);
}; }
/** /**
* Checks whether the value represented by this object is less than the other. * Checks whether the value represented by this object is less than the other.
@ -223,7 +223,7 @@ export class Money {
*/ */
lessThan(other: Money): boolean { lessThan(other: Money): boolean {
return -1 === this.compare(other); return -1 === this.compare(other);
}; }
/** /**
* Checks whether the value represented by this object is less than or equal to the other. * Checks whether the value represented by this object is less than or equal to the other.
@ -233,7 +233,7 @@ export class Money {
*/ */
lessThanOrEqual(other: Money): boolean { lessThanOrEqual(other: Money): boolean {
return 0 >= this.compare(other); return 0 >= this.compare(other);
}; }
/** /**
* Returns true if the amount is zero. * Returns true if the amount is zero.
@ -242,7 +242,7 @@ export class Money {
*/ */
isZero(): boolean { isZero(): boolean {
return this.amount === 0; return this.amount === 0;
}; }
/** /**
* Returns true if the amount is positive. * Returns true if the amount is positive.
@ -251,16 +251,11 @@ export class Money {
*/ */
isPositive(): boolean { isPositive(): boolean {
return this.amount > 0; return this.amount > 0;
}; }
/**
* Returns true if the amount is negative.
*
* @returns {boolean}
*/
isNegative(): boolean { isNegative(): boolean {
return this.amount < 0; return this.amount < 0;
}; }
/** /**
* Returns a serialised version of the instance. * Returns a serialised version of the instance.
@ -272,5 +267,5 @@ export class Money {
amount: this.amount, amount: this.amount,
currency: this.currency currency: this.currency
}; };
}; }
} }