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.gl.businessobject.lookup;
017    
018    import java.util.ArrayList;
019    import java.util.Collection;
020    import java.util.Iterator;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.commons.lang.StringUtils;
025    import org.kuali.kfs.gl.OJBUtility;
026    import org.kuali.kfs.gl.batch.service.EncumbranceCalculator;
027    import org.kuali.kfs.gl.businessobject.Encumbrance;
028    import org.kuali.kfs.gl.businessobject.inquiry.EncumbranceInquirableImpl;
029    import org.kuali.kfs.gl.service.EncumbranceService;
030    import org.kuali.kfs.sys.KFSConstants;
031    import org.kuali.kfs.sys.KFSKeyConstants;
032    import org.kuali.kfs.sys.KFSPropertyConstants;
033    import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry;
034    import org.kuali.rice.kns.bo.BusinessObject;
035    import org.kuali.rice.kns.exception.ValidationException;
036    import org.kuali.rice.kns.lookup.HtmlData;
037    import org.kuali.rice.kns.util.GlobalVariables;
038    
039    /**
040     * An extension of KualiLookupableImpl to support encumbrance lookups
041     */
042    public class EncumbranceLookupableHelperServiceImpl extends AbstractGeneralLedgerLookupableHelperServiceImpl {
043    
044        private EncumbranceCalculator postEncumbrance;
045        private EncumbranceService encumbranceService;
046    
047        /**
048         * Returns the url for any drill down links within the lookup
049         * @param bo the business object with a property being drilled down on
050         * @param propertyName the name of the property being drilled down on
051         * @return a String with the URL of the property
052         * @see org.kuali.rice.kns.lookup.Lookupable#getInquiryUrl(org.kuali.rice.kns.bo.BusinessObject, java.lang.String)
053         */
054        @Override
055        public HtmlData getInquiryUrl(BusinessObject businessObject, String propertyName) {
056            return (new EncumbranceInquirableImpl()).getInquiryUrl(businessObject, propertyName);
057        }
058        
059        /**
060         * Validates the fiscal year searched for in the inquiry
061         * @param fieldValues the values of the query
062         * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#validateSearchParameters(java.util.Map)
063         */
064        @Override
065        public void validateSearchParameters(Map fieldValues) {
066            super.validateSearchParameters(fieldValues);
067    
068            String valueFiscalYear = (String) fieldValues.get(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR);
069            if (!StringUtils.isEmpty(valueFiscalYear)) {
070                try {
071                    int year = Integer.parseInt(valueFiscalYear);
072                }
073                catch (NumberFormatException e) {
074                    GlobalVariables.getMessageMap().putError(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, KFSKeyConstants.ERROR_CUSTOM, new String[] { KFSKeyConstants.PendingEntryLookupableImpl.FISCAL_YEAR_FOUR_DIGIT });
075                    throw new ValidationException("errors in search criteria");
076                }
077            }
078            
079            if (!allRequiredsForAccountSearch(fieldValues) && !allRequiredsForDocumentSearch(fieldValues)) {
080                GlobalVariables.getMessageMap().putError("universityFiscalYear", KFSKeyConstants.ERROR_GL_LOOKUP_ENCUMBRANCE_NON_MATCHING_REQUIRED_FIELDS, new String[] {});
081                throw new ValidationException("errors in search criteria");
082            }
083        }
084        
085        /**
086         * Determines if all the required values for an account based search are present - fiscal year, chart, account number, and fiscal period code
087         * @param fieldValues field values to check
088         * @return true if all the account-based required search fields are present; false otherwise
089         */
090        protected boolean allRequiredsForAccountSearch(Map fieldValues) {
091            final String fiscalYearAsString = (String)fieldValues.get("universityFiscalYear");
092            final String chartOfAccountsCode = (String)fieldValues.get("chartOfAccountsCode");
093            final String accountNumber = (String)fieldValues.get("accountNumber");
094            return !StringUtils.isBlank(fiscalYearAsString) && !StringUtils.isBlank(chartOfAccountsCode) && !StringUtils.isBlank(accountNumber);
095        }
096        
097        /**
098         * Determines if all the required values for an document based search are present - fiscal year and document number
099         * @param fieldValues field values to check
100         * @return true if all the document-based required search fields are present; false otherwise
101         */
102        protected boolean allRequiredsForDocumentSearch(Map fieldValues) {
103            final String fiscalYearAsString = (String)fieldValues.get("universityFiscalYear");
104            final String documentNumber = (String)fieldValues.get("documentNumber");
105            return !StringUtils.isBlank(fiscalYearAsString) && !StringUtils.isBlank(documentNumber);
106        }
107    
108        /**
109         * Generates the list of search results for this inquiry
110         * @param fieldValues the field values of the query to carry out
111         * @return List the search results returned by the lookup
112         * @see org.kuali.rice.kns.lookup.Lookupable#getSearchResults(java.util.Map)
113         */
114        @Override
115        public List getSearchResults(Map fieldValues) {
116            setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION));
117            setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY));
118    
119            // get the pending entry option. This method must be prior to the get search results
120            String pendingEntryOption = this.getSelectedPendingEntryOption(fieldValues);
121    
122            // get the search result collection
123            Iterator encumbranceIterator = encumbranceService.findOpenEncumbrance(fieldValues);
124            Collection searchResultsCollection = this.buildEncumbranceCollection(encumbranceIterator);
125    
126            // update search results according to the selected pending entry option
127            updateByPendingLedgerEntry(searchResultsCollection, fieldValues, pendingEntryOption, false, false);
128    
129            // get the actual size of all qualified search results
130            Integer recordCount = encumbranceService.getOpenEncumbranceRecordCount(fieldValues);
131            Long actualSize = OJBUtility.getResultActualSize(searchResultsCollection, recordCount, fieldValues, new Encumbrance());
132    
133            return this.buildSearchResultList(searchResultsCollection, actualSize);
134        }
135    
136        /**
137         * Updates pending entries before their results are included in the lookup results
138         * 
139         * @param entryCollection a collection of balance entries
140         * @param fieldValues the map containing the search fields and values
141         * @param isApproved flag whether the approved entries or all entries will be processed
142         * @param isConsolidated flag whether the results are consolidated or not
143         * @param isCostShareExcluded flag whether the user selects to see the results with cost share subaccount
144         * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableImpl#updateEntryCollection(java.util.Collection, java.util.Map,
145         *      boolean, boolean, boolean)
146         */
147        @Override
148        protected void updateEntryCollection(Collection entryCollection, Map fieldValues, boolean isApproved, boolean isConsolidated, boolean isCostShareInclusive) {
149    
150            // convert the field names of balance object into corresponding ones of pending entry object
151            Map pendingEntryFieldValues = BusinessObjectFieldConverter.convertToTransactionFieldValues(fieldValues);
152    
153            // go through the pending entries to update the encumbrance collection
154            Iterator pendingEntryIterator = getGeneralLedgerPendingEntryService().findPendingLedgerEntriesForEncumbrance(pendingEntryFieldValues, isApproved);
155            while (pendingEntryIterator.hasNext()) {
156                GeneralLedgerPendingEntry pendingEntry = (GeneralLedgerPendingEntry) pendingEntryIterator.next();
157                Encumbrance encumbrance = postEncumbrance.findEncumbrance(entryCollection, pendingEntry);
158                postEncumbrance.updateEncumbrance(pendingEntry, encumbrance);
159            }
160        }
161    
162        /**
163         * go through the given iterator to get encumbrances and put them into a collection
164         * @param iterator an iterator of encumbrances
165         * @return a collection of those encumbrances
166         */
167        private Collection buildEncumbranceCollection(Iterator iterator) {
168            Collection encumbranceCollection = new ArrayList();
169    
170            while (iterator.hasNext()) {
171                Encumbrance encumrbance = (Encumbrance) iterator.next();
172                encumbranceCollection.add(encumrbance);
173            }
174            return encumbranceCollection;
175        }
176    
177        /**
178         * Sets the postEncumbrance attribute value.
179         * 
180         * @param postEncumbrance The postEncumbrance to set.
181         */
182        public void setPostEncumbrance(EncumbranceCalculator postEncumbrance) {
183            this.postEncumbrance = postEncumbrance;
184        }
185    
186        /**
187         * Sets the encumbranceService attribute value.
188         * 
189         * @param encumbranceService The encumbranceService to set.
190         */
191        public void setEncumbranceService(EncumbranceService encumbranceService) {
192            this.encumbranceService = encumbranceService;
193        }
194    }