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.module.endow.document.validation.impl; 017 018 import java.sql.Date; 019 import java.sql.Timestamp; 020 021 import org.apache.commons.lang.StringUtils; 022 import org.apache.log4j.Logger; 023 import org.kuali.kfs.module.endow.EndowKeyConstants; 024 import org.kuali.kfs.module.endow.businessobject.Tickler; 025 import org.kuali.kfs.module.endow.businessobject.TicklerRecipientGroup; 026 import org.kuali.kfs.module.endow.businessobject.TicklerRecipientPrincipal; 027 import org.kuali.kfs.module.endow.document.service.KEMService; 028 import org.kuali.kfs.module.endow.document.service.impl.FrequencyCodeServiceImpl; 029 import org.kuali.kfs.sys.context.SpringContext; 030 import org.kuali.rice.kns.document.MaintenanceDocument; 031 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase; 032 import org.kuali.rice.kns.util.DateUtils; 033 import org.kuali.rice.kns.util.GlobalVariables; 034 035 /** 036 * This TicklerRule class implements the Business rules associated with the Tickler. 037 * 038 * @author Tapan S Mokha 039 * @version 1.0 040 */ 041 public class TicklerRule extends MaintenanceDocumentRuleBase { 042 043 private static Logger log = org.apache.log4j.Logger.getLogger(TicklerRule.class); 044 045 private Tickler newTickler; 046 private Tickler oldTickler; 047 048 /** 049 * This method initializes the old and new Tickler. 050 * 051 * @param document 052 */ 053 private void initializeAttributes(MaintenanceDocument document) { 054 if (newTickler == null) { 055 newTickler = (Tickler) document.getNewMaintainableObject().getBusinessObject(); 056 } 057 if (oldTickler == null) { 058 oldTickler = (Tickler) document.getOldMaintainableObject().getBusinessObject(); 059 } 060 061 } 062 063 /** 064 * This method validates the Tickler before being submitted 065 * 1. Check Frequency Or Next Due Date presence and validity. 066 * 2. Check if at-least one Principal Or Group is present and active. 067 * 3. Mark the Termination Date on DeActivation of tickler. 068 * 4. Check Termination Date if the Tickler is marked as inactive and if > Todays' Date. 069 * 070 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument) 071 */ 072 @Override 073 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) 074 { 075 super.processCustomSaveDocumentBusinessRules(document); 076 077 if(GlobalVariables.getMessageMap().getErrorCount() == 0) 078 { 079 //Initialize Tickler Attributes 080 initializeAttributes(document); 081 082 //Rule 4 & 5: Ensure either Frequency or Next Tickler Date are entered. 083 checkFrequencyOrNextDueDateRequirement(); 084 085 //Rule 16 only applies is Tickler is active. 086 if(getNewTickler().isActive()) 087 { 088 //Rule 16 Ensure atleast one active Principal or Group is attached to the Tickler. 089 checkPrincipalOrGroup(); 090 } 091 092 //Rule 9: Put Termination date as system date if tickler is deactivated. 093 markTerminationDateonDeActivation(); 094 095 //Rule 23: Check Term date is greater than today if tickler is reactivated. 096 checkTerminationDateonActivation(); 097 098 return GlobalVariables.getMessageMap().getErrorCount() == 0; 099 } 100 else 101 { 102 return false; 103 } 104 } 105 106 /** 107 * Marks the Termination Date on DeActivation of tickler. 108 */ 109 private void markTerminationDateonDeActivation() 110 { 111 //The tickler was deactivated 112 if( getOldTickler().isActive() && !getNewTickler().isActive()) 113 { 114 //Obtain System Date 115 KEMService kemService = (KEMService) SpringContext.getBean(KEMService.class); 116 getNewTickler().setTerminationDate(kemService.getCurrentDate()); 117 } 118 } 119 120 /** 121 * Checks Termination Date if the Tickler is marked as inactive and if > Todays' Date. 122 */ 123 private void checkTerminationDateonActivation() 124 { 125 //Only if Tickler is being reactivated & termintaion field is not null 126 if( getNewTickler().isActive() && !getOldTickler().isActive() && getNewTickler().getTerminationDate() != null ) 127 { 128 //Obtain System Date 129 KEMService kemService = (KEMService) SpringContext.getBean(KEMService.class); 130 131 //Ensure Termination date is after today, non inclusive 132 if( DateUtils.getDifferenceInDays(new Timestamp(kemService.getCurrentSystemProcessDateObject().getTime()),new Timestamp(getNewTickler().getTerminationDate().getTime())) < 1 ) 133 { 134 putGlobalError(EndowKeyConstants.TicklerConstants.ERROR_TICKLER_TERMINATION_DATE_GREATER_SYSTEMDATE); 135 } 136 } 137 } 138 139 /** 140 * Checks Tickler's Frequency Or Next Due Date presence and validity. 141 */ 142 private void checkFrequencyOrNextDueDateRequirement() 143 { 144 //Check whether frequency and next due date are both missing. 145 if( (StringUtils.isEmpty(getNewTickler().getFrequencyCode()) && getNewTickler().getNextDueDate() == null) ) 146 { 147 putGlobalError(EndowKeyConstants.TicklerConstants.ERROR_TICKLER_FREQUENCYORNEXTDUEDATEREQUIREMENT); 148 } 149 150 //Check whether frequency and next due date are both present. If yes, then check if the date matches up with frequency next due date. 151 if( !StringUtils.isEmpty(getNewTickler().getFrequencyCode()) && getNewTickler().getNextDueDate() != null ) 152 { 153 FrequencyCodeServiceImpl frequencyCodeServiceImpl = (FrequencyCodeServiceImpl) SpringContext.getBean(FrequencyCodeServiceImpl.class); 154 Date date = frequencyCodeServiceImpl.calculateProcessDate(getNewTickler().getFrequencyCode()); 155 if( date.toString().compareTo((getNewTickler().getNextDueDate().toString())) != 0 ) 156 { 157 putGlobalError(EndowKeyConstants.TicklerConstants.ERROR_TICKLER_FREQUENCY_NEXTDUEDATE_MISMATCH); 158 } 159 } 160 } 161 162 /** 163 * Checks if at-least one Principal Or Group is present and active. 164 */ 165 private void checkPrincipalOrGroup() 166 { 167 //Check if atleast one principal is active. 168 boolean activePrincipal = false; 169 for(TicklerRecipientPrincipal principal : getNewTickler().getRecipientPrincipals()) 170 { 171 if(principal.isActive()) 172 { 173 activePrincipal = true; 174 } 175 } 176 177 //Check if atleast one group is active. 178 boolean activeGroup = false; 179 for(TicklerRecipientGroup group: getNewTickler().getRecipientGroups()) 180 { 181 if(group.isActive()) 182 { 183 activeGroup = true; 184 } 185 } 186 187 if( !activePrincipal && !activeGroup ) 188 { 189 putGlobalError(EndowKeyConstants.TicklerConstants.ERROR_TICKLER_PRINCIPAL_GROUP_REQUIRED); 190 } 191 } 192 193 public Tickler getNewTickler() { 194 return newTickler; 195 } 196 197 public void setNewTickler(Tickler newTickler) { 198 this.newTickler = newTickler; 199 } 200 201 public Tickler getOldTickler() { 202 return oldTickler; 203 } 204 205 public void setOldTickler(Tickler oldTickler) { 206 this.oldTickler = oldTickler; 207 } 208 209 210 211 212 }