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.fp.document.validation.impl;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Set;
21  
22  import org.kuali.ole.fp.document.DisbursementVoucherDocument;
23  import org.kuali.ole.sys.OLEKeyConstants;
24  import org.kuali.ole.sys.OLEPropertyConstants;
25  import org.kuali.ole.sys.OleAuthorizationConstants.DisbursementVoucherEditMode;
26  import org.kuali.ole.sys.context.SpringContext;
27  import org.kuali.ole.sys.document.AccountingDocument;
28  import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
29  import org.kuali.ole.sys.document.validation.impl.AccountingLineGroupTotalsUnchangedValidation;
30  import org.kuali.rice.kim.api.identity.Person;
31  import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer;
32  import org.kuali.rice.kns.document.authorization.TransactionalDocumentPresentationController;
33  import org.kuali.rice.kns.service.DocumentHelperService;
34  import org.kuali.rice.krad.util.GlobalVariables;
35  
36  public class DisbursementVoucherAccountingLineTotalsValidation extends AccountingLineGroupTotalsUnchangedValidation {
37      protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherAccountingLineTotalsValidation.class);
38  
39      /**
40       * @see org.kuali.ole.sys.document.validation.impl.AccountingLineGroupTotalsUnchangedValidation#validate(org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent)
41       */
42      @Override
43      public boolean validate(AttributedDocumentEvent event) {
44          if (LOG.isDebugEnabled()) {
45              LOG.debug("validate start");
46          }
47  
48          DisbursementVoucherDocument dvDocument = (DisbursementVoucherDocument) event.getDocument();
49          
50          
51          Person financialSystemUser = GlobalVariables.getUserSession().getPerson();
52          final Set<String> currentEditModes = getEditModesFromDocument(dvDocument, financialSystemUser);
53          
54          // amounts can only decrease
55          List<String> candidateEditModes = this.getCandidateEditModes();
56          if (this.hasRequiredEditMode(currentEditModes, candidateEditModes)) {
57  
58              //users in foreign or wire workgroup can increase or decrease amounts because of currency conversion            
59              List<String> foreignDraftAndWireTransferEditModes = this.getForeignDraftAndWireTransferEditModes(dvDocument);
60              if (!this.hasRequiredEditMode(currentEditModes, foreignDraftAndWireTransferEditModes)) {
61                  DisbursementVoucherDocument persistedDocument = (DisbursementVoucherDocument) retrievePersistedDocument(dvDocument);
62                  if (persistedDocument == null) {
63                      handleNonExistentDocumentWhenApproving(dvDocument);
64                      return true;
65                  }
66                  // KFSMI- 5183
67                  if (persistedDocument.getDocumentHeader().getWorkflowDocument().isSaved() && persistedDocument.getDisbVchrCheckTotalAmount().isZero()) return true;
68                                     
69                  // check total cannot decrease
70                  if (persistedDocument.getDisbVchrCheckTotalAmount().isLessThan(dvDocument.getDisbVchrCheckTotalAmount())) {
71                      GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DOCUMENT + "." + OLEPropertyConstants.DISB_VCHR_CHECK_TOTAL_AMOUNT, OLEKeyConstants.ERROR_DV_CHECK_TOTAL_CHANGE);
72                      return false;
73                  }
74              }
75  
76              return true;
77          }
78  
79          return super.validate(event);
80      }
81  
82      /**
83       * determine whether the give user has permission to any edit mode defined in the given candidate edit modes
84       * 
85       * @param currentEditModes the edit modes currently available to the given user on the document
86       * @param candidateEditEditModes the given candidate edit modes
87       * @return true if the give user has permission to any edit mode defined in the given candidate edit modes; otherwise, false
88       */
89      protected boolean hasRequiredEditMode(Set<String> currentEditModes, List<String> candidateEditModes) {
90          for (String editMode : candidateEditModes) {
91              if (currentEditModes.contains(editMode)) {
92                  return true;
93              }
94          }
95  
96          return false;
97      }
98      
99      /**
100      * Retrieves the current edit modes from the document
101      * @param accountingDocument the document to find edit modes of
102      * @param financialSystemUser the user requesting the edit modes
103      * @return the Set of current edit modes
104      */
105     protected Set<String> getEditModesFromDocument(AccountingDocument accountingDocument, Person financialSystemUser) {
106         final DocumentHelperService documentHelperService = SpringContext.getBean(DocumentHelperService.class);
107         final TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) documentHelperService.getDocumentAuthorizer(accountingDocument);
108         final TransactionalDocumentPresentationController presentationController = (TransactionalDocumentPresentationController) documentHelperService.getDocumentPresentationController(accountingDocument);
109 
110         final Set<String> presentationControllerEditModes = presentationController.getEditModes(accountingDocument);
111         final Set<String> editModes = documentAuthorizer.getEditModes(accountingDocument, financialSystemUser, presentationControllerEditModes);
112         
113         return editModes;
114     }
115 
116     /**
117      * define the possibly desired edit modes
118      * 
119      * @return the possibly desired edit modes
120      */
121     protected List<String> getCandidateEditModes() {
122         List<String> candidateEdiModes = new ArrayList<String>();
123         candidateEdiModes.add(DisbursementVoucherEditMode.TAX_ENTRY);
124         candidateEdiModes.add(DisbursementVoucherEditMode.FRN_ENTRY);
125         candidateEdiModes.add(DisbursementVoucherEditMode.TRAVEL_ENTRY);
126         candidateEdiModes.add(DisbursementVoucherEditMode.WIRE_ENTRY);
127 
128         return candidateEdiModes;
129     }
130     
131     /**
132      * get foreign draft And wire transfer edit mode names, as well as tax if the payee is a non-resident alien
133      * @param dvDocument the document we're validating 
134      * @return foreign draft And wire transfer edit mode names
135      */
136     protected List<String> getForeignDraftAndWireTransferEditModes(DisbursementVoucherDocument dvDocument) {
137         List<String> foreignDraftAndWireTransferEditModes = new ArrayList<String>();
138         foreignDraftAndWireTransferEditModes.add(DisbursementVoucherEditMode.FRN_ENTRY);
139         foreignDraftAndWireTransferEditModes.add(DisbursementVoucherEditMode.WIRE_ENTRY);
140         
141         if (includeTaxAsTotalChangingMode(dvDocument)) {
142             foreignDraftAndWireTransferEditModes.add(DisbursementVoucherEditMode.TAX_ENTRY);
143         }
144 
145         return foreignDraftAndWireTransferEditModes;
146     }
147     
148     /**
149      * Determines whether the tax edit mode should be allowed to change the accounting line totals,
150      * based on whether the payee is a non-resident alient or not
151      * @param dvDocument the document to check
152      * @return true if the tax entry mode can change accounting line totals, false otherwise
153      */
154     protected boolean includeTaxAsTotalChangingMode(DisbursementVoucherDocument dvDocument) {
155         return dvDocument.getDvPayeeDetail().isDisbVchrAlienPaymentCode();
156     }
157 }