001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.sys.service.impl;
017    
018    import java.util.ArrayList;
019    import java.util.HashMap;
020    import java.util.List;
021    import java.util.Map;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.kuali.kfs.sys.businessobject.TaxRegion;
025    import org.kuali.kfs.sys.businessobject.TaxRegionCounty;
026    import org.kuali.kfs.sys.businessobject.TaxRegionPostalCode;
027    import org.kuali.kfs.sys.businessobject.TaxRegionState;
028    import org.kuali.kfs.sys.service.TaxRegionService;
029    import org.kuali.rice.kns.bo.PostalCode;
030    import org.kuali.rice.kns.service.BusinessObjectService;
031    import org.kuali.rice.kns.service.PostalCodeService;
032    import org.kuali.rice.kns.util.ObjectUtils;
033    import org.springframework.transaction.annotation.Transactional;
034    
035    @Transactional
036    public class TaxRegionServiceImpl implements TaxRegionService {
037    
038        private BusinessObjectService businessObjectService;
039        private PostalCodeService postalCodeService;
040    
041        /**
042         * @see org.kuali.kfs.sys.service.TaxRegionService#getSalesTaxRegions(java.lang.String)
043         */
044        public List<TaxRegion> getSalesTaxRegions(String postalCode) {
045    
046            List<TaxRegion> salesTaxRegions = new ArrayList<TaxRegion>();
047    
048            PostalCode postalCodeObj = postalCodeService.getByPostalCodeInDefaultCountry(postalCode);
049            if(ObjectUtils.isNotNull(postalCodeObj)) {
050                salesTaxRegions.addAll(getPostalCodeTaxRegions(postalCodeObj.getPostalCode(), postalCodeObj.getPostalCountryCode(), false));
051                salesTaxRegions.addAll(getStateTaxRegions(postalCodeObj.getPostalStateCode(), postalCodeObj.getPostalCountryCode(), false));
052                salesTaxRegions.addAll(getCountyTaxRegions(postalCodeObj.getCountyCode(), postalCodeObj.getPostalStateCode(), postalCodeObj.getPostalCountryCode(), false));
053            }
054    
055            return salesTaxRegions;
056        }
057    
058        /**
059         * @see org.kuali.kfs.sys.service.TaxRegionService#getUseTaxRegions(java.lang.String)
060         */
061        public List<TaxRegion> getUseTaxRegions(String postalCode) {
062    
063            List<TaxRegion> useTaxRegions = new ArrayList<TaxRegion>();
064    
065            PostalCode postalCodeObj = postalCodeService.getByPostalCodeInDefaultCountry(postalCode);
066            useTaxRegions.addAll(getPostalCodeTaxRegions(postalCodeObj.getPostalCode(), postalCodeObj.getPostalCountryCode(), true));
067            useTaxRegions.addAll(getStateTaxRegions(postalCodeObj.getPostalStateCode(), postalCodeObj.getPostalCountryCode(), true));
068            useTaxRegions.addAll(getCountyTaxRegions(postalCodeObj.getCountyCode(), postalCodeObj.getPostalStateCode(), postalCodeObj.getPostalCountryCode(), true));
069    
070            return useTaxRegions;
071        }
072    
073        /**
074         * This method returns a list of tax regions that match postal code and country code.
075         * 
076         * @param postalCode postal code
077         * @param postalCountryCode country code
078         * @param useTaxOnly determines if only (use tax = true) tax regions are returned 
079         * @return
080         */
081        protected List<TaxRegion> getPostalCodeTaxRegions(String postalCode, String postalCountryCode, boolean useTaxOnly) {
082    
083            List<TaxRegion> postalCodeTaxRegions = new ArrayList<TaxRegion>();
084    
085            if (StringUtils.isNotEmpty(postalCode)) {
086                Map<String, Object> criteria = new HashMap<String, Object>();
087                criteria.put("postalCode", postalCode);
088                criteria.put("postalCountryCode", postalCountryCode);
089                criteria.put("active", true);
090                if (useTaxOnly) {
091                    criteria.put("taxRegion.taxRegionUseTaxIndicator", useTaxOnly);
092                }
093    
094                List<TaxRegionPostalCode> taxRegionPostalCodes = (List<TaxRegionPostalCode>) businessObjectService.findMatching(TaxRegionPostalCode.class, criteria);
095                for (TaxRegionPostalCode taxRegionPostalCode : taxRegionPostalCodes) {
096                    postalCodeTaxRegions.add(taxRegionPostalCode.getTaxRegion());
097                }
098            }
099            return postalCodeTaxRegions;
100        }
101    
102        /**
103         * This method returns a list of tax regions that match state code and country code.
104         * 
105         * @param stateCode state code
106         * @param postalCountryCode country code
107         * @param useTaxOnly determines if only (use tax = true) tax regions are returned
108         * @return
109         */
110        protected List<TaxRegion> getStateTaxRegions(String stateCode, String postalCountryCode, boolean useTaxOnly) {
111    
112            List<TaxRegion> stateTaxRegions = new ArrayList<TaxRegion>();
113    
114            if (StringUtils.isNotEmpty(stateCode)) {
115    
116                Map<String, Object> criteria = new HashMap<String, Object>();
117                criteria.put("stateCode", stateCode);
118                criteria.put("postalCountryCode", postalCountryCode);
119                criteria.put("active", true);
120                if (useTaxOnly) {
121                    criteria.put("taxRegion.taxRegionUseTaxIndicator", useTaxOnly);
122                }
123    
124                List<TaxRegionState> taxRegionStates = (List<TaxRegionState>) businessObjectService.findMatching(TaxRegionState.class, criteria);
125                for (TaxRegionState taxRegionState : taxRegionStates) {
126                    stateTaxRegions.add(taxRegionState.getTaxRegion());
127                }
128            }
129            return stateTaxRegions;
130        }
131    
132        /**
133         * This method returns a list of tax regions that match county code, state code, and country code
134         * @param countyCode county code
135         * @param stateCode state code
136         * @param postalCountryCode country code
137         * @param useTaxOnly determines if only (use tax = true) tax regions are returned
138         * @return
139         */
140        protected List<TaxRegion> getCountyTaxRegions(String countyCode, String stateCode, String postalCountryCode, boolean useTaxOnly) {
141    
142            List<TaxRegion> countyTaxRegions = new ArrayList<TaxRegion>();
143            if (StringUtils.isNotEmpty(countyCode)) {
144                Map<String, Object> criteria = new HashMap<String, Object>();
145                criteria.put("countyCode", countyCode);
146                criteria.put("stateCode", stateCode);
147                criteria.put("postalCountryCode", postalCountryCode);
148                criteria.put("active", true);
149                if (useTaxOnly) {
150                    criteria.put("taxRegion.taxRegionUseTaxIndicator", useTaxOnly);
151                }
152    
153                List<TaxRegionCounty> taxRegionCounties = (List<TaxRegionCounty>) businessObjectService.findMatching(TaxRegionCounty.class, criteria);
154                for (TaxRegionCounty taxRegionCounty : taxRegionCounties) {
155                    countyTaxRegions.add(taxRegionCounty.getTaxRegion());
156                }
157            }
158            return countyTaxRegions;
159        }
160    
161        public BusinessObjectService getBusinessObjectService() {
162            return businessObjectService;
163        }
164    
165        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
166            this.businessObjectService = businessObjectService;
167        }
168    
169        public PostalCodeService getPostalCodeService() {
170            return postalCodeService;
171        }
172    
173        public void setPostalCodeService(PostalCodeService postalCodeService) {
174            this.postalCodeService = postalCodeService;
175        }
176    }