From 7d09ed098019353b061c0cab5f920f83044d2ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Thu, 30 Sep 2010 21:53:49 +0200 Subject: [PATCH] Change Interval to use LocalDates and associated changes FEA: ItEr61S08TimeUnitConfigurablePlanning --- ganttzk/pom.xml | 5 + .../zkoss/ganttz/DatesMapperOnInterval.java | 29 +++-- .../zkoss/ganttz/timetracker/TimeTracker.java | 14 +-- .../zoom/DetailFourTimeTrackerState.java | 19 ++-- .../timetracker/zoom/TimeTrackerState.java | 39 +++---- ...meTrackerStateWithSubintervalsFitting.java | 14 +-- .../java/org/zkoss/ganttz/util/Interval.java | 102 ++++++++++-------- .../web/planner/chart/ChartFiller.java | 15 +-- .../planner/chart/EarnedValueChartFiller.java | 8 +- .../planner/company/CompanyPlanningModel.java | 66 +++++------- .../company/ICompanyPlanningModel.java | 8 +- .../web/resourceload/IResourceLoadModel.java | 10 +- .../resourceload/ResourceLoadController.java | 51 ++++----- .../web/resourceload/ResourceLoadModel.java | 65 +++++------ 14 files changed, 221 insertions(+), 224 deletions(-) diff --git a/ganttzk/pom.xml b/ganttzk/pom.xml index faead1e21..5221c2c5a 100644 --- a/ganttzk/pom.xml +++ b/ganttzk/pom.xml @@ -40,6 +40,11 @@ org.xnap.commons gettext-commons + + + commons-math + commons-math + joda-time joda-time diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/DatesMapperOnInterval.java b/ganttzk/src/main/java/org/zkoss/ganttz/DatesMapperOnInterval.java index 6b47a5d46..95356e052 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/DatesMapperOnInterval.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/DatesMapperOnInterval.java @@ -25,35 +25,46 @@ package org.zkoss.ganttz; import java.util.Date; +import org.apache.commons.lang.math.Fraction; +import org.joda.time.DateTime; import org.zkoss.ganttz.util.Interval; public class DatesMapperOnInterval implements IDatesMapper { private final int horizontalSize; - private final Interval stubInterval; + private final Interval interval; private long millisecondsPerPixel; + private Fraction pixelsPerDay; - public DatesMapperOnInterval(int horizontalSize, Interval stubInterval) { + public DatesMapperOnInterval(int horizontalSize, Interval interval) { this.horizontalSize = horizontalSize; - this.stubInterval = stubInterval; - this.millisecondsPerPixel = stubInterval.getLengthBetween() + this.interval = interval; + this.millisecondsPerPixel = interval.getLengthBetween().getMillis() / horizontalSize; + this.pixelsPerDay = Fraction.getFraction(horizontalSize, interval + .getDaysBetween().getDays()); } @Override public Date toDate(int pixels) { - return new Date(stubInterval.getStart().getTime() - + millisecondsPerPixel * pixels); + int daysInto = Fraction.getFraction(pixels, 1).divideBy(pixelsPerDay) + .intValue(); + return interval.getStart().plusDays(daysInto).toDateTimeAtStartOfDay() + .toDate(); } @Override public int toPixels(Date date) { - double proportion = stubInterval.getProportion(date); - return (int) (horizontalSize * proportion); + Fraction proportion = interval.getProportion(new DateTime(date + .getTime())); + return proportion.multiplyBy(Fraction.getFraction(horizontalSize, 1)) + .intValue(); } @Override public int toPixels(long milliseconds) { - Date date = new Date(stubInterval.getStart().getTime() + milliseconds); + Date date = new Date(interval.getStart().toDateTimeAtStartOfDay() + .getMillis() + + milliseconds); return this.toPixels(date); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java index af4d229ae..8de84e77d 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java @@ -40,8 +40,8 @@ import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.Interval; import org.zkoss.ganttz.util.LongOperationFeedback; -import org.zkoss.ganttz.util.WeakReferencedListeners; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; +import org.zkoss.ganttz.util.WeakReferencedListeners; import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.ui.Component; @@ -278,8 +278,8 @@ public class TimeTracker { endPlusOneMonth(task)); invalidatingChangeHappened(); } else { - Date newStart = interval.getStart(); - Date newFinish = interval.getFinish(); + LocalDate newStart = interval.getStart(); + LocalDate newFinish = interval.getFinish(); boolean changed = false; if (interval.getStart().compareTo(startMinusTwoWeeks(task)) > 0) { @@ -320,19 +320,19 @@ public class TimeTracker { return date1.compareTo(date2) <= 0 ? date1 : date2; } - private Date endPlusOneMonth(Task task) { + private LocalDate endPlusOneMonth(Task task) { Date taskEnd = max(task.getEndDate(), task.getDeadline()); - return new LocalDate(taskEnd).plusMonths(1).toDateMidnight().toDate(); + return new LocalDate(taskEnd).plusMonths(1); } - private Date startMinusTwoWeeks(Task task) { + private LocalDate startMinusTwoWeeks(Task task) { // the deadline could be before the start Date start = min(task.getBeginDate(), task.getDeadline()); // the last consolidated value could be before the start if (task.getConsolidatedline() != null) { start = min(start, task.getConsolidatedline()); } - return new LocalDate(start).minusWeeks(2).toDateMidnight().toDate(); + return new LocalDate(start).minusWeeks(2); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java index aa7273775..d4a27ebba 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java @@ -76,7 +76,8 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { @Override public DetailItem create(DateTime dateTime) { - int daysUntilFirstDayNextWeek = getDaysUntilFirstDayNextWeek(dateTime); + int daysUntilFirstDayNextWeek = getDaysUntilFirstDayNextWeek(dateTime + .toLocalDate()); int sizeWeek = new BigDecimal(pixelPerDay() * daysUntilFirstDayNextWeek).intValue(); @@ -120,22 +121,22 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { } @Override - protected Iterator getPeriodsFirstLevelGenerator(DateTime start) { - return new LazyGenerator(start) { + protected Iterator getPeriodsFirstLevelGenerator(LocalDate start) { + return new LazyGenerator(start) { @Override - protected DateTime next(DateTime last) { + protected LocalDate next(LocalDate last) { return last.plus(Months.ONE); } }; } @Override - protected Iterator getPeriodsSecondLevelGenerator(DateTime start) { - return new LazyGenerator(start) { + protected Iterator getPeriodsSecondLevelGenerator(LocalDate start) { + return new LazyGenerator(start) { @Override - protected DateTime next(DateTime last) { + protected LocalDate next(LocalDate last) { if (last.getDayOfWeek() != 1) { return last.plusDays(getDaysUntilFirstDayNextWeek(last)); } else { @@ -145,7 +146,7 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { }; } - private int getDaysUntilFirstDayNextWeek(DateTime dateTime) { - return 8 - dateTime.getDayOfWeek(); + private int getDaysUntilFirstDayNextWeek(LocalDate date) { + return 8 - date.getDayOfWeek(); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java index f8108c96d..21549f642 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java @@ -143,15 +143,14 @@ public abstract class TimeTrackerState { } private Collection createDetails(Interval interval, - Iterator datesGenerator, + Iterator datesGenerator, IDetailItemCreator detailItemCreator) { - DateTime current = asLocalDate(interval.getStart()) - .toDateTimeAtStartOfDay(); - DateTime end = asLocalDate(interval.getFinish()) - .toDateTimeAtStartOfDay(); + LocalDate current = interval.getStart(); + LocalDate end = interval.getFinish(); List result = new ArrayList(); while (current.isBefore(end)) { - result.add(detailItemCreator.create(current)); + result.add(detailItemCreator.create(current + .toDateTimeAtStartOfDay())); assert datesGenerator.hasNext(); current = datesGenerator.next(); } @@ -162,27 +161,23 @@ public abstract class TimeTrackerState { Interval interval) { Interval realInterval = getRealIntervalFor(interval); return createDetails(realInterval, - getPeriodsFirstLevelGenerator(startOf(realInterval)), + getPeriodsFirstLevelGenerator(realInterval.getStart()), getDetailItemCreatorFirstLevel()); } - protected abstract Iterator getPeriodsFirstLevelGenerator( - DateTime start); + protected abstract Iterator getPeriodsFirstLevelGenerator( + LocalDate start); private final Collection createDetailsForSecondLevel( Interval interval) { Interval realInterval = getRealIntervalFor(interval); return createDetails(realInterval, - getPeriodsSecondLevelGenerator(startOf(realInterval)), + getPeriodsSecondLevelGenerator(realInterval.getStart()), getDetailItemCreatorSecondLevel()); } - private static DateTime startOf(Interval interval) { - return new DateTime(interval.getStart().getTime()); - } - - protected abstract Iterator getPeriodsSecondLevelGenerator( - DateTime start); + protected abstract Iterator getPeriodsSecondLevelGenerator( + LocalDate start); protected abstract IDetailItemCreator getDetailItemCreatorFirstLevel(); @@ -263,9 +258,8 @@ public abstract class TimeTrackerState { } BaseSingleFieldPeriod asPeriod(Interval interval) { - LocalDate start = LocalDate.fromDateFields(interval.getStart()); - LocalDate end = LocalDate.fromDateFields(interval.getFinish()); - return type.differenceBetween(start, end); + return type.differenceBetween(interval.getStart(), + interval.getFinish()); } } @@ -280,8 +274,7 @@ public abstract class TimeTrackerState { } LocalDate newEnd = new LocalDate(interval.getStart()) .plus(minimumPeriod.toPeriod()); - return new Interval(interval.getStart(), newEnd - .toDateTimeAtStartOfDay().toDate()); + return new Interval(interval.getStart(), newEnd); } public Interval getRealIntervalFor(Interval testInterval) { @@ -289,8 +282,8 @@ public abstract class TimeTrackerState { } private Interval calculateForAtLeastMinimum(Interval atLeastMinimum) { - LocalDate start = round(asLocalDate(atLeastMinimum.getStart()), true); - LocalDate finish = round(asLocalDate(atLeastMinimum.getFinish()), false); + LocalDate start = round(atLeastMinimum.getStart(), true); + LocalDate finish = round(atLeastMinimum.getFinish(), false); Interval result = new Interval(start.toDateTimeAtStartOfDay().toDate(), finish.toDateTimeAtStartOfDay().toDate()); return result; diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java index 287ac2307..4f7f00840 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java @@ -22,7 +22,7 @@ package org.zkoss.ganttz.timetracker.zoom; import java.util.Iterator; import org.apache.commons.lang.Validate; -import org.joda.time.DateTime; +import org.joda.time.LocalDate; import org.joda.time.ReadablePeriod; /** @@ -38,29 +38,29 @@ public abstract class TimeTrackerStateWithSubintervalsFitting extends super(firstLevelModificator, secondLevelModificator); } - private final class PeriodicalGenerator extends LazyGenerator { + private final class PeriodicalGenerator extends LazyGenerator { private final ReadablePeriod period; - private PeriodicalGenerator(DateTime first, ReadablePeriod period) { + private PeriodicalGenerator(LocalDate first, ReadablePeriod period) { super(first); Validate.notNull(period); this.period = period; } @Override - protected DateTime next(DateTime last) { + protected LocalDate next(LocalDate last) { return last.plus(period); } } @Override - protected Iterator getPeriodsFirstLevelGenerator( - final DateTime start) { + protected Iterator getPeriodsFirstLevelGenerator( + final LocalDate start) { return new PeriodicalGenerator(start, getPeriodFirstLevel()); } @Override - protected Iterator getPeriodsSecondLevelGenerator(DateTime start) { + protected Iterator getPeriodsSecondLevelGenerator(LocalDate start) { return new PeriodicalGenerator(start, getPeriodSecondLevel()); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/Interval.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/Interval.java index e36f0fd6b..77d50202d 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/Interval.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/Interval.java @@ -23,75 +23,89 @@ */ package org.zkoss.ganttz.util; -import java.util.Arrays; +import static java.util.Arrays.asList; + import java.util.Collections; import java.util.Date; import org.apache.commons.lang.Validate; +import org.apache.commons.lang.math.Fraction; +import org.joda.time.DateTime; +import org.joda.time.Days; +import org.joda.time.Duration; +import org.joda.time.LocalDate; public class Interval { - private final Date start; - private final Date finish; + private final Duration lengthBetween; - private final long lengthBetween; + private final Days daysBetween; + + private LocalDate startInclusive; + + private LocalDate endExclusive; public Interval(Date start, Date finish) { - if (start == null) { - throw new IllegalArgumentException("begin cannot be null"); - } - if (finish == null) { - throw new IllegalArgumentException("end cannot be null"); - } - if (start.compareTo(finish) > 0) { - throw new IllegalArgumentException("start must be prior to end"); - } - this.start = start; - this.finish = finish; - lengthBetween = this.finish.getTime() - this.start.getTime(); + this(LocalDate.fromDateFields(start), LocalDate.fromDateFields(finish)); } - public Date getStart() { - return new Date(start.getTime()); + public Interval(LocalDate startInclusive, LocalDate endExclusive) { + Validate.notNull(startInclusive); + Validate.notNull(endExclusive); + Validate.isTrue(endExclusive.isAfter(startInclusive)); + this.startInclusive = startInclusive; + this.endExclusive = endExclusive; + this.lengthBetween = new Duration( + this.startInclusive.toDateTimeAtStartOfDay(), + this.endExclusive.toDateTimeAtStartOfDay()); + this.daysBetween = Days.daysBetween(this.startInclusive, + this.endExclusive); } - public Date getFinish() { - return new Date(finish.getTime()); + public Days getDaysBetween() { + return daysBetween; } - public long getLengthBetween() { + public LocalDate getStart() { + return startInclusive; + } + + public LocalDate getFinish() { + return endExclusive; + } + + public Duration getLengthBetween() { return lengthBetween; } - public Date atProportion(double proportion) { - // comparisons with doubles are dangerous, change it - if (proportion > 1.0d) { - throw new IllegalArgumentException( - "the proportion must be less or equal than one"); - } - if (proportion < 0d) { - throw new IllegalArgumentException( - "the proportion must be bigger than cero"); - } - return new Date(start.getTime() + (int) (lengthBetween * proportion)); + public Fraction getProportion(DateTime date) { + Validate.isTrue(!date.isAfter(endExclusive.toDateTimeAtStartOfDay())); + Days fromStartToDate = Days.daysBetween(startInclusive, + date.toLocalDate()); + Fraction fraction = Fraction.getFraction(fromStartToDate.getDays(), + this.daysBetween.getDays()); + return fraction.add(inTheDayIncrement(date)); } - public double getProportion(Date date) { - if (!isIncluded(date)) { - // Negative proportions are allowed for tasks starting before - // interval so no exception raised + private Fraction inTheDayIncrement(DateTime date) { + DateTime atStartOfDay = date.toLocalDate().toDateTimeAtStartOfDay(); + Duration duration = new Duration(atStartOfDay, date); + double result = ((double) duration.getMillis()) + / lengthBetween.getMillis(); + try { + return Fraction.getFraction(result); + } catch (ArithmeticException e) { + return Fraction.ZERO; } - return ((double) date.getTime() - start.getTime()) / lengthBetween; - } - - private boolean isIncluded(Date date) { - return start.compareTo(date) <= 0 && finish.compareTo(date) >= 0; } + @SuppressWarnings("unchecked") public Interval coalesce(Interval otherInterval) { Validate.notNull(otherInterval); - return new Interval(Collections.min(Arrays.asList(start, - otherInterval.start)), Collections.max(Arrays.asList(finish, - otherInterval.finish))); + LocalDate minStart = Collections.min(asList(startInclusive, + otherInterval.startInclusive)); + LocalDate maxEnd = Collections.max(asList(endExclusive, + otherInterval.endExclusive)); + return new Interval(minStart, maxEnd); } } \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/ChartFiller.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/ChartFiller.java index d39eb060f..80f58c15c 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/ChartFiller.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/ChartFiller.java @@ -114,8 +114,8 @@ public abstract class ChartFiller implements IChartFiller { private final SortedMap map; private final LocalDate start; - protected GraphicSpecificationCreator(Date finish, - SortedMap map, Date start) { + protected GraphicSpecificationCreator(LocalDate finish, + SortedMap map, LocalDate start) { this.finish = new LocalDate(finish); this.map = map; this.start = new LocalDate(start); @@ -229,8 +229,8 @@ public abstract class ChartFiller implements IChartFiller { protected class DefaultGraphicSpecificationCreator extends GraphicSpecificationCreator { - private DefaultGraphicSpecificationCreator(Date finish, - SortedMap map, Date start) { + private DefaultGraphicSpecificationCreator(LocalDate finish, + SortedMap map, LocalDate start) { super(finish, map, start); } @@ -248,8 +248,9 @@ public abstract class ChartFiller implements IChartFiller { protected class JustDaysWithInformationGraphicSpecificationCreator extends GraphicSpecificationCreator { - public JustDaysWithInformationGraphicSpecificationCreator(Date finish, - SortedMap map, Date start) { + public JustDaysWithInformationGraphicSpecificationCreator( + LocalDate finish, SortedMap map, + LocalDate start) { super(finish, map, start); } @@ -563,7 +564,7 @@ public abstract class ChartFiller implements IChartFiller { private String getServletUri( final SortedMap mapDayAssignments, - final Date start, final Date finish, + final LocalDate start, final LocalDate finish, final GraphicSpecificationCreator graphicSpecificationCreator) { if (mapDayAssignments.isEmpty()) { return ""; diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/EarnedValueChartFiller.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/EarnedValueChartFiller.java index 6281c2fd7..92fb17c5e 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/EarnedValueChartFiller.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/chart/EarnedValueChartFiller.java @@ -112,8 +112,8 @@ public abstract class EarnedValueChartFiller extends ChartFiller { } public static boolean includes(Interval interval, LocalDate date) { - LocalDate start = LocalDate.fromDateFields(interval.getStart()); - LocalDate end = LocalDate.fromDateFields(interval.getFinish()); + LocalDate start = interval.getStart(); + LocalDate end = interval.getFinish(); return start.compareTo(date) <= 0 && date.compareTo(end) < 0; } public enum EarnedValueType { @@ -407,8 +407,8 @@ public abstract class EarnedValueChartFiller extends ChartFiller { public LocalDate initialDateForIndicatorValues() { Interval chartInterval = getIndicatorsDefinitionInterval(); LocalDate today = new LocalDate(); - return includes(chartInterval, today) ? today - : LocalDate.fromDateFields(chartInterval.getFinish()); + return includes(chartInterval, today) ? today : chartInterval + .getFinish(); } protected void addZeroBeforeTheFirstValue( SortedMap map) { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java index fa4471f10..e43802951 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java @@ -23,6 +23,7 @@ package org.navalplanner.web.planner.company; import static org.navalplanner.business.workingday.EffortDuration.min; import static org.navalplanner.business.workingday.EffortDuration.zero; import static org.navalplanner.web.I18nHelper._; +import static org.navalplanner.web.resourceload.ResourceLoadModel.asDate; import java.math.BigDecimal; import java.util.ArrayList; @@ -34,10 +35,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; -import java.util.Map.Entry; import org.joda.time.LocalDate; import org.navalplanner.business.calendars.entities.BaseCalendar; @@ -75,8 +76,8 @@ import org.navalplanner.web.planner.ITaskElementAdapter; import org.navalplanner.web.planner.chart.Chart; import org.navalplanner.web.planner.chart.ChartFiller; import org.navalplanner.web.planner.chart.EarnedValueChartFiller; -import org.navalplanner.web.planner.chart.IChartFiller; import org.navalplanner.web.planner.chart.EarnedValueChartFiller.EarnedValueType; +import org.navalplanner.web.planner.chart.IChartFiller; import org.navalplanner.web.planner.order.BankHolidaysMarker; import org.navalplanner.web.planner.order.OrderPlanningModel; import org.navalplanner.web.planner.tabs.MultipleTabsPlannerController; @@ -176,8 +177,8 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { private Scenario currentScenario; - private Date filterStartDate; - private Date filterFinishDate; + private LocalDate filterStartDate; + private LocalDate filterFinishDate; private static final EnumSet STATUS_VISUALIZED = EnumSet .of(OrderStatusEnum.ACCEPTED, OrderStatusEnum.OFFERED, OrderStatusEnum.STARTED, @@ -735,8 +736,8 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { endDate = Collections.max(notNull(endDate, each.getDeadline(), associatedTaskElement.getEndDate())); } - filterStartDate = startDate; - filterFinishDate = endDate; + filterStartDate = LocalDate.fromDateFields(startDate); + filterFinishDate = LocalDate.fromDateFields(endDate); } private static List notNull(T... values) { @@ -753,25 +754,15 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { protected abstract ITaskElementAdapter getTaskElementAdapter(); @Override - public Date getFilterStartDate() { + public LocalDate getFilterStartDate() { return filterStartDate; } - private LocalDate getFilterStartLocalDate() { - return filterStartDate != null ? - LocalDate.fromDateFields(filterStartDate) : null; - } - @Override - public Date getFilterFinishDate() { + public LocalDate getFilterFinishDate() { return filterFinishDate; } - private LocalDate getFilterFinishLocalDate() { - return filterFinishDate != null ? - LocalDate.fromDateFields(filterFinishDate) : null; - } - private class CompanyLoadChartFiller extends ChartFiller { @Override @@ -784,8 +775,9 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { resetMinimumAndMaximumValueForChart(); - Date start = filterStartDate!=null ? filterStartDate : interval.getStart(); - Date finish = filterFinishDate != null ? filterFinishDate + LocalDate start = filterStartDate != null ? filterStartDate + : interval.getStart(); + LocalDate finish = filterFinishDate != null ? filterFinishDate : interval.getFinish(); Plotinfo plotInfoLoad = createPlotinfoFromDurations( @@ -815,18 +807,18 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { chart.setHeight("150px"); } - private SortedMap getLoad(Date start, - Date finish) { + private SortedMap getLoad(LocalDate start, + LocalDate finish) { List dayAssignments = dayAssignmentDAO.getAllFor( - currentScenario, LocalDate.fromDateFields(start), LocalDate - .fromDateFields(finish)); + currentScenario, start, finish); SortedMap> durationsGrouped = groupDurationsByDayAndResource(dayAssignments); return calculateHoursAdditionByDayWithoutOverload(durationsGrouped); } - private SortedMap getOverload(Date start, - Date finish) { - List dayAssignments = dayAssignmentDAO.getAllFor(currentScenario, LocalDate.fromDateFields(start), LocalDate.fromDateFields(finish)); + private SortedMap getOverload( + LocalDate start, LocalDate finish) { + List dayAssignments = dayAssignmentDAO.getAllFor( + currentScenario, start, finish); SortedMap> dayAssignmentGrouped = groupDurationsByDayAndResource(dayAssignments); SortedMap mapDayAssignments = calculateHoursAdditionByDayJustOverload(dayAssignmentGrouped); @@ -912,13 +904,13 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { } private SortedMap getCalendarMaximumAvailability( - Date start, Date finish) { + LocalDate start, LocalDate finish) { return calculateAvailabilityDurationByDay( resourceDAO.list(Resource.class), start, finish); } private SortedMap calculateAvailabilityDurationByDay( - List resources, Date start, Date finish) { + List resources, LocalDate start, LocalDate finish) { return new EffortByDayCalculator>>() { @Override @@ -939,10 +931,9 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { } private Set>> getResourcesByDateBetween( - List resources, Date start, Date finish) { - LocalDate end = new LocalDate(finish); + List resources, LocalDate start, LocalDate finish) { Map> result = new HashMap>(); - for (LocalDate date = new LocalDate(start); date.compareTo(end) <= 0; date = date + for (LocalDate date = new LocalDate(start); date.compareTo(finish) <= 0; date = date .plusDays(1)) { result.put(date, resources); } @@ -954,15 +945,14 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { private class CompanyEarnedValueChartFiller extends EarnedValueChartFiller { protected void calculateBudgetedCostWorkScheduled(Interval interval) { - List list = taskElementDAO.listFilteredByDate(filterStartDate, filterFinishDate); + List list = taskElementDAO.listFilteredByDate(asDate(filterStartDate), asDate(filterFinishDate)); SortedMap estimatedCost = new TreeMap(); for (TaskElement taskElement : list) { if (taskElement instanceof Task) { addCost(estimatedCost, hoursCostCalculator - .getEstimatedCost((Task) taskElement, - getFilterStartLocalDate(), getFilterFinishLocalDate())); + .getEstimatedCost((Task) taskElement, filterStartDate, filterFinishDate)); } } @@ -985,7 +975,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { SortedMap result = new TreeMap(); List workReportLines = workReportLineDAO - .findFilteredByDate(filterStartDate, filterFinishDate); + .findFilteredByDate(asDate(filterStartDate), asDate(filterFinishDate)); if (workReportLines.isEmpty()) { return result; @@ -1005,7 +995,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { } protected void calculateBudgetedCostWorkPerformed(Interval interval) { - List list = taskElementDAO.listFilteredByDate(filterStartDate, filterFinishDate); + List list = taskElementDAO.listFilteredByDate(asDate(filterStartDate), asDate(filterFinishDate)); SortedMap advanceCost = new TreeMap(); @@ -1013,7 +1003,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { if (taskElement instanceof Task) { addCost(advanceCost, hoursCostCalculator .getAdvanceCost((Task) taskElement, - getFilterStartLocalDate(), getFilterFinishLocalDate())); + filterStartDate, filterFinishDate)); } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/ICompanyPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/ICompanyPlanningModel.java index 6bcfe097e..7f7e53b87 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/ICompanyPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/ICompanyPlanningModel.java @@ -21,10 +21,8 @@ package org.navalplanner.web.planner.company; import java.util.Collection; -import java.util.Date; -import java.util.List; -import org.navalplanner.business.orders.entities.Order; +import org.joda.time.LocalDate; import org.navalplanner.business.planner.entities.TaskElement; import org.navalplanner.business.templates.entities.OrderTemplate; import org.navalplanner.web.planner.tabs.MultipleTabsPlannerController; @@ -52,9 +50,9 @@ public interface ICompanyPlanningModel { public void setTabsController(MultipleTabsPlannerController tabsController); - Date getFilterStartDate(); + LocalDate getFilterStartDate(); - Date getFilterFinishDate(); + LocalDate getFilterFinishDate(); void goToCreateOtherOrderFromTemplate(OrderTemplate template); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java index 4e672ab1c..8d821ba50 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/IResourceLoadModel.java @@ -20,9 +20,9 @@ package org.navalplanner.web.resourceload; -import java.util.Date; import java.util.List; +import org.joda.time.LocalDate; import org.navalplanner.business.orders.entities.Order; import org.navalplanner.business.planner.entities.DayAssignment; import org.navalplanner.business.planner.entities.TaskElement; @@ -56,13 +56,13 @@ public interface IResourceLoadModel { void clearCriteriaToShow(); - void setInitDateFilter(Date value); + void setInitDateFilter(LocalDate value); - void setEndDateFilter(Date value); + void setEndDateFilter(LocalDate value); - Date getInitDateFilter(); + LocalDate getInitDateFilter(); - Date getEndDateFilter(); + LocalDate getEndDateFilter(); List getDayAssignments(); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java index e6c5f104f..480f2480f 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadController.java @@ -23,10 +23,10 @@ package org.navalplanner.web.resourceload; import static org.navalplanner.business.workingday.EffortDuration.min; import static org.navalplanner.business.workingday.EffortDuration.zero; import static org.navalplanner.web.I18nHelper._; +import static org.navalplanner.web.resourceload.ResourceLoadModel.asDate; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -319,22 +319,24 @@ public class ResourceLoadController implements Composer { Label label1 = new Label(_("Time filter") + ":"); Label label2 = new Label("-"); final Datebox initDate = new Datebox(); - initDate.setValue(resourceLoadModel.getInitDateFilter()); + initDate.setValue(asDate(resourceLoadModel.getInitDateFilter())); initDate.setWidth("75px"); initDate.addEventListener(Events.ON_CHANGE, new EventListener() { @Override public void onEvent(Event event) throws Exception { - resourceLoadModel.setInitDateFilter(initDate.getValue()); + resourceLoadModel.setInitDateFilter(LocalDate + .fromDateFields(initDate.getValue())); reload(currentFilterByResources); } }); final Datebox endDate = new Datebox(); - endDate.setValue(resourceLoadModel.getEndDateFilter()); + endDate.setValue(asDate(resourceLoadModel.getEndDateFilter())); endDate.setWidth("75px"); endDate.addEventListener(Events.ON_CHANGE, new EventListener() { @Override public void onEvent(Event event) throws Exception { - resourceLoadModel.setEndDateFilter(endDate.getValue()); + resourceLoadModel.setEndDateFilter(LocalDate + .fromDateFields(endDate.getValue())); reload(currentFilterByResources); } }); @@ -419,9 +421,7 @@ public class ResourceLoadController implements Composer { } private void resetAdditionalFilters() { - Date initDateValue = new Date(); - initDateValue.setDate(initDateValue.getDate() -15); - resourceLoadModel.setInitDateFilter(initDateValue); + resourceLoadModel.setInitDateFilter(new LocalDate().minusDays(1)); resourceLoadModel.setEndDateFilter(null); resourceLoadModel.setCriteriaToShow(new ArrayList()); @@ -589,8 +589,8 @@ public class ResourceLoadController implements Composer { resetMinimumAndMaximumValueForChart(); - Date start = interval.getStart(); - Date finish = interval.getFinish(); + LocalDate start = interval.getStart(); + LocalDate finish = interval.getFinish(); if ((resourceLoadModel.getInitDateFilter() != null) && (resourceLoadModel.getInitDateFilter().compareTo(start) > 0)) { start = resourceLoadModel.getInitDateFilter(); @@ -631,11 +631,8 @@ public class ResourceLoadController implements Composer { chart.setHeight("150px"); } - private SortedMap getLoad(Date start, - Date finish) { - final LocalDate startDay = new LocalDate(start); - final LocalDate finishDay = new LocalDate(finish); - + private SortedMap getLoad(LocalDate start, + LocalDate finish) { List dayAssignments = resourceLoadModel .getDayAssignments(); @@ -645,18 +642,15 @@ public class ResourceLoadController implements Composer { for (Entry each : mapDayAssignments .entrySet()) { LocalDate day = each.getKey(); - if (day.compareTo(startDay) >= 0 - && day.compareTo(finishDay) <= 0) { + if (day.compareTo(start) >= 0 && day.compareTo(finish) <= 0) { result.put(day, each.getValue()); } } return result; } - private SortedMap getOverload(Date start, - Date finish) { - final LocalDate startDay = new LocalDate(start); - final LocalDate finishDay = new LocalDate(finish); + private SortedMap getOverload( + LocalDate start, LocalDate finish) { List dayAssignments = resourceLoadModel .getDayAssignments(); @@ -668,8 +662,7 @@ public class ResourceLoadController implements Composer { .entrySet()) { LocalDate day = each.getKey(); EffortDuration overload = each.getValue(); - if (day.compareTo(startDay) >= 0 - && day.compareTo(finishDay) <= 0) { + if (day.compareTo(start) >= 0 && day.compareTo(finish) <= 0) { EffortDuration maxAvailability = mapMaxAvailability .get(day); mapDayAssignments.put(day, overload.plus(maxAvailability)); @@ -677,8 +670,7 @@ public class ResourceLoadController implements Composer { } SortedMap result = new TreeMap(); for (LocalDate day : mapDayAssignments.keySet()) { - if (day.compareTo(startDay) >= 0 - && day.compareTo(finishDay) <= 0) { + if (day.compareTo(start) >= 0 && day.compareTo(finish) <= 0) { result.put(day, mapDayAssignments.get(day)); } } @@ -731,13 +723,13 @@ public class ResourceLoadController implements Composer { } private SortedMap getCalendarMaximumAvailability( - Date start, Date finish) { + LocalDate start, LocalDate finish) { return calculateHoursAdditionByDay( resourceLoadModel.getResources(), start, finish); } private SortedMap calculateHoursAdditionByDay( - List resources, Date start, Date finish) { + List resources, LocalDate start, LocalDate finish) { return new EffortByDayCalculator>>() { @Override @@ -756,10 +748,9 @@ public class ResourceLoadController implements Composer { } private Set>> getResourcesByDateBetween( - List resources, Date start, Date finish) { - LocalDate end = new LocalDate(finish); + List resources, LocalDate start, LocalDate finish) { Map> result = new HashMap>(); - for (LocalDate date = new LocalDate(start); date.compareTo(end) <= 0; date = date + for (LocalDate date = start; date.compareTo(finish) <= 0; date = date .plusDays(1)) { result.put(date, resources); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java index 11fe02c71..8a74b02da 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resourceload/ResourceLoadModel.java @@ -125,8 +125,8 @@ public class ResourceLoadModel implements IResourceLoadModel { */ private List criteriaToShowList = new ArrayList(); - private Date initDateFilter; - private Date endDateFilter; + private LocalDate initDateFilter; + private LocalDate endDateFilter; @Autowired private IDayAssignmentDAO dayAssignmentDAO; @@ -236,8 +236,9 @@ public class ResourceLoadModel implements IResourceLoadModel { // reattaching criterions so the query returns the same criteria as // keys allCriteriaList = new ArrayList(criteriaToShowList); - return resourceAllocationDAO - .findGenericAllocationsBySomeCriterion(criteriaToShowList, initDateFilter, endDateFilter); + return resourceAllocationDAO.findGenericAllocationsBySomeCriterion( + criteriaToShowList, asDate(initDateFilter), + asDate(endDateFilter)); } Map> toReturn; if (filter()) { @@ -245,10 +246,11 @@ public class ResourceLoadModel implements IResourceLoadModel { .getAllChildrenAssociatedTaskElements()); allCriteriaList = Criterion.sortByTypeAndName(getCriterionsOn(tasks)); toReturn = resourceAllocationDAO - .findGenericAllocationsBySomeCriterion(allCriteriaList, initDateFilter, endDateFilter); + .findGenericAllocationsBySomeCriterion(allCriteriaList, + asDate(initDateFilter), asDate(endDateFilter)); } else { - toReturn = - resourceAllocationDAO.findGenericAllocationsByCriterion(initDateFilter, endDateFilter); + toReturn = resourceAllocationDAO.findGenericAllocationsByCriterion( + asDate(initDateFilter), asDate(endDateFilter)); allCriteriaList = Criterion.sortByTypeAndName(toReturn.keySet()); } if(pageFilterPosition == -1) { @@ -266,6 +268,10 @@ public class ResourceLoadModel implements IResourceLoadModel { return toReturnFiltered; } + public static Date asDate(LocalDate date) { + return date.toDateTimeAtStartOfDay().toDate(); + } + private void reattachCriteriaToShow() { for (Criterion each : criteriaToShowList) { criterionDAO.reattachUnmodifiedEntity(each); @@ -550,10 +556,9 @@ public class ResourceLoadModel implements IResourceLoadModel { private List createPeriods(Criterion criterion, List value) { if(initDateFilter != null || endDateFilter != null) { - return PeriodsBuilder - .build(LoadPeriodGenerator.onCriterion(criterion, - resourcesDAO), value, - initDateFilter, endDateFilter); + return PeriodsBuilder.build( + LoadPeriodGenerator.onCriterion(criterion, resourcesDAO), + value, asDate(initDateFilter), asDate(endDateFilter)); } return PeriodsBuilder .build(LoadPeriodGenerator.onCriterion(criterion, @@ -574,9 +579,8 @@ public class ResourceLoadModel implements IResourceLoadModel { private LoadTimeLine buildGroup(Resource resource) { List> sortedByStartDate = ResourceAllocation .sortedByStartDate(resourceAllocationDAO - .findAllocationsRelatedTo(resource, - asLocalDate(initDateFilter), - asLocalDate(endDateFilter))); + .findAllocationsRelatedTo(resource, initDateFilter, + endDateFilter)); TimeLineRole role = getCurrentTimeLineRole(resource); LoadTimeLine result = new LoadTimeLine(buildTimeLine(resource, resource .getName(), sortedByStartDate, "resource", role), @@ -585,18 +589,6 @@ public class ResourceLoadModel implements IResourceLoadModel { } - /** - * @param date - * the date to extract the {@link LocalDate} from - * @return null if date is null - */ - private static LocalDate asLocalDate(Date date) { - if (date == null) { - return null; - } - return LocalDate.fromDateFields(date); - } - private List buildSecondLevel(Resource resource, List> sortedByStartDate) { List result = new ArrayList(); @@ -767,9 +759,10 @@ public class ResourceLoadModel implements IResourceLoadModel { TimeLineRole role) { List loadPeriods; if(initDateFilter != null || endDateFilter != null) { - loadPeriods = PeriodsBuilder - .build(LoadPeriodGenerator.onResource(resource), sortedByStartDate, - initDateFilter, endDateFilter); + loadPeriods = PeriodsBuilder.build( + LoadPeriodGenerator.onResource(resource), + sortedByStartDate, asDate(initDateFilter), + asDate(endDateFilter)); } else { loadPeriods = PeriodsBuilder @@ -803,9 +796,9 @@ public class ResourceLoadModel implements IResourceLoadModel { .onResourceSatisfying(resource, criterions); List loadPeriods; if(initDateFilter != null || endDateFilter != null) { - loadPeriods = PeriodsBuilder - .build(periodGeneratorFactory, allocationsSortedByStartDate, - initDateFilter, endDateFilter); + loadPeriods = PeriodsBuilder.build(periodGeneratorFactory, + allocationsSortedByStartDate, asDate(initDateFilter), + asDate(endDateFilter)); } else { loadPeriods = PeriodsBuilder @@ -871,22 +864,22 @@ public class ResourceLoadModel implements IResourceLoadModel { } @Override - public void setEndDateFilter(Date value) { + public void setEndDateFilter(LocalDate value) { endDateFilter = value; } @Override - public void setInitDateFilter(Date value) { + public void setInitDateFilter(LocalDate value) { initDateFilter = value; } @Override - public Date getEndDateFilter() { + public LocalDate getEndDateFilter() { return endDateFilter; } @Override - public Date getInitDateFilter() { + public LocalDate getInitDateFilter() { return initDateFilter; }