diff --git a/.gitignore b/.gitignore index a0a23a9..7b003fe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /node_modules/* /nbproject/ /bower_components/* +*.iml diff --git a/lib/money.js b/lib/money.js index a1bfd73..197fd1a 100644 --- a/lib/money.js +++ b/lib/money.js @@ -84,8 +84,6 @@ Money.fromInteger = function (amount, currency) { }; Money.fromDecimal = function (amount, currency) { - var multipliers = [1, 10, 100, 1000]; - if (isObject(amount)) { if (amount.amount === undefined || amount.currency === undefined) throw new TypeError('Missing required parameters amount,currency'); @@ -106,8 +104,41 @@ Money.fromDecimal = function (amount, currency) { throw new Error("The currency " + currency.code + " supports only " + currency.decimal_digits + " decimal digits"); - var integerAmount = amount * multipliers[currency.decimal_digits]; - return new Money(Math.round(integerAmount), currency); + var precisionMultiplier = Math.pow(10, currency.decimal_digits); + var integerAmount = amount * precisionMultiplier; + + return new Money(integerAmount, currency); +}; + +Money.fromDecimalRounded = function (amount, currency, rounder) { + if (isObject(amount)) { + if (amount.amount === undefined || amount.currency === undefined) + throw new TypeError('Missing required parameters amount,currency'); + + rounder = currency; + currency = amount.currency; + amount = amount.amount; + } + + if (isString(currency)) + currency = currencies[currency]; + + if (!isPlainObject(currency)) + throw new TypeError('Invalid currency'); + + if (rounder === undefined) + throw new TypeError('Missing required parameter roundType'); + + if (['round', 'floor', 'ceil'].indexOf(rounder) === -1 && typeof rounder !== 'function') + throw new TypeError('Invalid parameter rounder'); + + if (isString(rounder)) + rounder = Math[rounder]; + + var precisionMultiplier = Math.pow(10, currency.decimal_digits); + var roundedIntegerAmount = rounder(amount * precisionMultiplier); + + return new Money(roundedIntegerAmount, currency); }; /** diff --git a/package.json b/package.json index 117c31e..2922538 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "js-money", "description": "JavaScript implementation of the Money value object.", - "version": "0.6.1", + "version": "1.0.1", "main": "./lib", "author": { "name": "David Kalosi", @@ -14,10 +14,10 @@ }, "repository": { "type": "git", - "url": "git://github.com/davidkalosi/js-money.git" + "url": "git://github.com/HotelQuickly/js-money.git" }, "bugs": { - "url": "https://github.com/davidkalosi/js-money/issues" + "url": "https://github.com/HotelQuickly/js-money/issues" }, "dependencies": { "lodash": "4.x.x" diff --git a/test/money.test.js b/test/money.test.js index 9597aa4..bcb2d74 100755 --- a/test/money.test.js +++ b/test/money.test.js @@ -48,6 +48,27 @@ describe('Money', function () { }).to.throw(Error); }); + it('should create a new instance from decimal using `.fromDecimalRounded()` even if too many decimal places', function () { + var money = Money.fromDecimalRounded(10.01, Money.EUR, 'ceil'); + var money1 = Money.fromDecimalRounded({amount: 10.01, currency: 'EUR'}, Math.ceil); + var money2 = Money.fromDecimalRounded(10.0101, Money.EUR, Math.ceil); + var money3 = Money.fromDecimalRounded(10.0199, Money.EUR, Math.ceil); + var money4 = Money.fromDecimalRounded(10.0199, Money.EUR, Math.floor); + var money5 = Money.fromDecimalRounded(10.0199, Money.EUR, Math.round); + var money6 = Money.fromDecimalRounded(10.0199, Money.EUR, function (amount) { + return Math.round(amount) + }); + + expect(money.amount).to.equal(1001); + expect(money.currency).to.equal('EUR'); + expect(money1.amount).to.equal(1001); + expect(money2.amount).to.equal(1002); + expect(money3.amount).to.equal(1002); + expect(money4.amount).to.equal(1001); + expect(money5.amount).to.equal(1002); + expect(money6.amount).to.equal(1002); + }); + it('should create a new instance from string currency', function () { var money = new Money(1042, 'EUR');