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.sys.businessobject.lookup;
017
018 import java.util.ArrayList;
019 import java.util.Collection;
020 import java.util.HashMap;
021 import java.util.List;
022 import java.util.Map;
023
024 import org.apache.commons.lang.StringUtils;
025 import org.kuali.kfs.fp.document.AdvanceDepositDocument;
026 import org.kuali.kfs.sys.KFSConstants;
027 import org.kuali.kfs.sys.businessobject.ElectronicPaymentClaim;
028 import org.kuali.kfs.sys.businessobject.SourceAccountingLine;
029 import org.kuali.kfs.sys.context.SpringContext;
030 import org.kuali.rice.kns.bo.BusinessObject;
031 import org.kuali.rice.kns.bo.PersistableBusinessObject;
032 import org.kuali.rice.kns.dao.LookupDao;
033 import org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl;
034 import org.kuali.rice.kns.lookup.CollectionIncomplete;
035 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
036 import org.kuali.rice.kns.service.KualiConfigurationService;
037 import org.kuali.rice.kns.web.struts.form.LookupForm;
038 import org.kuali.rice.kns.web.ui.Column;
039 import org.kuali.rice.kns.web.ui.ResultRow;
040 import org.springframework.transaction.annotation.Transactional;
041
042 /**
043 * A helper class that gives us the ability to do special lookups on electronic payment claims.
044 */
045 @Transactional
046 public class ElectronicPaymentClaimLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
047 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ElectronicPaymentClaimLookupableHelperServiceImpl.class);
048 private LookupDao lookupDao;
049
050 /**
051 *
052 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getSearchResults(java.util.Map)
053 */
054 @Override
055 public List<PersistableBusinessObject> getSearchResults(Map<String, String> fieldValues) {
056 boolean unbounded = false;
057 String claimingStatus = fieldValues.remove("paymentClaimStatusCode");
058 if (claimingStatus != null && !claimingStatus.equals("A")) {
059 if (claimingStatus.equals(ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED)) {
060 fieldValues.put("paymentClaimStatusCode", ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED);
061 } else {
062 fieldValues.put("paymentClaimStatusCode", ElectronicPaymentClaim.ClaimStatusCodes.UNCLAIMED);
063 }
064 }
065 String organizationReferenceId = fieldValues.remove("generatingAccountingLine.organizationReferenceId");
066 List<PersistableBusinessObject> resultsList = (List)lookupDao.findCollectionBySearchHelper(ElectronicPaymentClaim.class, fieldValues, unbounded, false, null);
067 if (!StringUtils.isBlank(organizationReferenceId)) {
068
069 List<PersistableBusinessObject> prunedResults = pruneResults(resultsList, organizationReferenceId);
070 resultsList = new CollectionIncomplete<PersistableBusinessObject>(prunedResults, ((CollectionIncomplete)resultsList).getActualSizeIfTruncated());
071
072 }
073 return resultsList;
074 }
075
076 /**
077 * If organization reference id was present in lookup fields, only returns electronic payment claims which associate with the given organization reference id
078 * @param paymentsToPrune the Collection of electronic payment claims, still unfiltered by organization reference id
079 * @param organizationReferenceId the organization reference id to use as a filter
080 * @return the filtered results
081 */
082 protected List<PersistableBusinessObject> pruneResults(List<PersistableBusinessObject> paymentsToPrune, String organizationReferenceId) {
083 final String matchingAdvanceDepositDocumentNumbers = getAdvanceDepositsWithOrganizationReferenceId(organizationReferenceId);
084 final List<GeneratingLineHolder> generatingLineHolders = getGeneratingLinesForDocuments(matchingAdvanceDepositDocumentNumbers, organizationReferenceId);
085
086 List<PersistableBusinessObject> prunedResults = new ArrayList<PersistableBusinessObject>();
087 for (PersistableBusinessObject epcAsPBO : paymentsToPrune) {
088 final ElectronicPaymentClaim epc = (ElectronicPaymentClaim)epcAsPBO;
089
090 int count = 0;
091 boolean epcMatches = false;
092 while (count < generatingLineHolders.size() && !epcMatches) {
093 final GeneratingLineHolder generatingLine = generatingLineHolders.get(count);
094 if (generatingLine.isMommy(epc)) {
095 prunedResults.add(epc);
096 epcMatches = true;
097 }
098
099 count += 1;
100 }
101 }
102
103 return prunedResults;
104 }
105
106 /**
107 * Finds the document ids for all AD documents which have an accounting line with the given organizationReferenceId
108 * @param organizationReferenceId the organization reference id to find advance deposit documents for
109 * @return a lookup String that holds the document numbers of the matching advance deposit documents
110 */
111 protected String getAdvanceDepositsWithOrganizationReferenceId(String organizationReferenceId) {
112 StringBuilder documentNumbers = new StringBuilder();
113
114 Map fields = new HashMap();
115 fields.put("sourceAccountingLines.organizationReferenceId", organizationReferenceId);
116 Collection ads = getLookupService().findCollectionBySearchUnbounded(AdvanceDepositDocument.class, fields);
117 for (Object adAsObject : ads) {
118 final AdvanceDepositDocument adDoc = (AdvanceDepositDocument)adAsObject;
119 documentNumbers.append("|");
120 documentNumbers.append(adDoc.getDocumentNumber());
121 }
122
123 return documentNumbers.substring(1);
124 }
125
126 /**
127 * Looks up all of the generating lines and stores essential information about them on documents given by the matchingAdvanceDepositDocumentNumbers parameter
128 * and matching the given organization reference id
129 * @param matchingAdvanceDepositDocumentNumbers the document numbers of matching advance deposit documents in lookup form
130 * @param organizationReferenceId the organization reference id the accounting line must match
131 * @return a List of essential information about each of the matching accounting lines
132 */
133 protected List<GeneratingLineHolder> getGeneratingLinesForDocuments(String matchingAdvanceDepositDocumentNumbers, String organizationReferenceId) {
134 List<GeneratingLineHolder> holders = new ArrayList<GeneratingLineHolder>();
135
136 Map fields = new HashMap();
137 fields.put("documentNumber", matchingAdvanceDepositDocumentNumbers);
138 fields.put("organizationReferenceId", organizationReferenceId);
139
140 Collection als = getLookupService().findCollectionBySearchUnbounded(SourceAccountingLine.class, fields);
141 for (Object alAsObject : als) {
142 final SourceAccountingLine accountingLine = (SourceAccountingLine)alAsObject;
143 holders.add(new GeneratingLineHolder(accountingLine.getDocumentNumber(), accountingLine.getSequenceNumber()));
144 }
145
146 return holders;
147 }
148
149 /**
150 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#validateSearchParameters(java.util.Map)
151 */
152 @Override
153 public void validateSearchParameters(Map fieldValues) {
154 // grab the backLocation and the docFormKey
155 this.setDocFormKey((String)fieldValues.get("docFormKey"));
156 this.setBackLocation((String)fieldValues.get("backLocation"));
157 super.validateSearchParameters(fieldValues);
158 }
159
160 /**
161 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#isResultReturnable(org.kuali.rice.kns.bo.BusinessObject)
162 */
163 @Override
164 public boolean isResultReturnable(BusinessObject claimAsBO) {
165 boolean result = super.isResultReturnable(claimAsBO);
166 ElectronicPaymentClaim claim = (ElectronicPaymentClaim)claimAsBO;
167 if (result && ((claim.getPaymentClaimStatusCode() != null && claim.getPaymentClaimStatusCode().equals(ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED)) || (!StringUtils.isBlank(claim.getReferenceFinancialDocumentNumber())))) {
168 result = false;
169 }
170 return result;
171 }
172
173 /**
174 * Using default results, add columnAnchor link for reference financial document number to open document
175 *
176 * @param lookupForm
177 * @param kualiLookupable
178 * @param resultTable
179 * @param bounded
180 * @return
181 */
182 @Override
183 public Collection performLookup(LookupForm lookupForm, Collection resultTable, boolean bounded) {
184 Collection displayList = super.performLookup(lookupForm, resultTable, bounded);
185 for (ResultRow row : (Collection<ResultRow>)resultTable) {
186 for (Column col : row.getColumns()) {
187 if (StringUtils.equals("referenceFinancialDocumentNumber", col.getPropertyName()) && StringUtils.isNotBlank(col.getPropertyValue())) {
188 String propertyURL = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(KFSConstants.WORKFLOW_URL_KEY) + "/DocHandler.do?docId=" + col.getPropertyValue() + "&command=displayDocSearchView";
189 AnchorHtmlData htmlData = new AnchorHtmlData(propertyURL, "", col.getPropertyValue());
190 htmlData.setTitle(col.getPropertyValue());
191 col.setColumnAnchor(htmlData);
192 }
193 }
194 }
195 return displayList;
196 }
197
198 /**
199 * Sets the lookupDao attribute value.
200 * @param lookupDao The lookupDao to set.
201 */
202 public void setLookupDao(LookupDao lookupDao) {
203 this.lookupDao = lookupDao;
204 }
205
206 /**
207 * Holds information about an accounting line which created an electronic payment claim
208 */
209 class GeneratingLineHolder {
210 private String documentNumber;
211 private Integer lineNumber;
212
213 /**
214 * Constructs a GeneratingLineHolder
215 * @param documentNumber the document the generating line is on
216 * @param lineNumber the line number of the generating line
217 */
218 public GeneratingLineHolder(String documentNumber, Integer lineNumber) {
219 this.documentNumber = documentNumber;
220 this.lineNumber = lineNumber;
221 }
222
223 /**
224 * Determines if the given electronic payment claim was generated by the accounting line that this GeneratingLineHolder has information for
225 * @param epc the electronic payment claim to check
226 * @return true if this accounting line did generate the epc, false otherwise
227 */
228 public boolean isMommy(ElectronicPaymentClaim epc) {
229 return epc.getDocumentNumber().equals(documentNumber) && epc.getFinancialDocumentLineNumber().equals(lineNumber);
230 }
231 }
232 }