001: /*
002: * Copyright 2007 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: */
016: package org.kuali.module.pdp.lookup;
017:
018: import java.util.Collection;
019: import java.util.Collections;
020: import java.util.List;
021: import java.util.Map;
022:
023: import org.apache.commons.lang.StringUtils;
024: import org.kuali.RiceConstants;
025: import org.kuali.core.bo.BusinessObject;
026: import org.kuali.core.bo.user.UniversalUser;
027: import org.kuali.core.lookup.AbstractLookupableHelperServiceImpl;
028: import org.kuali.core.lookup.LookupUtils;
029: import org.kuali.core.lookup.LookupableHelperService;
030: import org.kuali.core.service.BusinessObjectDictionaryService;
031: import org.kuali.core.service.DataDictionaryService;
032: import org.kuali.core.util.BeanPropertyComparator;
033: import org.kuali.core.util.GlobalVariables;
034: import org.kuali.core.web.struts.form.LookupForm;
035: import org.kuali.core.web.ui.Row;
036: import org.kuali.module.vendor.VendorConstants;
037: import org.kuali.module.vendor.VendorKeyConstants;
038: import org.kuali.module.vendor.VendorPropertyConstants;
039:
040: /**
041: * This lookupable helper service is used to support lookups on the PayeeAchAccount BO because it deals with the vendor number,
042: * which isn't really a field, but rather a combination of 2 fields.
043: *
044: * This code mostly copies {@link org.kuali.core.lookup.KualiLookupableHelperServiceImpl}, but differs in that this class will
045: * not remove search criteria containing values corresponding to hidden fields.
046: *
047: * NOTE: this class is a good candidate for refactoring to combine code with {@link org.kuali.module.vendor.lookup.VendorLookupableHelperServiceImpl}, because
048: * it shares some common code with it.
049: */
050: public class PayeeAchAccountLookupableHelperService extends
051: AbstractLookupableHelperServiceImpl {
052: public void validateSearchParameters(Map fieldValues) {
053: super .validateSearchParameters(fieldValues);
054:
055: validateVendorNumber(fieldValues);
056: }
057:
058: /**
059: * Validates that the Vendor Number has no more than one dash in it, and does not consist solely of one dash. Then it calls
060: * extractVendorNumberToVendorIds to obtain vendorHeaderGeneratedId and vendorDetailAssignedId and if either one of the ids
061: * cannot be converted to integers, it will add error that the vendor number must be numerics or numerics separated by a dash.
062: *
063: * @param fieldValues a Map containing only those key-value pairs that have been filled in on the lookup
064: */
065: protected void validateVendorNumber(Map fieldValues) {
066: String vendorNumber = (String) fieldValues
067: .get(VendorPropertyConstants.VENDOR_NUMBER);
068: if (StringUtils.isNotBlank(vendorNumber)) {
069: int dashPos1 = vendorNumber.indexOf(VendorConstants.DASH);
070: if (dashPos1 > -1) { // There's a dash in the number.
071: if (vendorNumber.indexOf(VendorConstants.DASH,
072: dashPos1 + 1) > -1) { // There can't be more than one.
073: GlobalVariables
074: .getErrorMap()
075: .putError(
076: VendorPropertyConstants.VENDOR_NUMBER,
077: VendorKeyConstants.ERROR_VENDOR_LOOKUP_VNDR_NUM_TOO_MANY_DASHES);
078: }
079: if (vendorNumber.matches("\\-*")) {
080: GlobalVariables
081: .getErrorMap()
082: .putError(
083: VendorPropertyConstants.VENDOR_NUMBER,
084: VendorKeyConstants.ERROR_VENDOR_LOOKUP_VNDR_NUM_DASHES_ONLY);
085: }
086: }
087: extractVendorNumberToVendorIds(fieldValues, vendorNumber);
088: }
089: }
090:
091: /**
092: * Parses the vendorNumber string into vendorHeaderGeneratedIdentifier and vendorDetailAssignedIdentifier, validates that both
093: * fields would be able to be converted into integers, if so it will add both fields into the search criterias map in the
094: * fieldValues and remove the vendorNumber from the fieldValues. If the two fields cannot be converted into integers, this
095: * method will add error message to the errorMap in GlobalVariables that the vendor number must be numeric or numerics separated
096: * by a dash.
097: *
098: * @param fieldValues a Map containing only those key-value pairs that have been filled in on the lookup
099: * @param vendorNumber venodr number String
100: */
101: protected void extractVendorNumberToVendorIds(Map fieldValues,
102: String vendorNumber) {
103: String vendorHeaderGeneratedIdentifier = null;
104: String vendorDetailAssignedIdentifier = null;
105: int indexOfDash = vendorNumber.indexOf(VendorConstants.DASH);
106: if (indexOfDash < 0) {
107: vendorHeaderGeneratedIdentifier = vendorNumber;
108: } else {
109: vendorHeaderGeneratedIdentifier = vendorNumber.substring(0,
110: indexOfDash);
111: vendorDetailAssignedIdentifier = vendorNumber.substring(
112: indexOfDash + 1, vendorNumber.length());
113: }
114: try {
115: if (StringUtils.isNotEmpty(vendorHeaderGeneratedIdentifier)) {
116: Integer.parseInt(vendorHeaderGeneratedIdentifier);
117: }
118: if (StringUtils.isNotEmpty(vendorDetailAssignedIdentifier)) {
119: Integer.parseInt(vendorDetailAssignedIdentifier);
120: }
121: fieldValues.remove(VendorPropertyConstants.VENDOR_NUMBER);
122: fieldValues.put(
123: VendorPropertyConstants.VENDOR_HEADER_GENERATED_ID,
124: vendorHeaderGeneratedIdentifier);
125: fieldValues.put(
126: VendorPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID,
127: vendorDetailAssignedIdentifier);
128: } catch (NumberFormatException headerExc) {
129: GlobalVariables
130: .getErrorMap()
131: .putError(
132: VendorPropertyConstants.VENDOR_NUMBER,
133: VendorKeyConstants.ERROR_VENDOR_LOOKUP_VNDR_NUM_NUMERIC_DASH_SEPARATED);
134: }
135: }
136:
137: /**
138: * Uses Lookup Service to provide a basic search.
139: *
140: * @param fieldValues - Map containing prop name keys and search values
141: *
142: * @return List found business objects
143: * @see org.kuali.core.lookup.LookupableHelperService#getSearchResults(java.util.Map)
144: */
145: public List<? extends BusinessObject> getSearchResults(
146: Map<String, String> fieldValues) {
147: return getSearchResultsHelper(LookupUtils.forceUppercase(
148: getBusinessObjectClass(), fieldValues), false);
149: }
150:
151: /**
152: * Uses Lookup Service to provide a basic unbounded search.
153: *
154: * @param fieldValues - Map containing prop name keys and search values
155: *
156: * @return List found business objects
157: * @see org.kuali.core.lookup.LookupableHelperService#getSearchResultsUnbounded(java.util.Map)
158: */
159: public List<? extends BusinessObject> getSearchResultsUnbounded(
160: Map<String, String> fieldValues) {
161: return getSearchResultsHelper(LookupUtils.forceUppercase(
162: getBusinessObjectClass(), fieldValues), true);
163: }
164:
165: /**
166: *
167: * This method does the actual search, with the parameters specified, and returns the result.
168: *
169: * NOTE that it will not do any upper-casing based on the DD forceUppercase. That is handled through an external call to
170: * LookupUtils.forceUppercase().
171: *
172: * @param fieldValues A Map of the fieldNames and fieldValues to be searched on.
173: * @param unbounded Whether the results should be bounded or not to a certain max size.
174: * @return A List of search results.
175: *
176: */
177: protected List<? extends BusinessObject> getSearchResultsHelper(
178: Map<String, String> fieldValues, boolean unbounded) {
179: // pretty much the same code as exists in KualiLookupableHelperServiceImpl, except that we're not removing hidden fields
180:
181: boolean searchUsingOnlyPrimaryKeyValues = getLookupService()
182: .allPrimaryKeyValuesPresentAndNotWildcard(
183: getBusinessObjectClass(), fieldValues);
184:
185: setBackLocation(fieldValues.get(RiceConstants.BACK_LOCATION));
186: setDocFormKey(fieldValues.get(RiceConstants.DOC_FORM_KEY));
187: setReferencesToRefresh(fieldValues
188: .get(RiceConstants.REFERENCES_TO_REFRESH));
189: List searchResults;
190: if (UniversalUser.class.equals(getBusinessObjectClass())) {
191: searchResults = (List) getUniversalUserService()
192: .findUniversalUsers(fieldValues);
193: } else if (getUniversalUserService().hasUniversalUserProperty(
194: getBusinessObjectClass(), fieldValues)) {
195: // TODO WARNING: this does not support nested joins, because i don't have a test case
196: searchResults = (List) getUniversalUserService()
197: .findWithUniversalUserJoin(
198: getBusinessObjectClass(), fieldValues,
199: unbounded);
200: } else {
201: searchResults = (List) getLookupService()
202: .findCollectionBySearchHelper(
203: getBusinessObjectClass(), fieldValues,
204: unbounded);
205: }
206: // sort list if default sort column given
207: List defaultSortColumns = getDefaultSortColumns();
208: if (defaultSortColumns.size() > 0) {
209: Collections.sort(searchResults, new BeanPropertyComparator(
210: getDefaultSortColumns(), true));
211: }
212: return searchResults;
213: }
214: }
|