Skip to content

Commit

Permalink
all: bugfix BigDecimal usages missing RoundingMode (ArithmeticException)
Browse files Browse the repository at this point in the history
These are code errors that may throw ArithmeticException on values
with infinite decimals (1.33333333333....).

Refs https://gitlab.ilscipio.com/scipio-dev/dev/external/scipio-ide/issues/5
  • Loading branch information
pplx committed Apr 11, 2019
1 parent 16f80b4 commit a6c1794
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.ilscipio.scipio.accounting.external.datev.category;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.HashMap;
Expand Down Expand Up @@ -227,7 +228,7 @@ protected boolean validateField(GenericValue fieldDefinition, String value) {

validatedValue = BigDecimal.valueOf(df.parse(value).doubleValue());
if (UtilValidate.isNotEmpty(validatedValue) && UtilValidate.isNotEmpty(scale)) {
validatedValue = ((BigDecimal) validatedValue).setScale(Math.toIntExact(scale));
validatedValue = ((BigDecimal) validatedValue).setScale(Math.toIntExact(scale), RoundingMode.HALF_UP); // SCIPIO: Added missing RoundingMode
}
break;
case ACCOUNT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public int getReturnAmount() {

public BigDecimal getTransactionAmount() {
BigDecimal amt = new BigDecimal(getReturnAmount());
amt = amt.divide(new BigDecimal(100));
amt = amt.divide(new BigDecimal(100), RoundingMode.HALF_UP); // SCIPIO: Added missing RoundingMode
return amt.setScale(2, RoundingMode.HALF_UP);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,12 @@ private static void addCartDetails(NVPEncoder encoder, ShoppingCart cart) throws
encoder.add("L_QTY" + line, "1");
line++;
}
encoder.add("ITEMAMT", cart.getSubTotal().add(otherAdjustments).setScale(2).toPlainString());
encoder.add("ITEMAMT", cart.getSubTotal().add(otherAdjustments).setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
encoder.add("SHIPPINGAMT", "0.00");
encoder.add("TAXAMT", "0.00");
encoder.add("AMT", cart.getSubTotal().add(otherAdjustments).setScale(2).toPlainString());
encoder.add("AMT", cart.getSubTotal().add(otherAdjustments).setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
//NOTE: The docs say this is optional but then won't work without it
encoder.add("MAXAMT", cart.getSubTotal().add(otherAdjustments).setScale(2).toPlainString());
encoder.add("MAXAMT", cart.getSubTotal().add(otherAdjustments).setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
}

public static Map<String, Object> getExpressCheckout(DispatchContext dctx, Map<String, Object> context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.ofbiz.accounting.thirdparty.verisign;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Iterator;
import java.util.HashMap;
Expand Down Expand Up @@ -492,29 +493,29 @@ private static void addCartDetails(Map<String, String> parameterMap, ShoppingCar
//paramMap.put("L_NUMBER" + line, item.getProductId());
parameterMap.put("L_NAME" + line, item.getName());
parameterMap.put("L_DESC" + line, item.getDescription());
parameterMap.put("L_AMT" + line, item.getBasePrice().setScale(2).toPlainString());
parameterMap.put("L_AMT" + line, item.getBasePrice().setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
parameterMap.put("L_QTY" + line, item.getQuantity().toBigInteger().toString());
line++;
BigDecimal otherAdjustments = item.getOtherAdjustments();
if (otherAdjustments.compareTo(BigDecimal.ZERO) != 0) {
parameterMap.put("L_NAME" + line, item.getName() + " Adjustments");
parameterMap.put("L_DESC" + line, "Adjustments for item: " + item.getName());
parameterMap.put("L_AMT" + line, otherAdjustments.setScale(2).toPlainString());
parameterMap.put("L_AMT" + line, otherAdjustments.setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
parameterMap.put("L_QTY" + line, "1");
line++;
}
}
BigDecimal otherAdjustments = cart.getOrderOtherAdjustmentTotal();
if (otherAdjustments.compareTo(BigDecimal.ZERO) != 0) {
parameterMap.put("L_NAME" + line, "Order Adjustments");
parameterMap.put("L_AMT" + line, otherAdjustments.setScale(2).toPlainString());
parameterMap.put("L_AMT" + line, otherAdjustments.setScale(2).toPlainString()); // SCIPIO: Added missing RoundingMode
parameterMap.put("L_QTY" + line, "1");
line++;
}
parameterMap.put("ITEMAMT", cart.getSubTotal().add(otherAdjustments).setScale(2).toPlainString());
parameterMap.put("TAXAMT", cart.getTotalSalesTax().setScale(2).toPlainString());
parameterMap.put("FREIGHTAMT", cart.getTotalShipping().setScale(2).toPlainString());
parameterMap.put("AMT", cart.getGrandTotal().setScale(2).toPlainString());
parameterMap.put("ITEMAMT", cart.getSubTotal().add(otherAdjustments).setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
parameterMap.put("TAXAMT", cart.getTotalSalesTax().setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
parameterMap.put("FREIGHTAMT", cart.getTotalShipping().setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode
parameterMap.put("AMT", cart.getGrandTotal().setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode

if (!cart.shippingApplies()) {
parameterMap.put("NOSHIPPING", "1");
Expand Down Expand Up @@ -629,7 +630,7 @@ public static Map<String, Object> doExpressCheckout(DispatchContext dctx, Map<St
data.put("TOKEN", payPalPaymentMethod.getString("expressCheckoutToken"));
data.put("ACTION", "D");
// set the amount
data.put("AMT", processAmount.setScale(2).toPlainString());
data.put("AMT", processAmount.setScale(2, RoundingMode.HALF_UP).toPlainString()); // SCIPIO: Added missing RoundingMode

PayflowAPI pfp = init(delegator, paymentGatewayConfigId, null, context);

Expand Down
5 changes: 3 additions & 2 deletions framework/base/src/org/ofbiz/base/util/UtilFormatOut.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.ofbiz.base.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
Expand Down Expand Up @@ -219,9 +220,9 @@ public static String formatPercentage(double percentage) {
public static String formatPercentageRate(BigDecimal percentage, boolean negate) {
if (percentage == null) return "";
if (negate) {
return percentageDecimalFormat.format(percentage.divide(BigDecimal.valueOf(-100)));
return percentageDecimalFormat.format(percentage.divide(BigDecimal.valueOf(-100), RoundingMode.HALF_UP)); // SCIPIO: Added missing RoundingMode
}
return percentageDecimalFormat.format(percentage.divide(BigDecimal.valueOf(100)));
return percentageDecimalFormat.format(percentage.divide(BigDecimal.valueOf(100), RoundingMode.HALF_UP)); // SCIPIO: Added missing RoundingMode
}

/** Formats an Long representing a quantity into a string
Expand Down

0 comments on commit a6c1794

Please sign in to comment.