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 |
Free forum by Nabble | Edit this page |