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.document.validation.impl;
17  
18  import org.kuali.ole.sys.OLEConstants;
19  import org.kuali.ole.sys.OLEKeyConstants;
20  import org.kuali.ole.sys.context.SpringContext;
21  import org.kuali.ole.sys.document.AccountingDocument;
22  import org.kuali.ole.sys.document.validation.GenericValidation;
23  import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
24  import org.kuali.ole.sys.document.validation.event.AttributedSaveDocumentEvent;
25  import org.kuali.rice.core.api.util.type.KualiDecimal;
26  import org.kuali.rice.core.web.format.CurrencyFormatter;
27  import org.kuali.rice.kew.api.exception.WorkflowException;
28  import org.kuali.rice.krad.service.DocumentService;
29  import org.kuali.rice.krad.util.GlobalVariables;
30  
31  /**
32   * A validation, used on accounting document approval, that accounting line totals are unchanged
33   */
34  public class AccountingLineGroupTotalsUnchangedValidation extends GenericValidation {
35      private AccountingDocument accountingDocumentForValidation;
36      
37      /**
38       * Checks that the source and total amounts on the current version of the accounting document
39       * are equal to the persisted source and total totals.
40       * <strong>Expects a document to be sent in as the first parameter</strong>
41       * @see org.kuali.ole.sys.document.validation.GenericValidation#validate(java.lang.Object[])
42       */
43      public boolean validate(AttributedDocumentEvent event) {
44          AccountingDocument persistedDocument = null;
45          
46          if (event instanceof AttributedSaveDocumentEvent && !accountingDocumentForValidation.getDocumentHeader().getWorkflowDocument().isEnroute()) {
47              return true; // only check save document events if the document is enroute
48          }
49  
50          persistedDocument = retrievePersistedDocument(accountingDocumentForValidation);
51  
52          boolean isUnchanged = true;
53          if (persistedDocument == null) {
54              handleNonExistentDocumentWhenApproving(accountingDocumentForValidation);
55          }
56          else {
57              // retrieve the persisted totals
58              KualiDecimal persistedSourceLineTotal = persistedDocument.getSourceTotal();
59              KualiDecimal persistedTargetLineTotal = persistedDocument.getTargetTotal();
60  
61              // retrieve the updated totals
62              KualiDecimal currentSourceLineTotal = accountingDocumentForValidation.getSourceTotal();
63              KualiDecimal currentTargetLineTotal = accountingDocumentForValidation.getTargetTotal();
64  
65              // make sure that totals have remained unchanged, if not, recognize that, and
66              // generate appropriate error messages
67              if (currentSourceLineTotal.compareTo(persistedSourceLineTotal) != 0) {
68                  isUnchanged = false;
69  
70                  // build out error message
71                  buildTotalChangeErrorMessage(OLEConstants.SOURCE_ACCOUNTING_LINE_ERRORS, persistedSourceLineTotal, currentSourceLineTotal);
72              }
73  
74              if (currentTargetLineTotal.compareTo(persistedTargetLineTotal) != 0) {
75                  isUnchanged = false;
76  
77                  // build out error message
78                  buildTotalChangeErrorMessage(OLEConstants.TARGET_ACCOUNTING_LINE_ERRORS, persistedTargetLineTotal, currentTargetLineTotal);
79              }
80          }
81  
82          return isUnchanged;
83      }
84  
85      /**
86       * attempt to retrieve the document from the DB for comparison
87       * 
88       * @param accountingDocument
89       * @return AccountingDocument
90       */
91      protected AccountingDocument retrievePersistedDocument(AccountingDocument accountingDocument) {
92          AccountingDocument persistedDocument = null;
93  
94          try {
95              persistedDocument = (AccountingDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(accountingDocument.getDocumentNumber());
96          }
97          catch (WorkflowException we) {
98              handleNonExistentDocumentWhenApproving(accountingDocument);
99          }
100 
101         return persistedDocument;
102     }
103     
104     /**
105      * This method builds out the error message for when totals have changed.
106      * 
107      * @param propertyName
108      * @param persistedSourceLineTotal
109      * @param currentSourceLineTotal
110      */
111     protected void buildTotalChangeErrorMessage(String propertyName, KualiDecimal persistedSourceLineTotal, KualiDecimal currentSourceLineTotal) {
112         String persistedTotal = (String) new CurrencyFormatter().format(persistedSourceLineTotal);
113         String currentTotal = (String) new CurrencyFormatter().format(currentSourceLineTotal);
114         GlobalVariables.getMessageMap().putError(propertyName, OLEKeyConstants.ERROR_DOCUMENT_SINGLE_ACCOUNTING_LINE_SECTION_TOTAL_CHANGED, new String[] { persistedTotal, currentTotal });
115     }
116 
117     /**
118      * Handles the case when a non existent document is attempted to be retrieve and that if it's in an initiated state, it's ok.
119      * 
120      * @param accountingDocument
121      */
122     protected final void handleNonExistentDocumentWhenApproving(AccountingDocument accountingDocument) {
123         // check to make sure this isn't an initiated document being blanket approved
124         if (!accountingDocument.getDocumentHeader().getWorkflowDocument().isInitiated()) {
125             throw new IllegalStateException("Document " + accountingDocument.getDocumentNumber() + " is not a valid document that currently exists in the system.");
126         }
127     }
128 
129     /**
130      * Gets the accountingDocumentForValidation attribute. 
131      * @return Returns the accountingDocumentForValidation.
132      */
133     public AccountingDocument getAccountingDocumentForValidation() {
134         return accountingDocumentForValidation;
135     }
136 
137     /**
138      * Sets the accountingDocumentForValidation attribute value.
139      * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
140      */
141     public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
142         this.accountingDocumentForValidation = accountingDocumentForValidation;
143     }
144 }