diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java index 6321eb29d..ea299a028 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java @@ -24,11 +24,14 @@ package org.zkoss.ganttz; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; +import java.util.Date; import java.util.Map; import java.util.UUID; import org.apache.commons.lang.Validate; import org.joda.time.DateTime; +import org.joda.time.Days; +import org.joda.time.Duration; import org.joda.time.LocalDate; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.data.GanttDate; @@ -517,8 +520,34 @@ public class TaskComponent extends Div implements AfterCompose { this.task.getHoursAdvanceEndDate()) + "px"; response(null, new AuInvoke(this, "resizeCompletionAdvance", widthHoursAdvancePercentage)); + + Date firstTimesheetDate = task.getFirstTimesheetDate(); + Date lastTimesheetDate = task.getLastTimesheetDate(); + if (firstTimesheetDate != null && lastTimesheetDate != null) { + Duration firstDuration = Days.daysBetween( + task.getBeginDateAsLocalDate(), + LocalDate.fromDateFields(firstTimesheetDate)) + .toStandardDuration(); + int pixelsFirst = getMapper().toPixels(firstDuration); + String positionFirst = pixelsFirst + "px"; + + Duration lastDuration = Days + .daysBetween( + task.getBeginDateAsLocalDate(), + LocalDate.fromDateFields(lastTimesheetDate) + .plusDays(1)).toStandardDuration(); + int pixelsLast = getMapper().toPixels(lastDuration); + String positionLast = pixelsLast + "px"; + + response(null, new AuInvoke(this, "showTimsheetDateMarks", + positionFirst, positionLast)); + } else { + response(null, new AuInvoke(this, "hideTimsheetDateMarks")); + } + } else { response(null, new AuInvoke(this, "resizeCompletionAdvance", "0px")); + response(null, new AuInvoke(this, "hideTimsheetDateMarks")); } } 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 65a7c4390..d0427cb50 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/DefaultFundamentalProperties.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/DefaultFundamentalProperties.java @@ -313,4 +313,14 @@ public class DefaultFundamentalProperties implements ITaskFundamentalProperties return false; } + @Override + public Date getFirstTimesheetDate() { + return null; + } + + @Override + public Date getLastTimesheetDate() { + 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 464b1f7ee..aa32e7e16 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/ITaskFundamentalProperties.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/ITaskFundamentalProperties.java @@ -127,4 +127,8 @@ public interface ITaskFundamentalProperties { boolean isUpdatedFromTimesheets(); + Date getFirstTimesheetDate(); + + Date getLastTimesheetDate(); + } 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 0e24683f0..7da3a7fa7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java @@ -553,4 +553,14 @@ public abstract class Task implements ITaskFundamentalProperties { return fundamentalProperties.isUpdatedFromTimesheets(); } + @Override + public Date getFirstTimesheetDate() { + return fundamentalProperties.getFirstTimesheetDate(); + } + + @Override + public Date getLastTimesheetDate() { + return fundamentalProperties.getLastTimesheetDate(); + } + } diff --git a/ganttzk/src/main/resources/web/js/ganttz/TaskComponent.js b/ganttzk/src/main/resources/web/js/ganttz/TaskComponent.js index 86de72579..03e5203ab 100644 --- a/ganttzk/src/main/resources/web/js/ganttz/TaskComponent.js +++ b/ganttzk/src/main/resources/web/js/ganttz/TaskComponent.js @@ -221,6 +221,18 @@ ganttz.TaskComponent = zk.$extends(zul.Widget, { resizeCompletionAdvance : function(width){ jq('#' + this.uuid + ' .completion:first').css('width', width); }, + showTimsheetDateMarks : function(positionFirst, postionLast) { + var firstTimesheetDateMark = jq('#' + this.uuid + ' .first-timesheet-date'); + var lastTimesheetDateMark = jq('#' + this.uuid + ' .last-timesheet-date'); + firstTimesheetDateMark.css('left', positionFirst); + lastTimesheetDateMark.css('left', postionLast); + firstTimesheetDateMark.show(); + lastTimesheetDateMark.show(); + }, + hideTimsheetDateMarks : function() { + jq('#' + this.uuid + ' .first-timesheet-date').hide(); + jq('#' + this.uuid + ' .last-timesheet-date').hide(); + }, resizeCompletion2Advance : function(width){ jq('#' + this.uuid + ' .completion2:first').css('width', width); }, diff --git a/ganttzk/src/main/resources/web/js/ganttz/mold/task-component.js b/ganttzk/src/main/resources/web/js/ganttz/mold/task-component.js index 3685a791e..c4784599d 100644 --- a/ganttzk/src/main/resources/web/js/ganttz/mold/task-component.js +++ b/ganttzk/src/main/resources/web/js/ganttz/mold/task-component.js @@ -14,6 +14,8 @@ function(out){ out.push('
'); out.push('
'); out.push('
'); + out.push('
|
'); + out.push('
|
'); out.push('
', this.getTooltipText(), diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java index e3f1ae11f..57e3a1f88 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java +++ b/libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderElement.java @@ -1616,4 +1616,18 @@ public abstract class OrderElement extends IntegrationEntity implements return taskElement.isUpdatedFromTimesheets(); } + public Date getFirstTimesheetDate() { + if (sumChargedEffort == null) { + return null; + } + return sumChargedEffort.getFirstTimesheetDate(); + } + + public Date getLastTimesheetDate() { + if (sumChargedEffort == null) { + return null; + } + return sumChargedEffort.getLastTimesheetDate(); + } + } 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 e83e03ec1..3462132c2 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 @@ -1228,6 +1228,24 @@ _( return taskElement.isUpdatedFromTimesheets(); } + @Override + public Date getFirstTimesheetDate() { + OrderElement orderElement = taskElement.getOrderElement(); + if (orderElement != null) { + return orderElement.getFirstTimesheetDate(); + } + return null; + } + + @Override + public Date getLastTimesheetDate() { + OrderElement orderElement = taskElement.getOrderElement(); + if (orderElement != null) { + return orderElement.getLastTimesheetDate(); + } + return null; + } + } @Override diff --git a/libreplan-webapp/src/main/java/org/libreplan/web/planner/adaptplanning/AdaptPlanningCommand.java b/libreplan-webapp/src/main/java/org/libreplan/web/planner/adaptplanning/AdaptPlanningCommand.java index c9d688674..902bf4e19 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/web/planner/adaptplanning/AdaptPlanningCommand.java +++ b/libreplan-webapp/src/main/java/org/libreplan/web/planner/adaptplanning/AdaptPlanningCommand.java @@ -92,10 +92,9 @@ public class AdaptPlanningCommand implements IAdaptPlanningCommand { taskElement.setUpdatedFromTimesheets(false); if (orderElement.hasTimesheetsReportingHours()) { - setStartDateAndConstraint(taskElement, orderElement - .getSumChargedEffort().getFirstTimesheetDate()); - Date lastTimesheetDate = orderElement.getSumChargedEffort() - .getLastTimesheetDate(); + setStartDateAndConstraint(taskElement, + orderElement.getFirstTimesheetDate()); + Date lastTimesheetDate = orderElement.getLastTimesheetDate(); setEndDateIfNeeded(taskElement, lastTimesheetDate); if (orderElement.isFinishedTimesheets()) { diff --git a/libreplan-webapp/src/main/webapp/planner/css/ganttzk.css b/libreplan-webapp/src/main/webapp/planner/css/ganttzk.css index ff27669f8..a9aa526b4 100644 --- a/libreplan-webapp/src/main/webapp/planner/css/ganttzk.css +++ b/libreplan-webapp/src/main/webapp/planner/css/ganttzk.css @@ -274,6 +274,24 @@ div.box.limiting-unassigned { margin-top: 1px; } +.timesheet-date-mark { + color: #F21CFF; + font-size: 8px; + font-weight: bold; + /* By default marks are hidden */ + display: none; +} + +.first-timesheet-date { + position: absolute; + margin-top: -19px; +} + +.last-timesheet-date { + position: absolute; + margin-top: -19px; +} + .completion2 { width: 0%; height: 6px;