http://ofbiz.116.s1.nabble.com/Dev-Mods-to-the-TaxAuth-services-to-display-party-s-taxes-in-prices-instead-of-product-store-s-one-tp167724p167752.html
missed it... but given your current idea I thought I would share it.
resell and to be taxed on others.
product basis is an order... or would it also be worthwhile to add some
ordered as resale.
> Please,
>
> ignore the patches attached to my previous post and consider the ones
> attached to this one (there was an error in them).
>
> Jacopo
>
> Jacopo Cappellato wrote:
> > Hi all,
> >
> > I need your help to review some mods I did to the
> > TaxAuthorityServices.java file to improve the way prices are shown in
> > ecommerce when the ProductStore.showPricesWithVatTax is set to "Y".
> >
> > When the flag is set to "Y", prices in ecommerce pages are shown with
> > tax included.
> >
> > However there are some problems with the current code:
> >
> > 1) a NPE is thrown because the "shippingAmount" variable is not set when
> > you browse products' categories; easy to fix (see the mod in the
> > attached patch around lines @@ -295,7 +316,7 @@)
> >
> > 2) taxes are always shown for the authorities set in the ProductStore;
> > this is ok for anonymous users but not for logged in users: for the
> > latter we should try to show taxes based on the users' shipping (or
> > billing?) address instead of the ones of the store; yes, it's true that
> > if a user has more than one shipping address (belonging to different
> > states with different tax auths) we will know which taxes to apply only
> > after the user has selected the shipping destination in the checkout
> > process; however, in my opinion, it's better to show the taxes applied
> > to one of the user's addresses instead of the ones of the product store;
> > the code in the patch does exactly this:
> >
> > in the rateProductTaxCalcForDisplay method, if a party can be found for
> > the "billToPartyId" parameter, the first shipping address is searched,
> > if not found the first billing address is searched; if nothing is found,
> > then the product store's authorities are used, otherwise only the
> > authorities relevant for the party are considered.
> >
> > What do you thing of this? Can I put it in SVN?
> >
> > To facilitate the review of this mod, you'll find attached to this
> > message the patch and the whole class.
> >
> > Let me know! I've tested it and it works fine.
> >
> > Jacopo
> >
> >
>
> plain text document attachment (TaxAuthorityServices.java.patch)
> Index: applications/accounting/src/org/ofbiz/accounting/tax/TaxAuthorityServices.java
> ===================================================================
> --- applications/accounting/src/org/ofbiz/accounting/tax/TaxAuthorityServices.java (revision 7388)
> +++ applications/accounting/src/org/ofbiz/accounting/tax/TaxAuthorityServices.java (working copy)
> @@ -91,15 +91,32 @@
>
> if ("Y".equals(productStore.getString("showPricesWithVatTax"))) {
> Set taxAuthoritySet = FastSet.newInstance();
> - if (productStore.get("vatTaxAuthPartyId") == null) {
> - List taxAuthorityRawList = delegator.findByConditionCache("TaxAuthority", new EntityExpr("taxAuthGeoId", EntityOperator.EQUALS, productStore.get("vatTaxAuthGeoId")), null, null);
> - taxAuthoritySet.addAll(taxAuthorityRawList);
> - } else {
> - GenericValue taxAuthority = delegator.findByPrimaryKeyCache("TaxAuthority", UtilMisc.toMap("taxAuthGeoId", productStore.get("vatTaxAuthGeoId"), "taxAuthPartyId", productStore.get("vatTaxAuthPartyId")));
> - taxAuthoritySet.add(taxAuthority);
> + // First of all, search for tax authorities for the party (if there is one)
> + GenericValue party = delegator.findByPrimaryKey("Party", UtilMisc.toMap("partyId", billToPartyId));
> + if (party != null) {
> + List billingContactMechList = (List)org.ofbiz.party.contact.ContactHelper.getContactMech(party, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
> + GenericValue defaultShippingContactMech = EntityUtil.getFirst(billingContactMechList);
> + if (defaultShippingContactMech == null) {
> + billingContactMechList = (List)org.ofbiz.party.contact.ContactHelper.getContactMech(party, "BILLING_LOCATION", "POSTAL_ADDRESS", false);
> + defaultShippingContactMech = EntityUtil.getFirst(billingContactMechList);
> + }
> + GenericValue shippingAddress = null;
> + if (defaultShippingContactMech != null) {
> + shippingAddress = delegator.findByPrimaryKey("PostalAddress", UtilMisc.toMap("contactMechId", defaultShippingContactMech.getString("contactMechId")));
> + }
> + getTaxAuthorities(delegator, shippingAddress, taxAuthoritySet);
> }
> -
> + // If no tax authority is found for the given party, then use the product store's authority
> if (taxAuthoritySet.size() == 0) {
> + if (productStore.get("vatTaxAuthPartyId") == null) {
> + List taxAuthorityRawList = delegator.findByConditionCache("TaxAuthority", new EntityExpr("taxAuthGeoId", EntityOperator.EQUALS, productStore.get("vatTaxAuthGeoId")), null, null);
> + taxAuthoritySet.addAll(taxAuthorityRawList);
> + } else {
> + GenericValue taxAuthority = delegator.findByPrimaryKeyCache("TaxAuthority", UtilMisc.toMap("taxAuthGeoId", productStore.get("vatTaxAuthGeoId"), "taxAuthPartyId", productStore.get("vatTaxAuthPartyId")));
> + taxAuthoritySet.add(taxAuthority);
> + }
> + }
> + if (taxAuthoritySet.size() == 0) {
> throw new IllegalArgumentException("Could not find any Tax Authories for store with ID [" + productStoreId + "] for tax calculation; the store settings may need to be corrected.");
> }
>
> @@ -148,30 +165,14 @@
> BigDecimal orderShippingAmount = (BigDecimal) context.get("orderShippingAmount");
> GenericValue shippingAddress = (GenericValue) context.get("shippingAddress");
>
> + if (shippingAddress == null || (shippingAddress.get("countryGeoId") == null && shippingAddress.get("stateProvinceGeoId") == null)) {
> + return ServiceUtil.returnError("The address(es) used for tax calculation did not have State/Province or Country values set, so we cannot determine the taxes to charge.");
> + }
> // without knowing the TaxAuthority parties, just find all TaxAuthories for the set of IDs...
> Set taxAuthoritySet = FastSet.newInstance();
> GenericValue productStore = null;
> try {
> - Set geoIdSet = FastSet.newInstance();
> - if (shippingAddress != null) {
> - if (shippingAddress.getString("countryGeoId") != null) {
> - geoIdSet.add(shippingAddress.getString("countryGeoId"));
> - }
> - if (shippingAddress.getString("stateProvinceGeoId") != null) {
> - geoIdSet.add(shippingAddress.getString("stateProvinceGeoId"));
> - }
> - }
> -
> - if (geoIdSet.size() == 0) {
> - return ServiceUtil.returnError("The address(es) used for tax calculation did not have State/Province or Country values set, so we cannot determine the taxes to charge.");
> - }
> -
> - // get the most granular, or all available, geoIds and then find parents by GeoAssoc with geoAssocTypeId="REGIONS" and geoIdTo=<granular geoId> and find the GeoAssoc.geoId
> - geoIdSet = GeoWorker.expandGeoRegionDeep(geoIdSet, delegator);
> -
> - List taxAuthorityRawList = delegator.findByConditionCache("TaxAuthority", new EntityExpr("taxAuthGeoId", EntityOperator.IN, geoIdSet), null, null);
> - taxAuthoritySet.addAll(taxAuthorityRawList);
> -
> + getTaxAuthorities(delegator, shippingAddress, taxAuthoritySet);
> productStore = delegator.findByPrimaryKey("ProductStore", UtilMisc.toMap("productStoreId", productStoreId));
> } catch (GenericEntityException e) {
> String errMsg = "Data error getting tax settings: " + e.toString();
> @@ -212,6 +213,23 @@
> return result;
> }
>
> + private static void getTaxAuthorities(GenericDelegator delegator, GenericValue shippingAddress, Set taxAuthoritySet) throws GenericEntityException {
> + Set geoIdSet = FastSet.newInstance();
> + if (shippingAddress != null) {
> + if (shippingAddress.getString("countryGeoId") != null) {
> + geoIdSet.add(shippingAddress.getString("countryGeoId"));
> + }
> + if (shippingAddress.getString("stateProvinceGeoId") != null) {
> + geoIdSet.add(shippingAddress.getString("stateProvinceGeoId"));
> + }
> + }
> + // get the most granular, or all available, geoIds and then find parents by GeoAssoc with geoAssocTypeId="REGIONS" and geoIdTo=<granular geoId> and find the GeoAssoc.geoId
> + geoIdSet = GeoWorker.expandGeoRegionDeep(geoIdSet, delegator);
> +
> + List taxAuthorityRawList = delegator.findByConditionCache("TaxAuthority", new EntityExpr("taxAuthGeoId", EntityOperator.IN, geoIdSet), null, null);
> + taxAuthoritySet.addAll(taxAuthorityRawList);
> + }
> +
> private static List getTaxAdjustments(GenericDelegator delegator, GenericValue product, GenericValue productStore, String billToPartyId, Set taxAuthoritySet, BigDecimal itemPrice, BigDecimal itemAmount, BigDecimal shippingAmount) {
> Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
> List adjustments = FastList.newInstance();
> @@ -295,7 +313,7 @@
> if (product != null && (product.get("taxable") == null || (product.get("taxable") != null && product.getBoolean("taxable").booleanValue()))) {
> taxable = taxable.add(itemAmount);
> }
> - if (taxAuthorityRateProduct != null && (taxAuthorityRateProduct.get("taxShipping") == null || (taxAuthorityRateProduct.get("taxShipping") != null && taxAuthorityRateProduct.getBoolean("taxShipping").booleanValue()))) {
> + if (shippingAmount != null && taxAuthorityRateProduct != null && (taxAuthorityRateProduct.get("taxShipping") == null || (taxAuthorityRateProduct.get("taxShipping") != null && taxAuthorityRateProduct.getBoolean("taxShipping").booleanValue()))) {
> taxable = taxable.add(shippingAmount);
> }
>
> _______________________________________________
> Dev mailing list
>
[hidden email]
>
http://lists.ofbiz.org/mailman/listinfo/dev14150 NE 20th St. Suite F1