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.calendar;
017    
018    import org.joda.time.DateTime;
019    import org.kuali.hr.lm.leaveblock.LeaveBlock;
020    import org.kuali.hr.lm.util.LeaveBlockAggregate;
021    import org.kuali.hr.time.earncode.EarnCode;
022    import org.kuali.hr.time.service.base.TkServiceLocator;
023    import org.kuali.hr.time.timeblock.TimeBlock;
024    import org.kuali.hr.time.util.TkConstants;
025    import org.kuali.hr.time.util.TkTimeBlockAggregate;
026    
027    import java.util.ArrayList;
028    import java.util.List;
029    import java.util.Map;
030    
031    public class TkCalendar extends CalendarParent {
032        private List<TkCalendarWeek> weeks = new ArrayList<TkCalendarWeek>();
033        private CalendarEntries payCalEntry;
034        private DateTime beginDateTime;
035        private DateTime endDateTime;
036    
037        public TkCalendar() {}
038    
039        public TkCalendar(CalendarEntries calendarEntry) {
040            super(calendarEntry);
041        }
042    
043        public static TkCalendar getCalendar(TkTimeBlockAggregate tbAggregate, LeaveBlockAggregate lbAggregate) {
044            TkCalendar tc = new TkCalendar();
045             
046            if (tbAggregate != null && lbAggregate != null) {
047                    if(tbAggregate.getDayTimeBlockList().size() != lbAggregate.getDayLeaveBlockList().size()){
048                            throw new RuntimeException("TimeBlockAggregate and LeaveBlockAggregate should have the same size of Day Blocks List");
049                    }
050                            
051                    List<CalendarWeek> weeks = new ArrayList<CalendarWeek>();
052                    tc.setPayCalEntry(tbAggregate.getPayCalendarEntry());
053            
054                     int firstDay = 0;
055                     if (tc.getBeginDateTime().getDayOfWeek() != 7) {
056                         firstDay = 0 - tc.getBeginDateTime().getDayOfWeek();   // always render calendar weeks from Sundays
057                     }
058                     for (int i = 0; i < tbAggregate.numberOfAggregatedWeeks(); i++) {
059                         TkCalendarWeek week = new TkCalendarWeek();
060                         List<List<TimeBlock>> weekBlocks = tbAggregate.getWeekTimeBlocks(i);
061                         List<List<LeaveBlock>> weekLeaveBlocks = lbAggregate.getWeekLeaveBlocks(i);
062                         List<CalendarDay> days = new ArrayList<CalendarDay>(7);
063            
064                         for (int j = 0; j < weekBlocks.size(); j++) {
065                             List<TimeBlock> dayBlocks = weekBlocks.get(j);
066                             List<LeaveBlock> dayLeaveBlocks = weekLeaveBlocks.get(j);
067                             // Create the individual days.
068                             TkCalendarDay day = new TkCalendarDay();
069                             day.setTimeblocks(dayBlocks);
070                             day.setLeaveBlocks(dayLeaveBlocks);
071                             day.setDayNumberString(tc.getDayNumberString(i * 7 + j + firstDay));
072                             day.setDayNumberDelta(i * 7 + j + firstDay);
073                             day.setDateString(tc.getDateString(day.getDayNumberDelta()));
074                             assignDayLunchLabel(day);
075                             int dayIndex = i * 7 + j + firstDay;
076                             DateTime beginDateTemp = tc.getBeginDateTime().plusDays(dayIndex);
077                             day.setGray(false);
078                             if (beginDateTemp.isBefore(tc.getBeginDateTime().getMillis())
079                                     || beginDateTemp.isAfter(tc.getEndDateTime().getMillis())) {
080                                 day.setGray(true);
081                             }
082                             if (tc.getEndDateTime().getHourOfDay() == 0 && beginDateTemp.equals(tc.getEndDateTime())) {
083                                 day.setGray(true);
084                             }
085                             days.add(day);
086                         }
087                         week.setDays(days);
088                         weeks.add(week);
089                     }
090                     tc.setWeeks(weeks);
091                 } else {
092                     return null;
093                 }
094    
095            return tc;
096        }
097        
098        public static TkCalendar getCalendar(TkTimeBlockAggregate aggregate) {
099            TkCalendar tc = new TkCalendar();
100    
101            if (aggregate != null) {
102                List<CalendarWeek> weeks = new ArrayList<CalendarWeek>();
103                tc.setPayCalEntry(aggregate.getPayCalendarEntry());
104    
105                int firstDay = 0;
106                if (tc.getBeginDateTime().getDayOfWeek() != 7) {
107                    firstDay = 0 - tc.getBeginDateTime().getDayOfWeek();   // always render calendar weeks from Sundays
108                }
109                for (int i = 0; i < aggregate.numberOfAggregatedWeeks(); i++) {
110                    TkCalendarWeek week = new TkCalendarWeek();
111                    List<List<TimeBlock>> weekBlocks = aggregate.getWeekTimeBlocks(i);
112                    List<CalendarDay> days = new ArrayList<CalendarDay>(7);
113    
114                    for (int j = 0; j < weekBlocks.size(); j++) {
115                        List<TimeBlock> dayBlocks = weekBlocks.get(j);
116                        // Create the individual days.
117                        TkCalendarDay day = new TkCalendarDay();
118                        day.setTimeblocks(dayBlocks);
119                        day.setDayNumberString(tc.getDayNumberString(i * 7 + j + firstDay));
120                        day.setDayNumberDelta(i * 7 + j + firstDay);
121                        day.setDateString(tc.getDateString(day.getDayNumberDelta()));
122                        assignDayLunchLabel(day);
123                        int dayIndex = i * 7 + j + firstDay;
124                        DateTime beginDateTemp = tc.getBeginDateTime().plusDays(dayIndex);
125                        day.setGray(false);
126                        if (beginDateTemp.isBefore(tc.getBeginDateTime().getMillis())
127                                || beginDateTemp.isAfter(tc.getEndDateTime().getMillis())) {
128                            day.setGray(true);
129                        }
130                        if (tc.getEndDateTime().getHourOfDay() == 0 && beginDateTemp.equals(tc.getEndDateTime())) {
131                            day.setGray(true);
132                        }
133                        days.add(day);
134                    }
135                    week.setDays(days);
136                    weeks.add(week);
137                }
138                tc.setWeeks(weeks);
139            } else {
140                return null;
141            }
142    
143            return tc;
144        }
145    
146        public static void assignDayLunchLabel(TkCalendarDay day) {
147            EarnCode ec = null;
148            String label = "";
149            String id = "";
150            for (TimeBlockRenderer tbr : day.getBlockRenderers()) {
151                for (TimeHourDetailRenderer thdr : tbr.getDetailRenderers()) {
152                    if (thdr.getTitle().equals(TkConstants.LUNCH_EARN_CODE)) {
153                        ec = TkServiceLocator.getEarnCodeService().getEarnCode(thdr.getTitle(), tbr.getTimeBlock().getBeginDate());
154                        if (ec != null) {
155                            label = ec.getDescription() + " : " + thdr.getHours() + " hours";
156                            id = thdr.getTkTimeHourDetailId();
157                        }
158                    }
159                }
160                tbr.setLunchLabel(label);
161                tbr.setLunchLabelId(id);
162    
163                label = "";
164            }
165        }
166    
167        
168        public void assignAssignmentStyle(Map<String, String> styleMap) {
169            for (CalendarWeek aWeek : this.getWeeks()) {
170                for (CalendarDay aDay : aWeek.getDays()) {
171                    for (TimeBlockRenderer tbr : ((TkCalendarDay)aDay).getBlockRenderers()) {
172                        String assignmentKey = tbr.getTimeBlock().getAssignmentKey();
173                        if (assignmentKey != null && styleMap.containsKey(assignmentKey)) {
174                            tbr.setAssignmentClass(styleMap.get(assignmentKey));
175                        } else {
176                            tbr.setAssignmentClass("");
177                        }
178                    }
179                    for (LeaveBlockRenderer lbr : ((TkCalendarDay)aDay).getLeaveBlockRenderers()) {
180                        String assignmentKey = lbr.getLeaveBlock().getAssignmentKey();
181                        if (assignmentKey != null && styleMap.containsKey(assignmentKey)) {
182                            lbr.setAssignmentClass(styleMap.get(assignmentKey));
183                        } else {
184                            lbr.setAssignmentClass("");
185                        }
186                    } 
187                    
188                }
189            }
190        }
191    
192    
193    //    public List<TkCalendarWeek> getWeeks() {
194    //        return weeks;
195    //    }
196    //
197    //    public void setWeeks(List<TkCalendarWeek> weeks) {
198    //        this.weeks = weeks;
199    //    }
200    
201        public CalendarEntries getPayCalEntry() {
202            return payCalEntry;
203        }
204    
205        public void setPayCalEntry(CalendarEntries payCalEntry) {
206            this.payCalEntry = payCalEntry;
207            // Relative time, with time zone added.
208            this.beginDateTime = payCalEntry.getBeginLocalDateTime().toDateTime(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback());
209            this.endDateTime = payCalEntry.getEndLocalDateTime().toDateTime(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback());
210        }
211    
212        public DateTime getBeginDateTime() {
213            return beginDateTime;
214        }
215    
216        public DateTime getEndDateTime() {
217            return endDateTime;
218        }
219    
220        /**
221         * Provides the calendar title / heading. If the Pay Calendar entry spans
222         * multiple months, you get Abbreviated Month name + year of both the
223         * beginning month and the ending month.
224         *
225         * @return String for calendar title use.
226         */
227        public String getCalendarTitle() {
228            StringBuilder sb = new StringBuilder();
229    
230            if (getBeginDateTime().getMonthOfYear() == getEndDateTime().getMonthOfYear() ||
231                    (getBeginDateTime().getMonthOfYear() != getEndDateTime().getMonthOfYear()
232                            && getEndDateTime().getDayOfMonth() == 1 && getEndDateTime().getSecondOfDay() == 0)) {
233                sb.append(getBeginDateTime().toString("MMMM y"));
234            } else {
235                sb.append(getBeginDateTime().toString("MMM y"));
236                sb.append(" - ");
237                sb.append(getEndDateTime().toString("MMM y"));
238            }
239    
240            return sb.toString();
241        }
242    
243        /**
244         * Assumption of 7 "days" per week, or 7 "blocks" per row.
245         *
246         * @return A list of string titles for each row block (day)
247         */
248        public List<String> getCalendarDayHeadings() {
249            List<String> dayStrings = new ArrayList<String>(7);
250            // always render from Sunday
251            int firstDay = 0 - getBeginDateTime().getDayOfWeek();
252            int lastDay = firstDay + 7;
253    
254            if (getBeginDateTime().getMinuteOfDay() == 0) {
255                // "Standard" days.
256                for (int i = firstDay; i < lastDay; i++) {
257                    DateTime currDay = getBeginDateTime().plusDays(i);
258                    dayStrings.add(currDay.toString("E"));
259                }
260            } else {
261                // Day Split Strings
262    
263                for (int i = firstDay; i < lastDay; i++) {
264                    StringBuilder builder = new StringBuilder("");
265                    DateTime currStart = getBeginDateTime().plusDays(i);
266                    DateTime currEnd = getBeginDateTime().plusDays(i);
267    
268                    builder.append(currStart.toString("E HH:mm"));
269                    builder.append(" - ");
270                    builder.append(currEnd.toString("E HH:mm"));
271    
272                    dayStrings.add(builder.toString());
273                }
274            }
275    
276            return dayStrings;
277        }
278    
279        public String getCalenadrYear() {
280            return getBeginDateTime().toString("yyyy");
281        }
282    
283        public String getCalendarMonth() {
284            return getBeginDateTime().toString("M");
285        }
286    
287        private String getDayNumberString(int dayDelta) {
288            StringBuilder b = new StringBuilder();
289    
290            if (getBeginDateTime().getMinuteOfDay() == 0) {
291                DateTime currStart = getBeginDateTime().plusDays(dayDelta);
292                b.append(currStart.toString("d"));
293            } else {
294                DateTime currStart = getBeginDateTime().plusDays(dayDelta);
295                DateTime currEnd = getBeginDateTime().plusDays(dayDelta);
296    
297                b.append(currStart.toString("d HH:mm"));
298                b.append(" - ");
299                b.append(currStart.toString("d HH:mm"));
300            }
301    
302            return b.toString();
303        }
304    
305        private String getDateString(int dayDelta) {
306            return getBeginDateTime().plusDays(dayDelta).toString("M/d/yyyy");
307        }
308    
309    }