001    /**
002     * Copyright 2004-2013 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.hr.time.department;
017    
018    import java.sql.Date;
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.kuali.hr.time.roles.TkRole;
025    import org.kuali.hr.time.service.base.TkServiceLocator;
026    import org.kuali.hr.time.util.TKUtils;
027    import org.kuali.hr.time.util.TkConstants;
028    import org.kuali.kfs.coa.businessobject.Chart;
029    import org.kuali.kfs.coa.businessobject.Organization;
030    import org.kuali.rice.kns.document.MaintenanceDocument;
031    import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
032    import org.kuali.rice.krad.bo.PersistableBusinessObject;
033    import org.kuali.rice.krad.service.KRADServiceLocator;
034    
035    public class DepartmentRule extends MaintenanceDocumentRuleBase {
036            
037            boolean validateDepartment(Department department) {
038                    boolean valid = true;
039                    Department existingDept = TkServiceLocator.getDepartmentService().getDepartment(department.getDept(), department.getEffectiveDate());
040                    
041                    if ( department.getHrDeptId() == null ){ //KPME-1456. xichen. Only go through this validation when create a new dept. 
042                            if (department.getEffectiveDate() != null) {        
043                                    if (existingDept != null){
044                                            if ( existingDept.getDept().equalsIgnoreCase(department.getDept()) && 
045                                                     existingDept.getLocation().equalsIgnoreCase(department.getLocation()) ){
046                                                    // error.department.duplicate.exists=There is an exact duplicate version of this Department.                                    
047                                                    this.putFieldError("dept", "error.department.duplicate.exists", department.getDept());
048                                                    valid = false;
049                                            }
050                                    }
051                            }
052                    } 
053                    
054                    return valid;
055            }
056    
057            boolean validateChart(String value) {
058                    boolean valid = true;
059                    if (value != null) {
060                            Chart chart = KRADServiceLocator.getBusinessObjectService()
061                                            .findBySinglePrimaryKey(Chart.class, value);
062                            valid = (chart != null);
063    
064                            if (!valid) {
065                                    this.putFieldError("chart", "dept.chart.notfound", value);
066                            }
067                    }
068                    return valid;
069            }
070    
071            boolean validateOrg(String value) {
072                    boolean valid = true;
073                    if (value != null) {
074                            Organization org = this.getOrganization(value);
075                            valid = (org != null);
076    
077                            if (!valid) {
078                                    this.putFieldError("org", "dept.org.notfound", value);
079                            }
080                    }
081                    return valid;
082            }
083    
084            boolean validateChartAndOrg(String chartString, String orgString) {
085                    if(chartString != null && orgString != null) {
086                            Chart chart = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(Chart.class, chartString);
087                            Organization org = this.getOrganization(orgString);
088                            if(chart != null && org != null) {
089                                    Chart chartTemp = org.getChartOfAccounts();
090                                    if(!chart.getChartOfAccountsCode().equals(chartTemp.getChartOfAccountsCode())) {
091                                            String[] params = new String[]{orgString, chartString};
092                                            this.putFieldError("org", "dept.org.chart.notmatch", params);
093                                            return false;
094                                    }
095                            }
096                    }
097                    return true;
098            }
099    
100            Organization getOrganization(String orgCode) {
101                    Map<String, String> primaryKeys = new HashMap<String, String>();
102                    primaryKeys.put("organizationCode", orgCode);
103                    return (Organization) KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(Organization.class, primaryKeys);
104            }
105    
106            /**
107             * Checks for not null and size > 0, but follows the validation pattern
108             * given in this class for future expanding.
109             *
110             * @return true if there is a role, false otherwise.
111             */
112            protected boolean validateRolePresent(List<TkRole> roles, Date effectiveDate) {
113                    boolean valid = false;
114    
115                    if (roles != null && roles.size() > 0) {
116                            int pos = 0;
117                            for (TkRole role : roles) {
118                                    valid |= role.isActive()
119                                                    && StringUtils.equals(role.getRoleName(),
120                                                                    TkConstants.ROLE_TK_DEPT_ADMIN);
121                                    if(role.getExpirationDate() != null){
122                                            StringBuffer prefix = new StringBuffer("roles[");
123                                            prefix.append(pos).append("].");
124                                            if (effectiveDate.compareTo(role.getExpirationDate()) >= 0
125                                                    || role.getEffectiveDate().compareTo(
126                                                                    role.getExpirationDate()) >= 0) {
127                                                    this.putFieldError(prefix + "expirationDate",
128                                                            "error.role.expiration");
129                                            } else if (TKUtils.getDaysBetween(role.getEffectiveDate(), role.getExpirationDate()) > 180) {
130                                               this.putFieldError(prefix + "expirationDate",
131                                                                    "error.role.expiration.duration");
132                                                    valid = false;
133                                    }
134                                    }
135                                    pos++;
136                            }
137                    }
138    
139                    if (!valid) {
140                            this.putGlobalError("role.required");
141                    }
142    
143                    return valid;
144            }
145    
146            /**
147             * The calling method doesn't seem to examine the return value.
148             */
149            @Override
150            protected boolean processCustomRouteDocumentBusinessRules(
151                            MaintenanceDocument document) {
152                    boolean valid = false;
153    
154                    PersistableBusinessObject pbo = (PersistableBusinessObject) this.getNewBo();
155                    if (pbo instanceof Department) {
156                            Department clr = (Department) pbo;
157                            valid = validateChart(clr.getChart());
158                            valid &= validateOrg(clr.getOrg());
159                            valid &= validateChartAndOrg(clr.getChart(), clr.getOrg());
160                            valid &= validateRolePresent(clr.getRoles(), clr.getEffectiveDate());
161                            valid &= validateDepartment(clr); // KPME1400
162                    }
163    
164                    return valid;
165            }
166    
167    }