001/* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 1.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/ecl1.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 */ 016package org.kuali.ole.vnd.batch.dataaccess; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import org.apache.commons.lang.StringUtils; 022import org.kuali.ole.vnd.businessobject.DebarredVendorMatch; 023import org.kuali.ole.vnd.businessobject.VendorAddress; 024import org.kuali.ole.vnd.document.service.VendorService; 025import org.kuali.rice.core.framework.persistence.jdbc.dao.PlatformAwareDaoBaseJdbc; 026import org.springframework.jdbc.support.rowset.SqlRowSet; 027 028public class DebarredVendorDaoJdbc extends PlatformAwareDaoBaseJdbc implements DebarredVendorDao { 029 private VendorService vendorService; 030 private DebarredVendorMatchDao debarredVendorMatchDao; 031 032 @Override 033 public List<DebarredVendorMatch> match() { 034 String active = "dtl.DOBJ_MAINT_CD_ACTV_IND = 'Y'"; 035 String joinDtl = " INNER JOIN pur_vndr_dtl_t dtl"; 036 String joinExcl = " INNER JOIN PUR_VNDR_EXCL_MT excl"; 037 String where = " WHERE " + active; 038 String eplsFields = "excl.VNDR_EXCL_ID, excl.VNDR_EXCL_LOAD_DT, excl.VNDR_EXCL_NM, excl.VNDR_EXCL_LN1_ADDR, excl.VNDR_EXCL_LN2_ADDR, excl.VNDR_EXCL_CTY_NM" + 039 ", excl.VNDR_EXCL_ST_CD, excl.VNDR_EXCL_PRVN_NM, excl.VNDR_EXCL_ZIP_CD, excl.VNDR_EXCL_OTHR_NM, excl.VNDR_EXCL_DESC_TXT"; 040 041 String selectName = "SELECT dtl.VNDR_HDR_GNRTD_ID, dtl.VNDR_DTL_ASND_ID, " + eplsFields + " , 0 VNDR_ADDR_GNRTD_ID"; 042 String fromName = " FROM pur_vndr_dtl_t dtl"; 043 String name = filter("dtl.VNDR_NM", "., "); 044 String eplsName = filter("excl.VNDR_EXCL_NM", "., "); 045 String onName = " ON " + compare(name, eplsName, false); // use = to compare 046 String sqlName = selectName + fromName + joinExcl + onName + where; 047 048 String selectAlias = "SELECT als.VNDR_HDR_GNRTD_ID, als.VNDR_DTL_ASND_ID, " + eplsFields + " , 0 VNDR_ADDR_GNRTD_ID"; 049 String fromAlias = " FROM pur_vndr_alias_t als"; 050 String onAlsDtl = " ON als.VNDR_HDR_GNRTD_ID = dtl.VNDR_HDR_GNRTD_ID AND als.VNDR_DTL_ASND_ID = dtl.VNDR_DTL_ASND_ID"; 051 String alias = filter("als.VNDR_ALIAS_NM", "., "); 052 String eplsAlias = filter("excl.VNDR_EXCL_NM", "., "); 053 String onAlias = " ON " + compare(alias, eplsAlias, false); // use = to compare 054 String sqlAlias = selectAlias + fromAlias + joinDtl + onAlsDtl + joinExcl + onAlias + where; 055 056 String selectAddr = "SELECT addr.VNDR_HDR_GNRTD_ID, addr.VNDR_DTL_ASND_ID, " + eplsFields + " , addr.VNDR_ADDR_GNRTD_ID"; 057 String fromAddr = " FROM pur_vndr_addr_t addr"; 058 String onAddrDtl = " ON addr.VNDR_HDR_GNRTD_ID = dtl.VNDR_HDR_GNRTD_ID AND addr.VNDR_DTL_ASND_ID = dtl.VNDR_DTL_ASND_ID"; 059 // 060 String addr1 = filter("addr.VNDR_LN1_ADDR", ".,# "); 061 String eplsAddr1 = filter("excl.VNDR_EXCL_LN1_ADDR", ".,# "); 062 String cmpAddr1 = compare(addr1, eplsAddr1, true); // use LIKE to compare 063 // 064 String city = filter("addr.VNDR_CTY_NM", "., "); 065 String eplsCity = filter("excl.VNDR_EXCL_CTY_NM", "., "); 066 String cmpCity = compare(city, eplsCity, false); // use = to compare 067 // 068 String state = "upper(addr.VNDR_ST_CD)"; 069 String eplsState = "upper(excl.VNDR_EXCL_ST_CD)"; 070 String cmpState = compare(state, eplsState, false); // use = to compare 071 // 072 String zip = filter("addr.VNDR_ZIP_CD", "-"); 073 String eplsZip = filter("excl.VNDR_EXCL_ZIP_CD", "-"); 074 String cmpZip = compare(zip, eplsZip, false); // use = to compare 075 String fullZip = "length(addr.VNDR_ZIP_CD) > 5"; 076 // 077 String onAddr = " ON (" + cmpAddr1 + " OR " + cmpZip + " AND " + fullZip + ") AND " + cmpCity + " AND " + cmpState; 078 String sqlAddr = selectAddr + fromAddr + joinDtl + onAddrDtl + joinExcl + onAddr + where; 079 080 String max = ", MAX(VNDR_ADDR_GNRTD_ID)"; 081 String selectFields = "VNDR_HDR_GNRTD_ID, VNDR_DTL_ASND_ID, VNDR_EXCL_ID, VNDR_EXCL_LOAD_DT, VNDR_EXCL_NM, VNDR_EXCL_LN1_ADDR, VNDR_EXCL_LN2_ADDR, VNDR_EXCL_CTY_NM" + 082 ", VNDR_EXCL_ST_CD, VNDR_EXCL_PRVN_NM, VNDR_EXCL_ZIP_CD, VNDR_EXCL_OTHR_NM, VNDR_EXCL_DESC_TXT"; 083 String select = "SELECT " + selectFields + max; 084 String subqr = sqlName + " UNION " + sqlAlias + " UNION " + sqlAddr; 085 String from = " FROM (" + subqr + ")"; 086 String group = " GROUP BY " + selectFields; 087 String sql = select + from + group; 088 089 090 List<DebarredVendorMatch> matches = new ArrayList<DebarredVendorMatch>(); 091 try { 092 SqlRowSet rs = getJdbcTemplate().queryForRowSet(sql); 093 DebarredVendorMatch match; 094 095 while(rs.next()) { 096 match = new DebarredVendorMatch(); 097 match.setVendorHeaderGeneratedIdentifier(new Integer(rs.getInt(1))); 098 match.setVendorDetailAssignedIdentifier(new Integer(rs.getInt(2))); 099 match.setLoadDate(rs.getDate(4)); 100 match.setName(rs.getString(5)); 101 match.setAddress1(rs.getString(6)); 102 match.setAddress2(rs.getString(7)); 103 match.setCity(rs.getString(8)); 104 match.setState(rs.getString(9)); 105 match.setProvince(rs.getString(10)); 106 match.setZip(rs.getString(11)); 107 match.setAliases(rs.getString(12)); 108 match.setDescription(rs.getString(13)); 109 match.setAddressGeneratedId(rs.getLong(14)); 110 // didn't find a matched address, search for best one 111 if (match.getAddressGeneratedId() == 0) { 112 match.setAddressGeneratedId(getMatchAddressId(match)); 113 } 114 115 DebarredVendorMatch oldMatch = debarredVendorMatchDao.getPreviousVendorExcludeConfirmation(match); 116 if (oldMatch == null) { 117 // store the match only if an exact old match doesn't exist 118 match.setConfirmStatusCode("U"); // status - Unprocessed 119 matches.add(match); 120 } 121 } 122 } catch (Exception e) { 123 // if exception occurs, return empty results 124 throw new RuntimeException(e); 125 } 126 127 return matches; 128 } 129 130 /** 131 * Gets the addressGeneratedId of the vendor address that matches best with the address of the 132 * EPLS debarred vendor in the specified vendor exclude match. 133 * If no address matches, returns the default address for IU campus. 134 */ 135 protected long getMatchAddressId(DebarredVendorMatch match) { 136 long bestid = 0; 137 long defaultId = 0; 138 int maxPriority = 0; 139 List<VendorAddress> addresses = vendorService.getVendorDetail(match.getVendorHeaderGeneratedIdentifier(), 140 match.getVendorDetailAssignedIdentifier()).getVendorAddresses(); 141 if (addresses == null ) { 142 return bestid; 143 } 144 145 for (VendorAddress address : addresses) { 146 if (address.isVendorDefaultAddressIndicator()) { 147 defaultId = address.getVendorAddressGeneratedIdentifier(); 148 } 149 //each condition satisfied will increase the priority score for this address 150 int priority = 0; 151 String vendorAddr1 = StringUtils.replaceChars(address.getVendorLine1Address(), ".,# ", ""); 152 String eplsAddr1 = StringUtils.replaceChars(match.getAddress1(), ".,# ", ""); 153 if (StringUtils.equalsIgnoreCase(vendorAddr1, eplsAddr1)) { 154 priority++; 155 } 156 String vendorCity = StringUtils.replaceChars(address.getVendorCityName(), "., ", ""); 157 String eplsCity = StringUtils.replaceChars(match.getCity(), "., ", ""); 158 if (StringUtils.equalsIgnoreCase(vendorCity, eplsCity)) { 159 priority++; 160 } 161 if (StringUtils.equalsIgnoreCase(address.getVendorStateCode(), match.getState())) { 162 priority++; 163 } 164 String vendorZip = StringUtils.substring(address.getVendorZipCode(), 0, 5); 165 String eplsZip = StringUtils.substring(match.getZip(), 0, 5); 166 if (StringUtils.equals(vendorZip, eplsZip)) { 167 priority++; 168 } 169 if (priority >= maxPriority) { 170 bestid = address.getVendorAddressGeneratedIdentifier(); 171 maxPriority = priority; 172 } 173 } 174 if (bestid == 0) { 175 bestid = defaultId; 176 } 177 return bestid; 178 } 179 180 protected String filter(String field, String charset) { 181 // add upper function 182 String upper = "upper(" + field + ")"; 183 if (charset == null) 184 return upper; 185 186 // add replace functions layer by layer to filter out the chars in the charset one by one 187 String replace = upper; 188 char[] chararr = charset.toCharArray(); 189 for (char ch : chararr) { 190 // replace with empty string 191 replace = "replace(" + replace + ", '" + ch + "', '')"; 192 } 193 return replace; 194 } 195 196 protected String compare(String fieldl, String fieldr, boolean useLike) { 197 String cmpstr = ""; 198 199 // whether neither field is null 200 String notnulll = fieldl + " IS NOT NULL"; 201 String notnullr = fieldr + " IS NOT NULL"; 202 203 if (useLike) { 204 // whether one of the two fields is substring of the other 205 String like1 = notnullr + " AND " + fieldl + " LIKE '%'||" + fieldr + "||'%'"; 206 String like2 = notnulll + " AND " + fieldr + " LIKE '%'||" + fieldl + "||'%'"; 207 cmpstr += "(" + like1 + " OR " + like2 + ")"; // put () around the 'OR' to ensure integrity 208 } 209 else { 210 // whether the two fields equal 211 cmpstr = notnulll + " AND " + fieldl + " = " + fieldr; 212 } 213 214 return cmpstr; 215 } 216 217 /** 218 * Gets the vendorService attribute. 219 * @return Returns the vendorService. 220 */ 221 public VendorService getVendorService() { 222 return vendorService; 223 } 224 225 /** 226 * Sets the vendorService attribute value. 227 * @param vendorService The vendorService to set. 228 */ 229 public void setVendorService(VendorService vendorService) { 230 this.vendorService = vendorService; 231 } 232 233 /** 234 * Gets the debarredVendorMatchDao attribute. 235 * @return Returns the debarredVendorMatchDao. 236 */ 237 public DebarredVendorMatchDao getDebarredVendorMatchDao() { 238 return debarredVendorMatchDao; 239 } 240 241 /** 242 * Sets the debarredVendorMatchDao attribute value. 243 * @param debarredVendorMatchDao The debarredVendorMatchDao to set. 244 */ 245 public void setDebarredVendorMatchDao(DebarredVendorMatchDao debarredVendorMatchDao) { 246 this.debarredVendorMatchDao = debarredVendorMatchDao; 247 } 248 249}