Login  Register

Re: Dev - Mods to the TaxAuth services to display party's taxes in prices instead of product store's one

Posted by Daniel Kunkel on Apr 24, 2006; 4:46pm
URL: 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

Hi Jacopo

Please excuse me if there's a solution to a related issue and I've
missed it... but given your current idea I thought I would share it.

We have customers that want not to be taxed on the products that they
resell and to be taxed on others.

Is there an easy way to change the tax adjustments on a product by
product basis is an order...  or would it also be worthwhile to add some
user control as to whether or not to charge tax on a particular product?

Actually, a more flexible system would allow the qualified users (those
with tax resale status) to adjust the number of items up to the number
ordered as resale.

Thanks

Daniel




On Mon, 2006-04-24 at 17:02 +0200, Jacopo Cappellato wrote:

> 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/dev
--
Daniel

*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-
Have a GREAT Day!

Daniel Kunkel           [hidden email]
BioWaves, LLC           http://www.BioWaves.com
14150 NE 20th St. Suite F1
Bellevue, WA 98007
800-734-3588    425-895-0050
http://www.Apartment-Pets.com  http://www.Focus-Illusion.com
http://www.Brain-Fun.com       http://www.ColorGlasses.com
*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-.,,.-*"*-

 
_______________________________________________
Dev mailing list
[hidden email]
http://lists.ofbiz.org/mailman/listinfo/dev