001/* 002 * Copyright 2008 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.ole.sys.document.validation.impl; 017 018import org.kuali.ole.sys.OLEConstants; 019import org.kuali.ole.sys.OLEKeyConstants; 020import org.kuali.ole.sys.context.SpringContext; 021import org.kuali.ole.sys.document.AccountingDocument; 022import org.kuali.ole.sys.document.validation.GenericValidation; 023import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent; 024import org.kuali.ole.sys.document.validation.event.AttributedSaveDocumentEvent; 025import org.kuali.rice.core.api.util.type.KualiDecimal; 026import org.kuali.rice.core.web.format.CurrencyFormatter; 027import org.kuali.rice.kew.api.exception.WorkflowException; 028import org.kuali.rice.krad.service.DocumentService; 029import org.kuali.rice.krad.util.GlobalVariables; 030 031/** 032 * A validation, used on accounting document approval, that accounting line totals are unchanged 033 */ 034public class AccountingLineGroupTotalsUnchangedValidation extends GenericValidation { 035 private AccountingDocument accountingDocumentForValidation; 036 037 /** 038 * Checks that the source and total amounts on the current version of the accounting document 039 * are equal to the persisted source and total totals. 040 * <strong>Expects a document to be sent in as the first parameter</strong> 041 * @see org.kuali.ole.sys.document.validation.GenericValidation#validate(java.lang.Object[]) 042 */ 043 public boolean validate(AttributedDocumentEvent event) { 044 AccountingDocument persistedDocument = null; 045 046 if (event instanceof AttributedSaveDocumentEvent && !accountingDocumentForValidation.getDocumentHeader().getWorkflowDocument().isEnroute()) { 047 return true; // only check save document events if the document is enroute 048 } 049 050 persistedDocument = retrievePersistedDocument(accountingDocumentForValidation); 051 052 boolean isUnchanged = true; 053 if (persistedDocument == null) { 054 handleNonExistentDocumentWhenApproving(accountingDocumentForValidation); 055 } 056 else { 057 // retrieve the persisted totals 058 KualiDecimal persistedSourceLineTotal = persistedDocument.getSourceTotal(); 059 KualiDecimal persistedTargetLineTotal = persistedDocument.getTargetTotal(); 060 061 // retrieve the updated totals 062 KualiDecimal currentSourceLineTotal = accountingDocumentForValidation.getSourceTotal(); 063 KualiDecimal currentTargetLineTotal = accountingDocumentForValidation.getTargetTotal(); 064 065 // make sure that totals have remained unchanged, if not, recognize that, and 066 // generate appropriate error messages 067 if (currentSourceLineTotal.compareTo(persistedSourceLineTotal) != 0) { 068 isUnchanged = false; 069 070 // build out error message 071 buildTotalChangeErrorMessage(OLEConstants.SOURCE_ACCOUNTING_LINE_ERRORS, persistedSourceLineTotal, currentSourceLineTotal); 072 } 073 074 if (currentTargetLineTotal.compareTo(persistedTargetLineTotal) != 0) { 075 isUnchanged = false; 076 077 // build out error message 078 buildTotalChangeErrorMessage(OLEConstants.TARGET_ACCOUNTING_LINE_ERRORS, persistedTargetLineTotal, currentTargetLineTotal); 079 } 080 } 081 082 return isUnchanged; 083 } 084 085 /** 086 * attempt to retrieve the document from the DB for comparison 087 * 088 * @param accountingDocument 089 * @return AccountingDocument 090 */ 091 protected AccountingDocument retrievePersistedDocument(AccountingDocument accountingDocument) { 092 AccountingDocument persistedDocument = null; 093 094 try { 095 persistedDocument = (AccountingDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(accountingDocument.getDocumentNumber()); 096 } 097 catch (WorkflowException we) { 098 handleNonExistentDocumentWhenApproving(accountingDocument); 099 } 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}