View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.kpme.tklm.time.timeblock;
17  
18  import org.joda.time.DateTimeZone;
19  
20  import java.math.BigDecimal;
21  import java.sql.Time;
22  import java.sql.Timestamp;
23  import java.util.ArrayList;
24  import java.util.Date;
25  import java.util.List;
26  
27  import javax.persistence.Transient;
28  
29  import org.apache.commons.lang.builder.EqualsBuilder;
30  import org.apache.commons.lang.builder.HashCodeBuilder;
31  import org.joda.time.DateTime;
32  import org.joda.time.LocalDate;
33  import org.joda.time.LocalTime;
34  import org.kuali.kpme.core.assignment.Assignment;
35  import org.kuali.kpme.core.assignment.AssignmentDescriptionKey;
36  import org.kuali.kpme.core.block.CalendarBlock;
37  import org.kuali.kpme.core.block.CalendarBlockBase;
38  import org.kuali.kpme.core.service.HrServiceLocator;
39  import org.kuali.kpme.core.util.HrConstants;
40  import org.kuali.kpme.core.util.HrContext;
41  import org.kuali.kpme.core.util.TKUtils;
42  import org.kuali.kpme.tklm.api.time.timeblock.TimeBlockContract;
43  import org.kuali.kpme.tklm.common.TkConstants;
44  import org.kuali.kpme.tklm.time.clocklog.ClockLog;
45  import org.kuali.kpme.tklm.time.service.TkServiceLocator;
46  import org.kuali.kpme.tklm.time.timehourdetail.TimeHourDetail;
47  import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
48  import org.kuali.rice.kim.api.identity.Person;
49  import org.apache.commons.lang.ObjectUtils;
50  
51  public class TimeBlock extends CalendarBlock implements Comparable, TimeBlockContract {
52  
53      private static final long serialVersionUID = -4164042707879641855L;
54      public static final String CACHE_NAME = TkConstants.CacheNamespace.NAMESPACE_PREFIX + "TimeBlock";
55  
56      private String tkTimeBlockId;
57  
58      @Transient
59      private Date beginDate;
60      @Transient
61      private Date endDate;
62      @Transient
63      private Time beginTime;
64      @Transient
65      private Time endTime;
66  
67      private String earnCodeType;
68  
69      private Boolean clockLogCreated;
70      private BigDecimal hours = HrConstants.BIG_DECIMAL_SCALED_ZERO;
71      private BigDecimal amount = HrConstants.BIG_DECIMAL_SCALED_ZERO;
72      private DateTime beginTimeDisplay;
73      private DateTime endTimeDisplay;
74      private String clockLogBeginId;
75      private String clockLogEndId;
76      private String assignmentKey;
77      private String overtimePref;
78      //userPrincipalId == super.principalIdModified
79      private String userPrincipalId;
80      @Transient
81      private Boolean deleteable;
82      
83      @Transient
84      private Boolean overtimeEditable;
85  
86      // the two variables below are used to determine if a time block needs to be visually pushed forward / backward
87      @Transient
88      private Boolean pushBackward = false;
89  
90      private TimesheetDocumentHeader timesheetDocumentHeader;
91      private transient Person user;
92      private transient Person employeeObj;
93  
94      private transient List<TimeHourDetail> timeHourDetails = new ArrayList<TimeHourDetail>();
95      private transient List<TimeBlockHistory> timeBlockHistories = new ArrayList<TimeBlockHistory>();
96  	protected BigDecimal leaveAmount = new BigDecimal("0.0");
97  
98      public TimeBlock() {
99      	super();
100     }
101     
102     public Date getBeginDate() {
103     	Date beginDate = null;
104     	
105     	if (beginTimestamp != null) {
106     		beginDate = new Date(beginTimestamp.getTime());
107     	}
108         return beginDate;
109     }
110 
111     public Timestamp getBeginTimestampVal() {
112         return new Timestamp(beginTimestamp.getTime());
113     }
114 
115     public Timestamp getEndTimestampVal() {
116         return new Timestamp(endTimestamp.getTime());
117     }
118 
119     public void setBeginDate(Date beginDate) {
120     	DateTime dateTime = new DateTime(beginTimestamp);
121     	LocalDate localDate = new LocalDate(beginDate);
122     	LocalTime localTime = new LocalTime(beginTimestamp);
123     	beginTimestamp = localDate.toDateTime(localTime, dateTime.getZone()).toDate();
124     }
125     
126     public Time getBeginTime() {
127     	Time beginTime = null;
128     	
129     	if (beginTimestamp != null) {
130     		beginTime = new Time(beginTimestamp.getTime());
131     	}
132     	
133     	return beginTime;
134     }
135 
136     public void setBeginTime(Time beginTime) {
137     	DateTime dateTime = new DateTime(beginTimestamp);
138     	LocalDate localDate = new LocalDate(beginTimestamp);
139     	LocalTime localTime = new LocalTime(beginTime);
140     	beginTimestamp = localDate.toDateTime(localTime, dateTime.getZone()).toDate();
141     }
142     
143     public DateTime getBeginDateTime() {
144     	return beginTimestamp != null ? new DateTime(beginTimestamp) : null;
145     }
146     
147     public void setBeginDateTime(DateTime beginDateTime) {
148     	beginTimestamp = beginDateTime != null ? beginDateTime.toDate() : null;
149     }
150 
151     public Date getEndTimestamp() {
152         return endTimestamp;
153     }
154 
155     public void setEndTimestamp(Date endTimestamp) {
156         this.endTimestamp = endTimestamp;
157     }
158 
159     public Date getEndDate() {
160     	Date endDate = null;
161     	
162     	if (endTimestamp != null) {
163     		endDate = new Date(endTimestamp.getTime());
164     	}
165 
166         return endDate;
167     }
168 
169     public void setEndDate(Date endDate) {
170     	DateTime dateTime = new DateTime(endTimestamp);
171     	LocalDate localDate = new LocalDate(endDate);
172     	LocalTime localTime = new LocalTime(endTimestamp);
173     	endTimestamp = localDate.toDateTime(localTime, dateTime.getZone()).toDate();
174     }
175 
176     public Time getEndTime() {
177     	Time endTime = null;
178     	
179     	if (endTimestamp != null) {
180     		endTime = new Time(endTimestamp.getTime());
181     	}
182     	
183     	return endTime;
184     }
185 
186     public void setEndTime(Time endTime) {
187     	DateTime dateTime = new DateTime(endTimestamp);
188     	LocalDate localDate = new LocalDate(endTimestamp);
189     	LocalTime localTime = new LocalTime(endTime);
190     	endTimestamp = localDate.toDateTime(localTime, dateTime.getZone()).toDate();
191     }
192     
193     public DateTime getEndDateTime() {
194     	return endTimestamp != null ? new DateTime(endTimestamp) : null;
195     }
196     
197     public void setEndDateTime(DateTime endDateTime) {
198     	endTimestamp = endDateTime != null ? endDateTime.toDate() : null;
199     }
200     
201     public Boolean getClockLogCreated() {
202         return clockLogCreated;
203     }
204 
205     public void setClockLogCreated(Boolean clockLogCreated) {
206         this.clockLogCreated = clockLogCreated;
207     }
208 
209     public BigDecimal getHours() {
210         return hours;
211     }
212 
213     public void setHours(BigDecimal hours) {
214         if (hours != null) {
215             this.hours = hours.setScale(HrConstants.BIG_DECIMAL_SCALE, HrConstants.BIG_DECIMAL_SCALE_ROUNDING);
216         } else {
217             this.hours = hours;
218         }
219     }
220 
221     public BigDecimal getAmount() {
222         return amount;
223     }
224 
225     public void setAmount(BigDecimal amount) {
226         if (amount != null) {
227             this.amount = amount.setScale(HrConstants.BIG_DECIMAL_SCALE, HrConstants.BIG_DECIMAL_SCALE_ROUNDING);
228         } else {
229             this.amount = amount;
230         }
231     }
232 
233     public String getUserPrincipalId() {
234         return userPrincipalId;
235     }
236 
237     public void setUserPrincipalId(String userPrincipalId) {
238     	this.userPrincipalId = userPrincipalId;
239     }
240 
241     public Timestamp getTimestamp() {
242         return timestamp;
243     }
244 
245     public void setTimestamp(Timestamp timestamp) {
246         this.timestamp = timestamp;
247     }
248 
249     public String toCSVString() {
250         StringBuffer sb = new StringBuffer();
251         sb.append(this.earnCode + ",");
252         sb.append(this.getUserPrincipalId() + ",");
253         sb.append(this.amount + ",");
254         sb.append(this.beginTimestamp + ",");
255         sb.append(this.clockLogCreated + ",");
256         sb.append(this.endTimestamp + ",");
257         sb.append(this.hours + ",");
258         sb.append(this.jobNumber + ",");
259         sb.append(this.task + ",");
260         sb.append(this.tkTimeBlockId + ",");
261         sb.append(this.timestamp + ",");
262         sb.append(this.workArea + System.getProperty("line.separator"));
263         return sb.toString();
264     }
265 
266     public String getTkTimeBlockId() {
267         return tkTimeBlockId;
268     }
269 
270     public void setTkTimeBlockId(String tkTimeBlockId) {
271         this.tkTimeBlockId = tkTimeBlockId;
272         super.concreteBlockId = tkTimeBlockId;
273     }
274 
275     public List<TimeHourDetail> getTimeHourDetails() {
276         return timeHourDetails;
277     }
278     
279     public void addTimeHourDetail(TimeHourDetail timeHourDetail) {
280     	timeHourDetails.add(timeHourDetail);
281     }
282     
283     public void removeTimeHourDetail(TimeHourDetail timeHourDetail) {
284     	timeHourDetails.remove(timeHourDetail);
285     }
286 
287     public void setTimeHourDetails(List<TimeHourDetail> timeHourDetails) {
288         this.timeHourDetails = timeHourDetails;
289     }
290 
291     public Boolean getPushBackward() {
292         return pushBackward;
293     }
294 
295 	public void setPushBackward(Boolean pushBackward) {
296         this.pushBackward = pushBackward;
297     }
298 
299     /**
300      * Use this call for all GUI/Display related rendering of the BEGIN
301      * timestamp of the given time block. Timeblocks require pre-processing
302      * before there will be a non-null return value here.
303      *
304      * @return The Timeblock Begin time to display, with the Users Timezone
305      *         taken into account and applied to this DateTime object.
306      */
307     public DateTime getBeginTimeDisplay() {
308     	if(beginTimeDisplay == null && this.getBeginDateTime() != null) {
309     		DateTimeZone timezone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
310     		if(ObjectUtils.equals(timezone, TKUtils.getSystemDateTimeZone()))
311 				this.setBeginTimeDisplay(this.getBeginDateTime());
312     		else
313     			this.setBeginTimeDisplay(this.getBeginDateTime().withZone(timezone));
314     	}
315         return beginTimeDisplay;
316     }
317 
318     /**
319      * Helper to call DateTime.toDate().
320      *
321      * @return a date representing the getBeginTimeDisplay() DateTime.
322      */
323     public Date getBeginTimeDisplayDate() {
324         return getBeginTimeDisplay() != null ? getBeginTimeDisplay().toDate() : null;
325     }
326 
327     /*
328     *   fix timezone issues caused by JScript, for GUI use only,
329     */
330     public String getBeginTimeDisplayDateOnlyString() {
331     	DateTimeZone zone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
332         return getBeginDateTime() != null ? getBeginDateTime().withZone(zone).toString(HrConstants.DT_BASIC_DATE_FORMAT) : null;
333     }
334 
335     public String getBeginTimeDisplayTimeOnlyString() {
336     	DateTimeZone zone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
337     	return getBeginDateTime() != null ? getBeginDateTime().withZone(zone).toString(TkConstants.DT_BASIC_TIME_FORMAT) : null;
338     }
339 
340     public String getEndTimeDisplayDateOnlyString() {
341     	DateTimeZone zone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
342         return getEndDateTime() != null ? getEndDateTime().withZone(zone).toString(HrConstants.DT_BASIC_DATE_FORMAT) : null;
343     }
344 
345     public String getEndTimeDisplayTimeOnlyString() {
346     	DateTimeZone zone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
347         return getEndDateTime() != null ? getEndDateTime().withZone(zone).toString(TkConstants.DT_BASIC_TIME_FORMAT) : null;
348     }
349 
350     /**
351      * Set this value with a DateTime that is in the current users Timezone. This
352      * should happen as a pre processing step for display purposes. Do not use these
353      * values for server-side computation.
354      *
355      * @param beginTimeDisplay
356      */
357     public void setBeginTimeDisplay(DateTime beginTimeDisplay) {
358         this.beginTimeDisplay = beginTimeDisplay;
359     }
360 
361     /**
362      * Use this call for all GUI/Display related rendering of the END
363      * timestamp of the given time block. Timeblocks require pre-processing
364      * before there will be a non-null return value here.
365      *
366      * @return The Timeblock end time to display, with the Users Timezone
367      *         taken into account and applied to this DateTime object.
368      */
369     public DateTime getEndTimeDisplay() {
370     	if(endTimeDisplay == null && this.getEndDateTime() != null) {
371     		DateTimeZone timezone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
372      		if(ObjectUtils.equals(timezone, TKUtils.getSystemDateTimeZone()))
373  				this.setEndTimeDisplay(this.getBeginDateTime());
374      		else
375      			this.setEndTimeDisplay(this.getEndDateTime().withZone(timezone));
376     	}
377         return endTimeDisplay;
378     }
379 
380     /**
381      * Helper to call DateTime.toDate().
382      *
383      * @return a date representing the getEndTimeDisplay() DateTime.
384      */
385     public Date getEndTimeDisplayDate() {
386         return getEndTimeDisplay() != null ? getEndTimeDisplay().toDate() : null;
387     }
388 
389     /**
390      * Set this value with a DateTime that is in the current users Timezone. This
391      * should happen as a pre processing step for display purposes. Do not use these
392      * values for server-side computation.
393      *
394      * @param endTimeDisplay
395      */
396     public void setEndTimeDisplay(DateTime endTimeDisplay) {
397         this.endTimeDisplay = endTimeDisplay;
398     }
399 
400     public TimesheetDocumentHeader getTimesheetDocumentHeader() {
401         if (timesheetDocumentHeader == null && this.getDocumentId() != null) {
402             setTimesheetDocumentHeader(TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(this.getDocumentId()));
403         }
404         return timesheetDocumentHeader;
405     }
406 
407     public void setTimesheetDocumentHeader(
408             TimesheetDocumentHeader timesheetDocumentHeader) {
409         this.timesheetDocumentHeader = timesheetDocumentHeader;
410     }
411 
412     public List<TimeBlockHistory> getTimeBlockHistories() {
413         return timeBlockHistories;
414     }
415 
416     public void setTimeBlockHistories(List<TimeBlockHistory> timeBlockHistories) {
417         this.timeBlockHistories = timeBlockHistories;
418     }
419 
420     public String getClockLogBeginId() {
421         return clockLogBeginId;
422     }
423 
424     public void setClockLogBeginId(String clockLogBeginId) {
425         this.clockLogBeginId = clockLogBeginId;
426     }
427 
428     public String getClockLogEndId() {
429         return clockLogEndId;
430     }
431 
432     public void setClockLogEndId(String clockLogEndId) {
433         this.clockLogEndId = clockLogEndId;
434     }
435 
436     public String getAssignmentKey() {
437         AssignmentDescriptionKey adk = new AssignmentDescriptionKey(this.getJobNumber(), this.getWorkArea(), this.getTask());
438         this.setAssignmentKey(adk.toAssignmentKeyString());
439         return assignmentKey;
440     }
441 
442     public void setAssignmentKey(String assignmentDescription) {
443         this.assignmentKey = assignmentDescription;
444     }
445 
446     public String getAssignmentDescription() {
447         AssignmentDescriptionKey adk = new AssignmentDescriptionKey(this.getJobNumber(), this.getWorkArea(), this.getTask());
448         Assignment anAssignment = HrServiceLocator.getAssignmentService().getAssignment(principalId, adk, this.getBeginDateTime().toLocalDate());
449         return anAssignment == null ? this.getAssignmentKey() : anAssignment.getAssignmentDescription();
450     }
451 
452 
453     /**
454      * Word on the street is that Object.clone() is a POS. We only need some
455      * basics for comparison, so we'll implement a simple copy constructor
456      * instead.
457      * <p/>
458      * TODO: Check whether or not it matters if the History is copied, this
459      * operation needs to be as inexpensive as possible.
460      *
461      * @param b The TimeBlock to copy values from when creating this instance.
462      */
463     protected TimeBlock(TimeBlock b) {
464         // TODO : Implement "copy" constructor.
465         this.tkTimeBlockId = b.tkTimeBlockId;
466         this.documentId = b.documentId;
467         this.jobNumber = b.jobNumber;
468         this.workArea = b.workArea;
469         this.task = b.task;
470         this.earnCode = b.earnCode;
471         this.beginTimestamp = new Timestamp(b.beginTimestamp.getTime());
472         this.endTimestamp = new Timestamp(b.endTimestamp.getTime());
473         this.clockLogCreated = b.clockLogCreated;
474         this.hours = b.hours;
475         this.amount = b.amount;
476         this.setUserPrincipalId(b.getUserPrincipalId());
477         this.timestamp = new Timestamp(b.timestamp.getTime());
478         this.beginTimeDisplay = b.beginTimeDisplay;
479         this.endTimeDisplay = b.endTimeDisplay;
480         this.pushBackward = b.pushBackward;
481         this.clockLogBeginId = b.clockLogBeginId;
482         this.clockLogEndId = b.clockLogEndId;
483         this.principalId = b.principalId;
484 
485         // We just set the reference for this object, since splitting the
486         // TimeBlock would be abnormal behavior.
487         this.timesheetDocumentHeader = b.timesheetDocumentHeader;
488 
489         //private List<TimeHourDetail> timeHourDetails = new ArrayList<TimeHourDetail>();
490         for (TimeHourDetail thd : b.timeHourDetails) {
491             this.timeHourDetails.add(thd.copy());
492         }
493 
494         // TODO: For now, not copying TimeBlockHistory - The Object extends this one, which seems odd.
495         //private List<TimeBlockHistory> timeBlockHistories = new ArrayList<TimeBlockHistory>();
496     }
497 
498     /**
499      * @return A new copy of this TimeBlock.
500      */
501     public TimeBlock copy() {
502         return new TimeBlock(this);
503     }
504     
505     public void copy(TimeBlock b) {
506     	 this.tkTimeBlockId = b.tkTimeBlockId;
507          this.documentId = b.documentId;
508          this.jobNumber = b.jobNumber;
509          this.workArea = b.workArea;
510          this.task = b.task;
511          this.earnCode = b.earnCode;
512          this.beginTimestamp = new Timestamp(b.beginTimestamp.getTime());
513          this.endTimestamp = new Timestamp(b.endTimestamp.getTime());
514          this.clockLogCreated = b.clockLogCreated;
515          this.hours = b.hours;
516          this.amount = b.amount;
517          this.userPrincipalId = b.userPrincipalId;
518          this.timestamp = new Timestamp(b.timestamp.getTime());
519          this.beginTimeDisplay = b.beginTimeDisplay;
520          this.endTimeDisplay = b.endTimeDisplay;
521          this.pushBackward = b.pushBackward;
522          this.clockLogBeginId = b.clockLogBeginId;
523          this.clockLogEndId = b.clockLogEndId;
524          this.principalId = b.principalId;
525 
526          // We just set the reference for this object, since splitting the
527          // TimeBlock would be abnormal behavior.
528          this.timesheetDocumentHeader = b.timesheetDocumentHeader;
529 
530          //private List<TimeHourDetail> timeHourDetails = new ArrayList<TimeHourDetail>();
531          for (TimeHourDetail thd : b.timeHourDetails) {
532              this.timeHourDetails.add(thd.copy());
533          }
534          
535     }
536 
537     public String getEarnCodeType() {
538         return earnCodeType;
539     }
540 
541     public void setEarnCodeType(String earnCodeType) {
542         this.earnCodeType = earnCodeType;
543     }
544 
545     /**
546      * This is for distribute time block page to sort it by begin date/time
547      *
548      * @see java.lang.Comparable#compareTo(java.lang.Object)
549      */
550     public int compareTo(Object o) {
551         return compareTo((CalendarBlockBase) o);
552     }
553 
554     public int compareTo(CalendarBlockBase tb) {
555         return this.getBeginTimestamp().compareTo(tb.getBeginTimestamp());
556     }
557 
558     public Boolean getEditable() {
559         return TkServiceLocator.getTimeBlockService().getTimeBlockEditable(this);
560     }
561 
562     public String getPrincipalId() {
563         return principalId;
564     }
565 
566     public void setPrincipalId(String principalId) {
567         this.principalId = principalId;
568     }
569 
570     public String getOvertimePref() {
571         return overtimePref;
572     }
573 
574     public void setOvertimePref(String overtimePref) {
575         this.overtimePref = overtimePref;
576     }
577 
578     /* apply grace period rule to times of time block
579      * These strings are for GUI of Actual time inquiry
580     */
581     public String getActualBeginTimeString() {
582         if (this.getClockLogBeginId() != null) {
583         	 DateTimeZone dtz = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone());
584         	 if (getOvernightTimeClockLog(clockLogBeginId)) {
585                  return getBeginDateTime().withZone(dtz).toString(TkConstants.DT_FULL_DATE_TIME_FORMAT);
586              } else {
587                  ClockLog cl = TkServiceLocator.getClockLogService().getClockLog(this.getClockLogBeginId());
588                  if (cl != null) {
589                      return new DateTime(cl.getTimestamp()).withZone(dtz).toString(TkConstants.DT_FULL_DATE_TIME_FORMAT);
590                  }
591              }
592         }
593         return "";
594     }
595 
596     public String getActualEndTimeString() {
597         if (this.getClockLogEndId() != null) {
598         	DateTimeZone dtz = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone());
599             if (getOvernightTimeClockLog(clockLogEndId)) {
600                 return getEndDateTime().withZone(dtz).toString(TkConstants.DT_FULL_DATE_TIME_FORMAT);
601             } else {
602                 ClockLog cl = TkServiceLocator.getClockLogService().getClockLog(this.getClockLogEndId());
603                 if (cl != null) {
604                     return new DateTime(cl.getTimestamp()).withZone(dtz).toString(TkConstants.DT_FULL_DATE_TIME_FORMAT);
605                 }
606             }
607 
608         }
609         return "";
610     }
611 
612     private Boolean getOvernightTimeClockLog(String clockLogId) {
613         // https://jira.kuali.org/browse/KPME-1179
614         Integer overnightTimeBlocks = TkServiceLocator.getTimeBlockService().getOvernightTimeBlocks(clockLogEndId).size();
615         if (overnightTimeBlocks >= 2) {
616             return true;
617         }
618 
619         return false;
620     }
621 
622 	public Boolean getDeleteable() {
623 		return TkServiceLocator.getTKPermissionService().canDeleteTimeBlock(HrContext.getPrincipalId(), this);
624 	}
625 
626 	public Boolean getOvertimeEditable() {
627 		return TkServiceLocator.getTKPermissionService().canEditOvertimeEarnCode(HrContext.getPrincipalId(), this);
628 	}
629 
630     public Boolean getTimeBlockEditable(){
631         return TkServiceLocator.getTKPermissionService().canEditTimeBlock(HrContext.getPrincipalId(), this);
632     }
633 
634     public boolean isLunchDeleted() {
635         return lunchDeleted;
636     }
637 
638     public void setLunchDeleted(boolean lunchDeleted) {
639         this.lunchDeleted = lunchDeleted;
640     }
641 
642 	public Person getUser() {
643 		return user;
644 	}
645 
646 	public void setUser(Person user) {
647 		this.user = user;
648 	}
649 
650     public Person getEmployeeObj() {
651         return employeeObj;
652     }
653 
654     public void setEmployeeObj(Person employeeObj) {
655         this.employeeObj = employeeObj;
656     }
657 
658     @Override
659 	public boolean equals(Object obj) {
660 		if (obj == null) { 
661 			return false;
662 		}
663 		if (obj == this) { 
664 			return true;
665 		}
666 		if (obj.getClass() != getClass()) {
667 			return false;
668 		}
669 		TimeBlock timeBlock = (TimeBlock) obj;
670 		return new EqualsBuilder()
671 			.append(jobNumber, timeBlock.jobNumber)
672 			.append(workArea, timeBlock.workArea)
673 			.append(task, timeBlock.task)
674 			.append(earnCode, timeBlock.earnCode)
675 			.append(beginTimestamp, timeBlock.beginTimestamp)
676 			.append(endTimestamp, timeBlock.endTimestamp)
677 			.append(hours, timeBlock.hours)
678 			.append(timeHourDetails, timeBlock.timeHourDetails)
679 			.append(timestamp, timeBlock.timestamp)
680 			.isEquals();
681 	}
682 
683     @Override
684     public int hashCode() {
685     	return new HashCodeBuilder(17, 31)
686     		.append(jobNumber)
687     		.append(workArea)
688     		.append(task)
689     		.append(earnCode)
690     		.append(beginTimestamp)
691     		.append(endTimestamp)
692     		.append(hours)
693     		.append(timeHourDetails)
694     		.toHashCode();
695     }
696 
697 	public String getPrincipalIdModified() {
698 		return getUserPrincipalId();
699 	}
700 
701 	public void setPrincipalIdModified(String principalIdModified) {
702 		setUserPrincipalId(principalIdModified);
703 	}
704 
705 	public String getHrCalendarBlockId() {
706 		return super.hrCalendarBlockId;
707 	}
708 	
709 	@Override
710 	public void setHrCalendarBlockId(String hrCalendarBlockId) {
711 		this.hrCalendarBlockId = hrCalendarBlockId;
712 	}
713 
714 	@Override
715 	public String getConcreteBlockId() {
716 		return tkTimeBlockId;
717 	}
718 	
719 	@Override
720 	public void setConcreteBlockId(String concreteBlockId) {
721 		this.concreteBlockId = concreteBlockId;
722 		tkTimeBlockId = concreteBlockId;
723 	}
724 
725 	@Override
726 	public String getConcreteBlockType() {
727 		return super.concreteBlockType == null ? this.getClass().getName() : super.concreteBlockType;
728 	}
729 
730 	@Override
731 	public void setConcreteBlockType(String ojbConcreteClass) {
732 		super.concreteBlockType = ojbConcreteClass;
733 	}
734 	
735 }