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