View Javadoc
1   /*
2    * Copyright 2011 The Kuali Foundation.
3    *
4    * Licensed under the Educational Community License, Version 1.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl1.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.vnd.batch.dataaccess;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.apache.commons.lang.StringUtils;
22  import org.kuali.ole.vnd.businessobject.DebarredVendorMatch;
23  import org.kuali.ole.vnd.businessobject.VendorAddress;
24  import org.kuali.ole.vnd.document.service.VendorService;
25  import org.kuali.rice.core.framework.persistence.jdbc.dao.PlatformAwareDaoBaseJdbc;
26  import org.springframework.jdbc.support.rowset.SqlRowSet;
27  
28  public class DebarredVendorDaoJdbc extends  PlatformAwareDaoBaseJdbc implements DebarredVendorDao {
29      private VendorService vendorService;
30      private DebarredVendorMatchDao debarredVendorMatchDao;
31  
32      @Override
33      public List<DebarredVendorMatch> match() {
34          String active = "dtl.DOBJ_MAINT_CD_ACTV_IND = 'Y'";
35          String joinDtl = " INNER JOIN pur_vndr_dtl_t dtl";
36          String joinExcl = " INNER JOIN PUR_VNDR_EXCL_MT excl";
37          String where = " WHERE " + active;
38          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" +
39          		", 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";
40  
41          String selectName = "SELECT dtl.VNDR_HDR_GNRTD_ID, dtl.VNDR_DTL_ASND_ID, " + eplsFields + " , 0 VNDR_ADDR_GNRTD_ID";
42          String fromName = " FROM pur_vndr_dtl_t dtl";
43          String name = filter("dtl.VNDR_NM", "., ");
44          String eplsName = filter("excl.VNDR_EXCL_NM", "., ");
45          String onName = " ON " + compare(name, eplsName, false); // use = to compare
46          String sqlName = selectName + fromName + joinExcl + onName + where;
47  
48          String selectAlias = "SELECT als.VNDR_HDR_GNRTD_ID, als.VNDR_DTL_ASND_ID, " + eplsFields + " , 0 VNDR_ADDR_GNRTD_ID";
49          String fromAlias = " FROM pur_vndr_alias_t als";
50          String onAlsDtl = " ON als.VNDR_HDR_GNRTD_ID = dtl.VNDR_HDR_GNRTD_ID AND als.VNDR_DTL_ASND_ID = dtl.VNDR_DTL_ASND_ID";
51          String alias = filter("als.VNDR_ALIAS_NM", "., ");
52          String eplsAlias = filter("excl.VNDR_EXCL_NM", "., ");
53          String onAlias = " ON " + compare(alias, eplsAlias, false); // use = to compare
54          String sqlAlias = selectAlias + fromAlias + joinDtl + onAlsDtl + joinExcl + onAlias + where;
55  
56          String selectAddr = "SELECT addr.VNDR_HDR_GNRTD_ID, addr.VNDR_DTL_ASND_ID, " + eplsFields + " , addr.VNDR_ADDR_GNRTD_ID";
57          String fromAddr = " FROM pur_vndr_addr_t addr";
58          String onAddrDtl = " ON addr.VNDR_HDR_GNRTD_ID = dtl.VNDR_HDR_GNRTD_ID AND addr.VNDR_DTL_ASND_ID = dtl.VNDR_DTL_ASND_ID";
59          //
60          String addr1 = filter("addr.VNDR_LN1_ADDR", ".,# ");
61          String eplsAddr1 = filter("excl.VNDR_EXCL_LN1_ADDR", ".,# ");
62          String cmpAddr1 = compare(addr1, eplsAddr1, true); // use LIKE to compare
63          //
64          String city = filter("addr.VNDR_CTY_NM", "., ");
65          String eplsCity = filter("excl.VNDR_EXCL_CTY_NM", "., ");
66          String cmpCity = compare(city, eplsCity, false); // use = to compare
67          //
68          String state = "upper(addr.VNDR_ST_CD)";
69          String eplsState = "upper(excl.VNDR_EXCL_ST_CD)";
70          String cmpState = compare(state, eplsState, false); // use = to compare
71          //
72          String zip = filter("addr.VNDR_ZIP_CD", "-");
73          String eplsZip = filter("excl.VNDR_EXCL_ZIP_CD", "-");
74          String cmpZip = compare(zip, eplsZip, false); // use = to compare
75          String fullZip = "length(addr.VNDR_ZIP_CD) > 5";
76          //
77          String onAddr = " ON (" + cmpAddr1 + " OR " + cmpZip + " AND " + fullZip + ") AND " + cmpCity + " AND " + cmpState;
78          String sqlAddr = selectAddr + fromAddr + joinDtl + onAddrDtl + joinExcl + onAddr + where;
79  
80          String max = ", MAX(VNDR_ADDR_GNRTD_ID)";
81          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" +
82                  ", VNDR_EXCL_ST_CD, VNDR_EXCL_PRVN_NM, VNDR_EXCL_ZIP_CD, VNDR_EXCL_OTHR_NM, VNDR_EXCL_DESC_TXT";
83          String select = "SELECT " + selectFields + max;
84          String subqr = sqlName + " UNION " + sqlAlias + " UNION " + sqlAddr;
85          String from = " FROM (" + subqr + ")";
86          String group = " GROUP BY " + selectFields;
87          String sql = select + from + group;
88  
89  
90          List<DebarredVendorMatch> matches = new ArrayList<DebarredVendorMatch>();
91          try {
92              SqlRowSet rs = getJdbcTemplate().queryForRowSet(sql);
93              DebarredVendorMatch match;
94  
95              while(rs.next()) {
96                  match = new DebarredVendorMatch();
97                  match.setVendorHeaderGeneratedIdentifier(new Integer(rs.getInt(1)));
98                  match.setVendorDetailAssignedIdentifier(new Integer(rs.getInt(2)));
99                  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 }