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 }