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 }