diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/foundation/ERXMoney.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/foundation/ERXMoney.java index e462e144ed6..847221daecb 100644 --- a/Frameworks/Core/ERExtensions/Sources/er/extensions/foundation/ERXMoney.java +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/foundation/ERXMoney.java @@ -1,5 +1,7 @@ package er.extensions.foundation; +import java.math.BigDecimal; + import er.extensions.enums.ERXMoneyEnums; /** @@ -25,9 +27,13 @@ public ERXMoney(final ERXMoney x) { value = x.value; } - public ERXMoney(final double x, ERXMoneyEnums money) { - value = Math.round(x * money.scale()); - this.money = money; + public ERXMoney(final BigDecimal x, ERXMoneyEnums currency) { + this(x.doubleValue(), currency); + } + + public ERXMoney(final double x, ERXMoneyEnums currency) { + value = Math.round(x * currency.scale()); + this.money = currency; } //******************************************************************** @@ -39,6 +45,11 @@ public ERXMoney set(final double rs) { return this; } + public ERXMoney set(final BigDecimal rs) { + value = Math.round(rs.doubleValue() * money.scale()); + return this; + } + public ERXMoney set(final ERXMoney rs) { value = rs.value; return this; @@ -48,12 +59,18 @@ public ERXMoney set(final ERXMoney rs) { // Accessors //******************************************************************** - public long wholeUnits() { + public long wholeUnits() { return value / money.scale(); } - public short cents () { - return (short)((value * 100) / money.scale() - (100 * wholeUnits())); + public short cents() { + return (short) ((value * 100) / money.scale() - (100 * wholeUnits())); + } + + public BigDecimal asBigDecimal() { + int centScale = log10(money.scale()); + String centString = "00000000" + cents(); + return new BigDecimal(wholeUnits() + "." + centString.substring(centString.length() - centScale, centString.length())); } //******************************************************************** @@ -68,30 +85,30 @@ public ERXMoney abs() { } public short sign() { - return (short)(value > 0 ? 1 : value < 0 ? -1 : 0); + return (short) (value > 0 ? 1 : value < 0 ? -1 : 0); } //******************************************************************** // Relational (predicate) operations //******************************************************************** - public boolean equals (final ERXMoney rs) { + public boolean equals(final ERXMoney rs) { return value == rs.value; } - public boolean lessThan (final ERXMoney rs) { + public boolean lessThan(final ERXMoney rs) { return value < rs.value; } - public boolean greaterThan (final ERXMoney rs) { + public boolean greaterThan(final ERXMoney rs) { return value > rs.value; } - public boolean equals (final double rs) { + public boolean equals(final double rs) { return value == rs * money.scale(); } - public boolean lessThan (final double rs) { + public boolean lessThan(final double rs) { return value < rs * money.scale(); } - public boolean greaterThan (final double rs) { + public boolean greaterThan(final double rs) { return value > rs * money.scale(); } @@ -100,16 +117,16 @@ public boolean greaterThan (final double rs) { //******************************************************************** @Override - public boolean equals (final Object rs) { - return rs instanceof ERXMoney && ((ERXMoney)rs).value == value; + public boolean equals(final Object rs) { + return (rs instanceof ERXMoney) && (((ERXMoney) rs).value == value); } - public int compareTo (final Object rs) { - return sub((ERXMoney)rs).sign(); + public int compareTo(final Object rs) { + return sub((ERXMoney) rs).sign(); } @Override - public int hashCode () { + public int hashCode() { return (Long.valueOf(value)).hashCode(); } @@ -117,73 +134,101 @@ public int hashCode () { // Arithmetic operations //******************************************************************** - public ERXMoney addSet (final ERXMoney rs) { + public ERXMoney addSet(final ERXMoney rs) { value += rs.value; return this; } - public ERXMoney addSet (final double rs) { + public ERXMoney addSet(final double rs) { value += rs * money.scale(); return this; } - public ERXMoney subSet (final ERXMoney rs) { + public ERXMoney addSet(final BigDecimal rs) { + value += rs.doubleValue() * money.scale(); + return this; + } + + public ERXMoney subSet(final ERXMoney rs) { value -= rs.value; return this; } - public ERXMoney subSet (final double rs){ + public ERXMoney subSet(final double rs){ value -= rs * money.scale(); return this; } - public ERXMoney mpySet (final ERXMoney rs) { + public ERXMoney subSet(final BigDecimal rs){ + value -= rs.doubleValue() * money.scale(); + return this; + } + + public ERXMoney mpySet(final ERXMoney rs) { value *= rs.value; return this; } - public ERXMoney mpySet (final double rs) { + public ERXMoney mpySet(final double rs) { value *= rs; return this; } - public ERXMoney divSet (final ERXMoney rs) { - Math.round(value /= rs.value); - return this; + public ERXMoney mpySet(final BigDecimal rs) { + value *= rs.doubleValue(); + return this; } - public ERXMoney divSet (final double rs) { - Math.round(value /= rs); - return this; + + public ERXMoney divSet(final ERXMoney rs) { + value = Math.round(value / rs.value); + return this; + } + public ERXMoney divSet(final double rs) { + value = Math.round(value / rs); + return this; + } + public ERXMoney divSet(final BigDecimal rs) { + value = Math.round(value / rs.doubleValue()); + return this; } + public ERXMoney percentSet(final double rs) { + value = Math.round((double) value / 100 * rs); + return this; + } + public ERXMoney percentSet(final BigDecimal rs) { + value = Math.round((double) value / 100 * rs.doubleValue()); + return this; + } + public ERXMoney minusSet() { value = - value; return this; } - public ERXMoney add (final ERXMoney rs) { + public ERXMoney add(final ERXMoney rs) { return new ERXMoney(this).addSet(rs); } - public ERXMoney add (final double rs) { + public ERXMoney add(final double rs) { return new ERXMoney(this).addSet(rs); } - public ERXMoney sub (final ERXMoney rs) { + public ERXMoney sub(final ERXMoney rs) { return new ERXMoney(this).subSet(rs); } - public ERXMoney sub (final double rs) { + public ERXMoney sub(final double rs) { return new ERXMoney(this).subSet(rs); } - public ERXMoney mpy (final ERXMoney rs) { + public ERXMoney mpy(final ERXMoney rs) { return new ERXMoney(this).mpySet(rs); } - public ERXMoney mpy (final double rs) { + public ERXMoney mpy(final double rs) { return new ERXMoney(this).mpySet(rs); } - public ERXMoney div (final ERXMoney rs) { + public ERXMoney div(final ERXMoney rs) { return new ERXMoney(this).divSet(rs); } - public ERXMoney div (final double rs) { + public ERXMoney div(final double rs) { return new ERXMoney(this).divSet(rs); } - public ERXMoney minus() { + public ERXMoney minus() { return new ERXMoney(this).minusSet(); } @@ -193,56 +238,63 @@ public ERXMoney minus() { private static short log10(long x) { short result; // of decimal digits in an integer - for (result=0; x>=10; result++, x/=10); // Decimal "shift" and count + for (result=0; x>=10; result++, x/=10) { + // Decimal "shift" and count + } return result; } @Override - public String toString () { - boolean negative = (value < 0); // Remember original sign - value = negative ? -value : value; // Discard sign temporarily - long whole = wholeUnits(); // Separate arg. into whole - short cents = cents(); // and fractional monetary units - short rest = (short)(value - (cents + 100 * whole) * money.scale() / 100); + public String toString() { + boolean negative = (value < 0); // Remember original sign + value = negative ? -value : value; // Discard sign temporarily + long whole = wholeUnits(); // Separate arg. into whole + short cents = cents(); // and fractional monetary units + short rest = (short) (value - (cents + 100 * whole) * money.scale() / 100); - String result = (negative ? "-" : ""); // Insert prefix minus, if needed - result = result + money.prefixSymbol(); // Insert dollar sign or equiv. + String result = (negative ? "-" : ""); // Insert prefix minus, if needed + result = result + money.prefixSymbol(); // Insert dollar sign or equiv. - long divisors[] = { 1, 1000, 1000000, (long)1E9, (long)1E12,(long)1E15, (long)1E18}; + long divisors[] = { 1, 1000, 1000000, (long) 1E9, (long) 1E12,(long) 1E15, (long) 1E18 }; int group_no = log10(whole) / 3; int group_val = (int)(whole / divisors[group_no]); - result = result + group_val; // Append leftmost 3-digits + result = result + group_val; // Append leftmost 3-digits - while (group_no > 0) { // For each remaining 3-digit group - result = result + money.group_separator(); // Insert punctuation + while (group_no > 0) { // For each remaining 3-digit group + result = result + money.group_separator(); // Insert punctuation whole -= group_val * divisors[group_no--]; // Compute new remainder - group_val = (short)(whole/divisors[group_no]); // Get next 3-digit value - if (group_val < 100) - result = result + "0"; // Insert embedded 0's - if (group_val < 10) - result = result + "0"; // as needed - result = result + group_val; // Append group value + group_val = (short) (whole/divisors[group_no]); // Get next 3-digit value + if (group_val < 100) { + result = result + "0"; // Insert embedded 0's + } + if (group_val < 10) { + result = result + "0"; // as needed + } + result = result + group_val; // Append group value } - // Append the fractional portion + // Append the fractional portion if(money.scale() > 1) { - result = result + money.decimal_point(); // Append decimal point + result = result + money.decimal_point(); // Append decimal point int centScale = log10(money.scale()); String centString = "00000000" + cents; - // Append cents value + // Append cents value result += centString.substring(centString.length() - centScale, centString.length()); } - if (rest > 0) { // Test for fractional pennies - while ((rest *= 10) < money.scale()); // (rest *= power(10,log10(money.scale()))) - result = result + (rest/money.scale()); // Append fractional pennies, if any + if (rest > 0) { // Test for fractional pennies + while ((rest *= 10) < money.scale()) { + // (rest *= power(10,log10(money.scale()))) + } + result = result + (rest/money.scale()); // Append fractional pennies, if any } - if (negative) // Restore original sign + if (negative) { // Restore original sign value = - value; - - return result + money.suffixSymbol(); // Append final symbol, if any + } + + return result + money.suffixSymbol(); // Append final symbol, if any } }