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 }