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