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.identity;
017    
018    import java.util.ArrayList;
019    import java.util.Collection;
020    import java.util.Collections;
021    import java.util.HashMap;
022    import java.util.HashSet;
023    import java.util.Iterator;
024    import java.util.List;
025    import java.util.Map;
026    import java.util.Properties;
027    import java.util.Set;
028    
029    import org.apache.commons.lang.StringUtils;
030    import org.kuali.kfs.coa.document.OrgReviewRoleMaintainableImpl;
031    import org.kuali.kfs.sys.KFSConstants;
032    import org.kuali.kfs.sys.context.SpringContext;
033    import org.kuali.kfs.sys.identity.KfsKimAttributes;
034    import org.kuali.rice.core.util.RiceUtilities;
035    import org.kuali.rice.kew.doctype.bo.DocumentType;
036    import org.kuali.rice.kew.doctype.service.DocumentTypeService;
037    import org.kuali.rice.kew.dto.DocumentTypeDTO;
038    import org.kuali.rice.kew.exception.WorkflowException;
039    import org.kuali.rice.kew.service.KEWServiceLocator;
040    import org.kuali.rice.kew.service.WorkflowInfo;
041    import org.kuali.rice.kim.bo.Group;
042    import org.kuali.rice.kim.bo.Person;
043    import org.kuali.rice.kim.bo.Role;
044    import org.kuali.rice.kim.bo.role.dto.DelegateMemberCompleteInfo;
045    import org.kuali.rice.kim.bo.role.dto.KimRoleInfo;
046    import org.kuali.rice.kim.bo.role.dto.RoleMemberCompleteInfo;
047    import org.kuali.rice.kim.bo.role.impl.KimDelegationImpl;
048    import org.kuali.rice.kim.bo.role.impl.KimDelegationMemberImpl;
049    import org.kuali.rice.kim.bo.types.dto.KimTypeInfo;
050    import org.kuali.rice.kim.service.GroupService;
051    import org.kuali.rice.kim.service.IdentityManagementService;
052    import org.kuali.rice.kim.service.KIMServiceLocator;
053    import org.kuali.rice.kim.service.KimTypeInfoService;
054    import org.kuali.rice.kim.service.RoleManagementService;
055    import org.kuali.rice.kim.util.KimCommonUtils;
056    import org.kuali.rice.kim.util.KimConstants;
057    import org.kuali.rice.kns.authorization.BusinessObjectRestrictions;
058    import org.kuali.rice.kns.bo.BusinessObject;
059    import org.kuali.rice.kns.exception.ValidationException;
060    import org.kuali.rice.kns.inquiry.KualiInquirableImpl;
061    import org.kuali.rice.kns.lookup.HtmlData;
062    import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
063    import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl;
064    import org.kuali.rice.kns.service.KNSServiceLocator;
065    import org.kuali.rice.kns.service.KualiModuleService;
066    import org.kuali.rice.kns.util.KNSConstants;
067    import org.kuali.rice.kns.util.ObjectUtils;
068    import org.kuali.rice.kns.util.UrlFactory;
069    import org.kuali.rice.kns.web.struts.form.LookupForm;
070    import org.kuali.rice.ksb.cache.RiceCacheAdministrator;
071    public class OrgReviewRoleLookupableHelperServiceImpl extends KualiLookupableHelperServiceImpl {
072    
073        private GroupService groupService;
074        private RoleManagementService roleManagementService;
075        private IdentityManagementService identityManagementService;
076        private DocumentTypeService documentTypeService;
077        private KimTypeInfoService typeInfoService;
078        private RiceCacheAdministrator cacheAdministrator;
079        
080    //    private KualiInquirableImpl orgReviewRoleInquirable;
081        
082        protected static final String WILDCARD = "*";
083        protected static final String DOCUMENT_TYPE_NAME = KfsKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE;
084        protected static final String SEARCH_CRITERIA_DOCUMENT_TYPE_NAME = "documentTypeName";
085        public static final String MEMBER_ATTRIBUTE_CHART_OF_ACCOUNTS_CODE = "chartOfAccountsCode";
086        public static final String MEMBER_ATTRIBUTE_ORGANIZATION_CODE = "organizationCode";
087        protected static final String MEMBER_PRINCIPAL_NAME = "principalMemberPrincipalName";
088        protected static final String MEMBER_GROUP_NAMESPACE_CODE = "groupMemberGroupNamespaceCode";
089        protected static final String MEMBER_GROUP_NAME = "groupMemberGroupName";
090        protected static final String MEMBER_ROLE_NAMESPACE = "roleMemberRoleNamespaceCode";
091        protected static final String MEMBER_ROLE_NAME = "roleMemberRoleName";
092    
093        protected static final String MEMBER_ID = "memberId";
094        protected static final String MEMBER_ATTRIBUTE_NAME_KEY = "attributes.kimAttribute.attributeName";
095        protected static final String MEMBER_ATTRIBUTE_VALUE_KEY = "attributes.attributeValue";
096    
097        protected static final String DELEGATION_MEMBER_ID = "members.memberId";
098        protected static final String DELEGATION_MEMBER_ATTRIBUTE_NAME_KEY = "members.attributes.kimAttribute.attributeName";
099        protected static final String DELEGATION_MEMBER_ATTRIBUTE_VALUE_KEY = "members.attributes.attributeValue";
100        
101        protected static final String DELEGATE = "delegate";
102        protected static final String ACTIVE = "active";
103        protected static final String ACTIVE_FROM_DATE = "activeFromDate";
104        protected static final String ACTIVE_TO_DATE = "activeToDate";
105        public static final String ORG_ACCT_REVIEW_ROLE_DOC_TYPE_CACHE_GROUP = "OrgAcctReviewRoleDocType";
106        public static final String ORG_ACCT_REVIEW_ROLE_DOC_TYPE_CACHE_PREFIX = ORG_ACCT_REVIEW_ROLE_DOC_TYPE_CACHE_GROUP + ":";
107        
108        @Override
109        public Collection performLookup(LookupForm lookupForm, Collection resultTable, boolean bounded) {
110            lookupForm.setShowMaintenanceLinks(true);
111            lookupForm.setSuppressActions(false);
112            lookupForm.setHideReturnLink(true);
113            return super.performLookup(lookupForm, resultTable, bounded);
114        }
115        
116        @Override
117        public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, List pkNames){
118            OrgReviewRole orr = (OrgReviewRole)businessObject;
119            List<HtmlData> htmlDataList = super.getCustomActionUrls(businessObject, pkNames);
120            if(StringUtils.isNotBlank(getMaintenanceDocumentTypeName()) && allowsMaintenanceEditAction(businessObject) && !orr.isDelegate()) {
121                HtmlData createDelegationUrl = getUrlData(businessObject, KNSConstants.MAINTENANCE_EDIT_METHOD_TO_CALL, KFSConstants.COAConstants.ORG_REVIEW_ROLE_CREATE_DELEGATION_DISPLAY_TEXT, pkNames);
122                //createDelegationUrl.setDisplayText(KFSConstants.COAConstants.ORG_REVIEW_ROLE_CREATE_DELEGATION_DISPLAY_TEXT);
123                htmlDataList.add(createDelegationUrl);
124            }
125            return htmlDataList;
126        }
127    
128        @Override
129        protected AnchorHtmlData getUrlData(BusinessObject businessObject, String methodToCall, String displayText, List pkNames){
130            if(KFSConstants.COAConstants.ORG_REVIEW_ROLE_CREATE_DELEGATION_DISPLAY_TEXT.equals(displayText)){
131                return getCreateDelegationUrl(businessObject, pkNames);
132            } else
133                return super.getUrlData(businessObject, methodToCall, displayText, pkNames);
134        }
135        
136        protected AnchorHtmlData getCreateDelegationUrl(BusinessObject businessObject, List pkNames){
137            OrgReviewRole orr = (OrgReviewRole)businessObject;
138            Properties parameters = new Properties();
139            parameters.put(OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY, OrgReviewRole.NEW_DELEGATION_ID_KEY_VALUE);
140            parameters.put(KFSConstants.DISPATCH_REQUEST_PARAMETER, KNSConstants.MAINTENANCE_EDIT_METHOD_TO_CALL);
141            parameters.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObject.getClass().getName());
142            parameters.put(KNSConstants.COPY_KEYS, OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY+","+OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY+","+KNSConstants.DISPATCH_REQUEST_PARAMETER);
143            parameters.put(OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY, orr.getRoleMemberId());
144            //parameters.putAll(getParametersFromPrimaryKey(businessObject, pkNames));
145            String href = UrlFactory.parameterizeUrl(KNSConstants.MAINTENANCE_ACTION, parameters);
146    
147            return new AnchorHtmlData(href, KNSConstants.DOC_HANDLER_METHOD, KFSConstants.COAConstants.ORG_REVIEW_ROLE_CREATE_DELEGATION_DISPLAY_TEXT);
148        }
149    
150        protected String getActionUrlHref(BusinessObject businessObject, String methodToCall, List pkNames){
151            OrgReviewRole orr = (OrgReviewRole)businessObject;
152            Properties parameters = new Properties();
153            parameters.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
154            parameters.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, OrgReviewRole.class.getName());
155    
156            if(orr.isDelegate()){
157                parameters.put(KNSConstants.COPY_KEYS, OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY+","+KNSConstants.DISPATCH_REQUEST_PARAMETER);
158                parameters.put(OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY, orr.getDelegationMemberId());
159            } else {
160                parameters.put(KNSConstants.COPY_KEYS, OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY+","+OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY+","+KNSConstants.DISPATCH_REQUEST_PARAMETER);
161                parameters.put(OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY, orr.getRoleMemberId());
162            }
163            return UrlFactory.parameterizeUrl(KNSConstants.MAINTENANCE_ACTION, parameters);
164        }
165    
166        protected List<String> getOverridePKNames(OrgReviewRole orr){
167            List overridePKNames = new ArrayList<String>();
168            if(orr.isDelegate())
169                overridePKNames.add(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID);
170            else
171                overridePKNames.add(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID);
172            return overridePKNames;
173        }
174        
175        protected String getActionUrlTitleText(BusinessObject businessObject, String displayText, List pkNames, BusinessObjectRestrictions businessObjectRestrictions){
176            OrgReviewRole orr = (OrgReviewRole)businessObject;
177            return super.getActionUrlTitleText(businessObject, displayText, getOverridePKNames(orr), businessObjectRestrictions);
178        }
179        
180        @Override
181        public List<? extends BusinessObject> getSearchResults(Map<String,String> fieldValues) {
182            return getMemberSearchResults(fieldValues);
183        }
184    
185        /**
186         * @see org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl#getSearchResultsUnbounded(java.util.Map)
187         */
188        @Override 
189        public List<? extends BusinessObject> getSearchResultsUnbounded(
190                Map<String, String> fieldValues) {
191            return getMemberSearchResults(fieldValues);
192        }
193        
194        protected List<? extends BusinessObject> getMemberSearchResults(Map<String, String> fieldValues){
195            String delegateStr = fieldValues.get(DELEGATE);
196            String documentTypeName = fieldValues.get(DOCUMENT_TYPE_NAME);
197            List<Class> classesToSearch = new ArrayList<Class>();
198            List<DelegateMemberCompleteInfo> searchResultsDelegationMembers = new ArrayList<DelegateMemberCompleteInfo>();
199            List<RoleMemberCompleteInfo> searchResultsRoleMembers = new ArrayList<RoleMemberCompleteInfo>();
200            Map<String, String> searchCriteriaRoleMembers;
201            Map<String, String> searchCriteriaDelegations;
202            if(StringUtils.isEmpty(delegateStr)){
203                //Search for both, role members and delegations
204                searchCriteriaRoleMembers = buildOrgReviewRoleSearchCriteria(documentTypeName, fieldValues);
205                searchCriteriaDelegations = buildOrgReviewRoleSearchCriteriaForDelegations(documentTypeName, fieldValues);
206                if(searchCriteriaRoleMembers == null && searchCriteriaDelegations==null){
207                    return new ArrayList<BusinessObject>();
208                } else if(searchCriteriaRoleMembers!=null && searchCriteriaDelegations!=null){
209                    searchResultsRoleMembers.addAll((Collection)searchRoleMembers(searchCriteriaRoleMembers));
210                    searchResultsDelegationMembers.addAll((Collection)searchDelegations(searchCriteriaDelegations));
211                } else if(searchCriteriaRoleMembers!=null){
212                    searchResultsRoleMembers.addAll((Collection)searchRoleMembers(searchCriteriaRoleMembers));
213                } else if(searchCriteriaDelegations!=null){
214                    searchResultsDelegationMembers.addAll((Collection)searchDelegations(searchCriteriaDelegations));
215                }
216            } else{
217                boolean delegate = RiceUtilities.getBooleanValueForString(delegateStr, false);
218                if(delegate){
219                    searchCriteriaDelegations = buildOrgReviewRoleSearchCriteriaForDelegations(documentTypeName, fieldValues);
220                    searchResultsDelegationMembers.addAll((Collection)searchDelegations(searchCriteriaDelegations));
221                } else{
222                    searchCriteriaRoleMembers = buildOrgReviewRoleSearchCriteria(documentTypeName, fieldValues);
223                    searchResultsRoleMembers.addAll((Collection)searchRoleMembers(searchCriteriaRoleMembers));
224                }
225            }
226            List<OrgReviewRole> flattenedSearchResults = new ArrayList<OrgReviewRole>();
227            flattenedSearchResults.addAll(flattenToOrgReviewMembers(fieldValues.get(ACTIVE), documentTypeName, searchResultsRoleMembers));
228            flattenedSearchResults.addAll(flattenToOrgReviewDelegationMembers(fieldValues.get(ACTIVE), documentTypeName, searchResultsDelegationMembers));        
229            filterOrgReview(fieldValues, flattenedSearchResults);
230            
231            return flattenedSearchResults;
232        }
233    
234        protected void filterOrgReview(Map<String, String> fieldValues, List<OrgReviewRole> searchResults){
235        
236            String principalName = fieldValues.get(MEMBER_PRINCIPAL_NAME);
237            List<Person> principals = null;
238            if(StringUtils.isNotEmpty(principalName)){
239                Map<String, Object> criteria = new HashMap<String, Object>();
240                criteria.put(KimConstants.UniqueKeyConstants.PRINCIPAL_NAME, WILDCARD+principalName+WILDCARD);
241                principals = (List<Person>)getPersons(criteria);
242            }
243            String assignedToGroupNamespaceCode = fieldValues.get(MEMBER_GROUP_NAMESPACE_CODE);
244            String assignedToGroupName = fieldValues.get(MEMBER_GROUP_NAME);
245            List<Group> groups = null;
246            if(StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isEmpty(assignedToGroupName) ||
247                    StringUtils.isEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName) ||
248                    StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName)){
249                Map<String, Object> searchCriteria = new HashMap<String, Object>();
250                searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, getQueryString(assignedToGroupNamespaceCode));
251                searchCriteria.put(KimConstants.UniqueKeyConstants.GROUP_NAME, getQueryString(assignedToGroupName));
252                groups = getGroups(searchCriteria);
253            }
254    
255            String assignedToRoleNamespaceCode = fieldValues.get(MEMBER_ROLE_NAMESPACE);
256            String assignedToRoleName = fieldValues.get(MEMBER_ROLE_NAME);
257    
258            List<Role> roles = null;
259            if(StringUtils.isNotEmpty(assignedToRoleNamespaceCode) && StringUtils.isEmpty(assignedToRoleName) ||
260                    StringUtils.isEmpty(assignedToRoleNamespaceCode) && StringUtils.isNotEmpty(assignedToRoleName) ||
261                    StringUtils.isNotEmpty(assignedToRoleNamespaceCode) && StringUtils.isNotEmpty(assignedToRoleName)){
262                Map<String, Object> searchCriteria = new HashMap<String, Object>();
263                searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, getQueryString(assignedToRoleNamespaceCode));
264                searchCriteria.put(KimConstants.UniqueKeyConstants.ROLE_NAME, getQueryString(assignedToRoleName));
265                roles = getRoles(searchCriteria);
266            }
267    
268            String financialSystemDocumentTypeCode = fieldValues.get(DOCUMENT_TYPE_NAME);
269            String chartOfAccountsCode = fieldValues.get(MEMBER_ATTRIBUTE_CHART_OF_ACCOUNTS_CODE);
270            String organizationCode = fieldValues.get(MEMBER_ATTRIBUTE_ORGANIZATION_CODE);
271            
272            //Loop through org review roles and remove rows where necessary
273            Iterator<OrgReviewRole> it = searchResults.iterator();
274            OrgReviewRole orgReviewRole = null;
275            boolean remove = false;
276            
277            while(it.hasNext()){
278            
279                orgReviewRole = it.next();
280                remove = false;
281                
282                //check member attribute parameters
283                if(StringUtils.isNotBlank(organizationCode)){
284                    //filter by chart/document type if they exist
285                    if(StringUtils.isNotBlank(chartOfAccountsCode)){
286                        if(!chartOfAccountsCode.equals(orgReviewRole.getChartOfAccountsCode())){                            
287                            remove = true;
288                        }
289                    }
290                    
291                    if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
292                        if(!financialSystemDocumentTypeCode.equals(orgReviewRole.getFinancialSystemDocumentTypeCode())){                            
293                            remove = true;
294                        }
295                    }
296                }else if(StringUtils.isNotBlank(chartOfAccountsCode)){
297                    //filter by document type if it exists
298                    if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
299                        if(!financialSystemDocumentTypeCode.equals(orgReviewRole.getFinancialSystemDocumentTypeCode())){                        
300                            remove = true;
301                        }                    
302                    }
303                }
304    
305                List<String> items = new ArrayList<String>();
306                
307                //check member id parameters, and only if it hasn't already been marked for removal.
308                if(remove == false){
309                    if(roles!=null){
310                        if(groups!=null){
311                            for(Group group: groups){                                                        
312                                items.add(group.getGroupId());
313                            }
314                            if(!items.contains(orgReviewRole.getGroupMemberGroupId())){
315                                remove = true;
316                            }
317                        }
318                        if(principals!=null){                                            
319                            for(Person principal: principals){
320                                items.add(principal.getPrincipalId());                            
321                            }
322                            if(!items.contains(orgReviewRole.getPrincipalMemberPrincipalId())){
323                                remove = true;
324                            }                        
325                        }
326    
327                    }else if(groups!=null){
328                        if(principals!=null){                    
329                            for(Person principal: principals){
330                                items.add(principal.getPrincipalId());                            
331                            }
332                            if(!items.contains(orgReviewRole.getPrincipalMemberPrincipalId())){
333                                remove = true;
334                            }                        
335                        }
336                    }
337                }
338                
339                //remove if necessary
340                if(remove){
341                    it.remove();
342                }
343            }
344        }
345        
346        protected Map<String, String> addRoleToConsiderSearchCriteria(String documentTypeName, Map<String, String> searchCriteria){
347            List<String> roleNamesToSearchInto = getRolesToConsider(documentTypeName);
348            if(searchCriteria==null)
349                searchCriteria = new HashMap<String, String>();
350            if(roleNamesToSearchInto!=null){
351                StringBuffer rolesQueryString = new StringBuffer();
352                for(String roleName: roleNamesToSearchInto){
353                    rolesQueryString.append(
354                        getRoleManagementService().getRoleIdByName(KFSConstants.SysKimConstants.ORGANIZATION_REVIEWER_ROLE_NAMESPACECODE, roleName)+
355                        KimConstants.KimUIConstants.OR_OPERATOR);
356                }
357                if(rolesQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR))
358                    rolesQueryString.delete(rolesQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), rolesQueryString.length());
359                searchCriteria.put(KimConstants.PrimaryKeyConstants.ROLE_ID, rolesQueryString.toString());
360            }
361            return searchCriteria;
362        }
363    
364        protected List<RoleMemberCompleteInfo> searchRoleMembers(Map<String, String> searchCriteriaRoleMembers){
365            List<RoleMemberCompleteInfo> members = new ArrayList<RoleMemberCompleteInfo>();
366            members.addAll(getRoleManagementService().findRoleMembersCompleteInfo(searchCriteriaRoleMembers));
367            return members;
368        }
369    
370        protected List<DelegateMemberCompleteInfo> searchDelegations(Map<String, String> searchCriteriaDelegateMembers){
371            List<DelegateMemberCompleteInfo> members = new ArrayList<DelegateMemberCompleteInfo>();
372            members.addAll(getRoleManagementService().findDelegateMembersCompleteInfo(searchCriteriaDelegateMembers));
373            return members;
374        }
375    
376        public boolean hasOrganizationHierarchy(final String documentTypeName) {
377            if(StringUtils.isEmpty(documentTypeName)) return false;
378            try {
379                return (new WorkflowInfo()).hasRouteNode(documentTypeName, KFSConstants.RouteLevelNames.ORGANIZATION_HIERARCHY);
380            } catch(WorkflowException wex){
381                throw new RuntimeException("Workflow Exception occurred: "+wex);
382            }
383        }
384    
385        public boolean hasAccountingOrganizationHierarchy(final String documentTypeName) {
386            if(StringUtils.isEmpty(documentTypeName)) return false;
387            try{ 
388                return (new WorkflowInfo()).hasRouteNode(documentTypeName, KFSConstants.RouteLevelNames.ACCOUNTING_ORGANIZATION_HIERARCHY);
389            } catch(WorkflowException wex){
390                throw new RuntimeException("Workflow Exception occurred: "+wex);
391            }
392        }
393    
394        public String getClosestOrgReviewRoleParentDocumentTypeName(final String documentTypeName){
395            if(StringUtils.isEmpty(documentTypeName)) return null;
396            Set<String> potentialParentDocumentTypeNames = new HashSet<String>();
397            potentialParentDocumentTypeNames.add(KFSConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT);
398            potentialParentDocumentTypeNames.add(KFSConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT);
399            potentialParentDocumentTypeNames.add(KFSConstants.FINANCIAL_SYSTEM_SIMPLE_MAINTENANCE_DOCUMENT);
400            return KimCommonUtils.getClosestParentDocumentTypeName(getDocumentTypeService().findByName(documentTypeName), potentialParentDocumentTypeNames);
401        }
402    
403        public List<String> getRolesToConsider(String documentTypeName) {
404            return getRolesToConsider(documentTypeName, 
405                    hasOrganizationHierarchy(documentTypeName), 
406                    hasAccountingOrganizationHierarchy(documentTypeName), 
407                    getClosestOrgReviewRoleParentDocumentTypeName(documentTypeName));
408        }
409        
410        /**
411         *  1. Check WorkflowInfo.hasNode(documentTypeName, nodeName) to see if the document type selected has 
412         *  OrganizationHierarchy and/or AccountingOrganizationHierarchy - if it has either or both, 
413         *  set the Review Types radio group appropriately and make it read only.
414         *  2. Else, if KFS is the document type selected, set the Review Types radio group to both and leave it editable.
415         *  3. Else, if FinancialSystemTransactionalDocument is the closest parent (per KimCommonUtils.getClosestParent), 
416         *  set the Review Types radio group to Organization Accounting Only and leave it editable.
417         *  4. Else, if FinancialSystemComplexMaintenanceDocument is the closest parent (per KimCommonUtils.getClosestParent), 
418         *  set the Review Types radio group to Organization Only and make read-only.
419         *  5. Else, if FinancialSystemSimpleMaintenanceDocument is the closest parent (per KimCommonUtils.getClosestParent), 
420         *  this makes no sense and should generate an error. 
421         * @param documentTypeName
422         * @param hasOrganizationHierarchy
423         * @param hasAccountingOrganizationHierarchy
424         * @param closestParentDocumentTypeName
425         * @return
426         */
427        public List<String> getRolesToConsider(String documentTypeName, boolean hasOrganizationHierarchy, boolean hasAccountingOrganizationHierarchy, String closestParentDocumentTypeName){
428            if(StringUtils.isEmpty(documentTypeName)){
429                List<String> roleToConsider = new ArrayList<String>();
430                roleToConsider.add(KFSConstants.SysKimConstants.ORGANIZATION_REVIEWER_ROLE_NAME);                
431                roleToConsider.add(KFSConstants.SysKimConstants.ACCOUNTING_REVIEWER_ROLE_NAME);
432                return roleToConsider;
433            }
434    
435            List<String> roleToConsider = new ArrayList<String>();
436            if(documentTypeName.equals(KFSConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT) || KFSConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT.equals(closestParentDocumentTypeName))
437                roleToConsider.add(KFSConstants.SysKimConstants.ACCOUNTING_REVIEWER_ROLE_NAME);
438            else if(hasOrganizationHierarchy || hasAccountingOrganizationHierarchy){
439                if(hasOrganizationHierarchy) roleToConsider.add(KFSConstants.SysKimConstants.ORGANIZATION_REVIEWER_ROLE_NAME);                
440                if(hasAccountingOrganizationHierarchy) roleToConsider.add(KFSConstants.SysKimConstants.ACCOUNTING_REVIEWER_ROLE_NAME);
441                //readonly
442            } else if(KFSConstants.ROOT_DOCUMENT_TYPE.equals(documentTypeName)){
443                roleToConsider.add(KFSConstants.SysKimConstants.ORGANIZATION_REVIEWER_ROLE_NAME);                
444                roleToConsider.add(KFSConstants.SysKimConstants.ACCOUNTING_REVIEWER_ROLE_NAME);
445            } else{
446                if(documentTypeName.equals(KFSConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT) || KFSConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT.equals(closestParentDocumentTypeName))
447                    roleToConsider.add(KFSConstants.SysKimConstants.ORGANIZATION_REVIEWER_ROLE_NAME);
448                else if(currentDocTypeAndChildrenHaveZeroOrgAndAccountReviewRoles(documentTypeName)){
449                    throw new ValidationException("Invalid document type chosen for Organization Review: " + documentTypeName);
450                }
451            }
452    
453            return roleToConsider;
454        }
455        
456        public boolean isValidDocumentTypeForOrgReview(String documentTypeName){
457    
458            boolean isValid = true;
459            
460            if(StringUtils.isEmpty(documentTypeName)){
461                return false;        
462            }
463    
464            String closestParentDocumentTypeName = getClosestOrgReviewRoleParentDocumentTypeName(documentTypeName);
465            boolean hasOrganizationHierarchy = hasOrganizationHierarchy(documentTypeName);
466            boolean hasAccountingOrganizationHierarchy = hasAccountingOrganizationHierarchy(documentTypeName);
467        
468            if(documentTypeName.equals(KFSConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT) || KFSConstants.FINANCIAL_SYSTEM_TRANSACTIONAL_DOCUMENT.equals(closestParentDocumentTypeName)){
469                //valid
470            }else if(hasOrganizationHierarchy || hasAccountingOrganizationHierarchy){
471              //valid
472            } else if(KFSConstants.ROOT_DOCUMENT_TYPE.equals(documentTypeName)){
473              //valid
474            } else{
475                if(documentTypeName.equals(KFSConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT) || KFSConstants.FINANCIAL_SYSTEM_COMPLEX_MAINTENANCE_DOCUMENT.equals(closestParentDocumentTypeName)){
476                  //valid
477                }else if(currentDocTypeAndChildrenHaveZeroOrgAndAccountReviewRoles(documentTypeName)){
478                    isValid = false;
479                }
480            }
481    
482            return isValid;
483        }
484        
485        public boolean currentDocTypeAndChildrenHaveZeroOrgAndAccountReviewRoles(String currentDocumentTypeName){     
486            boolean hasZeroQualifyingNodes = true;
487            Object hasZeroNodesCache  = null;
488            
489            //check cache
490            hasZeroNodesCache = getCacheAdministrator().getFromCache(ORG_ACCT_REVIEW_ROLE_DOC_TYPE_CACHE_PREFIX + currentDocumentTypeName);        
491            if( ObjectUtils.isNotNull(hasZeroNodesCache)){
492                return ((Boolean)hasZeroNodesCache).booleanValue();
493            }
494    
495            //check current doc type for qualifying nodes
496            if(hasOrganizationHierarchy(currentDocumentTypeName) || hasAccountingOrganizationHierarchy(currentDocumentTypeName) ){                       
497                hasZeroQualifyingNodes = false;        
498            }
499            
500            //if still has no qualifying nodes, check current nodes children
501            if(hasZeroQualifyingNodes){
502                DocumentTypeDTO currentDocType = SpringContext.getBean(DocumentTypeService.class).getDocumentTypeVO(currentDocumentTypeName);
503                List<DocumentType> docTypes = SpringContext.getBean(DocumentTypeService.class).getChildDocumentTypes(currentDocType.getDocTypeId());
504                
505                for(DocumentType docType : docTypes){
506                    hasZeroQualifyingNodes &= currentDocTypeAndChildrenHaveZeroOrgAndAccountReviewRoles(docType.getName());
507                    if(hasZeroQualifyingNodes == false) break;
508                }
509            }
510            
511            //add to cache if there are qualifying nodes
512            if(hasZeroQualifyingNodes == false){
513                getCacheAdministrator().putInCache(ORG_ACCT_REVIEW_ROLE_DOC_TYPE_CACHE_PREFIX + currentDocumentTypeName, new Boolean(hasZeroQualifyingNodes), ORG_ACCT_REVIEW_ROLE_DOC_TYPE_CACHE_GROUP);
514            }
515            
516            return hasZeroQualifyingNodes;
517        }
518        
519        protected List<OrgReviewRole> flattenToOrgReviewMembers(String active, String documentTypeName, List<RoleMemberCompleteInfo> members){
520            List<OrgReviewRole> orgReviewRoles = new ArrayList<OrgReviewRole>();
521            if(members==null || members.size()<1) return orgReviewRoles;
522            
523            OrgReviewRole orgReviewRole;
524            String memberType;
525            KimRoleInfo roleInfo;
526            KimTypeInfo kimTypeInfo;
527            Boolean activeInd = null;
528            if(StringUtils.isNotEmpty(active)){
529                activeInd = new Boolean(RiceUtilities.getBooleanValueForString(active, true));
530            }
531            for(RoleMemberCompleteInfo member: members){
532                if(activeInd==null || (activeInd.booleanValue()==true && member.isActive()) || (activeInd.booleanValue()==false && !member.isActive())){
533                    orgReviewRole = new OrgReviewRole();
534                    OrgReviewRoleMaintainableImpl orgReviewRoleMaintainableImpl = new OrgReviewRoleMaintainableImpl();
535                    orgReviewRole.setMemberId(member.getMemberId());
536                    orgReviewRole.setMemberTypeCode(member.getMemberTypeCode());           
537                    orgReviewRole.setActiveFromDate(member.getActiveFromDate());
538                    orgReviewRole.setActiveToDate(member.getActiveToDate());
539                    orgReviewRole.setActive(member.isActive());
540                    orgReviewRole.setFinancialSystemDocumentTypeCode(documentTypeName);
541                    orgReviewRole.setMemberName(member.getMemberName());
542                    orgReviewRole.setMemberNamespaceCode(member.getMemberNamespaceCode());
543                    
544                    roleInfo = getRoleManagementService().getRole(member.getRoleId());
545                    kimTypeInfo = getTypeInfoService().getKimType(roleInfo.getKimTypeId());
546                    orgReviewRole.setAttributes(orgReviewRole.getAttributeSetAsQualifierList(kimTypeInfo, member.getQualifier()));
547    
548                    orgReviewRole.setRoleRspActions(orgReviewRoleMaintainableImpl.getRoleRspActions(member.getRoleMemberId()));
549                    orgReviewRole.setRoleMemberId(member.getRoleMemberId());
550                    orgReviewRole.setRoleId(member.getRoleId());
551                    orgReviewRole.setNamespaceCode(roleInfo.getNamespaceCode());
552                    orgReviewRole.setRoleName(roleInfo.getRoleName());
553                    orgReviewRole.setDelegate(false);
554    
555                    orgReviewRole.setChartOfAccountsCode(orgReviewRole.getAttributeValue(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE));
556                    orgReviewRole.setOrganizationCode(orgReviewRole.getAttributeValue(KfsKimAttributes.ORGANIZATION_CODE));
557                    orgReviewRole.setOverrideCode(orgReviewRole.getAttributeValue(KfsKimAttributes.ACCOUNTING_LINE_OVERRIDE_CODE));
558                    orgReviewRole.setFromAmount(orgReviewRole.getAttributeValue(KfsKimAttributes.FROM_AMOUNT));
559                    orgReviewRole.setToAmount(orgReviewRole.getAttributeValue(KfsKimAttributes.TO_AMOUNT));
560                    orgReviewRole.setFinancialSystemDocumentTypeCode(orgReviewRole.getAttributeValue(KfsKimAttributes.DOCUMENT_TYPE_NAME));
561                    
562                    orgReviewRoles.add(orgReviewRole);
563                }
564            }
565            return orgReviewRoles;
566        }
567        
568        protected List<OrgReviewRole> flattenToOrgReviewDelegationMembers(String active, String documentTypeName, List<DelegateMemberCompleteInfo> delegationMembers){
569            List<OrgReviewRole> orgReviewRoles = new ArrayList<OrgReviewRole>();
570            if(delegationMembers==null || delegationMembers.size()<1) return orgReviewRoles;
571            
572            OrgReviewRole orgReviewRole;
573            String memberType;
574            KimRoleInfo roleInfo;
575            Boolean activeInd = null;
576            if(StringUtils.isNotEmpty(active)){
577                activeInd = new Boolean(RiceUtilities.getBooleanValueForString(active, true));
578            }
579            KimTypeInfo kimTypeInfo;
580            for(DelegateMemberCompleteInfo member: delegationMembers){
581                if(activeInd==null || (activeInd.booleanValue()==true && member.isActive()) || (activeInd.booleanValue()==false && !member.isActive())){
582                    orgReviewRole = new OrgReviewRole();
583                    OrgReviewRoleMaintainableImpl orgReviewRoleMaintainableImpl = new OrgReviewRoleMaintainableImpl();
584                    orgReviewRole.setMemberId(member.getMemberId());
585                    orgReviewRole.setMemberTypeCode(member.getMemberTypeCode());
586                    orgReviewRole.setActiveFromDate(member.getActiveFromDate());
587                    orgReviewRole.setActiveToDate(member.getActiveToDate());
588                    orgReviewRole.setActive(member.isActive());
589                    orgReviewRole.setFinancialSystemDocumentTypeCode(documentTypeName);
590                    orgReviewRole.setMemberName(member.getMemberName());
591                    orgReviewRole.setMemberNamespaceCode(member.getMemberNamespaceCode());
592    
593                    roleInfo = getRoleManagementService().getRole(member.getRoleId());
594                    kimTypeInfo = getTypeInfoService().getKimType(roleInfo.getKimTypeId());
595                    orgReviewRole.setAttributes(orgReviewRole.getAttributeSetAsQualifierList(kimTypeInfo, member.getQualifier()));
596    
597                    orgReviewRole.setDelegationMemberId(member.getDelegationMemberId());
598                    orgReviewRole.setRoleMemberId(member.getRoleMemberId());
599                    orgReviewRole.setRoleId(member.getRoleId());
600                    roleInfo = getRoleManagementService().getRole(member.getRoleId());
601                    orgReviewRole.setNamespaceCode(roleInfo.getNamespaceCode());
602                    orgReviewRole.setRoleName(roleInfo.getRoleName());
603                    orgReviewRole.setDelegationTypeCode(member.getDelegationTypeCode());
604                    orgReviewRole.setDelegate(true);
605    
606                    orgReviewRole.setChartOfAccountsCode(orgReviewRole.getAttributeValue(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE));
607                    orgReviewRole.setOrganizationCode(orgReviewRole.getAttributeValue(KfsKimAttributes.ORGANIZATION_CODE));
608                    orgReviewRole.setOverrideCode(orgReviewRole.getAttributeValue(KfsKimAttributes.ACCOUNTING_LINE_OVERRIDE_CODE));
609                    orgReviewRole.setFromAmount(orgReviewRole.getAttributeValue(KfsKimAttributes.FROM_AMOUNT));
610                    orgReviewRole.setToAmount(orgReviewRole.getAttributeValue(KfsKimAttributes.TO_AMOUNT));
611                    orgReviewRole.setFinancialSystemDocumentTypeCode(orgReviewRole.getAttributeValue(KfsKimAttributes.DOCUMENT_TYPE_NAME));
612                    
613                    orgReviewRoles.add(orgReviewRole);
614                }
615            }
616            return orgReviewRoles;
617        }
618        
619        protected KimDelegationImpl getDelegation(KimDelegationMemberImpl delegationMember){
620            Map<String, String> criteria = new HashMap<String, String>();
621            KimDelegationImpl delegation;
622            criteria.put(KimConstants.PrimaryKeyConstants.DELEGATION_ID, delegationMember.getDelegationId());
623            return (KimDelegationImpl)KNSServiceLocator.getBusinessObjectService().findByPrimaryKey(KimDelegationImpl.class, criteria);
624        }
625    
626        protected String getQueryString(String parameter){
627            if(StringUtils.isEmpty(parameter))
628                return WILDCARD;
629            else
630                return WILDCARD+parameter+WILDCARD;
631        }
632    
633        public Person getPerson(Map<String, Object> fieldValues) {
634            return (Person) SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(
635                    Person.class).getExternalizableBusinessObject(Person.class, fieldValues);
636        }
637    
638        public List<Person> getPersons(Map<String, Object> fieldValues) {
639            return (List<Person>) SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(
640                    Person.class).getExternalizableBusinessObjectsList(Person.class, fieldValues);
641        }
642        
643        public Role getRole(Map<String, Object> fieldValues) {
644            return (Role) SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(
645                    Role.class).getExternalizableBusinessObject(Role.class, fieldValues);
646        }
647    
648        public List<Role> getRoles(Map<String, Object> fieldValues) {
649            return (List<Role>) SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(
650                    Role.class).getExternalizableBusinessObjectsList(Role.class, fieldValues);
651        }
652        
653        public Group getGroup(Map<String, Object> fieldValues) {
654            return (Group) SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(
655                    Group.class).getExternalizableBusinessObject(Group.class, fieldValues);
656        }
657    
658        public List<Group> getGroups(Map<String, Object> fieldValues) {
659            return (List<Group>) SpringContext.getBean(KualiModuleService.class).getResponsibleModuleService(
660                    Group.class).getExternalizableBusinessObjectsList(Group.class, fieldValues);
661        }
662        
663        protected Map<String, String> buildOrgReviewRoleSearchCriteria(String documentTypeName, Map<String, String> fieldValues){
664            String principalName = fieldValues.get(MEMBER_PRINCIPAL_NAME);
665            List<Person> principals = null;
666            if(StringUtils.isNotEmpty(principalName)){
667                Map<String, Object> criteria = new HashMap<String, Object>();
668                criteria.put(KimConstants.UniqueKeyConstants.PRINCIPAL_NAME, WILDCARD+principalName+WILDCARD);
669                principals = (List<Person>)getPersons(criteria);
670                if(principals==null || principals.isEmpty())
671                    return null;
672            }
673            String assignedToGroupNamespaceCode = fieldValues.get(MEMBER_GROUP_NAMESPACE_CODE);
674            String assignedToGroupName = fieldValues.get(MEMBER_GROUP_NAME);
675            List<Group> groups = null;
676            if(StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isEmpty(assignedToGroupName) ||
677                    StringUtils.isEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName) ||
678                    StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName)){
679                Map<String, Object> searchCriteria = new HashMap<String, Object>();
680                searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, getQueryString(assignedToGroupNamespaceCode));
681                searchCriteria.put(KimConstants.UniqueKeyConstants.GROUP_NAME, getQueryString(assignedToGroupName));
682                groups = getGroups(searchCriteria);
683                if(groups==null || groups.size()==0)
684                    return null;
685            }
686    
687            String assignedToRoleNamespaceCode = fieldValues.get(MEMBER_ROLE_NAMESPACE);
688            String assignedToRoleName = fieldValues.get(MEMBER_ROLE_NAME);
689    
690            List<Role> roles = null;
691            if(StringUtils.isNotEmpty(assignedToRoleNamespaceCode) && StringUtils.isEmpty(assignedToRoleName) ||
692                    StringUtils.isEmpty(assignedToRoleNamespaceCode) && StringUtils.isNotEmpty(assignedToRoleName) ||
693                    StringUtils.isNotEmpty(assignedToRoleNamespaceCode) && StringUtils.isNotEmpty(assignedToRoleName)){
694                Map<String, Object> searchCriteria = new HashMap<String, Object>();
695                searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, getQueryString(assignedToRoleNamespaceCode));
696                searchCriteria.put(KimConstants.UniqueKeyConstants.ROLE_NAME, getQueryString(assignedToRoleName));
697                roles = getRoles(searchCriteria);
698                if(roles==null || roles.size()==0)
699                    return null;
700            }
701    
702            Map<String, String> searchCriteriaMain = new HashMap<String, String>();
703    
704            String financialSystemDocumentTypeCode = fieldValues.get(DOCUMENT_TYPE_NAME);
705            if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
706                searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, SEARCH_CRITERIA_DOCUMENT_TYPE_NAME);
707                searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, financialSystemDocumentTypeCode);
708            }        
709            String chartOfAccountsCode = fieldValues.get(MEMBER_ATTRIBUTE_CHART_OF_ACCOUNTS_CODE);
710            if(StringUtils.isNotBlank(chartOfAccountsCode)){
711                searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, KfsKimAttributes.CHART_OF_ACCOUNTS_CODE);
712                searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, chartOfAccountsCode);
713            }
714            String organizationCode = fieldValues.get(MEMBER_ATTRIBUTE_ORGANIZATION_CODE);
715            if(StringUtils.isNotBlank(organizationCode)){
716                searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, KfsKimAttributes.ORGANIZATION_CODE);
717                searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, organizationCode);
718            }
719            StringBuffer memberQueryString = null;
720            if(principals!=null){
721                memberQueryString = new StringBuffer();
722                for(Person principal: principals){
723                    memberQueryString.append(principal.getPrincipalId()+KimConstants.KimUIConstants.OR_OPERATOR);
724                }
725                if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR))
726                    memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
727                searchCriteriaMain.put(MEMBER_ID, memberQueryString.toString());
728            }
729            if(groups!=null){
730                if(memberQueryString==null)
731                    memberQueryString = new StringBuffer();
732                else if(StringUtils.isNotEmpty(memberQueryString.toString()))
733                    memberQueryString.append(KimConstants.KimUIConstants.OR_OPERATOR);
734                for(Group group: groups){
735                    memberQueryString.append(group.getGroupId()+KimConstants.KimUIConstants.OR_OPERATOR);
736                }
737                if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR))
738                    memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
739                searchCriteriaMain.put(MEMBER_ID, memberQueryString.toString());
740            }
741            if(roles!=null){
742                if(memberQueryString==null)
743                    memberQueryString = new StringBuffer();
744                else if(StringUtils.isNotEmpty(memberQueryString.toString()))
745                    memberQueryString.append(KimConstants.KimUIConstants.OR_OPERATOR);
746                for(Role role: roles){
747                    memberQueryString.append(role.getRoleId()+KimConstants.KimUIConstants.OR_OPERATOR);
748                }
749                if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR))
750                    memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
751                searchCriteriaMain.put(MEMBER_ID, memberQueryString.toString());
752            }
753            return addRoleToConsiderSearchCriteria(documentTypeName, searchCriteriaMain);
754        }
755        
756        protected Map<String, String> buildOrgReviewRoleSearchCriteriaForDelegations(String documentTypeName, Map<String, String> fieldValues){
757            String principalName = fieldValues.get(MEMBER_PRINCIPAL_NAME);
758            Map<String, Object> searchCriteriaTemp;
759            List<Person> principals = null;
760            if(StringUtils.isNotEmpty(principalName)){
761                searchCriteriaTemp = new HashMap<String, Object>();
762                searchCriteriaTemp.put(KimConstants.UniqueKeyConstants.PRINCIPAL_NAME, WILDCARD+principalName+WILDCARD);
763                principals = (List<Person>)getPersons(searchCriteriaTemp);
764                if(principals==null || principals.isEmpty())
765                    return null;
766            }
767            String assignedToGroupNamespaceCode = fieldValues.get(MEMBER_GROUP_NAMESPACE_CODE);
768            String assignedToGroupName = fieldValues.get(MEMBER_GROUP_NAME);
769            List<Group> groups = null;
770            if(StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isEmpty(assignedToGroupName) ||
771                    StringUtils.isEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName) ||
772                    StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName)){
773                Map<String, Object> searchCriteria = new HashMap<String, Object>();
774                searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, getQueryString(assignedToGroupNamespaceCode));
775                searchCriteria.put(KimConstants.UniqueKeyConstants.GROUP_NAME, getQueryString(assignedToGroupName));
776                groups = getGroups(searchCriteria);
777    
778                if(groups==null || groups.size()==0)
779                    return null;
780            }
781    
782            String assignedToRoleNamespaceCode = fieldValues.get(MEMBER_ROLE_NAMESPACE);
783            String assignedToRoleName = fieldValues.get(MEMBER_ROLE_NAME);
784    
785            /*if(StringUtils.isNotEmpty(assignedToRoleNamespaceCode))
786                searchCriteria.put(MEMBER_ROLE_NAMESPACE, WILDCARD+assignedToRoleNamespaceCode+WILDCARD);
787            if(StringUtils.isNotEmpty(assignedToRoleName))
788                searchCriteria.put(MEMBER_ROLE_NAME, WILDCARD+assignedToRoleName+WILDCARD);*/
789            List<Role> roles = null;
790            if(StringUtils.isNotEmpty(assignedToRoleNamespaceCode) && StringUtils.isEmpty(assignedToRoleName) ||
791                    StringUtils.isEmpty(assignedToRoleNamespaceCode) && StringUtils.isNotEmpty(assignedToRoleName) ||
792                    StringUtils.isNotEmpty(assignedToRoleNamespaceCode) && StringUtils.isNotEmpty(assignedToRoleName)){
793                Map<String, Object> searchCriteria = new HashMap<String, Object>();
794                searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, getQueryString(assignedToRoleNamespaceCode));
795                searchCriteria.put(KimConstants.UniqueKeyConstants.ROLE_NAME, getQueryString(assignedToRoleName));
796                roles = getRoles(searchCriteria);
797                if(roles==null || roles.size()==0)
798                    return null;
799            }
800    
801            final Map<String, String> searchCriteriaMain = new HashMap<String, String>();
802            String financialSystemDocumentTypeCode = fieldValues.get(DOCUMENT_TYPE_NAME);
803            if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
804                searchCriteriaMain.put(DELEGATION_MEMBER_ATTRIBUTE_NAME_KEY, SEARCH_CRITERIA_DOCUMENT_TYPE_NAME);
805                searchCriteriaMain.put(DELEGATION_MEMBER_ATTRIBUTE_VALUE_KEY, financialSystemDocumentTypeCode);
806            }                
807            String chartOfAccountsCode = fieldValues.get(MEMBER_ATTRIBUTE_CHART_OF_ACCOUNTS_CODE);
808            if(StringUtils.isNotBlank(chartOfAccountsCode)){
809                searchCriteriaMain.put(DELEGATION_MEMBER_ATTRIBUTE_NAME_KEY, KfsKimAttributes.CHART_OF_ACCOUNTS_CODE);
810                searchCriteriaMain.put(DELEGATION_MEMBER_ATTRIBUTE_VALUE_KEY, chartOfAccountsCode);
811            }
812            String organizationCode = fieldValues.get(MEMBER_ATTRIBUTE_ORGANIZATION_CODE);
813            if(StringUtils.isNotBlank(organizationCode)){
814                searchCriteriaMain.put(DELEGATION_MEMBER_ATTRIBUTE_NAME_KEY, KfsKimAttributes.ORGANIZATION_CODE);
815                searchCriteriaMain.put(DELEGATION_MEMBER_ATTRIBUTE_VALUE_KEY, organizationCode);
816            }
817            StringBuffer memberQueryString = null;
818            if(principals!=null){
819                memberQueryString = new StringBuffer();
820                for(Person principal: principals){
821                    memberQueryString.append(principal.getPrincipalId()+KimConstants.KimUIConstants.OR_OPERATOR);
822                }
823                if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR))
824                    memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
825                searchCriteriaMain.put(DELEGATION_MEMBER_ID, memberQueryString.toString());
826            }
827            if(groups!=null){
828                if(memberQueryString==null)
829                    memberQueryString = new StringBuffer();
830                else if(StringUtils.isNotEmpty(memberQueryString.toString()))
831                    memberQueryString.append(KimConstants.KimUIConstants.OR_OPERATOR);
832                for(Group group: groups){
833                    memberQueryString.append(group.getGroupId()+KimConstants.KimUIConstants.OR_OPERATOR);
834                }
835                if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR))
836                    memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
837                searchCriteriaMain.put(DELEGATION_MEMBER_ID, memberQueryString.toString());
838            }
839            if(roles!=null){
840                if(memberQueryString==null)
841                    memberQueryString = new StringBuffer();
842                else if(StringUtils.isNotEmpty(memberQueryString.toString()))
843                    memberQueryString.append(KimConstants.KimUIConstants.OR_OPERATOR);
844                for(Role role: roles){
845                    memberQueryString.append(role.getRoleId()+KimConstants.KimUIConstants.OR_OPERATOR);
846                }
847                if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR))
848                    memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
849                searchCriteriaMain.put(DELEGATION_MEMBER_ID, memberQueryString.toString());
850            }
851            return addRoleToConsiderSearchCriteria(documentTypeName, searchCriteriaMain);
852        }
853    
854        /**
855         * @return the roleService
856         */
857        public RoleManagementService getRoleManagementService() {
858            if(roleManagementService == null){
859                roleManagementService = KIMServiceLocator.getRoleManagementService();
860            }
861            return this.roleManagementService;
862        }
863    
864        /**
865         * @param roleService the roleService to set
866         */
867        public void setRoleManagementService(RoleManagementService roleManagementService) {
868            this.roleManagementService = roleManagementService;
869        }
870    
871        public DocumentTypeService getDocumentTypeService() {
872            if ( documentTypeService == null ) {
873                documentTypeService = KEWServiceLocator.getDocumentTypeService();
874            }
875            return this.documentTypeService;
876        }
877    
878        public void validateDocumentType(String documentTypeName){
879            try{
880                getRolesToConsider(documentTypeName);
881            } catch(Exception ex){
882                throw new ValidationException(ex.getMessage());
883            }
884        }
885        
886        @Override
887        public void validateSearchParameters(Map fieldValues) {
888            String documentTypeName = (String)fieldValues.get(DOCUMENT_TYPE_NAME);
889            /*if (StringUtils.isEmpty(documentTypeName)){
890                throw new ValidationException("Please select a document type name.");
891            }*/
892            validateDocumentType(documentTypeName);
893            super.validateSearchParameters(fieldValues);
894        }
895    
896        /**
897         * Gets the groupService attribute. 
898         * @return Returns the groupService.
899         */
900        public GroupService getGroupService() {
901            if(groupService==null){
902                groupService = KIMServiceLocator.getGroupService();
903            }
904            return groupService;
905        }
906    
907        /**
908         * Sets the groupService attribute value.
909         * @param groupService The groupService to set.
910         */
911        public void setGroupService(GroupService groupService) {
912            this.groupService = groupService;
913        }
914    
915        /**
916         * Gets the identityManagementService attribute. 
917         * @return Returns the identityManagementService.
918         */
919        public IdentityManagementService getIdentityManagementService() {
920            if(identityManagementService==null){
921                identityManagementService = KIMServiceLocator.getIdentityManagementService();
922            }
923            return identityManagementService;
924        }
925    
926        /**
927         * Sets the identityManagementService attribute value.
928         * @param identityManagementService The identityManagementService to set.
929         */
930        public void setIdentityManagementService(IdentityManagementService identityManagementService) {
931            this.identityManagementService = identityManagementService;
932        }
933    
934        protected KimTypeInfoService getTypeInfoService(){
935            if(typeInfoService==null){
936                typeInfoService = KIMServiceLocator.getTypeInfoService();
937            }
938            return typeInfoService;
939        }
940        protected RiceCacheAdministrator getCacheAdministrator(){
941            if(cacheAdministrator==null){
942                cacheAdministrator = KEWServiceLocator.getCacheAdministrator();
943            }
944            return cacheAdministrator;
945        }
946    }