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.coa.document.validation.impl; 017 018 import java.util.ArrayList; 019 import java.util.HashMap; 020 import java.util.List; 021 import java.util.Map; 022 023 import org.apache.commons.lang.StringUtils; 024 import org.apache.log4j.Logger; 025 import org.kuali.kfs.coa.identity.KfsKimDocumentAttributeData; 026 import org.kuali.kfs.coa.identity.OrgReviewRole; 027 import org.kuali.kfs.coa.identity.OrgReviewRoleLookupableHelperServiceImpl; 028 import org.kuali.kfs.sys.KFSConstants; 029 import org.kuali.kfs.sys.KFSKeyConstants; 030 import org.kuali.kfs.sys.identity.KfsKimAttributes; 031 import org.kuali.rice.kim.bo.entity.KimPrincipal; 032 import org.kuali.rice.kim.bo.group.dto.GroupInfo; 033 import org.kuali.rice.kim.bo.role.dto.DelegateMemberCompleteInfo; 034 import org.kuali.rice.kim.bo.role.dto.KimRoleInfo; 035 import org.kuali.rice.kim.bo.role.dto.RoleMemberCompleteInfo; 036 import org.kuali.rice.kim.bo.role.dto.RoleMembershipInfo; 037 import org.kuali.rice.kim.bo.types.dto.AttributeSet; 038 import org.kuali.rice.kim.bo.types.dto.KimTypeInfo; 039 import org.kuali.rice.kim.service.GroupService; 040 import org.kuali.rice.kim.service.KIMServiceLocator; 041 import org.kuali.rice.kim.service.KimTypeInfoService; 042 import org.kuali.rice.kim.service.UiDocumentService; 043 import org.kuali.rice.kim.util.KimConstants; 044 import org.kuali.rice.kns.document.Document; 045 import org.kuali.rice.kns.document.MaintenanceDocument; 046 import org.kuali.rice.kns.exception.ValidationException; 047 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 048 import org.kuali.rice.kns.util.GlobalVariables; 049 import org.kuali.rice.kns.util.KualiDecimal; 050 051 /** 052 * This class represents the business rules for the maintenance of {@link AccountGlobal} business objects 053 */ 054 public class OrgReviewRoleRule extends MaintenanceDocumentRuleBase { 055 056 protected UiDocumentService uiDocumentService; 057 protected transient static GroupService groupService; 058 protected transient static KimTypeInfoService typeInfoService; 059 protected static Logger LOG = Logger.getLogger(OrgReviewRoleRule.class); 060 061 /** 062 * Need to override to avoid the primary key check which (wrongly) assumes that the object's PKs can be found in the persistence service. 063 * 064 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processGlobalSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) 065 */ 066 @Override 067 protected boolean processGlobalSaveDocumentBusinessRules(MaintenanceDocument document) { 068 return dataDictionaryValidate(document); 069 } 070 071 @Override 072 public boolean processRouteDocument(Document document) { 073 boolean valid = super.processRouteDocument(document); 074 OrgReviewRole orr = (OrgReviewRole)((MaintenanceDocument)document).getNewMaintainableObject().getBusinessObject(); 075 OrgReviewRoleLookupableHelperServiceImpl lookupableHelperService = new OrgReviewRoleLookupableHelperServiceImpl(); 076 lookupableHelperService.validateDocumentType(orr.getFinancialSystemDocumentTypeCode()); 077 if(orr!=null){ 078 if(!orr.hasAnyMember()){ 079 valid = false; 080 putFieldError("principalMemberPrincipalName", KFSKeyConstants.NO_MEMBER_SELECTED); 081 } else{ 082 validateRoleMembersToSave(orr); 083 if(orr.isDelegate()){ 084 // Save delegation(s) 085 valid = validateDelegation(orr, ((MaintenanceDocument)document).isEdit()); 086 } else{ 087 // Save role member(s) 088 valid = validateRoleMember(orr, ((MaintenanceDocument)document).isEdit()); 089 } 090 } 091 } 092 return valid; 093 } 094 095 protected void validateRoleMembersToSave(OrgReviewRole orr){ 096 if(orr==null) return; 097 boolean valid = true; 098 String memberId; 099 if(StringUtils.isNotEmpty(orr.getPrincipalMemberPrincipalName())){ 100 KimPrincipal principal = getIdentityManagementService().getPrincipalByPrincipalName(orr.getPrincipalMemberPrincipalName()); 101 if(principal == null || StringUtils.isEmpty(principal.getPrincipalId())){ 102 GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PATH+"."+OrgReviewRole.PRINCIPAL_NAME_FIELD_NAME, 103 KFSKeyConstants.ERROR_DOCUMENT_OBJCODE_MUST_BEVALID, KimConstants.KimUIConstants.MEMBER_TYPE_PRINCIPAL); 104 valid = false; 105 } 106 } 107 if(StringUtils.isNotEmpty(orr.getRoleMemberRoleName())){ 108 memberId = getRoleService().getRoleIdByName(orr.getRoleMemberRoleNamespaceCode(), orr.getRoleMemberRoleName()); 109 if(memberId == null){ 110 GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PATH+"."+OrgReviewRole.ROLE_NAME_FIELD_NAME, 111 KFSKeyConstants.ERROR_DOCUMENT_OBJCODE_MUST_BEVALID, KimConstants.KimUIConstants.MEMBER_TYPE_ROLE); 112 valid = false; 113 } 114 } 115 if(StringUtils.isNotEmpty(orr.getGroupMemberGroupName())){ 116 GroupInfo groupInfo = getGroupService().getGroupInfoByName(orr.getGroupMemberGroupNamespaceCode(), orr.getGroupMemberGroupName()); 117 if(groupInfo == null || StringUtils.isEmpty(groupInfo.getGroupId())){ 118 GlobalVariables.getMessageMap().putError(MAINTAINABLE_ERROR_PATH+"."+OrgReviewRole.GROUP_NAME_FIELD_NAME, 119 KFSKeyConstants.ERROR_DOCUMENT_OBJCODE_MUST_BEVALID, KimConstants.KimUIConstants.MEMBER_TYPE_GROUP); 120 valid = false; 121 } 122 } 123 if(!valid) 124 throw new ValidationException("Invalid Role Member Data"); 125 } 126 127 protected boolean validateDelegation(OrgReviewRole orr, boolean isEdit){ 128 boolean valid = true; 129 String roleId; 130 if(!isEdit && orr.getRoleNamesToConsider()!=null){ 131 for(String roleName: orr.getRoleNamesToConsider()){ 132 roleId = KIMServiceLocator.getRoleService().getRoleIdByName( 133 KFSConstants.SysKimConstants.ORGANIZATION_REVIEWER_ROLE_NAMESPACECODE, roleName); 134 Map<String, String> criteria = new HashMap<String, String>(); 135 criteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, roleId); 136 List<DelegateMemberCompleteInfo> roleDelegationMembers = getRoleService().findDelegateMembersCompleteInfo(criteria); 137 138 DelegateMemberCompleteInfo member; 139 String memberId; 140 //validate if the newly entered delegation members are already assigned to the role 141 if(roleDelegationMembers!=null){ 142 for(DelegateMemberCompleteInfo delegationMember: roleDelegationMembers){ 143 member = orr.getDelegationMemberOfType(delegationMember.getMemberTypeCode()); 144 if(member!=null && StringUtils.isNotEmpty(member.getMemberName())){ 145 memberId = getUiDocumentService().getMemberIdByName(member.getMemberTypeCode(), member.getMemberNamespaceCode(), member.getMemberName()); 146 boolean attributesUnique = areAttributesUnique(orr, delegationMember.getQualifier()); 147 if(!attributesUnique && member!=null && StringUtils.isNotEmpty(memberId) && memberId.equals(delegationMember.getMemberId()) 148 && (StringUtils.isNotEmpty(orr.getRoleMemberId()) && StringUtils.isNotEmpty(delegationMember.getRoleMemberId()) 149 && orr.getRoleMemberId().equals(delegationMember.getRoleMemberId()))){ 150 putFieldError(orr.getDelegationMemberFieldName(member), KFSKeyConstants.ALREADY_ASSIGNED_MEMBER); 151 valid = false; 152 } 153 } 154 } 155 } 156 } 157 } 158 if(StringUtils.isNotEmpty(orr.getRoleMemberId())){ 159 valid = validateAmounts(orr); 160 //TODO: put from and to amounts validation here 161 Map<String, String> criteria = new HashMap<String, String>(); 162 criteria.put("roleMemberId", orr.getRoleMemberId()); 163 List<RoleMemberCompleteInfo> roleMembers = getRoleService().findRoleMembersCompleteInfo(criteria); 164 RoleMemberCompleteInfo roleMember = null; 165 if(roleMembers!=null && roleMembers.size()>0) 166 roleMember = roleMembers.get(0); 167 KimRoleInfo roleInfo = getRoleService().getRole(roleMember.getRoleId()); 168 KimTypeInfo typeInfo = getTypeInfoService().getKimType(roleInfo.getKimTypeId()); 169 List<KfsKimDocumentAttributeData> attributes = orr.getAttributeSetAsQualifierList(typeInfo, roleMember.getQualifier()); 170 if(roleMember!=null && attributes!=null){ 171 for(KfsKimDocumentAttributeData attribute: attributes){ 172 if(KfsKimAttributes.FROM_AMOUNT.equals(attribute.getKimAttribute().getAttributeName())){ 173 KualiDecimal roleMemberFromAmount = new KualiDecimal(attribute.getAttrVal()); 174 if(orr.getFromAmount()!=null){ 175 KualiDecimal inputFromAmount = orr.getFromAmount(); 176 if((roleMemberFromAmount!=null && inputFromAmount==null) || (inputFromAmount!=null && inputFromAmount.isLessThan(roleMemberFromAmount))){ 177 putFieldError(KfsKimAttributes.FROM_AMOUNT, KFSKeyConstants.FROM_AMOUNT_OUT_OF_RANGE); 178 valid = false; 179 } 180 } 181 } 182 if(KfsKimAttributes.TO_AMOUNT.equals(attribute.getKimAttribute().getAttributeName())){ 183 KualiDecimal roleMemberToAmount = new KualiDecimal(attribute.getAttrVal()); 184 if(orr.getToAmount()!=null){ 185 KualiDecimal inputToAmount = orr.getToAmount(); 186 if((roleMemberToAmount!=null && inputToAmount==null) || (inputToAmount!=null && inputToAmount.isGreaterThan(roleMemberToAmount))){ 187 putFieldError(KfsKimAttributes.TO_AMOUNT, KFSKeyConstants.TO_AMOUNT_OUT_OF_RANGE); 188 valid = false; 189 } 190 } 191 } 192 } 193 } 194 } 195 //putFieldError("bankOfficeCode", KFSKeyConstants.ERROR_DOCUMENT_ACHBANKMAINT_INVALID_OFFICE_CODE); 196 return valid; 197 } 198 199 protected boolean validateAmounts(OrgReviewRole orr){ 200 boolean valid = true; 201 if(orr.getFromAmount()!=null && orr.getToAmount()!=null && orr.getFromAmount().isGreaterThan(orr.getToAmount())){ 202 putFieldError(KfsKimAttributes.FROM_AMOUNT, KFSKeyConstants.FROM_AMOUNT_GREATER_THAN_TO_AMOUNT); 203 valid = false; 204 } 205 return valid; 206 } 207 208 protected boolean validateRoleMember(OrgReviewRole orr, boolean isEdit){ 209 boolean valid = true; 210 String roleId; 211 if(orr==null) return false; 212 boolean attributesUnique = true; 213 valid = validateAmounts(orr); 214 if(!isEdit && orr.getRoleNamesToConsider()!=null){ 215 for(String roleName: orr.getRoleNamesToConsider()){ 216 roleId = KIMServiceLocator.getRoleService().getRoleIdByName( 217 KFSConstants.SysKimConstants.ORGANIZATION_REVIEWER_ROLE_NAMESPACECODE, roleName); 218 //validate if the newly entered role members are already assigned to the role 219 Map<String, Object> criteria = new HashMap<String, Object>(); 220 criteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, roleId); 221 List<String> roleIds = new ArrayList<String>(); 222 roleIds.add(roleId); 223 List<RoleMembershipInfo> roleMembershipInfoList = getRoleService().getFirstLevelRoleMembers(roleIds); 224 RoleMemberCompleteInfo member; 225 String memberId; 226 if(roleMembershipInfoList!=null){ 227 for(RoleMembershipInfo roleMembershipInfo: roleMembershipInfoList){ 228 member = orr.getRoleMemberOfType(roleMembershipInfo.getMemberTypeCode()); 229 if(member!=null && StringUtils.isNotEmpty(member.getMemberName())){ 230 memberId = getUiDocumentService().getMemberIdByName(member.getMemberTypeCode(), member.getMemberNamespaceCode(), member.getMemberName()); 231 attributesUnique = areAttributesUnique(orr, roleMembershipInfo.getQualifier()); 232 if(!attributesUnique && member!=null && StringUtils.isNotEmpty(memberId) && memberId.equals(roleMembershipInfo.getMemberId()) && 233 member.getMemberTypeCode().equals(roleMembershipInfo.getMemberTypeCode())){ 234 putFieldError(orr.getMemberFieldName(member), KFSKeyConstants.ALREADY_ASSIGNED_MEMBER); 235 valid = false; 236 } 237 } 238 } 239 } 240 } 241 } 242 return valid; 243 } 244 245 protected boolean areAttributesUnique(OrgReviewRole orr, AttributeSet attributeSet){ 246 String docTypeName = orr.getFinancialSystemDocumentTypeCode(); 247 String chartOfAccountCode = orr.getChartOfAccountsCode(); 248 String organizationCode = orr.getOrganizationCode(); 249 boolean uniqueAttributes = 250 !StringUtils.equals(docTypeName, getAttributeValue(attributeSet, KfsKimAttributes.DOCUMENT_TYPE_NAME)) || 251 !StringUtils.equals(chartOfAccountCode, getAttributeValue(attributeSet, KfsKimAttributes.CHART_OF_ACCOUNTS_CODE)) || 252 !StringUtils.equals(organizationCode, getAttributeValue(attributeSet, KfsKimAttributes.ORGANIZATION_CODE)); 253 return uniqueAttributes; 254 } 255 256 protected String getAttributeValue(AttributeSet aSet, String attributeName){ 257 if(StringUtils.isEmpty(attributeName)) return null; 258 for(String attributeNameKey: aSet.keySet()){ 259 if(attributeName.equals(attributeNameKey)) 260 return aSet.get(attributeNameKey); 261 } 262 return null; 263 } 264 265 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) { 266 return super.processCustomRouteDocumentBusinessRules(document); 267 } 268 269 /** 270 * Gets the uiDocumentService attribute. 271 * @return Returns the uiDocumentService. 272 */ 273 public UiDocumentService getUiDocumentService() { 274 if(this.uiDocumentService==null){ 275 this.uiDocumentService = KIMServiceLocator.getUiDocumentService(); 276 } 277 return this.uiDocumentService; 278 } 279 280 /** 281 * Sets the uiDocumentService attribute value. 282 * @param uiDocumentService The uiDocumentService to set. 283 */ 284 public void setUiDocumentService(UiDocumentService uiDocumentService) { 285 this.uiDocumentService = uiDocumentService; 286 } 287 288 protected KimTypeInfoService getTypeInfoService(){ 289 if(typeInfoService==null){ 290 typeInfoService = KIMServiceLocator.getTypeInfoService(); 291 } 292 return typeInfoService; 293 } 294 295 protected GroupService getGroupService(){ 296 if(groupService==null){ 297 groupService = KIMServiceLocator.getGroupService(); 298 } 299 return groupService; 300 } 301 }