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.Collection;
019 import java.util.Collections;
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.sys.KFSPropertyConstants;
027 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
028 import org.kuali.rice.kns.bo.BusinessObject;
029 import org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl;
030 import org.kuali.rice.kns.lookup.CollectionIncomplete;
031 import org.kuali.rice.kns.lookup.HtmlData;
032 import org.kuali.rice.kns.util.BeanPropertyComparator;
033 import org.kuali.rice.kns.web.ui.Field;
034 import org.kuali.rice.kns.web.ui.Row;
035
036 /**
037 * The abstract parent class for GL Lookupables, providing base implementations of methods
038 * to make adding new lookupable reports easier
039 */
040 public abstract class AbstractGeneralLedgerLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
041
042 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AbstractGeneralLedgerLookupableHelperServiceImpl.class);
043
044 private GeneralLedgerPendingEntryService generalLedgerPendingEntryService;
045
046 protected GeneralLedgerPendingEntryService getGeneralLedgerPendingEntryService() {
047 return generalLedgerPendingEntryService;
048 }
049
050 public void setGeneralLedgerPendingEntryService(GeneralLedgerPendingEntryService generalLedgerPendingEntryService) {
051 this.generalLedgerPendingEntryService = generalLedgerPendingEntryService;
052 }
053
054 /**
055 * This method overides that in parent class so that the maintainance actions are surpressed
056 *
057 * @returns links to edit and copy maintenance action for the current maintenance record. For GL balance inquire, there are no
058 * maintenance links.
059 */
060 @Override
061 public List<HtmlData> getCustomActionUrls(BusinessObject bo, List pkNames) {
062 return super.getEmptyActionUrls();
063 }
064
065 /**
066 * This method tests if the user selects to see the general ledager pending entries
067 *
068 * @param fieldValues the map containing the search fields and values
069 * @return the value of pending entry option
070 */
071 protected String getSelectedPendingEntryOption(Map fieldValues) {
072 // truncate the non-property filed
073 String pendingEntryOption = (String) fieldValues.get(Constant.PENDING_ENTRY_OPTION);
074 fieldValues.remove(Constant.PENDING_ENTRY_OPTION);
075
076 return pendingEntryOption;
077 }
078
079 /**
080 * This method tests if the user selects to see the reports by monthly or accumulated
081 *
082 * @param fieldValues the map containing the search fields and values
083 * @return the value of amount view option
084 */
085 protected String getSelectedAmountViewOption(Map fieldValues) {
086
087 String amountViewOption = Constant.EMPTY_STRING;
088 if (fieldValues.containsKey(Constant.AMOUNT_VIEW_OPTION)) {
089 amountViewOption = (String) fieldValues.get(Constant.AMOUNT_VIEW_OPTION);
090
091 // truncate the non-property filed
092 fieldValues.remove(Constant.AMOUNT_VIEW_OPTION);
093 }
094 return amountViewOption;
095 }
096
097 /**
098 * This method tests if the user selects to see the details or consolidated results
099 *
100 * @param fieldValues the map containing the search fields and values
101 * @return true if consolidation is selected and subaccount is not specified
102 */
103 protected boolean isConsolidationSelected(Map fieldValues) {
104 // truncate the non-property filed
105 String consolidationOption = (String) fieldValues.get(Constant.CONSOLIDATION_OPTION);
106 fieldValues.remove(Constant.CONSOLIDATION_OPTION);
107
108 // detail option would be used
109 if (Constant.DETAIL.equals(consolidationOption)) {
110 return false;
111 }
112
113 // if the subAccountNumber is specified, detail option could be used
114 String subAccountNumber = (String) fieldValues.get(KFSPropertyConstants.SUB_ACCOUNT_NUMBER);
115 if (!StringUtils.isBlank(subAccountNumber)) {
116 this.changeFieldValue(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
117 return false;
118 }
119
120 // if the subObjectCode is specified, detail option could be used
121 String subObjectCode = (String) fieldValues.get(KFSPropertyConstants.SUB_OBJECT_CODE);
122 if (!StringUtils.isBlank(subObjectCode)) {
123 this.changeFieldValue(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
124 return false;
125 }
126
127 // if the objectTypeCode is specified, detail option could be used
128 String objectTypeCode = (String) fieldValues.get(KFSPropertyConstants.OBJECT_TYPE_CODE);
129 if (!StringUtils.isBlank(objectTypeCode)) {
130 this.changeFieldValue(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
131 return false;
132 }
133 return true;
134 }
135
136 /**
137 * This method tests if the user selects to see the results with cost share subaccount
138 *
139 * @param fieldValues the map containing the search fields and values
140 * @return true if inclusive option is selected
141 */
142 protected boolean isCostShareInclusive(Map fieldValues) {
143 // TODO: is this method being called?
144 // truncate the non-property filed
145 String costShareOption = (String) fieldValues.get(Constant.COST_SHARE_OPTION);
146 fieldValues.remove(Constant.COST_SHARE_OPTION);
147
148 if (costShareOption.equals(Constant.COST_SHARE_INCLUDE)) {
149 return true;
150 }
151 return false;
152 }
153
154
155 /**
156 * build the serach result list from the given collection and the number of all qualified search results
157 *
158 * @param searchResultsCollection the given search results, which may be a subset of the qualified search results
159 * @param actualSize the number of all qualified search results
160 * @return the serach result list with the given results and actual size
161 */
162 protected List buildSearchResultList(Collection searchResultsCollection, Long actualSize) {
163 CollectionIncomplete results = new CollectionIncomplete(searchResultsCollection, actualSize);
164
165 // sort list if default sort column given
166 List searchResults = (List) results;
167 List defaultSortColumns = getDefaultSortColumns();
168 if (defaultSortColumns.size() > 0) {
169 Collections.sort(results, new BeanPropertyComparator(defaultSortColumns, true));
170 }
171 return searchResults;
172 }
173
174 /**
175 * This method is used to update amounts of the given entries with the corresponding pending amounts. It is a factory that
176 * executes the update methods of individual derived classes.
177 *
178 * @param entryCollection a collection of balance entries
179 * @param fieldValues the map containing the search fields and values
180 * @param pendingEntryOption flag whether the approved entries or all entries will be processed
181 * @param isCostShareInclusive flag whether the user selects to see the results with cost share subaccount
182 * @param isConsolidated flag whether the results are consolidated or not
183 */
184 protected void updateByPendingLedgerEntry(Collection entryCollection, Map fieldValues, String pendingEntryOption, boolean isConsolidated, boolean isCostShareInclusive) {
185
186 // determine if search results need to be updated by pending ledger entries
187 if (Constant.ALL_PENDING_ENTRY.equals(pendingEntryOption)) {
188 updateEntryCollection(entryCollection, fieldValues, false, isConsolidated, isCostShareInclusive);
189 }
190 else if (Constant.APPROVED_PENDING_ENTRY.equals(pendingEntryOption)) {
191 updateEntryCollection(entryCollection, fieldValues, true, isConsolidated, isCostShareInclusive);
192 }
193 }
194
195 /**
196 * This method is an abstract method and implemented to update the given entry collection by the children classes. It is called
197 * by updateByPendingLedgerEntry method.
198 *
199 * @param entryCollection a collection of balance entries
200 * @param fieldValues the map containing the search fields and values
201 * @param isApproved flag whether the approved entries or all entries will be processed
202 * @param isCostShareInclusive flag whether the user selects to see the results with cost share subaccount
203 * @param isConsolidated flag whether the results are consolidated or not
204 */
205 protected abstract void updateEntryCollection(Collection entryCollection, Map fieldValues, boolean isApproved, boolean isConsolidated, boolean isCostShareInclusive);
206
207 // change the value of the field with the given field name into the given field value
208 private void changeFieldValue(String fieldName, String fieldValue) {
209 for (Iterator rowIterator = getRows().iterator(); rowIterator.hasNext();) {
210 Row row = (Row) rowIterator.next();
211
212 for (Iterator fieldIterator = row.getFields().iterator(); fieldIterator.hasNext();) {
213 Field field = (Field) fieldIterator.next();
214
215 if (field.getPropertyName().equals(fieldName)) {
216 field.setPropertyValue(fieldValue);
217 }
218 }
219 }
220 }
221 }