1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.flsa;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.joda.time.DateTime;
20 import org.joda.time.DateTimeZone;
21 import org.joda.time.Interval;
22 import org.joda.time.LocalDateTime;
23 import org.kuali.hr.time.timeblock.TimeBlock;
24 import org.kuali.hr.time.timeblock.TimeHourDetail;
25 import org.kuali.hr.time.util.TKUtils;
26 import org.kuali.hr.time.util.TkConstants;
27
28 import java.math.BigDecimal;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33
34 public class FlsaDay {
35 private Map<String,BigDecimal> earnCodeToHours = new HashMap<String,BigDecimal>();
36 private Map<String,List<TimeBlock>> earnCodeToTimeBlocks = new HashMap<String,List<TimeBlock>>();
37 private List<TimeBlock> appliedTimeBlocks = new ArrayList<TimeBlock>();
38
39 Interval flsaDateInterval;
40 LocalDateTime flsaDate;
41 DateTimeZone timeZone;
42
43
44
45
46
47
48
49
50 public FlsaDay(LocalDateTime flsaDate, List<TimeBlock> timeBlocks, DateTimeZone timeZone) {
51 this.flsaDate = flsaDate;
52 this.timeZone = timeZone;
53 flsaDateInterval = new Interval(flsaDate.toDateTime(timeZone), flsaDate.toDateTime(timeZone).plusHours(24));
54 this.setTimeBlocks(timeBlocks);
55 }
56
57
58
59
60
61
62
63
64
65
66 public void setTimeBlocks(List<TimeBlock> timeBlocks) {
67 for (TimeBlock block : timeBlocks)
68 if (!applyBlock(block, this.appliedTimeBlocks))
69 break;
70 }
71
72
73
74
75
76
77
78
79 public void remapTimeHourDetails() {
80 List<TimeBlock> reApplied = new ArrayList<TimeBlock>(appliedTimeBlocks.size());
81 earnCodeToHours.clear();
82 earnCodeToTimeBlocks.clear();
83 for (TimeBlock block : appliedTimeBlocks) {
84 applyBlock(block, reApplied);
85 }
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 private boolean applyBlock(TimeBlock block, List<TimeBlock> applyList) {
117 DateTime beginDateTime = new DateTime(block.getBeginTimestamp(), this.timeZone);
118 DateTime endDateTime = new DateTime(block.getEndTimestamp(), this.timeZone);
119
120 if (beginDateTime.isAfter(flsaDateInterval.getEnd()))
121 return false;
122
123 Interval timeBlockInterval = null;
124
125 boolean zeroHoursTimeBlock = false;
126 if(endDateTime.getMillis() > beginDateTime.getMillis()){
127 timeBlockInterval = new Interval(beginDateTime,endDateTime);
128 }
129
130 if(flsaDateInterval.contains(beginDateTime)){
131 zeroHoursTimeBlock = true;
132 }
133
134 Interval overlapInterval = flsaDateInterval.overlap(timeBlockInterval);
135 long overlap = (overlapInterval == null) ? 0L : overlapInterval.toDurationMillis();
136 BigDecimal overlapHours = TKUtils.convertMillisToHours(overlap);
137 if((overlapHours.compareTo(BigDecimal.ZERO) == 0) && flsaDateInterval.contains(beginDateTime) && flsaDateInterval.contains(endDateTime)){
138 if(block.getHours().compareTo(BigDecimal.ZERO) > 0){
139 overlapHours = block.getHours();
140 }
141 }
142
143
144
145
146
147 Map<String,BigDecimal> localEarnCodeToHours = new HashMap<String,BigDecimal>();
148
149 if (zeroHoursTimeBlock || overlapHours.compareTo(BigDecimal.ZERO) > 0 || (flsaDateInterval.contains(beginDateTime) && StringUtils.equals(block.getEarnCodeType(),TkConstants.EARN_CODE_AMOUNT))) {
150
151 List<TimeHourDetail> details = block.getTimeHourDetails();
152 for (TimeHourDetail thd : details) {
153 BigDecimal ecHours = earnCodeToHours.containsKey(thd.getEarnCode()) ? earnCodeToHours.get(thd.getEarnCode()) : BigDecimal.ZERO;
154 BigDecimal localEcHours = localEarnCodeToHours.containsKey(thd.getEarnCode()) ? localEarnCodeToHours.get(thd.getEarnCode()) : BigDecimal.ZERO;
155
156 if (overlapHours.compareTo(localEcHours) >= 0 || thd.getAmount().compareTo(BigDecimal.ZERO) == 0) {
157 ecHours = ecHours.add(thd.getHours(), TkConstants.MATH_CONTEXT);
158 localEcHours = localEcHours.add(thd.getHours(), TkConstants.MATH_CONTEXT);
159 earnCodeToHours.put(thd.getEarnCode(), ecHours);
160 localEarnCodeToHours.put(thd.getEarnCode(), localEcHours);
161 }
162 }
163
164 List<TimeBlock> blocks = earnCodeToTimeBlocks.get(block.getEarnCode());
165 if (blocks == null) {
166 blocks = new ArrayList<TimeBlock>();
167 earnCodeToTimeBlocks.put(block.getEarnCode(), blocks);
168 }
169 blocks.add(block);
170 applyList.add(block);
171 }
172
173 return true;
174 }
175
176 public Map<String, BigDecimal> getEarnCodeToHours() {
177 return earnCodeToHours;
178 }
179
180 public Map<String, List<TimeBlock>> getEarnCodeToTimeBlocks() {
181 return earnCodeToTimeBlocks;
182 }
183
184 public void setEarnCodeToTimeBlocks(Map<String, List<TimeBlock>> earnCodeToTimeBlocks) {
185 this.earnCodeToTimeBlocks = earnCodeToTimeBlocks;
186 }
187
188 public List<TimeBlock> getAppliedTimeBlocks() {
189 return appliedTimeBlocks;
190 }
191
192 public void setAppliedTimeBlocks(List<TimeBlock> appliedTimeBlocks) {
193 this.appliedTimeBlocks = appliedTimeBlocks;
194 }
195
196
197 }