001/* 002 * Copyright 2010 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 1.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/ecl1.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.coa.service.impl; 017 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.commons.lang.StringUtils; 027import org.joda.time.DateTime; 028import org.kuali.ole.coa.identity.OleKimDocDelegateMember; 029import org.kuali.ole.coa.identity.OleKimDocRoleMember; 030import org.kuali.ole.coa.identity.OleKimDocumentAttributeData; 031import org.kuali.ole.coa.identity.OrgReviewRole; 032import org.kuali.ole.coa.service.OrgReviewRoleService; 033import org.kuali.ole.sys.OLEConstants; 034import org.kuali.ole.sys.identity.OleKimAttributes; 035import org.kuali.rice.core.api.criteria.PredicateUtils; 036import org.kuali.rice.core.api.criteria.QueryByCriteria; 037import org.kuali.rice.core.api.delegation.DelegationType; 038import org.kuali.rice.core.api.membership.MemberType; 039import org.kuali.rice.kew.api.KewApiServiceLocator; 040import org.kuali.rice.kew.api.doctype.DocumentTypeService; 041import org.kuali.rice.kim.api.KimConstants; 042import org.kuali.rice.kim.api.common.attribute.KimAttribute; 043import org.kuali.rice.kim.api.common.delegate.DelegateMember; 044import org.kuali.rice.kim.api.common.delegate.DelegateType; 045import org.kuali.rice.kim.api.group.Group; 046import org.kuali.rice.kim.api.identity.principal.Principal; 047import org.kuali.rice.kim.api.role.Role; 048import org.kuali.rice.kim.api.role.RoleMember; 049import org.kuali.rice.kim.api.role.RoleMemberContract; 050import org.kuali.rice.kim.api.role.RoleMemberQueryResults; 051import org.kuali.rice.kim.api.role.RoleResponsibilityAction; 052import org.kuali.rice.kim.api.role.RoleService; 053import org.kuali.rice.kim.api.services.KimApiServiceLocator; 054import org.kuali.rice.kim.api.type.KimType; 055import org.kuali.rice.kim.api.type.KimTypeAttribute; 056import org.kuali.rice.kim.util.KimCommonUtils; 057import org.kuali.rice.krad.exception.ValidationException; 058import org.kuali.rice.krad.util.GlobalVariables; 059import org.springframework.cache.annotation.Cacheable; 060 061public class OrgReviewRoleServiceImpl implements OrgReviewRoleService { 062 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OrgReviewRoleServiceImpl.class); 063 064 // note: this assumes that all use the OLE-SYS namespace 065 protected static final Map<String,Role> ROLE_CACHE = new HashMap<String, Role>(); 066 protected static final Map<String,Map<String,KimAttribute>> ATTRIBUTE_CACHE = new HashMap<String, Map<String,KimAttribute>>(); 067 068 protected Set<String> potentialParentDocumentTypeNames = new HashSet<String>(); 069 { 070 potentialParentDocumentTypeNames.add(OLEConstants.COAConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT); 071 potentialParentDocumentTypeNames.add(OLEConstants.COAConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT); 072 potentialParentDocumentTypeNames.add(OLEConstants.COAConstants.FINANCIAL_SYSTEM_SIMPLE_MAINTENANCE_DOCUMENT); 073 potentialParentDocumentTypeNames = Collections.unmodifiableSet(potentialParentDocumentTypeNames); 074 } 075 protected DocumentTypeService documentTypeService; 076 077 @Override 078 public RoleMember getRoleMemberFromKimRoleService( String roleMemberId ) { 079 if ( StringUtils.isEmpty(roleMemberId) ) { 080 throw new IllegalArgumentException( "Role member ID may not be blank." ); 081 } 082 RoleMemberQueryResults roleMembers = KimApiServiceLocator.getRoleService().findRoleMembers(QueryByCriteria.Builder.fromPredicates( PredicateUtils.convertMapToPredicate(Collections.singletonMap(KimConstants.PrimaryKeyConstants.ID, roleMemberId)))); 083 if ( roleMembers == null || roleMembers.getResults() == null || roleMembers.getResults().isEmpty() ) { 084 throw new IllegalArgumentException( "Unknown role member ID passed in - nothing returned from KIM RoleService: " + roleMemberId ); 085 } 086 return roleMembers.getResults().get(0); 087 } 088 089 @Override 090 public void populateOrgReviewRoleFromRoleMember(OrgReviewRole orr, String roleMemberId) { 091 if ( StringUtils.isBlank(roleMemberId) ) { 092 throw new IllegalArgumentException( "Role member ID may not be blank" ); 093 } 094 RoleMember roleMember = getRoleMemberFromKimRoleService(roleMemberId); 095 orr.setRoleMember(roleMember); 096 097 populateObjectExtras(orr); 098 } 099 100 @Override 101 public void populateOrgReviewRoleFromDelegationMember(OrgReviewRole orr, String roleMemberId, String delegationMemberId) { 102 RoleMember roleMember = null; 103 if ( StringUtils.isNotBlank(roleMemberId) ) { 104 roleMember = getRoleMemberFromKimRoleService(roleMemberId); 105 } 106 RoleService roleService = KimApiServiceLocator.getRoleService(); 107 DelegateMember delegationMember = roleService.getDelegationMemberById(delegationMemberId); 108 DelegateType delegation = roleService.getDelegateTypeByDelegationId(delegationMember.getDelegationId()); 109 110 orr.setDelegationTypeCode(delegation.getDelegationType().getCode()); 111 //orr.setRoleMember(roleMember); 112 orr.setDelegateMember(roleMember,delegationMember); 113 114 orr.setRoleRspActions(roleService.getRoleMemberResponsibilityActions(delegationMember.getRoleMemberId())); 115 116 populateObjectExtras(orr); 117 } 118 119 protected void populateObjectExtras( OrgReviewRole orr ) { 120 if( !orr.getRoleRspActions().isEmpty() ){ 121 orr.setActionTypeCode(orr.getRoleRspActions().get(0).getActionTypeCode()); 122 orr.setPriorityNumber(orr.getRoleRspActions().get(0).getPriorityNumber()==null?"":String.valueOf(orr.getRoleRspActions().get(0).getPriorityNumber())); 123 orr.setActionPolicyCode(orr.getRoleRspActions().get(0).getActionPolicyCode()); 124 orr.setForceAction(orr.getRoleRspActions().get(0).isForceAction()); 125 } 126 } 127 128 @Override 129 @Cacheable(value=OrgReviewRole.CACHE_NAME,key="'{ValidDocumentTypeForOrgReview}'+#p0") 130 public boolean isValidDocumentTypeForOrgReview(String documentTypeName){ 131 if(StringUtils.isEmpty(documentTypeName)){ 132 return false; 133 } 134 135 return !getRolesToConsider(documentTypeName).isEmpty(); 136 } 137 138 @Override 139 public void validateDocumentType(String documentTypeName) throws ValidationException { 140 if ( getRolesToConsider(documentTypeName).isEmpty() ) { 141 GlobalVariables.getMessageMap().putError(OrgReviewRole.DOC_TYPE_NAME_FIELD_NAME, "error.document.orgReview.invalidDocumentType", documentTypeName); 142 } 143 } 144 145 @Override 146 @Cacheable(value=OrgReviewRole.CACHE_NAME,key="'{hasOrganizationHierarchy}'+#p0") 147 public boolean hasOrganizationHierarchy(String documentTypeName) { 148 if(StringUtils.isBlank(documentTypeName)) { 149 return false; 150 } 151 return getDocumentTypeService().hasRouteNodeForDocumentTypeName(OLEConstants.RouteLevelNames.ORGANIZATION_HIERARCHY, documentTypeName); 152 } 153 154 @Override 155 @Cacheable(value=OrgReviewRole.CACHE_NAME,key="'{hasAccountingOrganizationHierarchy}'+#p0") 156 public boolean hasAccountingOrganizationHierarchy(String documentTypeName) { 157 if(StringUtils.isBlank(documentTypeName)) { 158 return false; 159 } 160 return getDocumentTypeService().hasRouteNodeForDocumentTypeName(OLEConstants.RouteLevelNames.ACCOUNTING_ORGANIZATION_HIERARCHY, documentTypeName); 161 } 162 163 @Override 164 @Cacheable(value=OrgReviewRole.CACHE_NAME,key="'{ClosestOrgReviewRoleParentDocumentTypeName}'+#p0") 165 public String getClosestOrgReviewRoleParentDocumentTypeName(final String documentTypeName){ 166 if(StringUtils.isBlank(documentTypeName)) { 167 return null; 168 } 169 return KimCommonUtils.getClosestParentDocumentTypeName(getDocumentTypeService().getDocumentTypeByName(documentTypeName), potentialParentDocumentTypeNames); 170 } 171 172 /** 173 * 1. Check WorkflowInfo.hasNode(documentTypeName, nodeName) to see if the document type selected has 174 * OrganizationHierarchy and/or AccountingOrganizationHierarchy - if it has either or both, 175 * set the Review Types radio group appropriately and make it read only. 176 * 2. Else, if OLE is the document type selected, set the Review Types radio group to both and leave it editable. 177 * 3. Else, if FinancialSystemTransactionalDocument is the closest parent (per KimCommonUtils.getClosestParent), 178 * set the Review Types radio group to Organization Accounting Only and leave it editable. 179 * 4. Else, if FinancialSystemComplexMaintenanceDocument is the closest parent (per KimCommonUtils.getClosestParent), 180 * set the Review Types radio group to Organization Only and make read-only. 181 * 5. Else, if FinancialSystemSimpleMaintenanceDocument is the closest parent (per KimCommonUtils.getClosestParent), 182 * this makes no sense and should generate an error. 183 * @param documentTypeName 184 * @param hasOrganizationHierarchy 185 * @param hasAccountingOrganizationHierarchy 186 * @param closestParentDocumentTypeName 187 * @return 188 */ 189 @Override 190 @Cacheable(value=OrgReviewRole.CACHE_NAME,key="'{getRolesToConsider}'+#p0") 191 public List<String> getRolesToConsider(String documentTypeName) throws ValidationException { 192 List<String> rolesToConsider = new ArrayList<String>(2); 193 if(StringUtils.isBlank(documentTypeName) || OLEConstants.ROOT_DOCUMENT_TYPE.equals(documentTypeName) ){ 194 rolesToConsider.add(OLEConstants.SysKimApiConstants.ORGANIZATION_REVIEWER_ROLE_NAME); 195 rolesToConsider.add(OLEConstants.SysKimApiConstants.ACCOUNTING_REVIEWER_ROLE_NAME); 196 } else { 197 String closestParentDocumentTypeName = getClosestOrgReviewRoleParentDocumentTypeName(documentTypeName); 198 if(documentTypeName.equals(OLEConstants.COAConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT) 199 || OLEConstants.COAConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT.equals(closestParentDocumentTypeName)) { 200 rolesToConsider.add(OLEConstants.SysKimApiConstants.ACCOUNTING_REVIEWER_ROLE_NAME); 201 } else { 202 boolean hasOrganizationHierarchy = hasOrganizationHierarchy(documentTypeName); 203 boolean hasAccountingOrganizationHierarchy = hasAccountingOrganizationHierarchy(documentTypeName); 204 if(hasOrganizationHierarchy || documentTypeName.equals(OLEConstants.COAConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT) 205 || OLEConstants.COAConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT.equals(closestParentDocumentTypeName) ) { 206 rolesToConsider.add(OLEConstants.SysKimApiConstants.ORGANIZATION_REVIEWER_ROLE_NAME); 207 } 208 if(hasAccountingOrganizationHierarchy) { 209 rolesToConsider.add(OLEConstants.SysKimApiConstants.ACCOUNTING_REVIEWER_ROLE_NAME); 210 } 211 } 212 } 213 return rolesToConsider; 214 } 215 216 @Override 217 public void saveOrgReviewRoleToKim( OrgReviewRole orr ) { 218 if(orr.isDelegate() || orr.isCreateDelegation()){ 219 saveDelegateMemberToKim(orr); 220 } else{ 221 saveRoleMemberToKim(orr); 222 } 223 } 224 225 protected void updateDelegateMemberFromDocDelegateMember( DelegateMember.Builder member, OleKimDocDelegateMember dm ) { 226 member.setMemberId(dm.getMemberId()); 227 member.setType(dm.getType()); 228 member.setRoleMemberId(dm.getRoleMemberId()); 229 member.setAttributes(dm.getAttributes()); 230 member.setActiveFromDate(dm.getActiveFromDate()); 231 member.setActiveToDate(dm.getActiveToDate()); 232 } 233 234 protected void saveDelegateMemberToKim( OrgReviewRole orr ) { 235 if ( LOG.isDebugEnabled() ) { 236 LOG.debug( "Saving delegate member from OrgReviewRole: " + orr ); 237 } 238 RoleService roleService = KimApiServiceLocator.getRoleService(); 239 // Save delegation(s) 240 List<OleKimDocDelegateMember> delegationMembers = getDelegationMembersToSave(orr); 241 242 for( OleKimDocDelegateMember dm : delegationMembers ) { 243 // retrieve the delegate type so it can be updated 244 DelegationType delegationType = dm.getDelegationType(); 245 DelegateType delegateType = roleService.getDelegateTypeByRoleIdAndDelegateTypeCode(orr.getRoleId(), delegationType); 246 // KIM always returns a non-null value even if it has never been persisted 247 if ( delegateType == null || delegateType.getDelegationId() == null ) { 248 DelegateType.Builder newDelegateType = DelegateType.Builder.create(orr.getRoleId(), delegationType, new ArrayList<DelegateMember.Builder>(1)); 249 // ensure this is set (for new delegation types) 250 newDelegateType.setKimTypeId( orr.getKimTypeId()); 251 delegateType = roleService.createDelegateType(newDelegateType.build()); 252 if ( LOG.isDebugEnabled() ) { 253 LOG.debug("No DelegateType in KIM. Created new one: " + delegateType); 254 } 255 } else { 256 if ( LOG.isDebugEnabled() ) { 257 LOG.debug("Pulled DelegateType from KIM: " + delegateType); 258 } 259 } 260 261 boolean foundExistingMember = false; 262 DelegateMember addedMember = null; 263 264 // check for an existing delegation member given its unique ID 265 // if found, update that record 266 if ( StringUtils.isNotBlank(dm.getDelegationMemberId()) ) { 267 DelegateMember member = roleService.getDelegationMemberById(dm.getDelegationMemberId()); 268 if ( member != null ) { 269 foundExistingMember = true; 270 if ( LOG.isDebugEnabled() ) { 271 LOG.debug("Found existing delegate member - updating existing record. " + member); 272 } 273 DelegateMember.Builder updatedMember = DelegateMember.Builder.create(member); 274 // OLEMI-9628 : fixing issue with the delegate switch from primary to secondary 275 // IN this case, we need to delete the member from the "other" delegate type 276 277 // need to determine what the "existing" type was 278 DelegateType originalDelegateType = roleService.getDelegateTypeByDelegationId(member.getDelegationId()); 279 // if they are the same, we can just update the existing record 280 if ( originalDelegateType.getDelegationType().equals(dm.getDelegationType()) ) { 281 updateDelegateMemberFromDocDelegateMember(updatedMember, dm); 282 addedMember = roleService.updateDelegateMember(updatedMember.build()); 283 } else { 284 // Otherwise, we need to remove the old one and add a new one 285 // Remove old 286 roleService.removeDelegateMembers(Collections.singletonList(member)); 287 // add new 288 DelegateMember.Builder newMember = DelegateMember.Builder.create(); 289 newMember.setDelegationId(delegateType.getDelegationId()); 290 updateDelegateMemberFromDocDelegateMember(newMember, dm); 291 addedMember = roleService.createDelegateMember(newMember.build()); 292 } 293 } 294 } 295 // if we did not find one, then we need to create a new member 296 if ( !foundExistingMember ) { 297 if ( LOG.isDebugEnabled() ) { 298 LOG.debug("No existing delegate member found, adding as a new delegate: " + dm); 299 } 300 DelegateMember.Builder newMember = DelegateMember.Builder.create(); 301 newMember.setDelegationId(delegateType.getDelegationId()); 302 updateDelegateMemberFromDocDelegateMember(newMember, dm); 303 addedMember = roleService.createDelegateMember(newMember.build()); 304 } 305 306 if ( addedMember != null ) { 307 orr.setDelegationMemberId(addedMember.getDelegationMemberId()); 308 } 309 } 310 } 311 312 protected void saveRoleMemberToKim( OrgReviewRole orr ) { 313 if ( LOG.isDebugEnabled() ) { 314 LOG.debug( "Saving role member from OrgReviewRole: " + orr ); 315 } 316 RoleService roleService = KimApiServiceLocator.getRoleService(); 317 // Save role member(s) 318 for( RoleMemberContract roleMember : getRoleMembers(orr) ) { 319 List<RoleResponsibilityAction.Builder> roleRspActionsToSave = getRoleResponsibilityActions(orr, roleMember); 320 RoleMemberQueryResults roleMembers = roleService.findRoleMembers(QueryByCriteria.Builder.fromPredicates( PredicateUtils.convertMapToPredicate(Collections.singletonMap(KimConstants.PrimaryKeyConstants.ID, roleMember.getId())))); 321 if ( orr.isEdit() && roleMembers != null && roleMembers.getResults() != null && !roleMembers.getResults().isEmpty() ) { 322 RoleMember existingRoleMember = roleMembers.getResults().get(0); 323 RoleMember.Builder updatedRoleMember = RoleMember.Builder.create(roleMember); 324 updatedRoleMember.setVersionNumber(existingRoleMember.getVersionNumber()); 325 updatedRoleMember.setObjectId(existingRoleMember.getObjectId()); 326 roleMember = roleService.updateRoleMember( updatedRoleMember.build() ); 327 } else { 328 RoleMember.Builder newRoleMember = RoleMember.Builder.create(roleMember); 329 roleMember = roleService.createRoleMember( newRoleMember.build() ); 330 } 331 for ( RoleResponsibilityAction.Builder rra : roleRspActionsToSave ) { 332 // ensure linked to the right record 333 rra.setRoleMemberId(roleMember.getId()); 334 if ( StringUtils.isBlank( rra.getId() ) ) { 335 roleService.createRoleResponsibilityAction(rra.build()); 336 } else { 337 roleService.updateRoleResponsibilityAction(rra.build()); 338 } 339 } 340 orr.setRoleMemberId(roleMember.getId()); 341 orr.setORMId(roleMember.getId()); 342 } 343 } 344 345 protected Role getRoleInfo( String roleName ) { 346 if ( roleName == null ) { 347 return null; 348 } 349 Role role = ROLE_CACHE.get(roleName); 350 if ( role == null ) { 351 role = KimApiServiceLocator.getRoleService().getRoleByNamespaceCodeAndName( OLEConstants.SysKimApiConstants.ORGANIZATION_REVIEWER_ROLE_NAMESPACECODE, roleName); 352 synchronized ( ROLE_CACHE ) { 353 ROLE_CACHE.put(roleName, role); 354 } 355 } 356 return role; 357 } 358 359 protected List<OleKimDocDelegateMember> getDelegationMembersToSave(OrgReviewRole orr){ 360 OleKimDocDelegateMember delegationMember = null; 361 if(orr.isEdit() && StringUtils.isNotBlank(orr.getDelegationMemberId())){ 362 delegationMember = new OleKimDocDelegateMember( KimApiServiceLocator.getRoleService().getDelegationMemberById(orr.getDelegationMemberId()) ); 363 } 364 365 if(delegationMember==null){ 366 delegationMember = new OleKimDocDelegateMember(); 367 if(StringUtils.isNotEmpty(orr.getRoleMemberRoleNamespaceCode()) && StringUtils.isNotEmpty(orr.getRoleMemberRoleName())){ 368 String roleId = KimApiServiceLocator.getRoleService().getRoleIdByNamespaceCodeAndName(orr.getRoleMemberRoleNamespaceCode(), orr.getRoleMemberRoleName()); 369 delegationMember.setMemberId(roleId); 370 delegationMember.setType(MemberType.ROLE); 371 } else if(StringUtils.isNotEmpty(orr.getGroupMemberGroupNamespaceCode()) && StringUtils.isNotEmpty(orr.getGroupMemberGroupName())){ 372 Group groupInfo = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(orr.getGroupMemberGroupNamespaceCode(), orr.getGroupMemberGroupName()); 373 delegationMember.setMemberId(groupInfo.getId()); 374 delegationMember.setType(MemberType.GROUP); 375 } else if(StringUtils.isNotEmpty(orr.getPrincipalMemberPrincipalName())){ 376 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(orr.getPrincipalMemberPrincipalName()); 377 delegationMember.setMemberId(principal.getPrincipalId()); 378 delegationMember.setType(MemberType.PRINCIPAL); 379 } 380 } 381 delegationMember.setDelegationType(DelegationType.fromCode( orr.getDelegationTypeCode() )); 382 delegationMember.setAttributes(getAttributes(orr, orr.getKimTypeId())); 383 if ( orr.getActiveFromDate() != null ) { 384 delegationMember.setActiveFromDate( new DateTime( orr.getActiveFromDate() ) ); 385 } 386 if ( orr.getActiveToDate() != null ) { 387 delegationMember.setActiveToDate( new DateTime( orr.getActiveToDate() ) ); 388 } 389 delegationMember.setRoleMemberId(orr.getRoleMemberId()); 390 return Collections.singletonList(delegationMember); 391 } 392 393 protected OleKimDocRoleMember getRoleMemberToSave(Role role, OrgReviewRole orr){ 394 OleKimDocRoleMember roleMember = null; 395 if ( orr.getPerson() != null ) { 396 roleMember = new OleKimDocRoleMember(role.getId(), MemberType.PRINCIPAL, orr.getPerson().getPrincipalId()); 397 } else if ( orr.getGroup() != null ) { 398 roleMember = new OleKimDocRoleMember(role.getId(), MemberType.GROUP, orr.getGroup().getId() ); 399 } else if( orr.getRole() != null ){ 400 roleMember = new OleKimDocRoleMember(role.getId(), MemberType.ROLE, orr.getRole().getId() ); 401 } 402 if ( roleMember != null ) { 403 if(orr.isEdit()){ 404 roleMember.setId(orr.getRoleMemberId()); 405 } 406 roleMember.setAttributes(getAttributes(orr, role.getKimTypeId())); 407 if ( orr.getActiveFromDate() != null ) { 408 roleMember.setActiveFromDate( new DateTime( orr.getActiveFromDate().getTime() ) ); 409 } 410 if ( orr.getActiveToDate() != null ) { 411 roleMember.setActiveToDate( new DateTime( orr.getActiveToDate().getTime() ) ); 412 } 413 } 414 return roleMember; 415 } 416 417 protected List<String> getRolesToSaveFor(List<String> roleNamesToConsider, String reviewRolesIndicator){ 418 if(roleNamesToConsider!=null){ 419 List<String> roleToSaveFor = new ArrayList<String>(); 420 if(OLEConstants.COAConstants.ORG_REVIEW_ROLE_ORG_ACC_ONLY_CODE.equals(reviewRolesIndicator)){ 421 roleToSaveFor.add(OLEConstants.SysKimApiConstants.ACCOUNTING_REVIEWER_ROLE_NAME); 422 } else if(OLEConstants.COAConstants.ORG_REVIEW_ROLE_ORG_ONLY_CODE.equals(reviewRolesIndicator)){ 423 roleToSaveFor.add(OLEConstants.SysKimApiConstants.ORGANIZATION_REVIEWER_ROLE_NAME); 424 } else{ 425 roleToSaveFor.addAll(roleNamesToConsider); 426 } 427 return roleToSaveFor; 428 } else { 429 return Collections.emptyList(); 430 } 431 } 432 433 protected List<OleKimDocRoleMember> getRoleMembers(OrgReviewRole orr){ 434 List<OleKimDocRoleMember> objectsToSave = new ArrayList<OleKimDocRoleMember>(); 435 List<String> roleNamesToSaveFor = getRolesToSaveFor(orr.getRoleNamesToConsider(), orr.getReviewRolesIndicator()); 436 for(String roleName: roleNamesToSaveFor){ 437 Role roleInfo = getRoleInfo(roleName); 438 OleKimDocRoleMember roleMemberToSave = getRoleMemberToSave(roleInfo, orr); 439 if ( roleMemberToSave != null ) { 440 objectsToSave.add(roleMemberToSave); 441 } 442 } 443 return objectsToSave; 444 } 445 446 protected Map<String,String> getAttributes(OrgReviewRole orr, String kimTypeId){ 447 if( StringUtils.isBlank(kimTypeId) ) { 448 return Collections.emptyMap(); 449 } 450 451 List<OleKimDocumentAttributeData> attributeDataList = new ArrayList<OleKimDocumentAttributeData>(); 452 OleKimDocumentAttributeData attributeData = getAttribute(kimTypeId, OleKimAttributes.CHART_OF_ACCOUNTS_CODE, orr.getChartOfAccountsCode()); 453 if ( attributeData != null ) { 454 attributeDataList.add(attributeData); 455 } 456 457 attributeData = getAttribute(kimTypeId, OleKimAttributes.ORGANIZATION_CODE, orr.getOrganizationCode()); 458 if ( attributeData != null ) { 459 attributeDataList.add(attributeData); 460 } 461 462 attributeData = getAttribute(kimTypeId, KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, orr.getFinancialSystemDocumentTypeCode()); 463 if ( attributeData != null ) { 464 attributeDataList.add(attributeData); 465 } 466 467 attributeData = getAttribute(kimTypeId, OleKimAttributes.ACCOUNTING_LINE_OVERRIDE_CODE, orr.getOverrideCode()); 468 if ( attributeData != null ) { 469 attributeDataList.add(attributeData); 470 } 471 472 attributeData = getAttribute(kimTypeId, OleKimAttributes.FROM_AMOUNT, orr.getFromAmountStr()); 473 if ( attributeData != null ) { 474 attributeDataList.add(attributeData); 475 } 476 477 attributeData = getAttribute(kimTypeId, OleKimAttributes.TO_AMOUNT, orr.getToAmountStr()); 478 if ( attributeData != null ) { 479 attributeDataList.add(attributeData); 480 } 481 482 return orr.getQualifierAsAttributeSet(attributeDataList); 483 } 484 485// JHK: Commented out as it is not needed at the moment. If we decide that we need to link these to the 486// exact responsibilities in the future, I didn't want anyone to have to re-invent the wheel. 487// protected List<RoleResponsibility> getResponsibilitiesWithRoleMemberLevelActions( String roleId ) { 488// List<RoleResponsibility> roleResponsibilities = KimApiServiceLocator.getRoleService().getRoleResponsibilities(roleId); 489// //Assuming that there is only 1 responsibility for both the org review roles 490// if ( roleResponsibilities == null || roleResponsibilities.isEmpty() ) { 491// throw new IllegalStateException("The Org Review Role id: " + roleId + " does not have any responsibilities associated with it"); 492// } 493// List<RoleResponsibility> respWithRoleMemberActions = new ArrayList<RoleResponsibility>( roleResponsibilities.size() ); 494// for ( RoleResponsibility rr : roleResponsibilities ) { 495// Responsibility r = KimApiServiceLocator.getResponsibilityService().getResponsibility(rr.getResponsibilityId()); 496// if ( Boolean.parseBoolean( r.getAttributes().get(KimConstants.AttributeConstants.ACTION_DETAILS_AT_ROLE_MEMBER_LEVEL) ) ) { 497// respWithRoleMemberActions.add(rr); 498// } 499// } 500// return respWithRoleMemberActions; 501// } 502 503 protected List<RoleResponsibilityAction.Builder> getRoleResponsibilityActions(OrgReviewRole orr, RoleMemberContract roleMember){ 504 List<RoleResponsibilityAction.Builder> roleResponsibilityActions = new ArrayList<RoleResponsibilityAction.Builder>(1); 505 506 RoleResponsibilityAction.Builder rra = RoleResponsibilityAction.Builder.create(); 507 // if this is an existing role member, pull matching role resp action record (and set ID in object) so it can be updated 508 // otherwise, it will be left blank and a new one will be created 509 if ( StringUtils.isNotBlank( roleMember.getId() ) ) { 510 List<RoleResponsibilityAction> origRoleRspActions = KimApiServiceLocator.getRoleService().getRoleMemberResponsibilityActions(roleMember.getId()); 511 if ( origRoleRspActions!=null && !origRoleRspActions.isEmpty() ) { 512 rra.setId(origRoleRspActions.get(0).getId()); 513 rra.setVersionNumber(origRoleRspActions.get(0).getVersionNumber()); 514 } 515 } 516 517 rra.setRoleMemberId(roleMember.getId()); 518 rra.setRoleResponsibilityId("*"); 519 rra.setActionTypeCode(orr.getActionTypeCode()); 520 rra.setActionPolicyCode(orr.getActionPolicyCode()); 521 522 if(StringUtils.isNotBlank(orr.getPriorityNumber())){ 523 try{ 524 rra.setPriorityNumber(Integer.valueOf(orr.getPriorityNumber())); 525 } catch(Exception nfx){ 526 rra.setPriorityNumber(null); 527 } 528 } 529 rra.setForceAction(orr.isForceAction()); 530 roleResponsibilityActions.add(rra); 531 return roleResponsibilityActions; 532 } 533 534 protected OleKimDocumentAttributeData getAttribute( String kimTypeId, String attributeName, String attributeValue ) { 535 if ( StringUtils.isNotBlank(attributeValue) ) { 536 KimAttribute attribute = getAttributeDefinition(kimTypeId, attributeName); 537 if( attribute != null ){ 538 OleKimDocumentAttributeData attributeData = new OleKimDocumentAttributeData(); 539 attributeData.setKimTypId(kimTypeId); 540 attributeData.setAttrVal(attributeValue); 541 attributeData.setKimAttrDefnId(attribute.getId()); 542 attributeData.setKimAttribute(attribute); 543 return attributeData; 544 } 545 } 546 return null; 547 } 548 549 protected KimAttribute getAttributeDefinition( String kimTypeId, String attributeName ) { 550 // attempt to pull from cache 551 Map<String,KimAttribute> typeAttributes = ATTRIBUTE_CACHE.get(kimTypeId); 552 // if type has not been loaded, init 553 if ( typeAttributes == null ) { 554 KimType kimType = KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId); 555 if ( kimType != null ) { 556 List<KimTypeAttribute> attributes = kimType.getAttributeDefinitions(); 557 typeAttributes = new HashMap<String, KimAttribute>(); 558 if ( attributes != null ) { 559 // build the map and put it into the cache 560 for ( KimTypeAttribute att : attributes ) { 561 typeAttributes.put( att.getKimAttribute().getAttributeName(), att.getKimAttribute() ); 562 } 563 } 564 synchronized ( ATTRIBUTE_CACHE ) { 565 ATTRIBUTE_CACHE.put(kimTypeId, typeAttributes); 566 } 567 } 568 } 569 // now, see if the attribute is in there 570 if ( typeAttributes != null ) { 571 return typeAttributes.get(attributeName); 572 } 573 return null; 574 } 575 576 577 protected DocumentTypeService getDocumentTypeService() { 578 if ( documentTypeService == null ) { 579 documentTypeService = KewApiServiceLocator.getDocumentTypeService(); 580 } 581 return documentTypeService; 582 } 583 584}