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.vnd.service.impl;
017
018 import java.util.List;
019
020 import org.kuali.kfs.sys.KFSKeyConstants;
021 import org.kuali.kfs.vnd.VendorConstants;
022 import org.kuali.kfs.vnd.VendorParameterConstants;
023 import org.kuali.kfs.vnd.businessobject.VendorDetail;
024 import org.kuali.kfs.vnd.service.TaxNumberService;
025 import org.kuali.rice.kns.service.ParameterService;
026 import org.kuali.rice.kns.util.ObjectUtils;
027 import org.kuali.rice.kns.web.format.FormatException;
028
029 public class TaxNumberServiceImpl implements TaxNumberService {
030
031 public ParameterService parameterService;
032
033
034 public void setParameterService(ParameterService parameterService) {
035 this.parameterService = parameterService;
036 }
037
038
039 public static List<String> taxNumberFormats;
040 public static List<String> feinNumberFormats;
041 public static List<String> notAllowedTaxNumbers;
042
043
044 public String formatToDefaultFormat(String taxNbr) throws FormatException {
045 String digits = taxNbr.replaceAll("\\D", "");
046
047 Integer defaultTaxNumberDigits = new Integer(parameterService.getParameterValue(VendorDetail.class, VendorParameterConstants.DEFAULT_TAX_NUMBER_DIGITS));
048
049 if (digits.length() < defaultTaxNumberDigits) {
050 throw new FormatException("Tax number has fewer than " + defaultTaxNumberDigits + " digits.", KFSKeyConstants.ERROR_CUSTOM, taxNbr);
051 }
052 else if (digits.length() > defaultTaxNumberDigits) {
053 throw new FormatException("Tax number has more than " + defaultTaxNumberDigits + " digits.", KFSKeyConstants.ERROR_CUSTOM, taxNbr);
054 }
055 else {
056 return digits;
057 }
058 }
059
060 /**
061 * A predicate to determine if a String field is all numbers
062 *
063 * @param field A String tax number
064 * @return True if String is numeric
065 */
066 public boolean isStringAllNumbers(String field) {
067 if (!isStringEmpty(field)) {
068 field = field.trim();
069 for (int x = 0; x < field.length(); x++) {
070 char c = field.charAt(x);
071 if (!Character.isDigit(c)) {
072 return false;
073 }
074 }
075 return true;
076 }
077 return false;
078 }
079
080 /**
081 * A predicate to determine if a String field is null or empty
082 *
083 * @param field A String tax number
084 * @return True if String is null or empty
085 */
086 public boolean isStringEmpty(String field) {
087 if (field == null || field.equals("")) {
088 return true;
089 }
090 else {
091 return false;
092 }
093 }
094
095 /**
096 * A predicate to determine the validity of tax numbers We're using regular expressions stored in the business rules table to
097 * validate whether the tax number is in the correct format. The regular expressions are : (please update this javadoc comment
098 * when the regular expressions change) 1. For SSN : (?!000)(?!666)(\d{3})([ \-]?)(?!00)(\d{2})([\-]?)(?!0000)(\d{4}) 2. For
099 * FEIN : (?!00)(\d{3})([ \-]?)(\d{2})([\-]?)(?!0000)(\d{4})
100 *
101 * @param taxNbr A tax number String (SSN or FEIN)
102 * @param taxType determines SSN or FEIN tax number type
103 * @return True if the tax number is known to be in a valid format
104 */
105 public boolean isValidTaxNumber(String taxNbr, String taxType) {
106 String[] ssnFormats = parseSSNFormats();
107 String[] feinFormats = parseFEINFormats();
108 Integer defaultTaxNumberDigits = new Integer(parameterService.getParameterValue(VendorDetail.class, "DEFAULT_TAX_NUMBER_DIGITS"));
109
110 if (taxNbr.length() != defaultTaxNumberDigits || !isStringAllNumbers(taxNbr)) {
111 return false;
112 }
113
114 if (taxType.equals(VendorConstants.TAX_TYPE_SSN)) {
115
116 for (int i = 0; i < ssnFormats.length; i++) {
117 if (taxNbr.matches(ssnFormats[i])) {
118 return true;
119 }
120 }
121 return false;
122 }
123 else if (taxType.equals(VendorConstants.TAX_TYPE_FEIN)) {
124 for (int i = 0; i < feinFormats.length; i++) {
125 if (taxNbr.matches(feinFormats[i])) {
126 return true;
127 }
128 }
129 return false;
130 }
131
132 return true;
133 }
134
135
136 /**
137 * Someday we'll have to use the rules table instead of using constants. This method will return true if the tax number is an
138 * allowed tax number and return false if it's not allowed.
139 *
140 * @param taxNbr The tax number to be processed.
141 * @return boolean true if the tax number is allowed and false otherwise.
142 */
143 public boolean isAllowedTaxNumber(String taxNbr) {
144 String[] notAllowedTaxNumbers = parseNotAllowedTaxNumbers();
145 for (int i = 0; i < notAllowedTaxNumbers.length; i++) {
146 if (taxNbr.matches(notAllowedTaxNumbers[i])) {
147 return false;
148 }
149 }
150 return true;
151 }
152
153 /**
154 * Splits the set of tax number formats which are returned from the rule service as a semicolon-delimeted String into a String
155 * array.
156 *
157 * @return A String array of the tax number format regular expressions.
158 */
159 public String[] parseSSNFormats() {
160 if (ObjectUtils.isNull(taxNumberFormats)) {
161 taxNumberFormats = parameterService.getParameterValues(VendorDetail.class, VendorParameterConstants.TAX_SSN_NUMBER_FORMATS);
162 }
163 return taxNumberFormats.toArray(new String[] {});
164 }
165
166 /**
167 * Splits the set of tax fein number formats which are returned from the rule service as a semicolon-delimeted String into a
168 * String array.
169 *
170 * @return A String array of the tax fein number format regular expressions.
171 */
172 public String[] parseFEINFormats() {
173 if (ObjectUtils.isNull(feinNumberFormats)) {
174 feinNumberFormats = parameterService.getParameterValues(VendorDetail.class, VendorParameterConstants.TAX_FEIN_NUMBER_FORMATS);
175 }
176 return feinNumberFormats.toArray(new String[] {});
177 }
178
179 /**
180 * Splits the set of not allowed tax number formats which are returned from the rule service as a semicolon-delimeted String
181 * into a String array.
182 *
183 * @return A String array of the not allowed tax number format regular expressions.
184 */
185 public String[] parseNotAllowedTaxNumbers() {
186 if (ObjectUtils.isNull(notAllowedTaxNumbers)) {
187 notAllowedTaxNumbers = parameterService.getParameterValues(VendorDetail.class, VendorParameterConstants.NOT_ALLOWED_TAX_NUMBERS);
188 }
189 return notAllowedTaxNumbers.toArray(new String[] {});
190 }
191
192 }