1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.service.impl;
17
18 import java.math.BigDecimal;
19 import java.sql.Date;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import org.apache.commons.lang.StringUtils;
24 import org.kuali.ole.fp.businessobject.SalesTax;
25 import org.kuali.ole.sys.businessobject.TaxDetail;
26 import org.kuali.ole.sys.businessobject.TaxRegion;
27 import org.kuali.ole.sys.service.TaxRegionService;
28 import org.kuali.ole.sys.service.TaxService;
29 import org.kuali.rice.core.api.util.type.KualiDecimal;
30 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
31 import org.kuali.rice.krad.util.ObjectUtils;
32 import org.springframework.transaction.annotation.Transactional;
33
34 @Transactional
35 public class TaxServiceImpl implements TaxService {
36
37 protected static final String POSTAL_CODE_DIGITS_PASSED_TO_SALES_TAX_REGION_SERVICE = "POSTAL_CODE_DIGITS_PASSED_TO_SALES_TAX_REGION_SERVICE";
38
39 protected TaxRegionService taxRegionService;
40 protected ParameterService parameterService;
41
42
43
44
45
46 @Override
47 public List<TaxDetail> getSalesTaxDetails(Date dateOfTransaction, String postalCode, KualiDecimal amount) {
48 List<TaxDetail> salesTaxDetails = new ArrayList<TaxDetail>();
49
50 if (StringUtils.isNotEmpty(postalCode)) {
51 List<TaxRegion> salesTaxRegions = taxRegionService.getSalesTaxRegions(postalCode);
52 TaxDetail newTaxDetail = null;
53 for (TaxRegion taxRegion : salesTaxRegions) {
54 if (taxRegion.isActive()) {
55 newTaxDetail = populateTaxDetail(taxRegion, dateOfTransaction, amount);
56 salesTaxDetails.add(newTaxDetail);
57 }
58 }
59 }
60
61 return salesTaxDetails;
62 }
63
64
65
66
67
68 @Override
69 public List<TaxDetail> getUseTaxDetails(Date dateOfTransaction, String postalCode, KualiDecimal amount) {
70 List<TaxDetail> useTaxDetails = new ArrayList<TaxDetail>();
71
72 if (StringUtils.isNotEmpty(postalCode)) {
73
74
75 postalCode = truncatePostalCodeForSalesTaxRegionService(postalCode);
76
77 for (TaxRegion taxRegion : taxRegionService.getUseTaxRegions(postalCode)) {
78 useTaxDetails.add(populateTaxDetail(taxRegion, dateOfTransaction, amount));
79 }
80 }
81
82 return useTaxDetails;
83 }
84
85
86
87
88
89 @Override
90 public KualiDecimal getTotalSalesTaxAmount(Date dateOfTransaction, String postalCode, KualiDecimal amount) {
91 KualiDecimal totalSalesTaxAmount = KualiDecimal.ZERO;
92
93 if (StringUtils.isNotEmpty(postalCode)) {
94
95
96
97 postalCode = truncatePostalCodeForSalesTaxRegionService(postalCode);
98
99 List<TaxDetail> salesTaxDetails = getSalesTaxDetails(dateOfTransaction, postalCode, amount);
100 KualiDecimal newTaxAmount = KualiDecimal.ZERO;
101 for (TaxDetail taxDetail : salesTaxDetails) {
102 newTaxAmount = taxDetail.getTaxAmount();
103 totalSalesTaxAmount = totalSalesTaxAmount.add(newTaxAmount);
104 }
105 }
106
107 return totalSalesTaxAmount;
108 }
109
110
111
112
113
114
115
116
117
118
119 @Override
120 public KualiDecimal getPretaxAmount(Date dateOfTransaction, String postalCode, KualiDecimal amountWithTax) {
121 BigDecimal totalTaxRate = BigDecimal.ZERO;
122
123
124 if (StringUtils.isEmpty(postalCode))
125 return amountWithTax;
126
127
128
129 postalCode = truncatePostalCodeForSalesTaxRegionService(postalCode);
130
131 List<TaxRegion> salesTaxRegions = taxRegionService.getSalesTaxRegions(postalCode);
132 if (salesTaxRegions.size() == 0)
133 return amountWithTax;
134
135 for (TaxRegion taxRegion : salesTaxRegions) {
136 if (ObjectUtils.isNotNull((taxRegion.getEffectiveTaxRegionRate(dateOfTransaction))))
137 totalTaxRate = totalTaxRate.add(taxRegion.getEffectiveTaxRegionRate(dateOfTransaction).getTaxRate());
138 }
139
140 KualiDecimal divisor = new KualiDecimal(totalTaxRate.add(BigDecimal.ONE));
141 KualiDecimal pretaxAmount = amountWithTax.divide(divisor);
142
143 return pretaxAmount;
144 }
145
146
147
148
149
150
151
152
153 protected TaxDetail populateTaxDetail(TaxRegion taxRegion, Date dateOfTransaction, KualiDecimal amount) {
154 TaxDetail taxDetail = new TaxDetail();
155 taxDetail.setAccountNumber(taxRegion.getAccountNumber());
156 taxDetail.setChartOfAccountsCode(taxRegion.getChartOfAccountsCode());
157 taxDetail.setFinancialObjectCode(taxRegion.getFinancialObjectCode());
158 taxDetail.setRateCode(taxRegion.getTaxRegionCode());
159 taxDetail.setRateName(taxRegion.getTaxRegionName());
160 taxDetail.setTypeCode(taxRegion.getTaxRegionTypeCode());
161 if (ObjectUtils.isNotNull((taxRegion.getEffectiveTaxRegionRate(dateOfTransaction)))) {
162 taxDetail.setTaxRate(taxRegion.getEffectiveTaxRegionRate(dateOfTransaction).getTaxRate());
163 if (amount != null) {
164 taxDetail.setTaxAmount(new KualiDecimal((amount.bigDecimalValue().multiply(taxDetail.getTaxRate())).setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR)));
165 }
166 }
167 return taxDetail;
168 }
169
170 protected String truncatePostalCodeForSalesTaxRegionService(String postalCode) {
171 Integer digitsToUse = postalCodeDigitsToUse();
172 if (digitsToUse != null) {
173 return postalCode.substring(0, digitsToUse.intValue());
174 } else {
175 return postalCode;
176 }
177 }
178
179 protected Integer postalCodeDigitsToUse() {
180 String digits = parameterService.getParameterValueAsString(SalesTax.class,
181 POSTAL_CODE_DIGITS_PASSED_TO_SALES_TAX_REGION_SERVICE);
182 if (StringUtils.isBlank(digits)) { return null; }
183 Integer digitsToUse;
184 try {
185 digitsToUse = new Integer(digits);
186 }
187 catch (NumberFormatException ex) {
188 throw new RuntimeException("The value returned for Parameter " + POSTAL_CODE_DIGITS_PASSED_TO_SALES_TAX_REGION_SERVICE + " was non-numeric and cannot be processed.", ex);
189 }
190 return digitsToUse;
191 }
192
193 public void setTaxRegionService(TaxRegionService taxRegionService) {
194 this.taxRegionService = taxRegionService;
195 }
196
197 public void setParameterService(ParameterService parameterService) {
198 this.parameterService = parameterService;
199 }
200 }