Switch to GanttDates

Otherwise LoadPeriods of less than one day would not be shown.

FEA: ItEr75S04BugFixing
This commit is contained in:
Óscar González Fernández 2011-08-01 18:58:17 +02:00
parent c6cbb12833
commit 6d44f44c1a
7 changed files with 115 additions and 82 deletions

View file

@ -31,15 +31,15 @@ import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.data.GanttDate;
public class LoadPeriod {
private static final Log LOG = LogFactory.getLog(LoadPeriod.class);
private final LocalDate start;
private final GanttDate start;
private final LocalDate end;
private final GanttDate end;
private final LoadLevel loadLevel;
@ -47,14 +47,14 @@ public class LoadPeriod {
private final int assignedHours;
public LoadPeriod(LocalDate start, LocalDate end,
public LoadPeriod(GanttDate start, GanttDate end,
int totalResourceWorkHours, int assignedHours, LoadLevel loadLevel) {
Validate.notNull(start);
Validate.notNull(end);
Validate.notNull(loadLevel);
Validate.notNull(totalResourceWorkHours);
Validate.notNull(assignedHours);
Validate.isTrue(!start.isAfter(end));
Validate.isTrue(start.compareTo(end) <= 0);
this.start = start;
this.end = end;
this.loadLevel = loadLevel;
@ -62,16 +62,16 @@ public class LoadPeriod {
this.assignedHours = assignedHours;
}
public LocalDate getStart() {
public GanttDate getStart() {
return start;
}
public LocalDate getEnd() {
public GanttDate getEnd() {
return end;
}
public boolean overlaps(LoadPeriod other) {
return start.isBefore(other.end) && end.isAfter(other.start);
return start.compareTo(other.end) < 0 && end.compareTo(other.start) > 0;
}
/**

View file

@ -24,18 +24,17 @@ package org.zkoss.ganttz.data.resourceload;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import org.apache.commons.collections.ComparatorUtils;
import org.apache.commons.lang.Validate;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.data.GanttDate;
import org.zkoss.ganttz.util.Interval;
public class LoadTimeLine {
@SuppressWarnings("unchecked")
private static final Comparator<LocalDate> nullSafeComparator = ComparatorUtils
private static final Comparator<GanttDate> nullSafeComparator = ComparatorUtils
.nullLowComparator(ComparatorUtils.naturalComparator());
public static Comparator<LoadTimeLine> byStartAndEndDate() {
@ -120,7 +119,7 @@ public class LoadTimeLine {
return loadPeriods.get(loadPeriods.size() - 1);
}
public LocalDate getStartPeriod() {
public GanttDate getStartPeriod() {
if (isEmpty()) {
return null;
}
@ -131,7 +130,7 @@ public class LoadTimeLine {
return loadPeriods.isEmpty();
}
public LocalDate getEndPeriod() {
public GanttDate getEndPeriod() {
if (isEmpty()) {
return null;
}
@ -144,22 +143,18 @@ public class LoadTimeLine {
public static Interval getIntervalFrom(List<LoadTimeLine> timeLines) {
Validate.notEmpty(timeLines);
LocalDate start = null;
LocalDate end = null;
GanttDate start = null;
GanttDate end = null;
for (LoadTimeLine loadTimeLine : timeLines) {
Validate.notNull(loadTimeLine.getStart());
start = min(start, loadTimeLine.getStart());
Validate.notNull(loadTimeLine.getEnd());
end = max(end, loadTimeLine.getEnd());
}
return new Interval(toDate(start), toDate(end));
return new Interval(start.toLocalDate(), end.asExclusiveEnd());
}
private static Date toDate(LocalDate localDate) {
return localDate.toDateTimeAtStartOfDay().toDate();
}
private static LocalDate max(LocalDate one, LocalDate other) {
private static GanttDate max(GanttDate one, GanttDate other) {
if (one == null) {
return other;
}
@ -169,7 +164,7 @@ public class LoadTimeLine {
return one.compareTo(other) > 0 ? one : other;
}
private static LocalDate min(LocalDate one, LocalDate other) {
private static GanttDate min(GanttDate one, GanttDate other) {
if (one == null) {
return other;
}
@ -196,24 +191,25 @@ public class LoadTimeLine {
return result;
}
public LocalDate getStart() {
LocalDate result = getStartPeriod();
public GanttDate getStart() {
GanttDate result = getStartPeriod();
for (LoadTimeLine loadTimeLine : getChildren()) {
LocalDate start = loadTimeLine.getStart();
GanttDate start = loadTimeLine.getStart();
if (start != null) {
result = result == null || result.compareTo(start) > 0 ? start
: result;
result = result == null || result.compareTo(start) > 0 ? start
: result;
}
}
return result;
}
public LocalDate getEnd() {
LocalDate result = getEndPeriod();
public GanttDate getEnd() {
GanttDate result = getEndPeriod();
for (LoadTimeLine loadTimeLine : getChildren()) {
LocalDate end = loadTimeLine.getEnd();
GanttDate end = loadTimeLine.getEnd();
if (end != null) {
result = result == null || result.compareTo(end) < 0 ? end : result;
result = result == null || result.compareTo(end) < 0 ? end
: result;
}
}
return result;

View file

@ -29,8 +29,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.joda.time.Duration;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.IDatesMapper;
import org.zkoss.ganttz.data.resourceload.LoadPeriod;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
@ -38,8 +36,8 @@ import org.zkoss.ganttz.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.MenuBuilder;
import org.zkoss.ganttz.util.WeakReferencedListeners;
import org.zkoss.ganttz.util.MenuBuilder.ItemAction;
import org.zkoss.ganttz.util.WeakReferencedListeners;
import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@ -209,10 +207,8 @@ public class ResourceLoadComponent extends XulElement {
private static int getWidthPixels(IDatesMapper datesMapper,
LoadPeriod loadPeriod) {
LocalDate start = loadPeriod.getStart();
LocalDate end = loadPeriod.getEnd();
return datesMapper.toPixels(new Duration(
start.toDateTimeAtStartOfDay(), end.toDateTimeAtStartOfDay()));
return Math.max(loadPeriod.getEnd().toPixels(datesMapper)
- getStartPixels(datesMapper, loadPeriod), 0);
}
private static String forCSS(int pixels) {
@ -221,7 +217,7 @@ public class ResourceLoadComponent extends XulElement {
private static int getStartPixels(IDatesMapper datesMapper,
LoadPeriod loadPeriod) {
return datesMapper.toPixels(loadPeriod.getStart());
return loadPeriod.getStart().toPixels(datesMapper);
}
protected void renderProperties(ContentRenderer renderer) throws IOException{

View file

@ -32,28 +32,34 @@ import java.util.ListIterator;
import org.joda.time.LocalDate;
import org.junit.Test;
import org.zkoss.ganttz.data.GanttDate;
public class LoadPeriodTest {
private LocalDate start;
private LocalDate end;
private GanttDate start;
private GanttDate end;
private LoadLevel loadLevel;
private LoadPeriod loadPeriod;
private List<LoadPeriod> unsortedList;
private void givenExampleLoadPeriod() {
start = new LocalDate(2009, 11, 4);
end = new LocalDate(2009, 12, 8);
start = GanttDate.createFrom(new LocalDate(2009, 11, 4));
end = GanttDate.createFrom(new LocalDate(2009, 12, 8));
givenExampleLoadPeriod(start, end);
}
private void givenExampleLoadPeriod(LocalDate start, LocalDate end) {
givenExampleLoadPeriod(GanttDate.createFrom(start),
GanttDate.createFrom(end));
}
private void givenExampleLoadPeriod(GanttDate start, GanttDate end) {
loadLevel = new LoadLevel(50);
givenExampleLoadPeriod(start, end, loadLevel);
}
private void givenExampleLoadPeriod(LocalDate start, LocalDate end,
private void givenExampleLoadPeriod(GanttDate start, GanttDate end,
LoadLevel loadLevel) {
loadPeriod = new LoadPeriod(start, end, totalHours, assignedHours,
loadLevel);
@ -61,8 +67,8 @@ public class LoadPeriodTest {
@Test(expected = IllegalArgumentException.class)
public void aLoadPeriodMustHaveAStartDate() {
new LoadPeriod(null, new LocalDate(), totalHours, assignedHours,
correctLoadLevel());
new LoadPeriod(null, GanttDate.createFrom(new LocalDate()), totalHours,
assignedHours, correctLoadLevel());
}
private static final int totalHours = 100;
@ -75,24 +81,24 @@ public class LoadPeriodTest {
@Test(expected = IllegalArgumentException.class)
public void aLoadPeriodMustHaveAnEndDate() {
new LoadPeriod(new LocalDate(), null, totalHours, assignedHours,
correctLoadLevel());
new LoadPeriod(GanttDate.createFrom(new LocalDate()), null, totalHours,
assignedHours, correctLoadLevel());
}
@Test(expected = IllegalArgumentException.class)
public void theEndDateCantBeBeforeTheStartDate() {
LocalDate start = new LocalDate(2009, 10, 4);
LocalDate end = new LocalDate(2009, 10, 3);
new LoadPeriod(start, end, totalHours, assignedHours,
correctLoadLevel());
new LoadPeriod(GanttDate.createFrom(start), GanttDate.createFrom(end),
totalHours, assignedHours, correctLoadLevel());
}
@Test
public void theEndDateCanBeTheSameThanTheStartDate() {
LocalDate start = new LocalDate(2009, 10, 4);
LocalDate end = new LocalDate(2009, 10, 4);
new LoadPeriod(start, end, totalHours, assignedHours,
correctLoadLevel());
new LoadPeriod(GanttDate.createFrom(start), GanttDate.createFrom(end),
totalHours, assignedHours, correctLoadLevel());
}
@Test
@ -137,8 +143,9 @@ public class LoadPeriodTest {
private static LoadPeriod create(int startYear, int startMonth,
int startDay, int endYear, int endMonth, int endDay) {
return new LoadPeriod(new LocalDate(startYear, startMonth, startDay),
new LocalDate(endYear, endMonth, endDay), totalHours,
return new LoadPeriod(GanttDate.createFrom(new LocalDate(startYear,
startMonth, startDay)), GanttDate.createFrom(new LocalDate(
endYear, endMonth, endDay)), totalHours,
assignedHours, correctLoadLevel());
}
@ -181,7 +188,7 @@ public class LoadPeriodTest {
previous = current;
current = listIterator.next();
if (previous != null) {
assertFalse(current.getStart().isBefore(previous.getEnd()));
assertFalse(current.getStart().compareTo(previous.getEnd()) < 0);
}
}
}

View file

@ -32,6 +32,7 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.junit.Test;
import org.zkoss.ganttz.data.GanttDate;
public class LoadTimelineTest {
@ -61,10 +62,11 @@ public class LoadTimelineTest {
private void givenValidLoadTimeLine() {
conceptName = "bla";
loadTimeLine = new LoadTimeLine(conceptName, Arrays
.asList(new LoadPeriod(new LocalDate(2009, 10, 5),
new LocalDate(2009, 10, 11), 100, 20,
new LoadLevel(20))), null);
loadTimeLine = new LoadTimeLine(conceptName,
Arrays.asList(new LoadPeriod(GanttDate
.createFrom(new LocalDate(2009, 10, 5)), GanttDate
.createFrom(new LocalDate(2009, 10, 11)), 100, 20,
new LoadLevel(20))), null);
}
@Test
@ -76,10 +78,12 @@ public class LoadTimelineTest {
@Test
public void aLoadTimelineSortsItsReceivedPeriods() {
LoadPeriod l1 = new LoadPeriod(new LocalDate(2009, 10, 5),
new LocalDate(2009, 10, 11), 100, 20, new LoadLevel(20));
LoadPeriod l2 = new LoadPeriod(new LocalDate(2009, 5, 3),
new LocalDate(2009, 6, 3), 100, 20, new LoadLevel(20));
LoadPeriod l1 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
10, 5)), GanttDate.createFrom(new LocalDate(2009, 10, 11)),
100, 20, new LoadLevel(20));
LoadPeriod l2 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
5, 3)), GanttDate.createFrom(new LocalDate(2009, 6, 3)), 100,
20, new LoadLevel(20));
LoadTimeLine loadTimeLine = new LoadTimeLine("bla", Arrays.asList(l1,
l2), null);
@ -90,10 +94,12 @@ public class LoadTimelineTest {
@Test(expected = IllegalArgumentException.class)
public void theLoadPeriodsMustNotOverlap() {
LoadPeriod l1 = new LoadPeriod(new LocalDate(2009, 10, 5),
new LocalDate(2009, 10, 11), 100, 20, new LoadLevel(20));
LoadPeriod l2 = new LoadPeriod(new LocalDate(2009, 5, 3),
new LocalDate(2009, 10, 10), 100, 20, new LoadLevel(20));
LoadPeriod l1 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
10, 5)), GanttDate.createFrom(new LocalDate(2009, 10, 11)),
100, 20, new LoadLevel(20));
LoadPeriod l2 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
5, 3)), GanttDate.createFrom(new LocalDate(2009, 10, 10)), 100,
20, new LoadLevel(20));
new LoadTimeLine("bla", Arrays.asList(l1, l2), null);
}

View file

@ -34,6 +34,7 @@ import org.apache.commons.lang.Validate;
import org.apache.commons.lang.math.Fraction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.navalplanner.business.calendars.entities.ICalendar;
import org.navalplanner.business.planner.entities.ResourceAllocation;
import org.navalplanner.business.resources.daos.IResourcesSearcher;
import org.navalplanner.business.resources.entities.Criterion;
@ -43,6 +44,9 @@ import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.EffortDuration.IEffortFrom;
import org.navalplanner.business.workingday.IntraDayDate;
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
import org.navalplanner.web.planner.TaskElementAdapter;
import org.zkoss.ganttz.data.GanttDate;
import org.zkoss.ganttz.data.resourceload.LoadLevel;
import org.zkoss.ganttz.data.resourceload.LoadPeriod;
@ -200,12 +204,32 @@ abstract class LoadPeriodGenerator {
}
EffortDuration totalEffort = getTotalAvailableEffort();
EffortDuration effortAssigned = getEffortAssigned();
return new LoadPeriod(start.getDate(), end.getDate(),
return new LoadPeriod(asGantt(start), asGantt(end),
totalEffort.roundToHours(), effortAssigned.roundToHours(),
new LoadLevel(calculateLoadPercentage(totalEffort,
effortAssigned)));
}
private GanttDate asGantt(IntraDayDate date) {
return TaskElementAdapter.toGantt(
date,
inferDayCapacity(allocationsOnInterval,
PartialDay.wholeDay(date.getDate())));
}
private EffortDuration inferDayCapacity(
List<ResourceAllocation<?>> allocationsOnInterval, PartialDay day) {
if (allocationsOnInterval.isEmpty()) {
return null;
}
EffortDuration result = EffortDuration.zero();
for (ResourceAllocation<?> each : allocationsOnInterval) {
ICalendar allocationCalendar = each.getAllocationCalendar();
result = result.plus(allocationCalendar.getCapacityOn(day));
}
return result.divideBy(allocationsOnInterval.size());
}
protected abstract EffortDuration getTotalAvailableEffort();
private static int calculateLoadPercentage(EffortDuration totalEffort,

View file

@ -83,6 +83,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.ganttz.data.GanttDate;
import org.zkoss.ganttz.data.resourceload.LoadPeriod;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
import org.zkoss.ganttz.data.resourceload.TimeLineRole;
@ -1102,22 +1103,25 @@ class PeriodsBuilder {
Date startDateFilter, Date endDateFilter) {
List<LoadPeriod> list = new PeriodsBuilder(factory, sortedByStartDate).buildPeriods();
List<LoadPeriod> toReturn = new ArrayList<LoadPeriod>();
for(LoadPeriod loadPeriod : list) {
LocalDate finalStartDate = loadPeriod.getStart();
LocalDate finalEndDate = loadPeriod.getEnd();
if(startDateFilter != null) {
LocalDate startDateFilterLocalDate = new LocalDate(startDateFilter.getTime());
if(finalStartDate.compareTo(startDateFilterLocalDate) < 0) {
finalStartDate = startDateFilterLocalDate;
}
for (LoadPeriod loadPeriod : list) {
final GanttDate finalStartDate;
if (startDateFilter != null) {
finalStartDate = GanttDate.max(GanttDate
.createFrom(new LocalDate(startDateFilter.getTime())),
loadPeriod.getStart());
} else {
finalStartDate = loadPeriod.getStart();
}
if(endDateFilter != null) {
LocalDate endDateFilterLocalDate = new LocalDate(endDateFilter.getTime());
if(loadPeriod.getEnd().compareTo(endDateFilterLocalDate) > 0) {
finalEndDate = endDateFilterLocalDate;
}
final GanttDate finalEndDate;
if (endDateFilter != null) {
finalEndDate = GanttDate.min(loadPeriod.getEnd(), GanttDate
.createFrom(new LocalDate(endDateFilter.getTime())));
} else {
finalEndDate = loadPeriod.getEnd();
}
if(finalStartDate.compareTo(finalEndDate) < 0) {
if (finalStartDate.compareTo(finalEndDate) < 0) {
toReturn.add(new LoadPeriod(finalStartDate, finalEndDate,
loadPeriod.getTotalResourceWorkHours(),
loadPeriod.getAssignedHours(), loadPeriod.getLoadLevel()));