001 /* 002 * Copyright 2011 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 */ 016 package org.kuali.kfs.module.ld.document.validation.impl; 017 018 import java.util.HashMap; 019 import java.util.Map; 020 import java.util.Set; 021 import java.util.Map.Entry; 022 023 import org.kuali.kfs.module.ld.LaborConstants; 024 import org.kuali.kfs.module.ld.LaborKeyConstants; 025 import org.kuali.kfs.module.ld.document.SalaryExpenseTransferDocument; 026 import org.kuali.kfs.sys.KFSConstants; 027 import org.kuali.kfs.sys.KFSPropertyConstants; 028 import org.kuali.kfs.sys.businessobject.AccountingLine; 029 import org.kuali.kfs.sys.context.SpringContext; 030 import org.kuali.kfs.sys.document.AccountingDocument; 031 import org.kuali.kfs.sys.document.validation.GenericValidation; 032 import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent; 033 import org.kuali.kfs.sys.identity.KfsKimAttributes; 034 import org.kuali.rice.kns.document.Document; 035 import org.kuali.rice.kns.document.authorization.DocumentAuthorizer; 036 import org.kuali.rice.kns.service.DocumentHelperService; 037 import org.kuali.rice.kns.util.GlobalVariables; 038 import org.kuali.rice.kns.util.KualiDecimal; 039 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 040 041 /** 042 * Validates that an accounting document's balances by object codes are unchanged 043 */ 044 public class SalaryExpenseTransferValidAmountTransferredByObjectCodeValidation extends GenericValidation { 045 private Document documentForValidation; 046 047 /** 048 * Validates that an accounting document's unbalanced object code balances exist <strong>Expects an accounting document as the 049 * first a parameter</strong> 050 * 051 * @see org.kuali.kfs.validation.Validation#validate(java.lang.Object[]) 052 */ 053 public boolean validate(AttributedDocumentEvent event) { 054 SalaryExpenseTransferDocument expenseTransferDocument = (SalaryExpenseTransferDocument) documentForValidation; 055 KualiWorkflowDocument workflowDocument = expenseTransferDocument.getDocumentHeader().getWorkflowDocument(); 056 057 // check if user is allowed to edit the object code. 058 if(this.hasEditPermissionOnObjectCode(expenseTransferDocument, workflowDocument)) { 059 return true; 060 } 061 062 // if approving document, check the object code balances match when document was inititated, else check the balance 063 boolean isValid = true; 064 if (workflowDocument.isApprovalRequested()) { 065 if (!isObjectCodeBalancesUnchanged(expenseTransferDocument)) { 066 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.TARGET_ACCOUNTING_LINES, LaborKeyConstants.ERROR_TRANSFER_AMOUNT_BY_OBJECT_APPROVAL_CHANGE); 067 isValid = false; 068 } 069 } 070 else { 071 if (!expenseTransferDocument.getUnbalancedObjectCodes().isEmpty()) { 072 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.TARGET_ACCOUNTING_LINES, LaborKeyConstants.ERROR_TRANSFER_AMOUNT_NOT_BALANCED_BY_OBJECT); 073 isValid = false; 074 } 075 } 076 077 return isValid; 078 } 079 080 // check if user is allowed to edit the object code. 081 protected boolean hasEditPermissionOnObjectCode(SalaryExpenseTransferDocument expenseTransferDocument, KualiWorkflowDocument workflowDocument) { 082 String principalId = GlobalVariables.getUserSession().getPerson().getPrincipalId(); 083 DocumentAuthorizer documentAuthorizer = SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(expenseTransferDocument); 084 String templateName = KFSConstants.PermissionTemplate.MODIFY_ACCOUNTING_LINES.name; 085 086 Map<String, String> additionalPermissionDetails = new HashMap<String, String>(); 087 additionalPermissionDetails.put(KfsKimAttributes.DOCUMENT_TYPE_NAME, workflowDocument.getDocumentType()); 088 additionalPermissionDetails.put(KfsKimAttributes.PROPERTY_NAME, "targetAccountingLines.financialObjectCode"); 089 090 return documentAuthorizer.isAuthorizedByTemplate(expenseTransferDocument, KFSConstants.ParameterNamespaces.KFS, templateName, principalId, additionalPermissionDetails, null); 091 } 092 093 /** 094 * Checks the current object code balance map of the document against the balances captured before the document was returned for 095 * approval. 096 * 097 * @param accountingDocument SalaryExpenseTransferDocument to check 098 * @return true if the balances have not changed, false if they have 099 */ 100 protected boolean isObjectCodeBalancesUnchanged(AccountingDocument accountingDocument) { 101 boolean isUnchanged = true; 102 103 Map<String, KualiDecimal> initiatedObjectCodeBalances = ((SalaryExpenseTransferDocument) accountingDocument).getApprovalObjectCodeBalances(); 104 Map<String, KualiDecimal> currentObjectCodeBalances = ((SalaryExpenseTransferDocument) accountingDocument).getUnbalancedObjectCodes(); 105 106 Set<Entry<String, KualiDecimal>> initiatedObjectCodes = initiatedObjectCodeBalances.entrySet(); 107 Set<Entry<String, KualiDecimal>> currentObjectCodes = currentObjectCodeBalances.entrySet(); 108 109 if (initiatedObjectCodes == null) { 110 if (currentObjectCodes != null) { 111 isUnchanged = false; 112 } 113 } 114 else { 115 if (!initiatedObjectCodes.equals(currentObjectCodes)) { 116 isUnchanged = false; 117 } 118 } 119 120 return isUnchanged; 121 } 122 123 /** 124 * Sets the documentForValidation attribute value. 125 * 126 * @param documentForValidation The documentForValidation to set. 127 */ 128 public void setDocumentForValidation(Document documentForValidation) { 129 this.documentForValidation = documentForValidation; 130 } 131 }