View Javadoc

1   /**
2    * Copyright 2012 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   *
15   * Created by chongzhu on 10/24/12
16   */
17  package org.kuali.student.enrollment.class2.acal.service.impl;
18  
19  import org.apache.commons.lang.BooleanUtils;
20  import org.apache.commons.lang.StringUtils;
21  import org.apache.commons.lang.time.DateFormatUtils;
22  import org.kuali.rice.core.api.criteria.Predicate;
23  import org.kuali.rice.core.api.criteria.QueryByCriteria;
24  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
25  import org.kuali.rice.core.api.util.ConcreteKeyValue;
26  import org.kuali.rice.core.api.util.KeyValue;
27  import org.kuali.rice.core.api.util.RiceKeyConstants;
28  import org.kuali.rice.krad.uif.UifConstants;
29  import org.kuali.rice.krad.uif.container.CollectionGroup;
30  import org.kuali.rice.krad.uif.control.SelectControl;
31  import org.kuali.rice.krad.uif.field.InputField;
32  import org.kuali.rice.krad.uif.view.View;
33  import org.kuali.rice.krad.util.GlobalVariables;
34  import org.kuali.rice.krad.util.KRADConstants;
35  import org.kuali.student.enrollment.class2.acal.dto.HolidayCalendarWrapper;
36  import org.kuali.student.enrollment.class2.acal.dto.HolidayWrapper;
37  import org.kuali.student.enrollment.class2.acal.service.HolidayCalendarViewHelperService;
38  import org.kuali.student.r2.common.dto.StatusInfo;
39  import org.kuali.student.r2.common.util.date.DateFormatters;
40  import org.kuali.student.r2.core.acal.dto.HolidayCalendarInfo;
41  import org.kuali.student.r2.core.acal.dto.HolidayInfo;
42  import org.kuali.student.r2.core.acal.service.AcademicCalendarService;
43  import org.kuali.student.enrollment.class2.acal.dto.TimeSetWrapper;
44  import org.kuali.student.enrollment.class2.acal.form.HolidayCalendarForm;
45  import org.kuali.student.enrollment.class2.acal.util.CalendarConstants;
46  import org.kuali.student.enrollment.class2.acal.util.CommonUtils;
47  import org.kuali.student.common.uif.service.impl.KSViewHelperServiceImpl;
48  import org.kuali.student.r2.common.dto.ContextInfo;
49  import org.kuali.student.r2.common.exceptions.InvalidParameterException;
50  import org.kuali.student.r2.common.exceptions.MissingParameterException;
51  import org.kuali.student.r2.common.exceptions.OperationFailedException;
52  import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
53  import org.kuali.student.r2.core.constants.AcademicCalendarServiceConstants;
54  import org.kuali.student.r2.core.class1.state.dto.StateInfo;
55  import org.kuali.student.r2.core.class1.type.dto.TypeInfo;
56  import org.kuali.student.r2.core.constants.AtpServiceConstants;
57  
58  import javax.xml.namespace.QName;
59  import java.util.*;
60  
61  import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
62  
63  /**
64   * This class implements ViewHelperServiceImpl for  all HolidayCalendar views
65   *
66   * @author Kuali Student Team
67   */
68  public class HolidayCalendarViewHelperServiceImpl extends KSViewHelperServiceImpl implements HolidayCalendarViewHelperService {
69  
70      private AcademicCalendarService acalService;
71      private List<TypeInfo> holidayTypes;
72  
73  
74      public void saveHolidayCalendar(HolidayCalendarForm hcForm,boolean isSetOfficial) throws Exception{
75  
76          ContextInfo contextInfo = createContextInfo();
77          //Save holiday calendar
78          HolidayCalendarInfo hcInfo = hcForm.getHolidayCalendarInfo();
79          if (StringUtils.isBlank(hcInfo.getStateKey())){
80              hcInfo.setStateKey(AtpServiceConstants.ATP_DRAFT_STATE_KEY);
81          }
82          hcInfo.setTypeKey(AcademicCalendarServiceConstants.HOLIDAY_CALENDAR_TYPE_KEY);
83          hcInfo.setDescr(CommonUtils.buildDesc("no description"));
84  
85          if (StringUtils.isBlank(hcInfo.getId())){
86              HolidayCalendarInfo createdHCal = getAcalService().createHolidayCalendar(AcademicCalendarServiceConstants.HOLIDAY_CALENDAR_TYPE_KEY, hcInfo, contextInfo);
87              hcForm.setHolidayCalendarInfo(createdHCal);
88          }else{
89              HolidayCalendarInfo updatedHCal = getAcalService().updateHolidayCalendar(hcInfo.getId(), hcInfo, contextInfo);
90              hcForm.setHolidayCalendarInfo(updatedHCal);
91          }
92  
93          //Save holidays
94          List<HolidayWrapper> holidays = hcForm.getHolidays();
95          // save list of new holiday IDs here:
96          List<String> newHolidayIdList = new ArrayList<String>(holidays.size());
97  
98          HolidayInfo holidayInfo, storedHolidayInfo;
99          for (HolidayWrapper holidayWrapper : holidays){
100 
101             holidayInfo = holidayWrapper.getHolidayInfo();
102             holidayWrapper.setTypeName(getHolidayTypeName(holidayWrapper.getTypeKey()));
103             holidayInfo.setDescr(CommonUtils.buildDesc("no description"));
104             holidayInfo.setIsAllDay(holidayWrapper.isAllDay());
105             holidayInfo.setIsInstructionalDay(holidayWrapper.isInstructional());
106             holidayInfo.setStartDate(holidayWrapper.getStartDate());
107             holidayInfo.setName(holidayWrapper.getTypeName());
108             holidayInfo.setStartDate(getStartDateWithUpdatedTime(holidayWrapper,true));
109             holidayInfo.setTypeKey(holidayWrapper.getTypeKey());
110             setHolidayEndDate(holidayWrapper);
111 
112             if (StringUtils.isBlank(holidayInfo.getId())){
113                 if (StringUtils.equals(hcForm.getHolidayCalendarInfo().getStateKey(),AtpServiceConstants.ATP_OFFICIAL_STATE_KEY)){
114                     holidayInfo.setStateKey(AtpServiceConstants.MILESTONE_OFFICIAL_STATE_KEY);
115                 } else {
116                     holidayInfo.setStateKey(AtpServiceConstants.MILESTONE_DRAFT_STATE_KEY);
117                 }
118                 storedHolidayInfo = getAcalService().createHoliday(hcForm.getHolidayCalendarInfo().getId(), holidayWrapper.getTypeKey(), holidayInfo, contextInfo);
119             }else{
120                 storedHolidayInfo = getAcalService().updateHoliday(holidayInfo.getId(),holidayInfo, contextInfo);
121             }
122             holidayWrapper.setHolidayInfo(storedHolidayInfo);
123             newHolidayIdList.add(storedHolidayInfo.getId());
124             hcForm.setMeta(hcInfo.getMeta());
125         }
126 
127         if ( ! StringUtils.isBlank(hcInfo.getId())) { // calendar already exists
128             // remove all old holidays that are not contained in the list of new holidays
129             List<HolidayInfo> oldHolidayList =
130                     getAcalService().getHolidaysForHolidayCalendar(hcInfo.getId(), contextInfo);
131             for (HolidayInfo oldHoliday : oldHolidayList) {
132                 if ( ! newHolidayIdList.contains(oldHoliday.getId())) {
133                     getAcalService().deleteHoliday(oldHoliday.getId(), contextInfo);
134                 }
135             }
136         }
137 
138         if (isSetOfficial){
139             StatusInfo statusInfo = null;
140             try {
141                 statusInfo = getAcalService().changeHolidayCalendarState(hcForm.getHolidayCalendarInfo().getId(), AcademicCalendarServiceConstants.ACADEMIC_CALENDAR_OFFICIAL_STATE_KEY,createContextInfo());
142                 if (!statusInfo.getIsSuccess()){
143                     GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_MESSAGES, RiceKeyConstants.ERROR_CUSTOM, statusInfo.getMessage());
144                 } else{
145                     hcForm.setHolidayCalendarInfo(getAcalService().getHolidayCalendar(hcForm.getHolidayCalendarInfo().getId(),createContextInfo()));
146                     for (HolidayWrapper holidayWrapper : hcForm.getHolidays()) {
147                         holidayWrapper.setHolidayInfo(getAcalService().getHoliday(holidayWrapper.getHolidayInfo().getId(),createContextInfo()));
148                     }
149                 }
150             } catch (Exception e) {
151                 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_MESSAGES, CalendarConstants.MessageKeys.ERROR_ACAL_SAVE_FAILED + " - " + e.getMessage());
152             }
153         }
154     }
155 
156     public HolidayCalendarInfo getHolidayCalendar(String hcId) throws Exception{
157         HolidayCalendarInfo retrievedHc = getAcalService().getHolidayCalendar(hcId, createContextInfo());
158         return retrievedHc;
159     }
160 
161     /**
162      * Returns the most recently created calendar of the current year or past year.
163      *
164      * @return The found holiday calendar or null if no calendars found for the last 2 years.
165      * @throws Exception
166      */
167     public HolidayCalendarInfo getNewestHolidayCalendar() throws Exception {
168         int currentYear = Calendar.getInstance().get(Calendar.YEAR);
169 
170         // Get the list of holiday calendars for the current year
171         List<HolidayCalendarInfo> holidayCalendarInfoList =
172                 getAcalService().getHolidayCalendarsByStartYear(currentYear, createContextInfo());
173 
174         // Check if calendars were found for this year. If not found search for calenders in the previous year
175         if ((null == holidayCalendarInfoList) || holidayCalendarInfoList.isEmpty()) {
176             holidayCalendarInfoList =
177                     getAcalService().getHolidayCalendarsByStartYear((currentYear - 1), createContextInfo());
178         }
179 
180         if ((null == holidayCalendarInfoList) || (holidayCalendarInfoList.size() == 0)) {
181 
182             // If no calendars are found for current or previous year return null.
183             return null;
184         }
185         else {
186             // If Calendars are found search through them to find the most recently created.
187             // The number of calendars should be small so naive search possible.
188             HolidayCalendarInfo newestCalendar =  holidayCalendarInfoList.get(0);
189             for(HolidayCalendarInfo calendarTemp: holidayCalendarInfoList){
190                 // Compare the time when the calendars are created and pick the higher one (most recent).
191                 if(calendarTemp.getMeta().getCreateTime().compareTo(newestCalendar.getMeta().getCreateTime())>0){
192                     newestCalendar = calendarTemp;
193                 }
194             }
195 
196             return newestCalendar;
197         }
198     }
199 
200     public List<HolidayWrapper> getHolidayWrappersForHolidayCalendar(String holidayCalendarId) throws Exception {
201         List<HolidayInfo> holidayInfos =
202                 getAcalService().getHolidaysForHolidayCalendar(holidayCalendarId, createContextInfo());
203         return assembleHolidays(holidayInfos);
204     }
205 
206     private List<HolidayWrapper> assembleHolidays (List<HolidayInfo> holidayInfos) throws Exception{
207         List<HolidayWrapper> holidays = new ArrayList<HolidayWrapper>();
208         if (holidayInfos != null && !holidayInfos.isEmpty()){
209             for (HolidayInfo holidayInfo : holidayInfos) {
210                 HolidayWrapper holiday = assembleHoliday(holidayInfo);
211                 holidays.add(holiday);
212             }
213         }
214 
215         return holidays;
216     }
217 
218     private HolidayWrapper assembleHoliday(HolidayInfo holidayInfo) throws Exception{
219         HolidayWrapper holiday = new HolidayWrapper(holidayInfo);
220 //        holiday.setHolidayInfo(holidayInfo);
221         holiday.setTypeName(getHolidayTypeName(holidayInfo.getTypeKey()));
222 //        CommonUtils.assembleTimeSet(holiday, holidayInfo.getStartDate(), holidayInfo.getEndDate());
223 
224         return holiday;
225     }
226 
227     public String getHolidayTypeName(String holidayTypeKey) throws Exception {
228         TypeInfo typeInfo = getAcalService().getHolidayType(holidayTypeKey, createContextInfo());
229         return typeInfo.getName();
230     }
231 
232     public void deleteHoliday(int selectedIndex,HolidayCalendarForm hcForm) throws Exception{
233         hcForm.getHolidays().remove(selectedIndex);
234     }
235 
236     public String getHolidayCalendarState(String holidayCalendarStateKey) throws Exception{
237         StateInfo hcState = getAcalService().getHolidayCalendarState(holidayCalendarStateKey, createContextInfo());
238         return hcState.getName();
239     }
240 
241     public void deleteHolidayCalendar(String holidayCalendarId) throws Exception{
242         //delete hc
243         getAcalService().deleteHolidayCalendar(holidayCalendarId, createContextInfo());
244     }
245 
246     /**
247      * This method is being called by KRAD to populate holiday types drop down. There would be no reference
248      * for this method in the code as it has it's reference at the xml
249      *
250      * @param field
251      * @param hcForm
252      */
253     @SuppressWarnings("unused")
254     public void populateHolidayTypes(InputField field, HolidayCalendarForm hcForm){
255 
256         boolean isAddLine = BooleanUtils.toBoolean((Boolean) field.getContext().get(UifConstants.ContextVariableNames.IS_ADD_LINE));
257         if (!isAddLine) {
258             return;
259         }
260 
261         List<KeyValue> keyValues = new ArrayList<KeyValue>();
262         List<String> alreadyAddedTypes = new ArrayList<String>();
263 
264         for (HolidayWrapper holidayWrapper : hcForm.getHolidays()) {
265             alreadyAddedTypes.add(holidayWrapper.getTypeKey());
266         }
267 
268         //Hard code "Select holiday type"
269         ConcreteKeyValue topKeyValue = new ConcreteKeyValue();
270         topKeyValue.setKey("");
271         topKeyValue.setValue("Select holiday type");
272         keyValues.add(topKeyValue);
273 
274         try {
275             List<TypeInfo> types = getHolidayTypes();
276             for (TypeInfo type : types) {
277                 if (!alreadyAddedTypes.contains(type.getKey())){
278                     ConcreteKeyValue keyValue = new ConcreteKeyValue();
279                     keyValue.setKey(type.getKey());
280                     keyValue.setValue(type.getName());
281                     keyValues.add(keyValue);
282                 }
283             }
284         } catch (Exception e) {
285             throw new RuntimeException(e);
286         }
287 
288         ((SelectControl) field.getControl()).setOptions(keyValues);
289     }
290 
291 
292     public List<TypeInfo> getHolidayTypes() throws InvalidParameterException, MissingParameterException, PermissionDeniedException, OperationFailedException {
293         if(holidayTypes == null) {
294             holidayTypes = Collections.unmodifiableList(getAcalService().getHolidayTypes(createContextInfo()));
295         }
296         return holidayTypes;
297     }
298 
299     private Date getStartDateWithUpdatedTime(TimeSetWrapper timeSetWrapper,boolean isSaveAction){
300         //If start time not blank, set that with the date. If it's empty, just update with default
301         if (!timeSetWrapper.isAllDay()){
302             if (StringUtils.isNotBlank(timeSetWrapper.getStartTime())){
303                 String startTime = timeSetWrapper.getStartTime();
304                 String startTimeApPm = timeSetWrapper.getStartTimeAmPm();
305                 //On save to DB, have to replace 12AM to 00AM insead of DB considers as 12PM
306                 if (isSaveAction && StringUtils.startsWith(startTime,"12:") && StringUtils.equalsIgnoreCase(startTimeApPm,"am")){
307                     startTime = StringUtils.replace(startTime,"12:","00:");
308                 }
309                 return CommonUtils.getDateWithTime(timeSetWrapper.getStartDate(),startTime,startTimeApPm);
310             }else{
311                 timeSetWrapper.setStartTime("12:00");
312                 timeSetWrapper.setStartTimeAmPm("AM");
313                 return CommonUtils.getDateWithTime(timeSetWrapper.getStartDate(),
314                         timeSetWrapper.getStartTime(),timeSetWrapper.getStartTimeAmPm());
315             }
316         }else{
317             return timeSetWrapper.getStartDate();
318         }
319 
320     }
321 
322     private void setHolidayEndDate(HolidayWrapper holidayWrapper) {
323         holidayWrapper.getHolidayInfo().setIsDateRange(holidayWrapper.isDateRange());
324         Date endDateToInfo = timeSetWrapperEndDate(holidayWrapper);
325         holidayWrapper.getHolidayInfo().setEndDate(endDateToInfo);
326     }
327 
328     private Date timeSetWrapperEndDate(TimeSetWrapper timeSetWrapper) {
329         Date endDateToInfo;
330 
331         if (timeSetWrapper.isAllDay()) {
332             if (timeSetWrapper.isDateRange()) {
333                 //just clearing out any time already set in end date
334                 endDateToInfo = CommonUtils.getDateWithTime(timeSetWrapper.getEndDate(), CalendarConstants.DEFAULT_END_TIME, "PM");
335             }
336             else {
337                 endDateToInfo = null;
338                 timeSetWrapper.setEndDate(null);
339             }
340 
341             // set the UI time & am/pm fields to null in case they just had values:
342             timeSetWrapper.setStartTime(null);
343             timeSetWrapper.setStartTimeAmPm("AM");
344             timeSetWrapper.setEndTime(null);
345             timeSetWrapper.setEndTimeAmPm("AM");
346         }
347         else {
348             if (timeSetWrapper.isDateRange()){
349                 String endTime = timeSetWrapper.getEndTime();
350                 String endTimeAmPm = timeSetWrapper.getEndTimeAmPm();
351                 Date endDate = timeSetWrapper.getEndDate();
352 
353                 if (StringUtils.isBlank(endTime)){
354                     endTime = CalendarConstants.DEFAULT_END_TIME;
355                     endTimeAmPm = "PM";
356                 }
357                 timeSetWrapper.setEndTime(endTime);
358                 timeSetWrapper.setEndTimeAmPm(endTimeAmPm);
359 
360                 endDateToInfo = CommonUtils.getDateWithTime(endDate, endTime, endTimeAmPm);
361             } else {
362                 timeSetWrapper.setEndDate(null);
363                 timeSetWrapper.setEndTime(null);
364                 timeSetWrapper.setEndTimeAmPm("AM");
365                 endDateToInfo = null;
366             }
367         }
368 
369         return endDateToInfo;
370     }
371 
372     public AcademicCalendarService getAcalService() {
373         if(acalService == null) {
374             acalService = (AcademicCalendarService) GlobalResourceLoader.getService(new QName(AcademicCalendarServiceConstants.NAMESPACE, AcademicCalendarServiceConstants.SERVICE_NAME_LOCAL_PART));
375         }
376         return this.acalService;
377     }
378 
379 
380     public void validateHolidayCalendar(HolidayCalendarForm hcForm){
381         HolidayCalendarInfo hcInfo = hcForm.getHolidayCalendarInfo();
382 
383         if (!isValidHcalName(hcInfo)){
384             GlobalVariables.getMessageMap().putError("holidayCalendarInfo.name", "error.enroll.calendar.duplicateName");
385         }
386 
387         if (!CommonUtils.isValidDateRange(hcInfo.getStartDate(),hcInfo.getEndDate())){
388             GlobalVariables.getMessageMap().putErrorForSectionId("KS-HolidayCalendar-MetaSection",
389                     "error.enroll.daterange.invalid", "Calendar",
390                     CommonUtils.formatDate(hcInfo.getStartDate()), CommonUtils.formatDate(hcInfo.getEndDate()));
391         }
392 
393         //Validate Events
394         int index = -1;
395         for (HolidayWrapper holiday : hcForm.getHolidays()) {
396             ++index;
397 
398             if (!CommonUtils.isDateWithinRange(hcInfo.getStartDate(),hcInfo.getEndDate(),holiday.getStartDate()) ||
399                     !CommonUtils.isDateWithinRange(hcInfo.getStartDate(),hcInfo.getEndDate(),holiday.getEndDate())){
400                 GlobalVariables.getMessageMap().putWarningForSectionId("KS-HolidayCalendar-HolidaySection",
401                         "error.enroll.holiday.dateNotInHcal", holiday.getTypeName());
402             }
403 
404             isValidTimeSetWrapper("KS-HolidayCalendar-HolidaySection", holiday.getTypeKey(), holiday, holiday.getTypeName());
405         }
406 
407     }
408 
409     public void populateHolidayCalendarDefaults(HolidayCalendarForm hcForm){
410 
411         for (HolidayWrapper holidayWrapper : hcForm.getHolidays()) {
412             holidayWrapper.getHolidayInfo().setStartDate(getStartDateWithUpdatedTime(holidayWrapper,false));
413             setHolidayEndDate(holidayWrapper);
414         }
415     }
416 
417     private boolean isValidHcalName(HolidayCalendarInfo hcal){
418 
419         QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();
420         List<Predicate> pList = new ArrayList<Predicate>();
421         Predicate p = equal("atpType",AcademicCalendarServiceConstants.HOLIDAY_CALENDAR_TYPE_KEY);
422         pList.add(p);
423 
424         p = equalIgnoreCase("name", hcal.getName());
425         pList.add(p);
426 
427         Predicate[] preds = new Predicate[pList.size()];
428         pList.toArray(preds);
429         qBuilder.setPredicates(and(preds));
430 
431         try {
432             List<HolidayCalendarInfo> hcals = getAcalService().searchForHolidayCalendars(qBuilder.build(), createContextInfo());
433             boolean valid = hcals.isEmpty();
434             //Make sure it's not the same Hcal which is being edited by the user
435             if (!valid && StringUtils.isNotBlank(hcal.getId())){
436                 for (HolidayCalendarInfo hc : hcals) {
437                     if (!StringUtils.equals(hc.getId(),hcal.getId())){
438                         valid = false;
439                         break;
440                     }
441                     valid = true;
442                 }
443             }
444             return valid;
445         } catch (Exception e) {
446             throw new RuntimeException(e);
447         }
448     }
449 
450 
451     protected void processBeforeAddLine(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
452         ContextInfo contextInfo = createContextInfo();
453         if (addLine instanceof HolidayCalendarInfo) {
454             HolidayCalendarInfo inputLine = (HolidayCalendarInfo)addLine;
455             try {
456                 System.out.println("HC id =" +inputLine.getId());
457 
458                 HolidayCalendarInfo exists = getAcalService().getHolidayCalendar(inputLine.getId(), contextInfo);
459 
460                 inputLine.setName(exists.getName());
461                 inputLine.setId(exists.getId());
462                 inputLine.setTypeKey(exists.getTypeKey());
463                 inputLine.setAdminOrgId(exists.getAdminOrgId());
464                 inputLine.setStartDate(exists.getStartDate());
465                 inputLine.setEndDate(exists.getEndDate());
466             }catch (Exception e) {
467                 throw new RuntimeException(e);
468             }
469 
470         }else if (addLine instanceof HolidayCalendarWrapper){
471             HolidayCalendarWrapper inputLine = (HolidayCalendarWrapper)addLine;
472             List<HolidayWrapper> holidays = new ArrayList<HolidayWrapper>();
473             try {
474                 String holidayCalendarId = inputLine.getId();
475                 if (!StringUtils.isEmpty(holidayCalendarId)) {
476                     HolidayCalendarInfo hcInfo = getAcalService().getHolidayCalendar(inputLine.getId(), contextInfo);
477                     inputLine.setHolidayCalendarInfo(hcInfo);
478                     inputLine.setAdminOrgName(CommonUtils.getAdminOrgNameById(hcInfo.getAdminOrgId()));
479                     StateInfo hcState = getAcalService().getHolidayCalendarState(hcInfo.getStateKey(), contextInfo);
480                     inputLine.setStateName(hcState.getName());
481                     List<HolidayInfo> holidayInfoList = getAcalService().getHolidaysForHolidayCalendar(hcInfo.getId(), contextInfo);
482                     for(HolidayInfo holidayInfo : holidayInfoList){
483                         HolidayWrapper holiday = new HolidayWrapper(holidayInfo);
484                         TypeInfo typeInfo = getAcalService().getHolidayType(holidayInfo.getTypeKey(), contextInfo);
485                         holiday.setTypeName(typeInfo.getName());
486                         holidays.add(holiday);
487                     }
488                     inputLine.setHolidays(holidays);
489                 }
490             }catch (Exception e){
491                 throw new RuntimeException(e);
492             }
493 
494         }  else if (addLine instanceof HolidayWrapper){
495             HolidayWrapper holiday = (HolidayWrapper)addLine;
496             try {
497                 holiday.setTypeName(getHolidayTypeName(holiday.getTypeKey()));
498             } catch (Exception e) {
499                 throw new RuntimeException(e);
500             }
501             if (!CommonUtils.isValidDateRange(holiday.getStartDate(),holiday.getEndDate())){
502                 GlobalVariables.getMessageMap().putWarningForSectionId("KS-HolidayCalendar-HolidaySection", "error.enroll.daterange.invalid",holiday.getTypeName(),CommonUtils.formatDate(holiday.getStartDate()),CommonUtils.formatDate(holiday.getEndDate()));
503             }
504         } else {
505             super.processBeforeAddLine(view, collectionGroup, model, addLine);
506         }
507     }
508 
509     protected boolean performAddLineValidation(View view, CollectionGroup collectionGroup, Object model, Object addLine) {
510         if (model instanceof HolidayCalendarForm) {
511             if (addLine instanceof HolidayWrapper) {
512                 HolidayWrapper holidayWrapper = (HolidayWrapper)addLine;
513                 if (!isValidTimeSetWrapper(collectionGroup.getId(), holidayWrapper.getTypeKey(), holidayWrapper, holidayWrapper.getTypeName())) {
514                     return false;
515                 }
516             }
517         }
518 
519         return super.performAddLineValidation(view, collectionGroup, model, addLine);
520     }
521 
522     // NOTE: edits here should not be needed if KRAD validation is working properly...
523     private boolean isValidTimeSetWrapper(String collectionGroupId, String KeyDateType, TimeSetWrapper wrapper, String wrapperName) {
524         boolean isValid = true;
525 
526         if(StringUtils.isEmpty(KeyDateType)) {
527             GlobalVariables.getMessageMap().putErrorForSectionId(collectionGroupId, CalendarConstants.MessageKeys.ERROR_KEY_DATE_TYPE_REQUIRED);
528 //            GlobalVariables.getMessageMap().putErrorForSectionId(lineName+".typeKey", CalendarConstants.MessageKeys.ERROR_KEY_DATE_TYPE_REQUIRED);
529             return false;
530         }
531 
532         // Start Date not null, Start Time null, End Date null, End Time not null - illegal
533         if (wrapper.getStartDate()!=null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
534                 wrapper.getEndDate()==null && (wrapper.getEndTime()!=null && !StringUtils.isBlank(wrapper.getEndTime()))){
535             GlobalVariables.getMessageMap().putErrorForSectionId(collectionGroupId, CalendarConstants.MessageKeys.ERROR_INVALID_DATE_TIME, wrapperName);
536             return false;
537         }
538         // Start Date null, Start Time not null, different combinations of End Date and End Time - illegal
539         else if (wrapper.getStartDate()==null && (wrapper.getStartTime()!=null && !StringUtils.isBlank(wrapper.getStartTime()))){
540             GlobalVariables.getMessageMap().putErrorForSectionId(collectionGroupId, CalendarConstants.MessageKeys.ERROR_INVALID_DATE_TIME, wrapperName);
541             return false;
542         }
543         // Start Date null, Start Time null, End Date null, End Time not null - illegal
544         else if (wrapper.getStartDate()==null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
545                 wrapper.getEndDate()==null && (wrapper.getEndTime()!=null && !StringUtils.isBlank(wrapper.getEndTime()))){
546             GlobalVariables.getMessageMap().putErrorForSectionId(collectionGroupId, CalendarConstants.MessageKeys.ERROR_INVALID_DATE_TIME, wrapperName);
547             return false;
548         }
549 
550         // Start Date and End Date could be null but put a warning
551         if (wrapper.getStartDate()==null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
552                 wrapper.getEndDate()==null && (wrapper.getEndTime()==null || StringUtils.isBlank(wrapper.getEndTime()))){
553             GlobalVariables.getMessageMap().putWarningForSectionId(collectionGroupId, CalendarConstants.MessageKeys.ERROR_KEY_DATE_START_DATE_REQUIRED, wrapperName);
554         }
555 
556         if (wrapper.getStartDate()!=null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
557                 wrapper.getEndDate()==null && (wrapper.getEndTime()==null || StringUtils.isBlank(wrapper.getEndTime()))){
558             wrapper.setAllDay(true);
559             wrapper.setDateRange(false);
560         } else if (wrapper.getStartDate()!=null && (wrapper.getStartTime()!=null && !StringUtils.isBlank(wrapper.getStartTime())) &&
561                 wrapper.getEndDate()==null && (wrapper.getEndTime()==null || StringUtils.isBlank(wrapper.getEndTime()))){
562             wrapper.setAllDay(false);
563             wrapper.setDateRange(false);
564         } else if (wrapper.getStartDate()==null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
565                 wrapper.getEndDate()!=null && (wrapper.getEndTime()==null || StringUtils.isBlank(wrapper.getEndTime()))){
566             wrapper.setStartDate(wrapper.getEndDate());
567             wrapper.setEndDate(null);
568             wrapper.setAllDay(true);
569             wrapper.setDateRange(false);
570         } else if (wrapper.getStartDate()==null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
571                 wrapper.getEndDate()!=null && (wrapper.getEndTime()!=null && !StringUtils.isBlank(wrapper.getEndTime()))){
572             wrapper.setStartDate(wrapper.getEndDate());
573             wrapper.setStartTime(wrapper.getEndTime());
574             wrapper.setEndDate(null);
575             wrapper.setEndTime(null);
576             wrapper.setAllDay(false);
577             wrapper.setDateRange(false);
578         } else if (wrapper.getStartDate()!=null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
579                 wrapper.getEndDate()!=null && (wrapper.getEndTime()==null || StringUtils.isBlank(wrapper.getEndTime()))){
580             wrapper.setAllDay(true);
581             wrapper.setDateRange(true);
582         } else if (wrapper.getStartDate()!=null && (wrapper.getStartTime()!=null && !StringUtils.isBlank(wrapper.getStartTime())) &&
583                 wrapper.getEndDate()!=null && (wrapper.getEndTime()==null || StringUtils.isBlank(wrapper.getEndTime()))){
584             wrapper.setAllDay(false);
585             wrapper.setDateRange(true);
586             timeSetWrapperEndDate(wrapper);
587         } else if (wrapper.getStartDate()!=null && (wrapper.getStartTime()==null || StringUtils.isBlank(wrapper.getStartTime())) &&
588                 wrapper.getEndDate()!=null && (wrapper.getEndTime()!=null && !StringUtils.isBlank(wrapper.getEndTime()))){
589             wrapper.setAllDay(false);
590             wrapper.setDateRange(true);
591             getStartDateWithUpdatedTime(wrapper, false);
592         } else if (wrapper.getStartDate()!=null && (wrapper.getStartTime()!=null && !StringUtils.isBlank(wrapper.getStartTime())) &&
593                 wrapper.getEndDate()!=null && (wrapper.getEndTime()!=null && !StringUtils.isBlank(wrapper.getEndTime()))){
594             wrapper.setAllDay(false);
595             wrapper.setDateRange(true);
596         } else if (wrapper.getStartDate()!=null && (wrapper.getStartTime()!=null && !StringUtils.isBlank(wrapper.getStartTime())) &&
597                 wrapper.getEndDate()==null && (wrapper.getEndTime()!=null && !StringUtils.isBlank(wrapper.getEndTime()))){
598             wrapper.setEndDate(wrapper.getStartDate());
599             wrapper.setAllDay(false);
600             wrapper.setDateRange(true);
601         }
602 
603         // Start Date can't be later than End Date
604         if (wrapper.getStartDate()!=null && wrapper.getEndDate()!=null){
605             if ((wrapper.getStartTime()!=null && !StringUtils.isBlank(wrapper.getStartTime())) &&
606                     (wrapper.getEndTime()!=null && !StringUtils.isBlank(wrapper.getEndTime()))) {
607                 Date startDate = getStartDateWithUpdatedTime(wrapper, false);
608                 Date endDate =  timeSetWrapperEndDate(wrapper);
609                 if (!CommonUtils.isValidDateRange(startDate, endDate)) {
610                     GlobalVariables.getMessageMap().putErrorForSectionId(collectionGroupId, CalendarConstants.MessageKeys.ERROR_INVALID_DATE_RANGE, wrapperName, DateFormatUtils.format(startDate, DateFormatters.MONTH_DAY_YEAR_TIME_DATE_FORMAT), DateFormatUtils.format(endDate, DateFormatters.MONTH_DAY_YEAR_TIME_DATE_FORMAT));
611                     return false;
612                 }
613             } else {
614                 if (!CommonUtils.isValidDateRange(wrapper.getStartDate(), wrapper.getEndDate())) {
615                     GlobalVariables.getMessageMap().putErrorForSectionId(collectionGroupId, CalendarConstants.MessageKeys.ERROR_INVALID_DATE_RANGE, wrapperName, CommonUtils.formatDate(wrapper.getStartDate()), CommonUtils.formatDate(wrapper.getEndDate()));
616                     return false;
617                 }
618             }
619         }
620 
621         return isValid;
622     }
623 
624 }