View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.sys.businessobject.lookup;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.commons.lang.StringUtils;
28  import org.kuali.kfs.fp.document.AdvanceDepositDocument;
29  import org.kuali.kfs.sys.KFSConstants;
30  import org.kuali.kfs.sys.businessobject.ElectronicPaymentClaim;
31  import org.kuali.kfs.sys.businessobject.SourceAccountingLine;
32  import org.kuali.kfs.sys.context.SpringContext;
33  import org.kuali.rice.core.api.config.property.ConfigurationService;
34  import org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl;
35  import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
36  import org.kuali.rice.kns.web.struts.form.LookupForm;
37  import org.kuali.rice.kns.web.ui.Column;
38  import org.kuali.rice.kns.web.ui.ResultRow;
39  import org.kuali.rice.krad.bo.BusinessObject;
40  import org.kuali.rice.krad.bo.PersistableBusinessObject;
41  import org.kuali.rice.krad.dao.LookupDao;
42  import org.kuali.rice.krad.lookup.CollectionIncomplete;
43  import org.springframework.transaction.annotation.Transactional;
44  
45  /**
46   * A helper class that gives us the ability to do special lookups on electronic payment claims.
47   */
48  @Transactional
49  public class ElectronicPaymentClaimLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
50      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ElectronicPaymentClaimLookupableHelperServiceImpl.class);
51      private LookupDao lookupDao;
52  
53      /**
54       *
55       * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getSearchResults(java.util.Map)
56       */
57      @Override
58      public List<PersistableBusinessObject> getSearchResults(Map<String, String> fieldValues) {
59          boolean unbounded = false;
60          String claimingStatus = fieldValues.remove("paymentClaimStatusCode");
61          if (claimingStatus != null && !claimingStatus.equals("A")) {
62              if (claimingStatus.equals(ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED)) {
63                  fieldValues.put("paymentClaimStatusCode", ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED);
64              } else {
65                  fieldValues.put("paymentClaimStatusCode", ElectronicPaymentClaim.ClaimStatusCodes.UNCLAIMED);
66              }
67          }
68          String organizationReferenceId = fieldValues.remove("generatingAccountingLine.organizationReferenceId");
69          List<PersistableBusinessObject> resultsList = (List)lookupDao.findCollectionBySearchHelper(ElectronicPaymentClaim.class, fieldValues, unbounded, false);
70          if (!StringUtils.isBlank(organizationReferenceId)) {
71  
72              List<PersistableBusinessObject> prunedResults = pruneResults(resultsList, organizationReferenceId);
73              resultsList = new CollectionIncomplete<PersistableBusinessObject>(prunedResults, ((CollectionIncomplete)resultsList).getActualSizeIfTruncated());
74  
75          }
76          return resultsList;
77      }
78  
79      /**
80       * If organization reference id was present in lookup fields, only returns electronic payment claims which associate with the given organization reference id
81       * @param paymentsToPrune the Collection of electronic payment claims, still unfiltered by organization reference id
82       * @param organizationReferenceId the organization reference id to use as a filter
83       * @return the filtered results
84       */
85      protected List<PersistableBusinessObject> pruneResults(List<PersistableBusinessObject> paymentsToPrune, String organizationReferenceId) {
86          final String matchingAdvanceDepositDocumentNumbers = getAdvanceDepositsWithOrganizationReferenceId(organizationReferenceId);
87          final List<GeneratingLineHolder> generatingLineHolders = getGeneratingLinesForDocuments(matchingAdvanceDepositDocumentNumbers, organizationReferenceId);
88  
89          List<PersistableBusinessObject> prunedResults = new ArrayList<PersistableBusinessObject>();
90          for (PersistableBusinessObject epcAsPBO : paymentsToPrune) {
91              final ElectronicPaymentClaim epc = (ElectronicPaymentClaim)epcAsPBO;
92  
93              int count = 0;
94              boolean epcMatches = false;
95              while (count < generatingLineHolders.size() && !epcMatches) {
96                  final GeneratingLineHolder generatingLine = generatingLineHolders.get(count);
97                  if (generatingLine.isMommy(epc)) {
98                      prunedResults.add(epc);
99                      epcMatches = true;
100                 }
101 
102                 count += 1;
103             }
104         }
105 
106         return prunedResults;
107     }
108 
109     /**
110      * Finds the document ids for all AD documents which have an accounting line with the given organizationReferenceId
111      * @param organizationReferenceId the organization reference id to find advance deposit documents for
112      * @return a lookup String that holds the document numbers of the matching advance deposit documents
113      */
114     protected String getAdvanceDepositsWithOrganizationReferenceId(String organizationReferenceId) {
115         StringBuilder documentNumbers = new StringBuilder();
116 
117         Map fields = new HashMap();
118         fields.put("sourceAccountingLines.organizationReferenceId", organizationReferenceId);
119         Collection ads = getLookupService().findCollectionBySearchUnbounded(AdvanceDepositDocument.class, fields);
120         for (Object adAsObject : ads) {
121             final AdvanceDepositDocument adDoc = (AdvanceDepositDocument)adAsObject;
122             documentNumbers.append("|");
123             documentNumbers.append(adDoc.getDocumentNumber());
124         }
125 
126         return documentNumbers.substring(1);
127     }
128 
129     /**
130      * Looks up all of the generating lines and stores essential information about them on documents given by the matchingAdvanceDepositDocumentNumbers parameter
131      * and matching the given organization reference id
132      * @param matchingAdvanceDepositDocumentNumbers the document numbers of matching advance deposit documents in lookup form
133      * @param organizationReferenceId the organization reference id the accounting line must match
134      * @return a List of essential information about each of the matching accounting lines
135      */
136     protected List<GeneratingLineHolder> getGeneratingLinesForDocuments(String matchingAdvanceDepositDocumentNumbers, String organizationReferenceId) {
137         List<GeneratingLineHolder> holders = new ArrayList<GeneratingLineHolder>();
138 
139         Map fields = new HashMap();
140         fields.put("documentNumber", matchingAdvanceDepositDocumentNumbers);
141         fields.put("organizationReferenceId", organizationReferenceId);
142 
143         Collection als = getLookupService().findCollectionBySearchUnbounded(SourceAccountingLine.class, fields);
144         for (Object alAsObject : als) {
145             final SourceAccountingLine accountingLine = (SourceAccountingLine)alAsObject;
146             holders.add(new GeneratingLineHolder(accountingLine.getDocumentNumber(), accountingLine.getSequenceNumber()));
147         }
148 
149         return holders;
150     }
151 
152     /**
153      * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#validateSearchParameters(java.util.Map)
154      */
155     @Override
156     public void validateSearchParameters(Map fieldValues) {
157         // grab the backLocation and the docFormKey
158         this.setDocFormKey((String)fieldValues.get("docFormKey"));
159         this.setBackLocation((String)fieldValues.get("backLocation"));
160         super.validateSearchParameters(fieldValues);
161     }
162 
163     /**
164      * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#isResultReturnable(org.kuali.rice.krad.bo.BusinessObject)
165      */
166     @Override
167     public boolean isResultReturnable(BusinessObject claimAsBO) {
168         boolean result = super.isResultReturnable(claimAsBO);
169         ElectronicPaymentClaim claim = (ElectronicPaymentClaim)claimAsBO;
170         if (result && ((claim.getPaymentClaimStatusCode() != null && claim.getPaymentClaimStatusCode().equals(ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED)) || (!StringUtils.isBlank(claim.getReferenceFinancialDocumentNumber())))) {
171             result = false;
172         }
173         return result;
174     }
175 
176     /**
177      * Using default results, add columnAnchor link for reference financial document number to open document
178      *
179      * @param lookupForm
180      * @param kualiLookupable
181      * @param resultTable
182      * @param bounded
183      * @return
184      *
185      * KRAD Conversion: Lookupable performing customization of columns of the display list.
186      */
187     @Override
188     public Collection performLookup(LookupForm lookupForm, Collection resultTable, boolean bounded) {
189         Collection displayList = super.performLookup(lookupForm, resultTable, bounded);
190         for (ResultRow row : (Collection<ResultRow>)resultTable) {
191             for (Column col : row.getColumns()) {
192                 if (StringUtils.equals("referenceFinancialDocumentNumber", col.getPropertyName()) && StringUtils.isNotBlank(col.getPropertyValue())) {
193                     String propertyURL = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSConstants.WORKFLOW_URL_KEY) + "/DocHandler.do?docId=" + col.getPropertyValue() + "&command=displayDocSearchView";
194                     AnchorHtmlData htmlData = new AnchorHtmlData(propertyURL, "", col.getPropertyValue());
195                     htmlData.setTitle(col.getPropertyValue());
196                     col.setColumnAnchor(htmlData);
197                 }
198             }
199         }
200         return displayList;
201     }
202 
203     /**
204      * Sets the lookupDao attribute value.
205      * @param lookupDao The lookupDao to set.
206      */
207     public void setLookupDao(LookupDao lookupDao) {
208         this.lookupDao = lookupDao;
209     }
210 
211     /**
212      * Holds information about an accounting line which created an electronic payment claim
213      */
214     protected class GeneratingLineHolder {
215         private String documentNumber;
216         private Integer lineNumber;
217 
218         /**
219          * Constructs a GeneratingLineHolder
220          * @param documentNumber the document the generating line is on
221          * @param lineNumber the line number of the generating line
222          */
223         public GeneratingLineHolder(String documentNumber, Integer lineNumber) {
224             this.documentNumber = documentNumber;
225             this.lineNumber = lineNumber;
226         }
227 
228         /**
229          * Determines if the given electronic payment claim was generated by the accounting line that this GeneratingLineHolder has information for
230          * @param epc the electronic payment claim to check
231          * @return true if this accounting line did generate the epc, false otherwise
232          */
233         public boolean isMommy(ElectronicPaymentClaim epc) {
234             return epc.getDocumentNumber().equals(documentNumber) && epc.getFinancialDocumentLineNumber().equals(lineNumber);
235         }
236     }
237 }