svn commit: r1847670 - /ofbiz/ofbiz-framework/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/tax/TaxAuthorityServices.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1847670 - /ofbiz/ofbiz-framework/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/tax/TaxAuthorityServices.java

jleroux@apache.org
Author: jleroux
Date: Wed Nov 28 19:29:04 2018
New Revision: 1847670

URL: http://svn.apache.org/viewvc?rev=1847670&view=rev
Log:
Fixed: Tax not added for order shipping or promotion
(OFBIZ-4160)

The r1070830 commit works fine. Except when there are shippings and promotions
to calculate. Then the algorithm searches for all entries in
TAX_AUTHORITY_RATE_PRODUCT that are available for the PRODUCT_STORE and
TAX_AUTH (and apply to shipping/promotions). So all taxes (regular and reduced)
are applied to the shipping costs, which naturally leads to a higher
amount overall.

The correct procedure (at least in some countries in Europe) is to apply the
tax for shipping  according to the shipped items. So, if regular tax applies
to the good, regular tax is applied to the shipping-costs. If multiple items are
shipped and they  have mixed taxes (some regular, some reduced) the calculation
of the tax for shipping is weighted accordingly.

jleroux: there are other ways to calculate VAT on shipping depending on
countries and situations. This will be addressed by OFBIZ-10679

Thanks: Benjamin Jugl

Modified:
    ofbiz/ofbiz-framework/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/tax/TaxAuthorityServices.java

Modified: ofbiz/ofbiz-framework/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/tax/TaxAuthorityServices.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/tax/TaxAuthorityServices.java?rev=1847670&r1=1847669&r2=1847670&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/tax/TaxAuthorityServices.java (original)
+++ ofbiz/ofbiz-framework/trunk/applications/accounting/src/main/java/org/apache/ofbiz/accounting/tax/TaxAuthorityServices.java Wed Nov 28 19:29:04 2018
@@ -245,29 +245,47 @@ public class TaxAuthorityServices {
         List<GenericValue> orderAdjustments = new LinkedList<>();
         List<List<GenericValue>> itemAdjustments = new LinkedList<>();
 
+        BigDecimal totalPrice = ZERO_BASE;
+        Map<GenericValue,BigDecimal> productWeight = new HashMap<>();
         // Loop through the products; get the taxCategory; and lookup each in the cache.
-        for (int i = 0; i < itemProductList.size(); i++) {
+        for (int i = 0; i < itemProductList.size(); i++) {  
             GenericValue product = itemProductList.get(i);
             BigDecimal itemAmount = itemAmountList.get(i);
             BigDecimal itemPrice = itemPriceList.get(i);
             BigDecimal itemQuantity = itemQuantityList != null ? itemQuantityList.get(i) : null;
             BigDecimal shippingAmount = itemShippingList != null ? itemShippingList.get(i) : null;
-
+            
+            totalPrice = totalPrice.add(itemAmount);
+            
             List<GenericValue> taxList = getTaxAdjustments(delegator, product, productStore, payToPartyId,
                     billToPartyId, taxAuthoritySet, itemPrice, itemQuantity, itemAmount, shippingAmount, ZERO_BASE);
 
             // this is an add and not an addAll because we want a List of Lists of
             // GenericValues, one List of Adjustments per item
             itemAdjustments.add(taxList);
+            
+            //Calculates the TotalPrices for each Product in the Order
+            BigDecimal currentTotalPrice =  productWeight.containsKey(product) ? productWeight.get(product) : BigDecimal.ZERO;
+            currentTotalPrice = currentTotalPrice.add(itemAmount);
+            productWeight.put(product, currentTotalPrice);
+        }
+        // converts the totals of the products into percent weights
+        for (GenericValue prod : productWeight.keySet()) {
+            BigDecimal value = productWeight.get(prod);
+            BigDecimal weight = value.divide(totalPrice, 100, salestaxRounding);
+            productWeight.put(prod, weight);
         }
+
         if (orderShippingAmount != null && orderShippingAmount.compareTo(BigDecimal.ZERO) > 0) {
-            List<GenericValue> taxList = getTaxAdjustments(delegator, null, productStore, payToPartyId, billToPartyId,
-                    taxAuthoritySet, ZERO_BASE, ZERO_BASE, ZERO_BASE, orderShippingAmount, ZERO_BASE);
-            orderAdjustments.addAll(taxList);
+           for (GenericValue prod : productWeight.keySet()) {
+               List<GenericValue> taxList = getTaxAdjustments(delegator, prod, productStore, payToPartyId, billToPartyId,
+                       taxAuthoritySet, ZERO_BASE, ZERO_BASE, ZERO_BASE, orderShippingAmount, null, productWeight.get(prod));
+               orderAdjustments.addAll(taxList);
+           }
         }
         if (orderPromotionsAmount != null && orderPromotionsAmount.compareTo(BigDecimal.ZERO) != 0) {
             List<GenericValue> taxList = getTaxAdjustments(delegator, null, productStore, payToPartyId, billToPartyId,
-                    taxAuthoritySet, ZERO_BASE, ZERO_BASE, ZERO_BASE, ZERO_BASE, orderPromotionsAmount);
+                    taxAuthoritySet, ZERO_BASE, ZERO_BASE, ZERO_BASE, null, orderPromotionsAmount);
             orderAdjustments.addAll(taxList);
         }
 
@@ -315,9 +333,23 @@ public class TaxAuthorityServices {
             String payToPartyId, String billToPartyId, Set<GenericValue> taxAuthoritySet,
             BigDecimal itemPrice, BigDecimal itemQuantity, BigDecimal itemAmount,
             BigDecimal shippingAmount, BigDecimal orderPromotionsAmount) {
+            return getTaxAdjustments(delegator, product, productStore, payToPartyId, billToPartyId,
+                    taxAuthoritySet, itemPrice, itemQuantity, itemAmount, shippingAmount,
+                    orderPromotionsAmount, null);
+    }
+
+    private static List<GenericValue> getTaxAdjustments(Delegator delegator, GenericValue product,
+            GenericValue productStore,
+            String payToPartyId, String billToPartyId, Set<GenericValue> taxAuthoritySet,
+            BigDecimal itemPrice, BigDecimal itemQuantity, BigDecimal itemAmount,
+            BigDecimal shippingAmount, BigDecimal orderPromotionsAmount, BigDecimal weight) {
         Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
         List<GenericValue> adjustments = new LinkedList<>();
-
+        
+        if (weight == null) {
+            weight = BigDecimal.ONE;
+        }
+        
         if (payToPartyId == null) {
             if (productStore != null) {
                 payToPartyId = productStore.getString("payToPartyId");
@@ -405,6 +437,7 @@ public class TaxAuthorityServices {
             for (GenericValue taxAuthorityRateProduct : lookupList) {
                 BigDecimal taxRate = taxAuthorityRateProduct.get("taxPercentage") != null ? taxAuthorityRateProduct
                         .getBigDecimal("taxPercentage") : ZERO_BASE;
+                taxRate = taxRate.multiply(weight);
                 BigDecimal taxable = ZERO_BASE;
 
                 if (product != null && (product.get("taxable") == null || (product.get("taxable") != null && product