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.businessobject.lookup;
017    
018    import java.sql.Date;
019    import java.util.ArrayList;
020    import java.util.Collections;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.commons.lang.StringUtils;
025    import org.apache.ojb.broker.query.Criteria;
026    import org.kuali.kfs.sys.KFSConstants;
027    import org.kuali.kfs.vnd.VendorConstants;
028    import org.kuali.kfs.vnd.VendorKeyConstants;
029    import org.kuali.kfs.vnd.VendorPropertyConstants;
030    import org.kuali.kfs.vnd.businessobject.VendorContract;
031    import org.kuali.rice.kns.bo.PersistableBusinessObject;
032    import org.kuali.rice.kns.dao.LookupDao;
033    import org.kuali.rice.kns.exception.ValidationException;
034    import org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl;
035    import org.kuali.rice.kns.service.DateTimeService;
036    import org.kuali.rice.kns.util.BeanPropertyComparator;
037    import org.kuali.rice.kns.util.GlobalVariables;
038    
039    public class VendorContractLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
040        private LookupDao lookupDao;
041        private DateTimeService dateTimeService;
042    
043        public void setLookupDao(LookupDao lookupDao) {
044            this.lookupDao = lookupDao;
045        }
046    
047        public void setDateTimeService(DateTimeService dateTimeService) {
048            this.dateTimeService = dateTimeService;
049        }
050    
051        /**
052         * Overrides the getSearchResults in the super class so that we can do some customization in our vendor contract lookup.
053         * 
054         * @see org.kuali.rice.kns.lookup.Lookupable#getSearchResults(java.util.Map)
055         */
056        @Override
057        public List<PersistableBusinessObject> getSearchResults(Map<String, String> fieldValues) {
058    
059            boolean unbounded = false;
060            super.setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION));
061            super.setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY));
062    
063            Date now = dateTimeService.getCurrentSqlDate();
064            Criteria additionalCriteria = new Criteria();
065            additionalCriteria.addLessOrEqualThan("vendorContractBeginningDate", now);
066            additionalCriteria.addGreaterOrEqualThan("vendorContractEndDate", now);
067    
068            // We ought to call the findCollectionBySearchHelper that would accept the additionalCriteria
069            boolean usePrimaryKeyValuesOnly = getLookupService().allPrimaryKeyValuesPresentAndNotWildcard(getBusinessObjectClass(), fieldValues);
070            List<PersistableBusinessObject> searchResults = (List) lookupDao.findCollectionBySearchHelper(getBusinessObjectClass(), fieldValues, unbounded, usePrimaryKeyValuesOnly, additionalCriteria);
071    
072            List<PersistableBusinessObject> finalSearchResults = new ArrayList();
073            // loop through results to eliminate inactive or debarred vendors
074            for (PersistableBusinessObject object : searchResults) {
075                VendorContract vendorContract = (VendorContract) object;
076                if (vendorContract.getVendorDetail().isActiveIndicator() && !vendorContract.getVendorDetail().isVendorDebarred()) {
077                    finalSearchResults.add(vendorContract);
078                }
079            }
080    
081            // sort list if default sort column given
082            List<String> defaultSortColumns = getDefaultSortColumns();
083            if (defaultSortColumns.size() > 0) {
084                Collections.sort(finalSearchResults, new BeanPropertyComparator(getDefaultSortColumns(), true));
085            }
086    
087            return finalSearchResults;
088        }
089    
090        /**
091         * Overrides a method of the superclass and is now called instead of that one by the Search method of KualiLookupAction when the
092         * Lookupable is of this class. This method first calls the method from the superclass, which should do all the required field
093         * checking, and then goes through all the specific validations which aren't done at the JSP level. Both the superclass
094         * method and the various validation methods side-effect the adding of errors to the global error map when the input is found to
095         * have an issue.
096         *
097         * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#validateSearchParameters(java.util.Map)
098         */
099        @Override
100        public void validateSearchParameters(Map fieldValues) {
101            super.validateSearchParameters(fieldValues);
102    
103            validateVendorNumber(fieldValues);
104    
105            if (!GlobalVariables.getMessageMap().isEmpty()) {
106                throw new ValidationException("Error(s) in search criteria");
107            }
108        }
109    
110        /**
111         * Validates that the Vendor Number has no more than one dash in it, and does not consist solely of one dash. Then it calls
112         * extractVendorNumberToVendorIds to obtain vendorHeaderGeneratedId and vendorDetailAssignedId and if either one of the ids
113         * cannot be converted to integers, it will add error that the vendor number must be numerics or numerics separated by a dash.
114         *
115         * @param fieldValues a Map containing only those key-value pairs that have been filled in on the lookup
116         */
117        private void validateVendorNumber(Map fieldValues) {
118            String vendorNumber = (String) fieldValues.get(VendorPropertyConstants.VENDOR_NUMBER);
119            if (StringUtils.isNotBlank(vendorNumber)) {
120                int dashPos1 = vendorNumber.indexOf(VendorConstants.DASH);
121                if (dashPos1 > -1) { // There's a dash in the number.
122                    if (vendorNumber.indexOf(VendorConstants.DASH, dashPos1 + 1) > -1) { // There can't be more than one.
123                        GlobalVariables.getMessageMap().putError(VendorPropertyConstants.VENDOR_NUMBER, VendorKeyConstants.ERROR_VENDOR_LOOKUP_VNDR_NUM_TOO_MANY_DASHES);
124                    }
125                    if (vendorNumber.matches("\\-*")) {
126                        GlobalVariables.getMessageMap().putError(VendorPropertyConstants.VENDOR_NUMBER, VendorKeyConstants.ERROR_VENDOR_LOOKUP_VNDR_NUM_DASHES_ONLY);
127                    }
128                }
129                extractVendorNumberToVendorIds(fieldValues, vendorNumber);
130            }
131        }
132    
133        /**
134         * Parses the vendorNumber string into vendorHeaderGeneratedIdentifier and vendorDetailAssignedIdentifier, validates that both
135         * fields would be able to be converted into integers, if so it will add both fields into the search criterias map in the
136         * fieldValues and remove the vendorNumber from the fieldValues. If the two fields cannot be converted into integers, this
137         * method will add error message to the errorMap in GlobalVariables that the vendor number must be numeric or numerics separated
138         * by a dash.
139         *
140         * @param fieldValues a Map containing only those key-value pairs that have been filled in on the lookup
141         * @param vendorNumber vendor number String
142         */
143        private void extractVendorNumberToVendorIds(Map fieldValues, String vendorNumber) {
144            String vendorHeaderGeneratedIdentifier = null;
145            String vendorDetailAssignedIdentifier = null;
146            int indexOfDash = vendorNumber.indexOf(VendorConstants.DASH);
147            if (indexOfDash < 0) {
148                vendorHeaderGeneratedIdentifier = vendorNumber;
149            }
150            else {
151                vendorHeaderGeneratedIdentifier = vendorNumber.substring(0, indexOfDash);
152                vendorDetailAssignedIdentifier = vendorNumber.substring(indexOfDash + 1, vendorNumber.length());
153            }
154            try {
155                if (StringUtils.isNotEmpty(vendorHeaderGeneratedIdentifier)) {
156                    Integer.parseInt(vendorHeaderGeneratedIdentifier);
157                }
158                if (StringUtils.isNotEmpty(vendorDetailAssignedIdentifier)) {
159                    Integer.parseInt(vendorDetailAssignedIdentifier);
160                }
161                fieldValues.remove(VendorPropertyConstants.VENDOR_NUMBER);
162                fieldValues.put(VendorPropertyConstants.VENDOR_HEADER_GENERATED_ID, vendorHeaderGeneratedIdentifier);
163                fieldValues.put(VendorPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID, vendorDetailAssignedIdentifier);
164            }
165            catch (NumberFormatException headerExc) {
166                GlobalVariables.getMessageMap().putError(VendorPropertyConstants.VENDOR_NUMBER, VendorKeyConstants.ERROR_VENDOR_LOOKUP_VNDR_NUM_NUMERIC_DASH_SEPARATED);
167            }
168        }
169        
170    }