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  
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  		earnCodeToTimeBlocks.clear();
82  		for (TimeBlock block : appliedTimeBlocks) {
83  			applyBlock(block, reApplied);
84  		}
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 	private boolean applyBlock(TimeBlock block, List<TimeBlock> applyList) {
116 		DateTime beginDateTime = new DateTime(block.getBeginTimestamp(), this.timeZone);
117 		DateTime endDateTime = new DateTime(block.getEndTimestamp(), this.timeZone);
118 
119 		if (beginDateTime.isAfter(flsaDateInterval.getEnd()))
120 			return false;
121 
122 		Interval timeBlockInterval = null;
123 		
124 		boolean zeroHoursTimeBlock = false;
125 		if(endDateTime.getMillis() > beginDateTime.getMillis()){
126 			timeBlockInterval = new Interval(beginDateTime,endDateTime);
127 		}
128 		
129 		if(flsaDateInterval.contains(beginDateTime)){
130 			zeroHoursTimeBlock = true;
131 		}
132 
133 		Interval overlapInterval = flsaDateInterval.overlap(timeBlockInterval);
134 		long overlap = (overlapInterval == null) ? 0L : overlapInterval.toDurationMillis();
135 		BigDecimal overlapHours = TKUtils.convertMillisToHours(overlap);
136 		if((overlapHours.compareTo(BigDecimal.ZERO) == 0) && flsaDateInterval.contains(beginDateTime) && flsaDateInterval.contains(endDateTime)){
137 			if(block.getHours().compareTo(BigDecimal.ZERO) > 0){
138 				overlapHours = block.getHours();
139 			}
140 		}
141 
142         
143         
144         
145         
146         Map<String,BigDecimal> localEarnCodeToHours = new HashMap<String,BigDecimal>();
147 
148 		if (zeroHoursTimeBlock || overlapHours.compareTo(BigDecimal.ZERO) > 0 || (flsaDateInterval.contains(beginDateTime) && StringUtils.equals(block.getEarnCodeType(),TkConstants.EARN_CODE_AMOUNT)))  {
149 
150             List<TimeHourDetail> details = block.getTimeHourDetails();
151             for (TimeHourDetail thd : details) {
152                 BigDecimal localEcHours = localEarnCodeToHours.containsKey(thd.getEarnCode()) ? localEarnCodeToHours.get(thd.getEarnCode()) : BigDecimal.ZERO;
153                 
154                 if (overlapHours.compareTo(localEcHours) >= 0 || thd.getAmount().compareTo(BigDecimal.ZERO) == 0) {
155                     localEcHours = localEcHours.add(thd.getHours(), TkConstants.MATH_CONTEXT);
156                     localEarnCodeToHours.put(thd.getEarnCode(), localEcHours);
157                 }
158             }
159 
160 			List<TimeBlock> blocks = earnCodeToTimeBlocks.get(block.getEarnCode());
161 			if (blocks == null) {
162 				blocks = new ArrayList<TimeBlock>();
163 				earnCodeToTimeBlocks.put(block.getEarnCode(), blocks);
164 			}
165 			blocks.add(block);
166 			applyList.add(block);
167 		}
168 
169 		return true;
170 	}
171 
172 	public Map<String, List<TimeBlock>> getEarnCodeToTimeBlocks() {
173 		return earnCodeToTimeBlocks;
174 	}
175 
176 	public void setEarnCodeToTimeBlocks(Map<String, List<TimeBlock>> earnCodeToTimeBlocks) {
177 		this.earnCodeToTimeBlocks = earnCodeToTimeBlocks;
178 	}
179 
180 	public List<TimeBlock> getAppliedTimeBlocks() {
181 		return appliedTimeBlocks;
182 	}
183 
184 	public void setAppliedTimeBlocks(List<TimeBlock> appliedTimeBlocks) {
185 		this.appliedTimeBlocks = appliedTimeBlocks;
186 	}
187 
188 
189 }