/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.coa.identity;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.rice.core.api.uif.RemotableAttributeError;
import org.kuali.rice.core.api.uif.RemotableAttributeError.Builder;
import org.kuali.rice.core.api.util.RiceKeyConstants;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.kim.api.common.attribute.KimAttribute;
import org.kuali.rice.kim.api.type.KimType;
import org.kuali.rice.kim.api.type.KimTypeAttribute;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADUtils;
public class AccountingOrganizationHierarchyReviewRoleTypeServiceImpl extends OrganizationHierarchyReviewRoleTypeServiceImpl {
private static final Logger LOG = Logger.getLogger(AccountingOrganizationHierarchyReviewRoleTypeServiceImpl.class);
/**
* Create role type service - org.kuali.kfs.coa.identity.AccountingOrganizationHierarchyReviewRoleTypeService for
* KFS-COA/"Organization: Always Hierarchical, Document Type & Accounting" Attributes: Chart Code (required) Organization Code
* Document Type Name From Amount To Amount Override Code - total amount will be passed in as qualification and role type
* service will need to compare it to from and to amount qualifier values for assignees Requirements: - Traverse the org
* hierarchy but not the document type hierarchy - from amount must be null or <= total amount supplied / to amount must be null
* or >= total amount supplied, and null override code on assignment matches all override codes
*
* @see org.kuali.kfs.coa.identity.OrganizationOptionalHierarchyRoleTypeServiceImpl#performMatch(org.kuali.rice.kim.bo.types.dto.AttributeSet,
* org.kuali.rice.kim.bo.types.dto.AttributeSet)
*/
@Override
public boolean performMatch(Map<String,String> qualification, Map<String,String> roleQualifier) {
return doesOverrideCodeMatch(qualification, roleQualifier)
&& isValidTotalAmount(qualification, roleQualifier)
&& super.performMatch(qualification, roleQualifier);
}
protected boolean doesOverrideCodeMatch(Map<String,String> qualification, Map<String,String> roleQualifier) {
return qualification==null
|| roleQualifier==null
|| StringUtils.isBlank(qualification.get(KfsKimAttributes.ACCOUNTING_LINE_OVERRIDE_CODE))
|| StringUtils.isBlank(roleQualifier.get(KfsKimAttributes.ACCOUNTING_LINE_OVERRIDE_CODE))
|| qualification.get(KfsKimAttributes.ACCOUNTING_LINE_OVERRIDE_CODE)
.equals(roleQualifier.get(KfsKimAttributes.ACCOUNTING_LINE_OVERRIDE_CODE));
}
protected boolean isValidTotalAmount(Map<String,String> qualification, Map<String,String> roleQualifier) {
boolean isValidTotalAmount = false;
if(qualification==null || roleQualifier==null) {
return false;
}
String totalAmountStr = qualification.get(KfsKimAttributes.FINANCIAL_DOCUMENT_TOTAL_AMOUNT);
if ( StringUtils.isBlank(totalAmountStr) ) {
return false;
}
try {
KualiDecimal totalAmount = new KualiDecimal(totalAmountStr);
String toAmountStr = roleQualifier.get(KfsKimAttributes.TO_AMOUNT);
String fromAmountStr = roleQualifier.get(KfsKimAttributes.FROM_AMOUNT);
if ((StringUtils.isBlank(toAmountStr) || new KualiDecimal(toAmountStr).isGreaterEqual(totalAmount) )
&& (StringUtils.isBlank(fromAmountStr) || new KualiDecimal(fromAmountStr).isLessEqual(totalAmount) )) {
isValidTotalAmount = true;
}
} catch (Exception ex) {
isValidTotalAmount = false;
LOG.error( "Exception comparing document amount to role qualifiers.", ex );
}
return isValidTotalAmount;
}
@Override
public List<RemotableAttributeError> validateUnmodifiableAttributes(
String kimTypeId, Map<String,String> originalAttributeSet, Map<String,String> newAttributeSet){
List<RemotableAttributeError> validationErrors = super.validateUnmodifiableAttributes(kimTypeId, originalAttributeSet, newAttributeSet);
List<String> attributeErrors = null;
KimAttribute attributeImpl;
String fromAmountRoleMember = getAttributeValue(originalAttributeSet, KfsKimAttributes.FROM_AMOUNT);
String fromAmountDelegationMember = getAttributeValue(newAttributeSet, KfsKimAttributes.FROM_AMOUNT);
KimType kimType = getTypeInfoService().getKimType(kimTypeId);
KimTypeAttribute attributeInfo;
if(isLesserNumber(fromAmountDelegationMember, fromAmountRoleMember)){
attributeInfo = kimType.getAttributeDefinitionById(KfsKimAttributes.FROM_AMOUNT);
GlobalVariables.getMessageMap().putError(
KfsKimAttributes.FROM_AMOUNT, RiceKeyConstants.ERROR_DELEGATION_FROM_AMOUNT_LESSER,
getDataDictionaryService().getAttributeLabel(attributeInfo.getKimAttribute().getComponentName(), KfsKimAttributes.FROM_AMOUNT));
attributeErrors = extractErrorsFromGlobalVariablesErrorMap(KfsKimAttributes.FROM_AMOUNT);
}
Builder fromBuilder = RemotableAttributeError.Builder.create(KfsKimAttributes.FROM_AMOUNT);
if(attributeErrors!=null){
for(String err: attributeErrors){
fromBuilder.getErrors().add(err);
}
validationErrors.add(fromBuilder.build());
attributeErrors = null;
}
String toAmountRoleMember = getAttributeValue(originalAttributeSet, KfsKimAttributes.TO_AMOUNT);
String toAmountDelegationMember = getAttributeValue(newAttributeSet, KfsKimAttributes.TO_AMOUNT);
if(StringUtils.isNotEmpty(toAmountRoleMember) && isGreaterNumber(toAmountDelegationMember, toAmountRoleMember)){
attributeInfo = kimType.getAttributeDefinitionById(KfsKimAttributes.TO_AMOUNT);
GlobalVariables.getMessageMap().putError(
KfsKimAttributes.TO_AMOUNT, RiceKeyConstants.ERROR_DELEGATION_TO_AMOUNT_GREATER,
getDataDictionaryService().getAttributeLabel(attributeInfo.getKimAttribute().getComponentName(), KfsKimAttributes.TO_AMOUNT));
attributeErrors = extractErrorsFromGlobalVariablesErrorMap(KfsKimAttributes.TO_AMOUNT);
}
Builder toBuilder = RemotableAttributeError.Builder.create(KfsKimAttributes.TO_AMOUNT);
if(attributeErrors!=null){
for(String err: attributeErrors){
toBuilder.getErrors().add(err);
}
validationErrors.add(toBuilder.build());
attributeErrors = null;
}
return validationErrors;
}
protected boolean isLesserNumber(String numberStr1, String numberStr2){
if(StringUtils.isBlank(numberStr1) ) {
numberStr1 = "0";
}
if(StringUtils.isBlank(numberStr2) ) {
numberStr2 = "0";
}
int number1 = KRADUtils.getIntegerValue(numberStr1);
int number2 = KRADUtils.getIntegerValue(numberStr2);
return number1 < number2;
}
protected boolean isGreaterNumber(String numberStr1, String numberStr2){
if(StringUtils.isBlank(numberStr1) ) {
numberStr1 = "0";
}
if(StringUtils.isBlank(numberStr2) ) {
numberStr2 = "0";
}
int number1 = KRADUtils.getIntegerValue(numberStr1);
int number2 = KRADUtils.getIntegerValue(numberStr2);
return number1 > number2;
}
}