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 }