Fixes issue 36776: Amounts in invoice lines and taxes rounded to price precision
authorMark <markmm82@gmail.com>
Mon, 04 Sep 2017 12:44:00 -0400
changeset 32616 ef2a84e698c4
parent 32615 2873be0d1b66
child 32617 f103322dedd4
Fixes issue 36776: Amounts in invoice lines and taxes rounded to price precision
instead of standard precision in Create Lines From process.

In CreateFrom class, the price precision was used for rounding amounts instead of
standard precision and it was causing differences with totals when invoices were
created from orders or shipments.

Now all prices are rounded with the price precision of it currency and amounts
with standard precision.
src/org/openbravo/erpCommon/ad_actionButton/CreateFrom.java
src/org/openbravo/erpCommon/ad_actionButton/CreateFrom_Invoice_data.xsql
--- a/src/org/openbravo/erpCommon/ad_actionButton/CreateFrom.java	Mon Sep 04 14:03:39 2017 +0530
+++ b/src/org/openbravo/erpCommon/ad_actionButton/CreateFrom.java	Mon Sep 04 12:44:00 2017 -0400
@@ -1671,12 +1671,13 @@
               }
             }
 
-            final int curPrecision;
-            if (strType.equals("SHIPMENT")) {
-              curPrecision = Integer.valueOf(dataAux[0].priceprecision).intValue();
+            final int pricePrecision;
+            if (StringUtils.equals(strType, "SHIPMENT")) {
+              pricePrecision = Integer.valueOf(dataAux[0].priceprecision).intValue();
             } else {
-              curPrecision = Integer.valueOf(data[i].priceprecision).intValue();
+              pricePrecision = Integer.valueOf(data[i].priceprecision).intValue();
             }
+
             if (!data[i].cOrderlineId.equals("")) {
               price = CreateFromInvoiceData.selectPrices(conn, this, data[i].cOrderlineId);
               if (price != null && price.length > 0) {
@@ -1714,20 +1715,23 @@
               }
               price = null;
             }
-            BigDecimal lineNetAmt = (new BigDecimal(priceActual)).multiply(qty);
-            lineNetAmt = lineNetAmt.setScale(curPrecision, BigDecimal.ROUND_HALF_UP);
+            final int stdPrecision = StringUtils.isNotEmpty(data[i].currencystdprecision) ? Integer
+                .valueOf(data[i].currencystdprecision).intValue() : 2;
+            BigDecimal lineNetAmt = (new BigDecimal(priceActual).setScale(pricePrecision,
+                BigDecimal.ROUND_HALF_UP)).multiply(qty);
+            lineNetAmt = lineNetAmt.setScale(stdPrecision, BigDecimal.ROUND_HALF_UP);
             BigDecimal grossAmt = BigDecimal.ZERO;
-            if ("Y".equals(strIsTaxIncluded)) {
+            if (StringUtils.equals(strIsTaxIncluded, "Y")) {
               grossAmt = new BigDecimal(priceGross).multiply(qty);
-              grossAmt = grossAmt.setScale(curPrecision, BigDecimal.ROUND_HALF_UP);
+              grossAmt = grossAmt.setScale(stdPrecision, BigDecimal.ROUND_HALF_UP);
             }
-            if (!strPO.equals("")) {
+            if (StringUtils.isNotEmpty(strPO)) {
               String strInvoiceprepaymentamt = CreateFromInvoiceData.selectInvoicePrepaymentAmt(
                   this, strKey);
-              BigDecimal invoiceprepaymentamt = (strInvoiceprepaymentamt.equals("") ? BigDecimal.ZERO
+              BigDecimal invoiceprepaymentamt = (StringUtils.isEmpty(strInvoiceprepaymentamt) ? BigDecimal.ZERO
                   : new BigDecimal(strInvoiceprepaymentamt));
               String strprepaymentamt = CreateFromInvoiceData.selectPrepaymentAmt(this, strPO);
-              BigDecimal prepaymentamt = (strprepaymentamt.equals("") ? BigDecimal.ZERO
+              BigDecimal prepaymentamt = (StringUtils.isEmpty(strprepaymentamt) ? BigDecimal.ZERO
                   : new BigDecimal(strprepaymentamt));
 
               BigDecimal totalprepayment = invoiceprepaymentamt.add(prepaymentamt);
@@ -1735,10 +1739,10 @@
                   strKey);
             }
             String strTaxRate = CreateFromInvoiceData.selectTaxRate(this, C_Tax_ID);
-            BigDecimal taxRate = (strTaxRate.equals("") ? new BigDecimal(1) : new BigDecimal(
-                strTaxRate));
+            BigDecimal taxRate = (StringUtils.isEmpty(strTaxRate) ? BigDecimal.ONE
+                : new BigDecimal(strTaxRate));
             BigDecimal taxAmt = ((lineNetAmt.multiply(taxRate)).divide(new BigDecimal("100"), 12,
-                BigDecimal.ROUND_HALF_EVEN)).setScale(curPrecision, BigDecimal.ROUND_HALF_UP);
+                BigDecimal.ROUND_HALF_EVEN)).setScale(stdPrecision, BigDecimal.ROUND_HALF_UP);
             try {
               // Calculate Acc and Def Plan from Product
               String isDeferred = "N";
@@ -1765,7 +1769,7 @@
                     BigDecimal qtyOrdered = ol.getOrderedQuantity();
                     taxBaseAmt = ol.getTaxableAmount();
                     if (qtyOrdered.compareTo(ZERO) != 0) {
-                      taxBaseAmt = (taxBaseAmt.multiply(qty)).divide(qtyOrdered, curPrecision,
+                      taxBaseAmt = (taxBaseAmt.multiply(qty)).divide(qtyOrdered, stdPrecision,
                           BigDecimal.ROUND_HALF_UP);
                     }
                   }
--- a/src/org/openbravo/erpCommon/ad_actionButton/CreateFrom_Invoice_data.xsql	Mon Sep 04 14:03:39 2017 +0530
+++ b/src/org/openbravo/erpCommon/ad_actionButton/CreateFrom_Invoice_data.xsql	Mon Sep 04 12:44:00 2017 -0400
@@ -34,7 +34,7 @@
        WHERE  CI.C_INVOICE_ID=? AND CO.C_ORDERLINE_ID = l.c_orderline_id
        GROUP BY CI.C_orderline_id , CO.QtyORDERED),0) AS QTY, 
        l.C_UOM_ID,uom.UOMSymbol, l.M_Product_ID,Ad_Column_Identifier(to_char('M_Product'), to_char(l.m_product_id), to_char(?)) AS RELATION_NAME, 
-        l.C_OrderLine_ID,l.Line, l.ad_org_id, '' as STDPRECISION, 
+        l.C_OrderLine_ID,l.Line, l.ad_org_id, '' as STDPRECISION, '' AS currencyStdPrecision,
         '' as M_InOutLine_ID, '' AS PriceActual, '' AS PriceList, '' AS PriceLimit, '' AS Description, '' as PriceStd,
         '' AS QUANTITYORDER, l.M_Product_UOM_ID, '' AS M_ATTRIBUTESETINSTANCE_ID, '' AS M_Offer_ID, '' AS PricePrecision,
         l.taxbaseamt, l.CancelPriceAD, '' AS Rate, '' AS gross_unit_price, '' AS grosspricelist, '' AS grosspricestd,
@@ -276,7 +276,7 @@
       <![CDATA[
       SELECT (CASE WHEN B.M_InOutLine_ID IS NULL THEN A.QTY ELSE B.QTY END) AS ID, 
       A.C_UOM_ID,uom.UOMSymbol, A.M_Product_ID,Ad_Column_Identifier(to_char('M_Product'), to_char(A.m_product_id), to_char(?)) AS NAME, 
-      A.C_OrderLine_ID,A.Line, uom.stdprecision AS stdprecision, cur.priceprecision, 
+      A.C_OrderLine_ID,A.Line, uom.stdprecision AS stdprecision, cur.priceprecision, cur.stdprecision as currencyStdPrecision,
       B.M_InOutLine_ID, A.Description, (CASE WHEN B.M_InOutLine_ID IS NULL THEN A.quantityOrder ELSE B.quantityOrder END) AS quantityOrder, 
       (CASE WHEN B.M_InOutLine_ID IS NULL THEN A.M_Product_UOM_ID ELSE B.M_Product_UOM_ID END) AS M_Product_UOM_ID, A.M_ATTRIBUTESETINSTANCE_ID, A.ad_org_id,
       A.taxbaseamt, A.a_asset_id, A.c_project_id, A.c_costcenter_id, A.user1_id, A.user2_id, A.explode, 'Y' as isOrder,
@@ -327,7 +327,7 @@
       <![CDATA[
         SELECT (CASE WHEN il.M_INOUTLINE_ID IS NULL THEN (l.QtyOrdered-COALESCE(l.QTYINVOICED ,0)) ELSE il.MOVEMENTQTY END) AS ID, 
         l.C_UOM_ID,uom.UOMSymbol, l.M_Product_ID,Ad_Column_Identifier(to_char('M_Product'), to_char(l.m_product_id), to_char(?)) AS NAME, 
-        l.C_OrderLine_ID,l.Line, max(uom.stdprecision) AS stdprecision, cur.priceprecision, il.M_InOutLine_ID as M_InOutLine_ID, l.Description,
+        l.C_OrderLine_ID,l.Line, max(uom.stdprecision) AS stdprecision, cur.priceprecision, cur.stdprecision as currencyStdPrecision, il.M_InOutLine_ID as M_InOutLine_ID, l.Description,
         (CASE WHEN il.M_INOUTLINE_ID IS NULL THEN l.quantityOrder*C_DIVIDE((l.QtyOrdered-COALESCE(l.QTYINVOICED ,0)),(l.QtyOrdered)) ELSE il.quantityOrder END) AS quantityOrder, 
         (CASE WHEN il.M_INOUTLINE_ID IS NULL THEN l.M_Product_UOM_ID ELSE il.M_Product_UOM_ID END) AS M_Product_UOM_ID, il.M_ATTRIBUTESETINSTANCE_ID, l.ad_org_id,
         l.taxbaseamt, COALESCE(l.A_Asset_ID, o.A_Asset_ID) as A_Asset_ID, COALESCE(l.C_Project_ID, o.C_Project_ID) as C_Project_ID,
@@ -343,7 +343,7 @@
         AND l.M_Product_ID=p.M_Product_ID 
         GROUP BY l.QtyOrdered,l.qtydelivered,l.C_UOM_ID,uom.UOMSymbol,l.M_Product_ID,p.NAME,l.Line,l.C_OrderLine_ID, 
         l.QTYINVOICED, il.M_InOutLine_ID, il.MovementQty, l.Description, l.quantityOrder, il.quantityOrder, 
-        l.M_Product_UOM_ID, il.M_Product_UOM_ID, il.M_ATTRIBUTESETINSTANCE_ID, l.ad_org_id, cur.priceprecision,
+        l.M_Product_UOM_ID, il.M_Product_UOM_ID, il.M_ATTRIBUTESETINSTANCE_ID, l.ad_org_id, cur.priceprecision, cur.stdprecision,
         l.taxbaseamt, COALESCE(l.A_Asset_ID, o.A_Asset_ID), COALESCE(l.C_Project_ID, o.C_Project_ID), COALESCE(l.C_Costcenter_ID, o.C_Costcenter_ID),
         COALESCE(l.User1_ID, o.User1_ID), COALESCE(l.User2_ID, o.User2_ID), l.explode, o.C_DOCTYPE_ID, l.C_AUM, l.AUMQTY
         HAVING ( (l.explode='Y') OR ((l.QtyOrdered-COALESCE(l.QTYINVOICED ,0)) <> 0))