View Javadoc
1   /*
2    * Copyright 2008 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.sys.service.impl;
17  
18  import java.util.ArrayList;
19  import java.util.HashSet;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Set;
23  
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.struts.action.ActionForward;
26  import org.apache.struts.action.ActionMapping;
27  import org.kuali.ole.sys.OLEKeyConstants;
28  import org.kuali.ole.sys.businessobject.ElectronicPaymentClaim;
29  import org.kuali.ole.sys.service.ElectronicFundTransferActionHelper;
30  import org.kuali.ole.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy;
31  import org.kuali.ole.sys.service.ElectronicPaymentClaimingService;
32  import org.kuali.ole.sys.web.struts.ElectronicFundTransferForm;
33  import org.kuali.ole.sys.web.struts.ElectronicPaymentClaimClaimedHelper;
34  import org.kuali.rice.kim.api.identity.Person;
35  import org.kuali.rice.kns.service.DataDictionaryService;
36  import org.kuali.rice.krad.exception.AuthorizationException;
37  import org.kuali.rice.krad.service.BusinessObjectService;
38  import org.kuali.rice.krad.service.DocumentService;
39  import org.kuali.rice.krad.util.GlobalVariables;
40  
41  /**
42   * An Electronic Funds Transfer action which claims the electronic payment claims in a form and redirects
43   * to the claiming document.
44   */
45  public class ElectronicFundTransferClaimActionHelper implements ElectronicFundTransferActionHelper {
46      private ElectronicPaymentClaimingService electronicPaymentClaimingService;
47      private DataDictionaryService ddService;
48      private BusinessObjectService boService;
49      private DocumentService documentService;
50      
51      protected static final String ACTION_NAME = "claim";
52      protected static final String CHOSEN_DOCUMENT_PROPERTY = "chosenElectronicPaymentClaimingDocumentCode";
53      protected static final String CLAIM_PROPERTY = "claims";
54      protected static final String HAS_DOCUMENTATION_PROPERTY = "hasDocumentation";
55      protected static final String BASIC_FORWARD = "basic";
56      protected static final String PORTAL_FORWARD = "portal";
57  
58      /**
59       * Claims the ElectronicPaymentClaim records with a document and then redirects to that docment.
60       * @see org.kuali.ole.sys.service.ElectronicFundTransferActionHelper#performAction(org.kuali.rice.kns.web.struts.form.KualiForm, org.apache.struts.action.ActionMapping)
61       */
62      public ActionForward performAction(ElectronicFundTransferForm form, ActionMapping mapping, Map paramMap, String basePath) {
63          // can the user claim electronic payments at all?
64          Person currentUser = GlobalVariables.getUserSession().getPerson();
65  
66          if (!form.hasAvailableClaimingDocumentStrategies()) {
67              throw new AuthorizationException(currentUser.getPrincipalName(), ElectronicFundTransferClaimActionHelper.ACTION_NAME, ddService.getDataDictionary().getBusinessObjectEntry(ElectronicPaymentClaim.class.getName()).getTitleAttribute());
68          }
69          
70          // did the user say they have documentation?  If not, give an error...
71          boolean continueClaiming = true;
72          continueClaiming = handleDocumentationForClaim(form.getHasDocumentation());
73          
74          // process admin's pre-claimed records
75          List<ElectronicPaymentClaim> claims = form.getClaims();
76          
77          boolean isAuthorized = form.isAllowElectronicFundsTransferAdministration();
78          if (isAuthorized) {
79              claims = handlePreClaimedRecords(claims, generatePreClaimedByCheckboxSet(form.getClaimedByCheckboxHelpers()), form.getAvailableClaimingDocumentStrategies());
80              if (GlobalVariables.getMessageMap().getNumberOfPropertiesWithErrors() > 0) {
81                  // if there were any errors, we'll need to redirect to the page again
82                  return mapping.findForward(ElectronicFundTransferClaimActionHelper.BASIC_FORWARD);
83              }
84              else if (claims.size() == 0) {
85                  // no more claims to process...so don't make a document, just redirect to the portal
86                  return mapping.findForward(PORTAL_FORWARD);
87              }
88          }
89          
90          // put any remaining claims into a claiming doc
91          String chosenDoc = form.getChosenElectronicPaymentClaimingDocumentCode();
92          continueClaiming &= checkChosenDocumentType(chosenDoc);
93          // get the requested document claiming helper
94          if (continueClaiming) {
95              
96              ElectronicPaymentClaimingDocumentGenerationStrategy documentCreationHelper = getRequestedClaimingHelper(form.getChosenElectronicPaymentClaimingDocumentCode(), form.getAvailableClaimingDocumentStrategies(), currentUser);
97              // take the claims from the form, create a document, and redirect to the given URL...which is easy
98              String redirectURL = electronicPaymentClaimingService.createPaymentClaimingDocument(form.getClaims(), documentCreationHelper, currentUser);
99              return new ActionForward(redirectURL, true);
100         } else {
101             return mapping.findForward(ElectronicFundTransferClaimActionHelper.BASIC_FORWARD);
102         }
103     }
104     
105     /**
106      * Verifies that the chosenElectronicPaymentClaimingDocumentCode has been filled in.
107      * @param chosenDoc the value of chosenElectronicPaymentClaimingDocumentCode from the form
108      * @return true if the validation resulted in no errors, false if otherwise
109      */
110     protected boolean checkChosenDocumentType(String chosenDoc) {
111         boolean result = true;
112         if (StringUtils.isBlank(chosenDoc)) {
113             GlobalVariables.getMessageMap().putError(ElectronicFundTransferClaimActionHelper.CHOSEN_DOCUMENT_PROPERTY, OLEKeyConstants.ElectronicPaymentClaim.ERROR_EFT_NO_CHOSEN_CLAIMING_DOCTYPE, new String[]{});
114             result = false;
115         }
116         return result;
117     }
118 
119     /**
120      * Using user entered form values, determines which of the available ElectronicPaymentClaimingDocumentGenerationStrategy implementations to use. 
121      * @param chosenDoc the document type code for the doc that the user selected
122      * @param availableClaimingDocs a List of ElectronicPaymentClaimingDocumentGenerationStrategy implementations that can be used by the given user
123      * @param currentUser the currently logged in user
124      * @throws AuthorizationException thrown if the user entered an invalid or unusable ElectronicPaymentClaimingDocumentGenerationStrategy code
125      * @return an ElectronicPaymentClaimingDocumentGenerationStrategy helper to use to create the document
126      */
127     protected ElectronicPaymentClaimingDocumentGenerationStrategy getRequestedClaimingHelper(String chosenDoc, List<ElectronicPaymentClaimingDocumentGenerationStrategy> availableClaimingDocs, Person currentUser) {
128         ElectronicPaymentClaimingDocumentGenerationStrategy chosenDocHelper = null;
129         int count = 0;
130         while (count < availableClaimingDocs.size() && chosenDocHelper == null) {
131             ElectronicPaymentClaimingDocumentGenerationStrategy claimingDoc = availableClaimingDocs.get(count);
132             if (StringUtils.equals(claimingDoc.getClaimingDocumentWorkflowDocumentType(), chosenDoc)) {
133                 chosenDocHelper = claimingDoc;
134             }
135             count += 1;
136         }
137         if (chosenDocHelper == null || !chosenDocHelper.userMayUseToClaim(currentUser)) {
138             throw new AuthorizationException(currentUser.getPrincipalName(), ElectronicFundTransferClaimActionHelper.ACTION_NAME, ddService.getDataDictionary().getBusinessObjectEntry(ElectronicPaymentClaim.class.getName()).getObjectLabel());
139         }
140         return chosenDocHelper;
141     }
142     
143     /**
144      * Administrative users can fill in a field that says that a given electronic payment claim has already been claimed by another document.  This method
145      * traverses through the list of electronic payment claims, checks if it is pre-claimed, and saves it if it is pre-claimed
146      * @param claims the list of electronic payment claims 
147      * @return the list of electronic payment claims with all pre-claimed records removed
148      */
149     protected List<ElectronicPaymentClaim> handlePreClaimedRecords(List<ElectronicPaymentClaim> claims, Set<String> preClaimedByCheckbox, List<ElectronicPaymentClaimingDocumentGenerationStrategy> documentGenerationStrategies) {
150         List<ElectronicPaymentClaim> stillToClaim = new ArrayList<ElectronicPaymentClaim>();
151         int count = 0;
152         for (ElectronicPaymentClaim claim: claims) {
153             if (StringUtils.isBlank(claim.getReferenceFinancialDocumentNumber()) && !preClaimedByCheckbox.contains(claim.getElectronicPaymentClaimRepresentation())) {
154                 // not claimed by any mechanism, add to stillToClaim list
155                 stillToClaim.add(claim);
156             } else {
157                 boolean savePreClaimed = true;
158                 if (StringUtils.isNotBlank(claim.getReferenceFinancialDocumentNumber())) {
159                     // check that the document exists
160                     boolean isValidDocRef = false;
161                     int stratCount = 0;
162                     while (!isValidDocRef && stratCount < documentGenerationStrategies.size()) {
163                         isValidDocRef |= documentGenerationStrategies.get(stratCount).isDocumentReferenceValid(claim.getReferenceFinancialDocumentNumber());
164                         stratCount += 1;
165                     }
166                     if (!isValidDocRef) {
167                         GlobalVariables.getMessageMap().putError(ElectronicFundTransferClaimActionHelper.CLAIM_PROPERTY+"["+count+"]", OLEKeyConstants.ElectronicPaymentClaim.ERROR_PRE_CLAIMING_DOCUMENT_DOES_NOT_EXIST, new String[] { claim.getReferenceFinancialDocumentNumber() });
168                         savePreClaimed = false;
169                     }
170                 }
171                 if (savePreClaimed) {
172                     claim.setPaymentClaimStatusCode(ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED);
173                     // save that record
174                     boService.save(claim);
175                 }
176             }
177             count += 1;
178         }
179         return stillToClaim;
180     }
181     
182     /**
183      * Uses the list of checked pre-claimed checkbox helpers to create a Set of representations of electronic payment claim records that were marked as "pre-claimed"
184      * @param checkboxHelpers the list of checked ElectronicPaymentClaimClaimedHelpers from the form
185      * @return a Set of electronic payment claim representations for records that have been reclaimed
186      */
187     protected Set<String> generatePreClaimedByCheckboxSet(List<ElectronicPaymentClaimClaimedHelper> checkboxHelpers) {
188         Set<String> claimedByCheckboxRepresentations = new HashSet<String>();
189         for (ElectronicPaymentClaimClaimedHelper helper: checkboxHelpers) {
190             claimedByCheckboxRepresentations.add(helper.getElectronicPaymentClaimRepresentation());
191         }
192         return claimedByCheckboxRepresentations;
193     }
194     
195     /**
196      * Checks that the user was able to answer the "has documentation?" question correctly
197      * @param hasDocumentation the user's response to the "has documentation" question
198      * @return true if the user was able to successfully answer this question, false otherwise
199      */
200     protected boolean handleDocumentationForClaim(String hasDocumentation) {
201         boolean success = true;
202         if (StringUtils.isBlank(hasDocumentation) || !hasDocumentation.equalsIgnoreCase("yep")) {
203             GlobalVariables.getMessageMap().putError(ElectronicFundTransferClaimActionHelper.HAS_DOCUMENTATION_PROPERTY, OLEKeyConstants.ElectronicPaymentClaim.ERROR_NO_DOCUMENTATION, new String[] {});
204             success = false;
205         }
206         
207         return success;
208     }
209 
210     /**
211      * Sets the ddService attribute value.
212      * @param ddService The ddService to set.
213      */
214     public void setDataDictonaryService(DataDictionaryService ddService) {
215         this.ddService = ddService;
216     }
217 
218     /**
219      * Sets the electronicPaymentClaimingService attribute value.
220      * @param electronicPaymentClaimingService The electronicPaymentClaimingService to set.
221      */
222     public void setElectronicPaymentClaimingService(ElectronicPaymentClaimingService electronicPaymentClaimingService) {
223         this.electronicPaymentClaimingService = electronicPaymentClaimingService;
224     }
225 
226     /**
227      * Sets the boService attribute value.
228      * @param boService The boService to set.
229      */
230     public void setBusinessObjectService(BusinessObjectService boService) {
231         this.boService = boService;
232     }
233 
234     /**
235      * Sets the documentService attribute value.
236      * @param documentService The documentService to set.
237      */
238     public void setDocumentService(DocumentService documentService) {
239         this.documentService = documentService;
240     }
241     
242 }
243