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.sql.Date;
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.Constant;
026 import org.kuali.kfs.gl.businessobject.Entry;
027 import org.kuali.kfs.gl.businessobject.inquiry.EntryInquirableImpl;
028 import org.kuali.kfs.gl.businessobject.inquiry.InquirableFinancialDocument;
029 import org.kuali.kfs.gl.service.EntryService;
030 import org.kuali.kfs.gl.service.ScrubberValidator;
031 import org.kuali.kfs.sys.KFSConstants;
032 import org.kuali.kfs.sys.KFSKeyConstants;
033 import org.kuali.kfs.sys.KFSPropertyConstants;
034 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry;
035 import org.kuali.kfs.sys.businessobject.UniversityDate;
036 import org.kuali.kfs.sys.context.SpringContext;
037 import org.kuali.kfs.sys.service.UniversityDateService;
038 import org.kuali.rice.kns.bo.BusinessObject;
039 import org.kuali.rice.kns.exception.ValidationException;
040 import org.kuali.rice.kns.lookup.HtmlData;
041 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
042 import org.kuali.rice.kns.service.DateTimeService;
043 import org.kuali.rice.kns.util.GlobalVariables;
044 import org.kuali.rice.kns.util.KNSConstants;
045
046 /**
047 * An extension of KualiLookupableImpl to support entry lookups
048 */
049 public class EntryLookupableHelperServiceImpl extends AbstractGeneralLedgerLookupableHelperServiceImpl {
050 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EntryLookupableHelperServiceImpl.class);
051
052 private ScrubberValidator scrubberValidator;
053 private EntryService entryService;
054
055 /**
056 * Validate the university fiscal year that has been queried on
057 *
058 * @param fieldValues the queried fields
059 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#validateSearchParameters(java.util.Map)
060 */
061 @Override
062 public void validateSearchParameters(Map fieldValues) {
063 super.validateSearchParameters(fieldValues);
064
065 String valueFiscalYear = (String) fieldValues.get("universityFiscalYear");
066 if (!StringUtils.isEmpty(valueFiscalYear)) {
067 try {
068 int year = Integer.parseInt(valueFiscalYear);
069 }
070 catch (NumberFormatException e) {
071 GlobalVariables.getMessageMap().putError("universityFiscalYear", KFSKeyConstants.ERROR_CUSTOM, new String[] { "Fiscal Year must be a four-digit number" });
072 throw new ValidationException("errors in search criteria");
073 }
074 }
075
076 if (!allRequiredsForAccountSearch(fieldValues) && !allRequiredsForDocumentSearch(fieldValues)) {
077 GlobalVariables.getMessageMap().putError("universityFiscalYear", KFSKeyConstants.ERROR_GL_LOOKUP_ENTRY_NON_MATCHING_REQUIRED_FIELDS, new String[] {});
078 throw new ValidationException("errors in search criteria");
079 }
080 }
081
082 /**
083 * Determines if all the required values for an account based search are present - fiscal year, chart, account number, and fiscal period code
084 * @param fieldValues field values to check
085 * @return true if all the account-based required search fields are present; false otherwise
086 */
087 protected boolean allRequiredsForAccountSearch(Map fieldValues) {
088 final String fiscalYearAsString = (String)fieldValues.get("universityFiscalYear");
089 final String chartOfAccountsCode = (String)fieldValues.get("chartOfAccountsCode");
090 final String accountNumber = (String)fieldValues.get("accountNumber");
091 final String fiscalPeriodCode = (String)fieldValues.get("universityFiscalPeriodCode");
092 return !StringUtils.isBlank(fiscalYearAsString) && !StringUtils.isBlank(chartOfAccountsCode) && !StringUtils.isBlank(accountNumber) && !StringUtils.isBlank(fiscalPeriodCode);
093 }
094
095 /**
096 * Determines if all the required values for an document based search are present - fiscal year and document number
097 * @param fieldValues field values to check
098 * @return true if all the document-based required search fields are present; false otherwise
099 */
100 protected boolean allRequiredsForDocumentSearch(Map fieldValues) {
101 final String fiscalYearAsString = (String)fieldValues.get("universityFiscalYear");
102 final String documentNumber = (String)fieldValues.get("documentNumber");
103 return !StringUtils.isBlank(fiscalYearAsString) && !StringUtils.isBlank(documentNumber);
104 }
105
106 /**
107 * Returns the url for any drill down links within the lookup
108 * @param bo the business object with a property being drilled down on
109 * @param propertyName the name of the property being drilled down on
110 * @return a String with the URL of the property
111 * @see org.kuali.rice.kns.lookup.Lookupable#getInquiryUrl(org.kuali.rice.kns.bo.BusinessObject, java.lang.String)
112 */
113 @Override
114 public HtmlData getInquiryUrl(BusinessObject businessObject, String propertyName) {
115 if (KFSPropertyConstants.DOCUMENT_NUMBER.equals(propertyName)) {
116 if (businessObject instanceof Entry) {
117 Entry entry = (Entry) businessObject;
118 return new AnchorHtmlData(new InquirableFinancialDocument().getInquirableDocumentUrl(entry), KNSConstants.EMPTY_STRING, "view entry "+entry.toString());
119 }
120 }
121 return (new EntryInquirableImpl()).getInquiryUrl(businessObject, propertyName);
122 }
123
124 /**
125 * Generates the list of search results for this inquiry
126 * @param fieldValues the field values of the query to carry out
127 * @return List the search results returned by the lookup
128 * @see org.kuali.rice.kns.lookup.Lookupable#getSearchResults(java.util.Map)
129 */
130 @Override
131 public List getSearchResults(Map fieldValues) {
132 setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION));
133 setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY));
134
135 // get the pending entry option. This method must be prior to the get search results
136 String pendingEntryOption = this.getSelectedPendingEntryOption(fieldValues);
137
138 // get the search result collection
139 Collection searchResultsCollection = getLookupService().findCollectionBySearch(getBusinessObjectClass(), fieldValues);
140
141 // update search results according to the selected pending entry option
142 updateByPendingLedgerEntry(searchResultsCollection, fieldValues, pendingEntryOption, false, false);
143
144 // get the actual size of all qualified search results
145 Long actualSize = new Long(entryService.getEntryRecordCount(fieldValues));
146
147 return this.buildSearchResultList(searchResultsCollection, actualSize);
148 }
149
150 /**
151 * Updates pending entries before their results are included in the lookup results
152 *
153 * @param entryCollection a collection of balance entries
154 * @param fieldValues the map containing the search fields and values
155 * @param isApproved flag whether the approved entries or all entries will be processed
156 * @param isConsolidated flag whether the results are consolidated or not
157 * @param isCostShareExcluded flag whether the user selects to see the results with cost share subaccount
158 * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableImpl#updateEntryCollection(java.util.Collection, java.util.Map,
159 * boolean, boolean, boolean)
160 */
161 @Override
162 protected void updateEntryCollection(Collection entryCollection, Map fieldValues, boolean isApproved, boolean isConsolidated, boolean isCostShareInclusive) {
163 LOG.debug("updateEntryCollection started");
164
165 // convert the field names of balance object into corresponding ones of pending entry object
166 Map pendingEntryFieldValues = BusinessObjectFieldConverter.convertToTransactionFieldValues(fieldValues);
167
168 // go through the pending entries to update the balance collection
169 Iterator pendingEntryIterator = getGeneralLedgerPendingEntryService().findPendingLedgerEntriesForEntry(pendingEntryFieldValues, isApproved);
170
171 String pendingOption = isApproved ? Constant.APPROVED_PENDING_ENTRY : Constant.ALL_PENDING_ENTRY;
172 UniversityDate today = SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate();
173 String currentFiscalPeriodCode = today.getUniversityFiscalAccountingPeriod();
174 Integer currentFiscalYear = today.getUniversityFiscalYear();
175 Date postDate = SpringContext.getBean(DateTimeService.class).getCurrentSqlDate();
176
177 while (pendingEntryIterator.hasNext()) {
178 GeneralLedgerPendingEntry pendingEntry = (GeneralLedgerPendingEntry) pendingEntryIterator.next();
179
180 // Gotta circumvent date checks in the scrubberValidator. They totally kill performance.
181 if (pendingEntry.getUniversityFiscalYear() == null) {
182 pendingEntry.setUniversityFiscalYear(currentFiscalYear);
183 }
184
185 if (pendingEntry.getUniversityFiscalPeriodCode() == null) {
186 pendingEntry.setUniversityFiscalPeriodCode(currentFiscalPeriodCode);
187 }
188
189 scrubberValidator.validateForInquiry(pendingEntry);
190
191 Entry entry = new Entry(pendingEntry, postDate);
192
193 String approvedCode = pendingEntry.getFinancialDocumentApprovedCode();
194 String description = Constant.DocumentApprovedCode.getDescription(approvedCode);
195 entry.getDummyBusinessObject().setPendingEntryOption(description);
196
197 entryCollection.add(entry);
198 }
199 }
200
201 /**
202 * Sets the scrubberValidator attribute value.
203 *
204 * @param scrubberValidator The scrubberValidator to set.
205 */
206 public void setScrubberValidator(ScrubberValidator scrubberValidator) {
207 this.scrubberValidator = scrubberValidator;
208 }
209
210 /**
211 * Sets the entryService attribute value.
212 *
213 * @param entryService The entryService to set.
214 */
215 public void setEntryService(EntryService entryService) {
216 this.entryService = entryService;
217 }
218 }