From 872520dac2afa649276d76f29feba3ce45239a8e Mon Sep 17 00:00:00 2001 From: Manuel Rego Casasnovas Date: Mon, 19 Nov 2012 13:57:20 +0100 Subject: [PATCH] Calculate progress and hours bars always proportionally to task size Both bars will work like the money cost bar was already working. The change is done due to the problem that appears when you adapt the planning, and some planning remains before the start of the task. In that cases the bars were not being printed properly. Moreover current implementation was quite complex, and even if it gives some useful information in specific cases, it also causes some misunderstandings to the users. FEA: ItEr77S12AdaptPlanningAccordingTimesheets --- .../java/org/zkoss/ganttz/TaskComponent.java | 6 +- .../data/DefaultFundamentalProperties.java | 8 +- .../data/ITaskFundamentalProperties.java | 8 +- .../main/java/org/zkoss/ganttz/data/Task.java | 16 +- .../web/planner/TaskElementAdapter.java | 202 ++---------------- 5 files changed, 31 insertions(+), 209 deletions(-) diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java index c6cc9e8e6..4d981cb27 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java @@ -520,7 +520,7 @@ public class TaskComponent extends Div implements AfterCompose { int startPixels = this.task.getBeginDate().toPixels(getMapper()); String widthHoursAdvancePercentage = pixelsFromStartUntil( startPixels, - this.task.getHoursAdvanceEndDate()) + "px"; + this.task.getHoursAdvanceBarEndDate()) + "px"; response(null, new AuInvoke(this, "resizeCompletionAdvance", widthHoursAdvancePercentage)); @@ -573,7 +573,7 @@ public class TaskComponent extends Div implements AfterCompose { if (task.isShowingAdvances()) { int startPixels = this.task.getBeginDate().toPixels(getMapper()); String widthAdvancePercentage = pixelsFromStartUntil(startPixels, - this.task.getAdvanceEndDate()) + "px"; + this.task.getAdvanceBarEndDate()) + "px"; response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage)); } else { @@ -587,7 +587,7 @@ public class TaskComponent extends Div implements AfterCompose { int startPixels = this.task.getBeginDate().toPixels(getMapper()); String widthAdvancePercentage = pixelsFromStartUntil(startPixels, - this.task.getAdvanceEndDate(progressType)) + "px"; + this.task.getAdvanceBarEndDate(progressType)) + "px"; response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage)); } else { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/DefaultFundamentalProperties.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/DefaultFundamentalProperties.java index d0427cb50..68387ac79 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/DefaultFundamentalProperties.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/DefaultFundamentalProperties.java @@ -174,7 +174,7 @@ public class DefaultFundamentalProperties implements ITaskFundamentalProperties } @Override - public GanttDate getHoursAdvanceEndDate() { + public GanttDate getHoursAdvanceBarEndDate() { return GanttDate.createFrom(new Date(hoursAdvanceEndDate)); } @@ -189,13 +189,13 @@ public class DefaultFundamentalProperties implements ITaskFundamentalProperties } @Override - public GanttDate getAdvanceEndDate() { + public GanttDate getAdvanceBarEndDate() { return advanceEndDate != null ? GanttDate.createFrom(new Date( advanceEndDate.getTime())) : null; } @Override - public BigDecimal getHoursAdvancePercentage() { + public BigDecimal getHoursAdvanceBarPercentage() { return hoursAdvancePercentage; } @@ -284,7 +284,7 @@ public class DefaultFundamentalProperties implements ITaskFundamentalProperties } @Override - public GanttDate getAdvanceEndDate(String progressType) { + public GanttDate getAdvanceBarEndDate(String progressType) { return null; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/ITaskFundamentalProperties.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/ITaskFundamentalProperties.java index aa32e7e16..461366b35 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/ITaskFundamentalProperties.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/ITaskFundamentalProperties.java @@ -75,15 +75,15 @@ public interface ITaskFundamentalProperties { public void setNotes(String notes); - public GanttDate getHoursAdvanceEndDate(); + public GanttDate getHoursAdvanceBarEndDate(); public GanttDate getMoneyCostBarEndDate(); BigDecimal getMoneyCostBarPercentage(); - public GanttDate getAdvanceEndDate(); + public GanttDate getAdvanceBarEndDate(); - public BigDecimal getHoursAdvancePercentage(); + public BigDecimal getHoursAdvanceBarPercentage(); public BigDecimal getAdvancePercentage(); @@ -115,7 +115,7 @@ public interface ITaskFundamentalProperties { public List> getCurrentLengthConstraint(); - public GanttDate getAdvanceEndDate(String progressType); + public GanttDate getAdvanceBarEndDate(String progressType); String updateTooltipText(String progressType); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java index fcb215e11..911362273 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java @@ -384,8 +384,8 @@ public abstract class Task implements ITaskFundamentalProperties { } @Override - public BigDecimal getHoursAdvancePercentage() { - return fundamentalProperties.getHoursAdvancePercentage(); + public BigDecimal getHoursAdvanceBarPercentage() { + return fundamentalProperties.getHoursAdvanceBarPercentage(); } @Override @@ -394,8 +394,8 @@ public abstract class Task implements ITaskFundamentalProperties { } @Override - public GanttDate getHoursAdvanceEndDate() { - return fundamentalProperties.getHoursAdvanceEndDate(); + public GanttDate getHoursAdvanceBarEndDate() { + return fundamentalProperties.getHoursAdvanceBarEndDate(); } @Override @@ -409,12 +409,12 @@ public abstract class Task implements ITaskFundamentalProperties { } @Override - public GanttDate getAdvanceEndDate() { - return fundamentalProperties.getAdvanceEndDate(); + public GanttDate getAdvanceBarEndDate() { + return fundamentalProperties.getAdvanceBarEndDate(); } - public GanttDate getAdvanceEndDate(String progressType) { - return fundamentalProperties.getAdvanceEndDate(progressType); + public GanttDate getAdvanceBarEndDate(String progressType) { + return fundamentalProperties.getAdvanceBarEndDate(progressType); } public String getTooltipText() { diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java index 4c7ff4345..9c5a003f3 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/TaskElementAdapter.java @@ -21,10 +21,6 @@ package org.libreplan.web.planner; -import static org.libreplan.business.workingday.EffortDuration.fromHoursAsBigDecimal; -import static org.libreplan.business.workingday.EffortDuration.min; -import static org.libreplan.business.workingday.EffortDuration.seconds; -import static org.libreplan.business.workingday.EffortDuration.zero; import static org.libreplan.web.I18nHelper._; import static org.zkoss.ganttz.data.constraint.ConstraintOnComparableValues.biggerOrEqualThan; import static org.zkoss.ganttz.data.constraint.ConstraintOnComparableValues.equalTo; @@ -39,8 +35,6 @@ import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import org.apache.commons.lang.StringUtils; @@ -86,7 +80,6 @@ import org.libreplan.business.resources.entities.Criterion; import org.libreplan.business.resources.entities.Resource; import org.libreplan.business.scenarios.entities.Scenario; import org.libreplan.business.workingday.EffortDuration; -import org.libreplan.business.workingday.EffortDuration.IEffortFrom; import org.libreplan.business.workingday.IntraDayDate; import org.libreplan.business.workingday.IntraDayDate.PartialDay; import org.libreplan.web.common.Util; @@ -552,43 +545,12 @@ public class TaskElementAdapter { } @Override - public GanttDate getHoursAdvanceEndDate() { - OrderElement orderElement = taskElement.getOrderElement(); - - EffortDuration assignedEffort = EffortDuration.zero(); - if (orderElement.getSumChargedEffort() != null) { - assignedEffort = orderElement.getSumChargedEffort() - .getTotalChargedEffort(); - } - - GanttDate result = null; - if (!(taskElement instanceof TaskGroup)) { - result = calculateLimitDateByHours(assignedEffort - .toHoursAsDecimalWithScale(2)); - } - - if (result == null) { - EffortDuration effort = taskElement.getSumOfAssignedEffort(); - - if (effort.isZero()) { - effort = EffortDuration.hours(orderElement.getWorkHours()); - if (effort.isZero()) { - return getBeginDate(); - } - } - BigDecimal percentage = new BigDecimal(assignedEffort - .divivedBy(effort).doubleValue()).setScale(2, - RoundingMode.HALF_UP); - - result = calculateLimitDateByPercentage(percentage); - - } - - return result; + public GanttDate getHoursAdvanceBarEndDate() { + return calculateLimitDateProportionalToTaskElementSize(getHoursAdvanceBarPercentage()); } @Override - public BigDecimal getHoursAdvancePercentage() { + public BigDecimal getHoursAdvanceBarPercentage() { OrderElement orderElement = taskElement.getOrderElement(); if (orderElement == null) { return BigDecimal.ZERO; @@ -694,22 +656,22 @@ public class TaskElementAdapter { } @Override - public GanttDate getAdvanceEndDate(String progressType) { - return getAdvanceEndDate(ProgressType.asEnum(progressType)); + public GanttDate getAdvanceBarEndDate(String progressType) { + return getAdvanceBarEndDate(ProgressType.asEnum(progressType)); } - private GanttDate getAdvanceEndDate(ProgressType progressType) { + private GanttDate getAdvanceBarEndDate(ProgressType progressType) { BigDecimal advancePercentage = BigDecimal.ZERO; if (taskElement.getOrderElement() != null) { advancePercentage = taskElement .getAdvancePercentage(progressType); } - return getAdvanceEndDate(advancePercentage); + return getAdvanceBarEndDate(advancePercentage); } @Override - public GanttDate getAdvanceEndDate() { - return getAdvanceEndDate(getAdvancePercentage()); + public GanttDate getAdvanceBarEndDate() { + return getAdvanceBarEndDate(getAdvancePercentage()); } private boolean isTaskRoot(TaskElement taskElement) { @@ -728,148 +690,8 @@ public class TaskElementAdapter { }); } - private GanttDate getAdvanceEndDate(BigDecimal advancePercentage) { - if (advancePercentage.compareTo(BigDecimal.ONE) == 0) { - return getEndDate(); - } - - BigDecimal hours = BigDecimal.ZERO; - - if (taskElement instanceof TaskGroup) { - //progess calculation for TaskGroups is done with - //this method, which is much lighter - return calculateLimitDateByPercentage(advancePercentage); - } - - if (taskElement.getOrderElement() != null) { - hours = taskElement.getSumOfAssignedEffort() - .toHoursAsDecimalWithScale(2); - } - - // Calculate date according to advanceHours or advancePercentage - final BigDecimal advanceHours = advancePercentage - .multiply(hours); - GanttDate result = calculateLimitDateByHours(advanceHours); - if (result == null) { - result = calculateLimitDateByPercentage(advancePercentage); - - } else { - GanttDate endDate = toGantt(taskElement.getIntraDayEndDate()); - if (result.compareTo(endDate) > 0) { - //don't allow progress bars wider than the task itself - result = endDate; - } - } - return result; - } - - private GanttDate calculateLimitDateByPercentage(BigDecimal advancePercentage) { - BaseCalendar calendar = taskElement.getCalendar(); - if (advancePercentage.compareTo(BigDecimal.ZERO) == 0 - || calendar == null) { - return getBeginDate(); - } - IntraDayDate start = taskElement.getIntraDayStartDate(); - IntraDayDate end = taskElement.getIntraDayEndDate(); - int daysBetween = start.numberOfDaysUntil(end); - if (daysBetween == 0) { - return calculateLimitDateWhenDaysBetweenAreZero(advancePercentage); - } - BigDecimal daysAdvance = advancePercentage - .multiply(new BigDecimal(daysBetween)); - int days = daysAdvance.intValue(); - - LocalDate advanceDate = taskElement.getStartAsLocalDate() - .plusDays(days); - EffortDuration capacity = calendar.getCapacityOn(PartialDay - .wholeDay(advanceDate)); - - int seconds = daysAdvance.subtract(new BigDecimal(days)) - .multiply(new BigDecimal(capacity.getSeconds())) - .intValue(); - - return toGantt(IntraDayDate.create(advanceDate, - EffortDuration.seconds(seconds))); - } - - private GanttDate calculateLimitDateWhenDaysBetweenAreZero( - BigDecimal advancePercentage) { - IntraDayDate start = taskElement.getIntraDayStartDate(); - IntraDayDate end = taskElement.getIntraDayEndDate(); - final BaseCalendar calendar = taskElement.getCalendar(); - Iterable daysUntil = start.daysUntil(end); - - EffortDuration total = EffortDuration.sum(daysUntil, - new IEffortFrom() { - @Override - public EffortDuration from(PartialDay each) { - return calendar.getCapacityOn(each); - } - }); - - BigDecimal totalAsSeconds = new BigDecimal(total.getSeconds()); - EffortDuration advanceLeft = seconds(advancePercentage - .multiply(totalAsSeconds).intValue()); - for (PartialDay each : daysUntil) { - if (advanceLeft.compareTo(calendar.getCapacityOn(each)) <= 0) { - LocalDate dayDate = each.getStart().getDate(); - if (dayDate.equals(start.getDate())) { - return toGantt(IntraDayDate - .create(dayDate, advanceLeft.plus(start - .getEffortDuration()))); - } - return toGantt(IntraDayDate - .create(dayDate, advanceLeft)); - } - advanceLeft = advanceLeft.minus(calendar - .getCapacityOn(each)); - } - return toGantt(end); - } - - private GanttDate calculateLimitDateByHours(BigDecimal hours) { - if (hours == null || hours.compareTo(BigDecimal.ZERO) == 0) { - return null; - } - EffortDuration hoursLeft = fromHoursAsBigDecimal(hours); - IntraDayDate result = null; - EffortDuration effortLastDayNotZero = zero(); - - Map daysMap = taskElement - .getDurationsAssignedByDay(); - if (daysMap.isEmpty()) { - return null; - } - for (Entry entry : daysMap - .entrySet()) { - if (!entry.getValue().isZero()) { - effortLastDayNotZero = entry.getValue(); - } - EffortDuration decrement = min(entry.getValue(), hoursLeft); - hoursLeft = hoursLeft.minus(decrement); - if (hoursLeft.isZero()) { - result = IntraDayDate.create(entry.getKey(), - decrement); - break; - } else { - result = IntraDayDate.startOfDay(entry.getKey() - .plusDays(1)); - } - } - if (!hoursLeft.isZero() && effortLastDayNotZero.isZero()) { - LOG.warn("limit not reached and no day with effort not zero"); - } - if (!hoursLeft.isZero() && !effortLastDayNotZero.isZero()) { - while (!hoursLeft.isZero()) { - hoursLeft = hoursLeft.minus(min(effortLastDayNotZero, - hoursLeft)); - result = result.nextDayAtStart(); - } - } - if (result == null) { - return null; - } - return toGantt(result); + private GanttDate getAdvanceBarEndDate(BigDecimal advancePercentage) { + return calculateLimitDateProportionalToTaskElementSize(advancePercentage); } @Override @@ -1057,7 +879,7 @@ public class TaskElementAdapter { .append("% , "); result.append(_("Hours invested") + ": ") - .append(getHoursAdvancePercentage().multiply( + .append(getHoursAdvanceBarPercentage().multiply( new BigDecimal(100))).append("%
"); if (taskElement.getOrderElement() instanceof Order) {