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 }