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.apache.commons.lang.StringUtils;
23  import org.kuali.ole.fp.businessobject.DisbursementVoucherNonResidentAlienTax;
24  import org.kuali.ole.fp.businessobject.DisbursementVoucherPayeeDetail;
25  import org.kuali.ole.fp.businessobject.NonResidentAlienTaxPercent;
26  import org.kuali.ole.fp.document.DisbursementVoucherConstants;
27  import org.kuali.ole.fp.document.DisbursementVoucherDocument;
28  import org.kuali.ole.sys.OLEConstants;
29  import org.kuali.ole.sys.OLEKeyConstants;
30  import org.kuali.ole.sys.OLEPropertyConstants;
31  import org.kuali.ole.sys.OleAuthorizationConstants;
32  import org.kuali.ole.sys.context.SpringContext;
33  import org.kuali.ole.sys.document.AccountingDocument;
34  import org.kuali.ole.sys.document.validation.GenericValidation;
35  import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
36  import org.kuali.rice.core.api.util.type.KualiDecimal;
37  import org.kuali.rice.kim.api.identity.Person;
38  import org.kuali.rice.kns.document.authorization.TransactionalDocumentAuthorizer;
39  import org.kuali.rice.kns.document.authorization.TransactionalDocumentPresentationController;
40  import org.kuali.rice.kns.service.DocumentHelperService;
41  import org.kuali.rice.krad.bo.PersistableBusinessObject;
42  import org.kuali.rice.krad.service.BusinessObjectService;
43  import org.kuali.rice.krad.util.GlobalVariables;
44  import org.kuali.rice.krad.util.MessageMap;
45  
46  public class DisbursementVoucherNonResidentAlienInformationValidation extends GenericValidation implements DisbursementVoucherConstants {
47      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherNonResidentAlienInformationValidation.class);
48  
49      private AccountingDocument accountingDocumentForValidation;
50      private String validationType;
51  
52      /**
53       * @see org.kuali.ole.sys.document.validation.Validation#validate(org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent)
54       */
55      @Override
56      public boolean validate(AttributedDocumentEvent event) {
57          LOG.debug("validate start");
58          boolean isValid = true;
59  
60          DisbursementVoucherDocument document = (DisbursementVoucherDocument) accountingDocumentForValidation;
61          DisbursementVoucherNonResidentAlienTax nonResidentAlienTax = document.getDvNonResidentAlienTax();
62          DisbursementVoucherPayeeDetail payeeDetail = document.getDvPayeeDetail();
63  
64          Person financialSystemUser = GlobalVariables.getUserSession().getPerson();
65  
66          List<String> taxEditMode = this.getTaxEditMode();
67          if (!payeeDetail.isDisbVchrAlienPaymentCode() || !this.hasRequiredEditMode(document, financialSystemUser, taxEditMode)) {
68              return true;
69          }
70  
71          MessageMap errors = GlobalVariables.getMessageMap();        
72          errors.addToErrorPath(OLEPropertyConstants.DOCUMENT);
73          errors.addToErrorPath(OLEPropertyConstants.DV_NON_RESIDENT_ALIEN_TAX);
74  
75  // ICC SECTION
76  
77          /* income class code required */
78          if (StringUtils.isBlank(nonResidentAlienTax.getIncomeClassCode())) {
79              errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_REQUIRED, "Income class code");
80              return false;
81          }
82  
83          /* country code required, unless income type is nonreportable */
84          if (StringUtils.isBlank(nonResidentAlienTax.getPostalCountryCode()) && !NRA_TAX_INCOME_CLASS_NON_REPORTABLE.equals(nonResidentAlienTax.getIncomeClassCode())) {
85              errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_REQUIRED, "Country code");
86              return false;
87                  }
88  
89          // income class is FELLOWSHIP
90          if(nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_FELLOWSHIP) ){
91              // Place holder for logic related to the ICC
92          }
93          // income class is INDEPENDENT CONTRACTOR
94          if(nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_INDEPENDENT_CONTRACTOR)){
95              // Place holder for logic related to the ICC
96          }
97          // income class is ROYALTIES
98          if(nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_ROYALTIES)){
99              // Place holder for logic related to the ICC
100         }
101         // income class is NON_REPORTABLE
102         if(nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_NON_REPORTABLE)){
103             if( (nonResidentAlienTax.isForeignSourceIncomeCode()) || (nonResidentAlienTax.isIncomeTaxTreatyExemptCode()) ||
104                     (nonResidentAlienTax.isTaxOtherExemptIndicator()) || (nonResidentAlienTax.isIncomeTaxGrossUpCode()) ||
105                     (nonResidentAlienTax.isTaxUSAIDPerDiemIndicator()) || (nonResidentAlienTax.getTaxSpecialW4Amount() != null) ||
106                     (nonResidentAlienTax.getReferenceFinancialDocumentNumber() != null) || (nonResidentAlienTax.getTaxNQIId() != null) ||
107                     (nonResidentAlienTax.getPostalCountryCode() != null) ) {
108                 String boxCode = "";
109                 if(nonResidentAlienTax.isForeignSourceIncomeCode())
110                 {
111                     boxCode = "Foreign Source";
112                 }
113                 if(nonResidentAlienTax.isIncomeTaxTreatyExemptCode())
114                 {
115                     boxCode = "Treaty Exempt";
116                 }
117                 if(nonResidentAlienTax.isTaxOtherExemptIndicator())
118                 {
119                     boxCode = "Exempt Under Other Code";
120                 }
121                 if(nonResidentAlienTax.isIncomeTaxGrossUpCode())
122                 {
123                     boxCode = "Gross Up Payment";
124                 }
125                 if(nonResidentAlienTax.isTaxUSAIDPerDiemIndicator())
126                 {
127                     boxCode = "USAID Per Diem";
128                 }
129                 if(nonResidentAlienTax.getTaxSpecialW4Amount() != null)
130                 {
131                     boxCode = "Special W-4 Amount";
132                 }
133                 if(nonResidentAlienTax.getReferenceFinancialDocumentNumber() != null)
134                 {
135                     boxCode = "Reference Doc";
136                 }
137                 if(nonResidentAlienTax.getTaxNQIId() != null)
138                 {
139                     boxCode = "NQI Id";
140                 }
141                 if(nonResidentAlienTax.getPostalCountryCode() != null)
142                 {
143                     boxCode = "Country Code";
144                 }
145                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NON_REPORTABLE_ONLY, boxCode);
146                 return false;
147                 }
148                 }
149 
150 // TAX RATES SECTION
151 
152         /* check tax rates */
153         if (((nonResidentAlienTax.getFederalIncomeTaxPercent() == null) || (nonResidentAlienTax.getFederalIncomeTaxPercent().equals(KualiDecimal.ZERO))) && (nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_NON_REPORTABLE)) ) {
154             nonResidentAlienTax.setFederalIncomeTaxPercent(KualiDecimal.ZERO);
155             }
156             else {
157                 if (nonResidentAlienTax.getFederalIncomeTaxPercent() == null) {
158                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_REQUIRED, "Federal tax percent");
159                 return false;
160                 }
161                 else {
162                 // check Federal tax percent is in non-resident alien tax percent table for income class code
163                     NonResidentAlienTaxPercent taxPercent = new NonResidentAlienTaxPercent();
164                     taxPercent.setIncomeClassCode(nonResidentAlienTax.getIncomeClassCode());
165                     taxPercent.setIncomeTaxTypeCode(FEDERAL_TAX_TYPE_CODE);
166                     taxPercent.setIncomeTaxPercent(nonResidentAlienTax.getFederalIncomeTaxPercent());
167 
168                     NonResidentAlienTaxPercent retrievedPercent = (NonResidentAlienTaxPercent) SpringContext.getBean(BusinessObjectService.class).retrieve(taxPercent);
169                     if (retrievedPercent == null) {
170                     errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_INVALID_FED_TAX_PERCENT, new String[] { nonResidentAlienTax.getFederalIncomeTaxPercent().toString(), nonResidentAlienTax.getIncomeClassCode() });
171                     return false;
172                     }
173                 }
174         }
175         if (((nonResidentAlienTax.getStateIncomeTaxPercent() == null) || (nonResidentAlienTax.getStateIncomeTaxPercent().equals(KualiDecimal.ZERO))) && (nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_NON_REPORTABLE)) ) {
176             nonResidentAlienTax.setStateIncomeTaxPercent(KualiDecimal.ZERO);
177         }
178         else {
179                 if (nonResidentAlienTax.getStateIncomeTaxPercent() == null) {
180                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_REQUIRED, "State tax percent");
181                 return false;
182                 }
183                 else {
184                 // check State tax percent is in non-resident alien tax percent table for income class code
185                     NonResidentAlienTaxPercent taxPercent = new NonResidentAlienTaxPercent();
186                     taxPercent.setIncomeClassCode(nonResidentAlienTax.getIncomeClassCode());
187                     taxPercent.setIncomeTaxTypeCode(STATE_TAX_TYPE_CODE);
188                     taxPercent.setIncomeTaxPercent(nonResidentAlienTax.getStateIncomeTaxPercent());
189 
190                     PersistableBusinessObject retrievedPercent = SpringContext.getBean(BusinessObjectService.class).retrieve(taxPercent);
191                     if (retrievedPercent == null) {
192                     errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_INVALID_STATE_TAX_PERCENT, nonResidentAlienTax.getStateIncomeTaxPercent().toString(), nonResidentAlienTax.getIncomeClassCode());
193                     return false;
194                 }
195                 else {
196                     if ((!document.getDvNonResidentAlienTax().getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_ROYALTIES)) && (!document.getDvNonResidentAlienTax().getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_INDEPENDENT_CONTRACTOR))) {
197                         // If fed tax rate is greater than zero, the state tax rate should be greater than zero.
198                         if ((document.getDvNonResidentAlienTax().getFederalIncomeTaxPercent().isGreaterThan(KualiDecimal.ZERO)) && (document.getDvNonResidentAlienTax().getStateIncomeTaxPercent().isZero())) {
199                                     errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_STATE_INCOME_TAX_PERCENT_SHOULD_BE_GREATER_THAN_ZERO );
200                                     return false;
201                         }
202                         // If fed tax rate is zero, the state tax rate should be zero.
203                         if ((document.getDvNonResidentAlienTax().getFederalIncomeTaxPercent().equals(KualiDecimal.ZERO)) && (!document.getDvNonResidentAlienTax().getStateIncomeTaxPercent().isZero())) {
204                                     errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_STATE_TAX_SHOULD_BE_ZERO );
205                                     return false;
206                         }
207                     }
208                 }
209                     }
210                 }
211                 
212 // CHECK BOX SECTION
213 
214     /*examine check boxes*/
215        
216     // the 4 check boxes (Foreign Source, Treaty Exempt, Gross Up Payment, Exempt Under Other Code) shall be mutual exclusive
217     if( OneOrLessBoxesChecked(document) ) {
218 
219         // if Foreign Source is checked
220         if( nonResidentAlienTax.isForeignSourceIncomeCode() ) {
221             // Conditions to be met for "Foreign Source" error to be generated
222             // Federal and State tax rate should be zero.
223             if( (!nonResidentAlienTax.getFederalIncomeTaxPercent().equals(KualiDecimal.ZERO)) || (!nonResidentAlienTax.getStateIncomeTaxPercent().equals(KualiDecimal.ZERO)) ) {
224                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_FEDERAL_AND_STATE_TAXES_SHOULD_BE_ZERO , "Foreign Source");
225                 return false;
226             }
227             // No other items (mutual exclusiveness checking on USAID Per Diem and Special W-4 Amount are optional here since these are also ensured by their validation later)  
228             if((nonResidentAlienTax.isTaxUSAIDPerDiemIndicator()) || (nonResidentAlienTax.getTaxSpecialW4Amount() != null) ||
229                     (nonResidentAlienTax.getReferenceFinancialDocumentNumber() != null) || (nonResidentAlienTax.getTaxNQIId() != null) ){
230                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_CANNOT_HAVE_VALUE , "Foreign Source", "NQI Id, Reference Doc, USAID Per Diem, or Special W-4 Amount");
231                 return false;
232                     }
233                 }
234 
235         // if Treaty Exempt is checked
236         if( nonResidentAlienTax.isIncomeTaxTreatyExemptCode() ) {
237             // Conditions to be met for "Treaty Exempt" error to be generated
238             // No other items (mutual exclusiveness checking on USAID Per Diem and Special W-4 Amount are optional here since these are also ensured by their validation later)  
239             if((nonResidentAlienTax.isTaxUSAIDPerDiemIndicator()) || (nonResidentAlienTax.getTaxSpecialW4Amount() != null) ||
240                     (nonResidentAlienTax.getReferenceFinancialDocumentNumber() != null) || (nonResidentAlienTax.getTaxNQIId() != null) ){
241                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_CANNOT_HAVE_VALUE , "Treaty Exempt", "NQI Id, Reference Doc, USAID Per Diem, or Special W-4 Amount");
242                 return false;
243             }
244         }
245 
246         // if Gross Up Payment is checked
247         if( nonResidentAlienTax.isIncomeTaxGrossUpCode() ) {
248             // Conditions to be met for "Gross Up Payment" error to be generated
249             // Federal tax rate cannot be zero
250             // NOTE: Also, state tax not allowed to be zero for income classes "R" and "I", however, this rule is already checked in the tax rate section, so no need to re-check
251             if( (nonResidentAlienTax.getFederalIncomeTaxPercent().equals(KualiDecimal.ZERO))) {
252                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_FEDERAL_TAX_CANNOT_BE_ZERO, "Gross Up Payment" );
253                 return false;
254             }
255             // No other items (mutual exclusiveness checking on USAID Per Diem and Special W-4 Amount are optional here since these are also ensured by their validation later)  
256             if((nonResidentAlienTax.isTaxUSAIDPerDiemIndicator()) || (nonResidentAlienTax.getTaxSpecialW4Amount() != null) ||
257                     (nonResidentAlienTax.getReferenceFinancialDocumentNumber() != null) || (nonResidentAlienTax.getTaxNQIId() != null) ){
258                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_CANNOT_HAVE_VALUE , "Gross Up Payment", "NQI Id, Reference Doc, USAID Per Diem, or Special W-4 Amount");
259                 return false;
260             }
261         }
262 
263         // if Exempt Under Other Code is checked
264         if( nonResidentAlienTax.isTaxOtherExemptIndicator() ) {
265             // also exists in PurapPropertyConstants.java as PurapPropertyConstants.TAX_OTHER_EXEMPT_INDICATOR
266             // Conditions to be met for "Exempt Under Other Code" error to be generated
267             // Federal and State tax rate should be zero.
268             if( !(nonResidentAlienTax.getStateIncomeTaxPercent().equals(KualiDecimal.ZERO)) || !(nonResidentAlienTax.getFederalIncomeTaxPercent().equals(KualiDecimal.ZERO)) ) {
269                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_FEDERAL_AND_STATE_TAXES_SHOULD_BE_ZERO , "Exempt Under Other Code");
270                 return false;
271             }
272         }
273 
274         // if USAID Per Diem is checked
275         if( nonResidentAlienTax.isTaxUSAIDPerDiemIndicator() ) {
276             // Conditions to be met for "USAID Per Diem" error to be generated
277             // income class code should be fellowship
278             if( !nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_FELLOWSHIP)  ) {
279                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_SHOULD_BE_SELECTED, "USAID Per Diem", "Income Class Code : Fellowship");
280                 return false;
281             }
282             // Federal and State tax rate should be zero.
283             if( !(nonResidentAlienTax.getStateIncomeTaxPercent().equals(KualiDecimal.ZERO)) || !(nonResidentAlienTax.getFederalIncomeTaxPercent().equals(KualiDecimal.ZERO)) ) {
284                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_FEDERAL_AND_STATE_TAXES_SHOULD_BE_ZERO , "USAID Per Diem");
285                 return false;
286             }
287             // Exempt Under Other Code should be checked; this will ensure the other 3 check boxes not checked due to mutual exclusiveness
288             if( !nonResidentAlienTax.isTaxOtherExemptIndicator() ) {
289                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_SHOULD_BE_SELECTED, "USAID Per Diem", "Exempt Under Other Code");
290                 return false;
291             }
292             // Special W-4 Amount shall have no value 
293             if( nonResidentAlienTax.getTaxSpecialW4Amount() != null ) {
294                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_CANNOT_HAVE_VALUE, "USAID Per Diem", "Special W-4 Amount");
295                 return false;
296             }
297         }
298 
299         // if Special W-4 Amount is entered
300         if( nonResidentAlienTax.getTaxSpecialW4Amount() != null ) {
301             // Conditions to be met for "Special W-4 Amount" error to be generated
302             // income class code should be fellowship
303             if( !nonResidentAlienTax.getIncomeClassCode().equals(NRA_TAX_INCOME_CLASS_FELLOWSHIP) ) {
304                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_SHOULD_BE_SELECTED, "Special W-4 Amount", "Income Class Code : Fellowship" );
305                 return false;
306             }
307             // Federal and State tax rate should be zero.
308             if( !(nonResidentAlienTax.getStateIncomeTaxPercent().equals(KualiDecimal.ZERO)) || !(nonResidentAlienTax.getFederalIncomeTaxPercent().equals(KualiDecimal.ZERO)) ) {
309                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_FEDERAL_AND_STATE_TAXES_SHOULD_BE_ZERO , "Special W-4 Amount");
310                 return false;
311             }
312             // Exempt Under Other Code should be checked; this will ensure the other 3 check boxes not checked due to mutual exclusiveness
313             if( !nonResidentAlienTax.isTaxOtherExemptIndicator() ) {
314                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_SHOULD_BE_SELECTED, "Special W-4 Amount", "Exempt Under Other Code");
315                 return false;
316             }
317             // USAID Per Diem should not be checked (mutual exclusive checking on USAID Per Diem here is optional since this is also ensured by validation on Special W-4 Amount above   
318             if( ( nonResidentAlienTax.isTaxUSAIDPerDiemIndicator() ) ) {
319                 errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_WHEN_CHECKED_CANNOT_BE_SELECTED, "Special W-4 Amount", "USAID Per Diem");
320                 return false;
321             }
322         }
323 
324         // if NQI Id is entered
325         if( nonResidentAlienTax.getTaxNQIId() != null) {
326 
327         }
328 
329         // if Reference Doc is entered
330         if( nonResidentAlienTax.getReferenceFinancialDocumentNumber() != null) {
331 
332         }
333 
334     }
335 
336 // RUN FOR SUBMISSION
337 
338     if(validationType!="GENERATE") {
339         // verify tax lines have been generated
340         if ((nonResidentAlienTax.getFederalIncomeTaxPercent().isNonZero() || nonResidentAlienTax.getStateIncomeTaxPercent().isNonZero())) {
341             if (StringUtils.isBlank(nonResidentAlienTax.getFinancialDocumentAccountingLineText())) {
342                 errors.putErrorWithoutFullErrorPath(OLEConstants.GENERAL_NRATAX_TAB_ERRORS, OLEKeyConstants.ERROR_DV_NRA_NO_TAXLINES_GENERATED);
343                 return false;
344             }
345         }
346         }
347 
348         errors.removeFromErrorPath(OLEPropertyConstants.DV_NON_RESIDENT_ALIEN_TAX);
349         errors.removeFromErrorPath(OLEPropertyConstants.DOCUMENT);
350 
351         return isValid;
352     }
353 
354     private boolean stateAndFederalTaxesNotNull(DisbursementVoucherDocument document) {
355         if( (document.getDvNonResidentAlienTax().getFederalIncomeTaxPercent() != null) && (document.getDvNonResidentAlienTax().getStateIncomeTaxPercent() != null) ) {
356             return true;
357         }
358         return false;
359     }
360 
361 
362 
363 
364     /**
365      * determine whether the give user has permission to any edit mode defined in the given candidate edit modes
366      * 
367      * @param accountingDocument the given accounting document
368      * @param financialSystemUser the given user
369      * @param candidateEditEditModes the given candidate edit modes
370      * @return true if the give user has permission to any edit mode defined in the given candidate edit modes; otherwise, false
371      */
372     private boolean hasRequiredEditMode(AccountingDocument accountingDocument, Person financialSystemUser, List<String> candidateEditModes) {
373         DocumentHelperService documentHelperService = SpringContext.getBean(DocumentHelperService.class);
374         TransactionalDocumentAuthorizer documentAuthorizer = (TransactionalDocumentAuthorizer) documentHelperService.getDocumentAuthorizer(accountingDocument);
375         TransactionalDocumentPresentationController presentationController = (TransactionalDocumentPresentationController) documentHelperService.getDocumentPresentationController(accountingDocument);
376 
377         Set<String> presentationControllerEditModes = presentationController.getEditModes(accountingDocument);
378         Set<String> editModes = documentAuthorizer.getEditModes(accountingDocument, financialSystemUser, presentationControllerEditModes);
379 
380         for (String editMode : candidateEditModes) {
381             if (editModes.contains(editMode)) {
382                 return true;
383             }
384         }
385 
386         return false;
387     }
388 
389     /**
390      * define the tax edit mode name
391      * 
392      * @return the tax edit mode name
393      */
394     protected List<String> getTaxEditMode() {
395         List<String> candidateEdiModes = new ArrayList<String>();
396         candidateEdiModes.add(OleAuthorizationConstants.DisbursementVoucherEditMode.TAX_ENTRY);
397 
398         return candidateEdiModes;
399     }
400 
401     /**
402      * Sets the validationType attribute value.
403      *
404      * @param validationType The validationType to set.
405      */
406     public void setValidationType(String validationType) {
407         this.validationType = validationType;
408     }
409 
410     /**
411      * Sets the accountingDocumentForValidation attribute value.
412      * 
413      * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
414      */
415     public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
416         this.accountingDocumentForValidation = accountingDocumentForValidation;
417     }
418 
419     /**
420      * Gets the accountingDocumentForValidation attribute.
421      * 
422      * @return Returns the accountingDocumentForValidation.
423      */
424     public AccountingDocument getAccountingDocumentForValidation() {
425         return accountingDocumentForValidation;
426     }
427 
428     private boolean OneOrLessBoxesChecked(DisbursementVoucherDocument document) {
429         MessageMap errors = GlobalVariables.getMessageMap();
430         /* If more then one of the four boxes (FS, TE, EUOC, GUP) is checked throw an error. */
431         int boxCnt = 0 ;
432         if(document.getDvNonResidentAlienTax().isForeignSourceIncomeCode()) {
433             boxCnt++;
434         }
435         if(document.getDvNonResidentAlienTax().isIncomeTaxTreatyExemptCode()) {
436             boxCnt++;
437         }
438         if(document.getDvNonResidentAlienTax().isTaxOtherExemptIndicator()) {
439             boxCnt++;
440         }
441         if(document.getDvNonResidentAlienTax().isIncomeTaxGrossUpCode()) {
442             boxCnt++;
443         }
444         if(boxCnt > 1) {
445 //            errors.putError(OLEPropertyConstants.INCOME_TAX_TREATY_EXEMPT_CODE, OLEKeyConstants.ERROR_DV_ONLY_ONE_SELECTION_ALLOWED );
446             errors.putErrorWithoutFullErrorPath("DVNRATaxErrors", OLEKeyConstants.ERROR_DV_NRA_TAX_ONLY_ONE_SELECTION_ALLOWED);
447             return false;
448         }
449         else {
450             errors.removeFromErrorPath(OLEPropertyConstants.DV_NON_RESIDENT_ALIEN_TAX);
451             return true;
452         }
453     }
454 }