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