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