diff --git a/doc/src/user/en/15-1-report-hours-worked-by-resource.rst b/doc/src/user/en/15-1-report-hours-worked-by-resource.rst index ec030c766..690e97acb 100644 --- a/doc/src/user/en/15-1-report-hours-worked-by-resource.rst +++ b/doc/src/user/en/15-1-report-hours-worked-by-resource.rst @@ -8,22 +8,22 @@ Purpose This report allows to extract a list of the tasks and time devoted to them by workers in a period of time. There are several filters which allow users to adjust the query to get just the wanted information and avoiding extra data. -Input paratemers and filters +Input parameters and filters ============================ * **Dates**. * *Type*: Optional. * *Two date fields*: - * *Start Date.* This is the minimum date of the work reports which are wanted. Work reports with an earlier date than the *start date* are ignored. If this parameter is not filled, there is not inferior filtering date. - * *End Date.* This is the maximum date of the work reports which will be included in the results. Work reports with a later date than the *end date* will be skipped. If this parameter is not filled, there is not upper limit of the work reports filtered. + * *Start Date.* This is the minimum date of the work reports which are wanted. Work reports with an earlier date than the *start date* are ignored. If this parameter is not filled, there is no filtering of work reports by *start date*. + * *End Date.* This is the maximum date of the work reports which will be included in the results. Work reports with a later date than the *end date* will be ignored. If this parameter is not filled, there is no filtering of work reports by *end date*. * **Filter by workers** * *Type*: Optional. - * *How it works*: You can select one worker to restrict the work reports to the time tracking of that particular worker. If you leave it empty, the work reports are retrieved independently of the worker. + * *How it works*: You can select one or several workers to restrict the work reports to the time tracking of that particular worker. You can add a worker to be used as a filter by searching them in the selector and by pressing the *Add* button. If you leave it empty, the work reports are retrieved independently of the worker. * **Filter by labels** * *Type:* Optional. - * *How it works*: You can add one or several labels by searching them in the selector and by pressing the *Add* button to be used as filter. They are used to select the tasks that will be included in the results to compute the hours devoted in them. + * *How it works*: You can add one or several labels to be used as filter by searching them in the selector and by pressing the *Add* button. They are used to select the tasks that will be included in the results to compute the hours devoted in them. This filter can be applied to timesheets, tasks, both, or any. * **Filter by criteria** * *Type:* Optional. @@ -39,7 +39,7 @@ In the heading of the report is informed about the filters that were configured Foot page --------- -The date in which the repot was got is showed. +The date on which the report was run is listed. Body ---- diff --git a/doc/src/user/en/17-project-dashboard.rst b/doc/src/user/en/17-1-project-dashboard.rst similarity index 98% rename from doc/src/user/en/17-project-dashboard.rst rename to doc/src/user/en/17-1-project-dashboard.rst index 950d78e2f..4e26e6cf9 100644 --- a/doc/src/user/en/17-project-dashboard.rst +++ b/doc/src/user/en/17-1-project-dashboard.rst @@ -30,6 +30,8 @@ The progress is represented with two bars: * *Expected progress*. It is the progress the project should have at the moment according to the planning created. +To view each bar's actual measured valued hover the mouse cursor over the bar. + The project global progress is estimated in several different ways as there is not a unique right method to do it: @@ -79,7 +81,6 @@ There are several *Earned Value Management* cost indicators calculated: * = 100 is also good, means the cost is right on plan. * < 100 is bad, means that the cost of completing the work is higher than planned. - * **ETC (Estimate To Complete)**. It is the time that is pending to devote to the project to finish it. * **BAC (Budget At Completion)**. It is the total amount of work allocated diff --git a/doc/src/user/en/17-2-pipeline-dashboard.rst b/doc/src/user/en/17-2-pipeline-dashboard.rst new file mode 100644 index 000000000..34a3af1bb --- /dev/null +++ b/doc/src/user/en/17-2-pipeline-dashboard.rst @@ -0,0 +1,24 @@ +Pipeline planning dashboard +############################### + +.. contents:: + +The pipeline planning dashboard is a *LibrePlan* perspective which lists the names of all company projects in a table. +This 'pipeline' table has nine columns each corresponding to a project status: + + * PRE-SALES + * OFFERED + * OUTSOURCED + * ACCEPTED + * STARTED + * ON HOLD + * FINISHED + * CANCELLED + * ARCHIVED + +Projects are listed by name in each column based on their current status. + +A project's start date, end date, and current progress can be viewed in a 'tool tip' popup by hovering the mouse pointer +over a project's name. + +Projects with an *ARCHIVED* status can be hidden by unchecking the 'Show archived column data' checkbox. \ No newline at end of file diff --git a/doc/src/user/en/17-dashboards.rst b/doc/src/user/en/17-dashboards.rst new file mode 100644 index 000000000..3c09d420d --- /dev/null +++ b/doc/src/user/en/17-dashboards.rst @@ -0,0 +1,19 @@ +Dashboards +########## + +.. _informes: +.. contents:: + + +"LibrePlan" has dashboard views for projects that provide an overview of the current state of projects. + +The two dashboard views are: + +.. raw:: html + + diff --git a/doc/src/user/en/parts b/doc/src/user/en/parts index 760539e57..8fec6673f 100644 --- a/doc/src/user/en/parts +++ b/doc/src/user/en/parts @@ -25,7 +25,8 @@ 14-custos Xavier Castaño (xcastanho@igalia.com) 15-informes Xavier Castaño (xcastanho@igalia.com) 16-ldap-authentication Ignacio Diaz Teijido (ignacio.diaz@cafedered.com), Javier Moran Rua (jmoran@igalia.com) -17-project-dashboard Javier Moran Rua (jmoran@igalia.com) +17-dashboards Javier Moran Rua (jmoran@igalia.com) 18-connectors Miciele Ghiorghis (m.ghiorghis@antoniusziekenhuis.nl) 19-scheduler Miciele Ghiorghis (m.ghiorghis@antoniusziekenhuis.nl) 20-acerca-de Xavier Castaño (xcastanho@igalia.com) +21-communications Xavier Castaño (xcastanho@igalia.com) diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java index 23e74d03d..6d3622ad0 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java @@ -243,6 +243,8 @@ public class FunctionalityExposedForExtensions implements IContext { result.setShowingReportedHours(planner.showReportedHoursRightNow()); result.setShowingMoneyCostBar(planner.showMoneyCostBarRightNow()); result.setShowingAdvances(planner.showAdvancesRightNow()); + result.setShowingLabels(planner.showLabelsRightNow()); + result.setShowingResources(planner.showResourcesRightNow()); mapper.register(position, result, data); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java index 568d08154..1cc579285 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java @@ -156,6 +156,10 @@ public class Planner extends HtmlMacroComponent { private boolean shownMoneyCostBarByDefault = false; + private boolean shownLabelsByDefault = false; + + private boolean shownResourcesByDefault = false; + private FilterAndParentExpandedPredicates predicate; private boolean visibleChart; @@ -430,6 +434,27 @@ public class Planner extends HtmlMacroComponent { showMoneyCostBarButton.setVisible(false); } + // view buttons toggle state so set all off prior to toggling + if ( configuration.isShowResourcesOn() ) { + showAllResources(); + } + + if ( configuration.isShowAdvancesOn() ) { + showAdvances(); + } + + if ( configuration.isShowReportedHoursOn() ) { + showReportedHours(); + } + + if ( configuration.isShowLabelsOn() ) { + showAllLabels(); + } + + if ( configuration.isShowMoneyCostBarOn() ) { + showMoneyCostBar(); + } + listZoomLevels.setSelectedIndex(getZoomLevel().ordinal()); this.visibleChart = configuration.isExpandPlanningViewCharts(); @@ -656,7 +681,6 @@ public class Planner extends HtmlMacroComponent { public void showReportedHours() { Button showReportedHoursButton = (Button) getFellow("showReportedHours"); if ( disabilityConfiguration.isReportedHoursEnabled() ) { - if ( isShowingReportedHours ) { context.hideReportedHours(); diagramGraph.removePostGraphChangeListener(showReportedHoursOnChange); @@ -694,28 +718,33 @@ public class Planner extends HtmlMacroComponent { public void showAllLabels() { Button showAllLabelsButton = (Button) getFellow("showAllLabels"); - if ( isShowingLabels ) { - Clients.evalJavaScript("ganttz.TaskList.getInstance().hideAllTaskLabels()"); - showAllLabelsButton.setSclass("planner-command show-labels"); - } else { - Clients.evalJavaScript("ganttz.TaskList.getInstance().showAllTaskLabels()"); - showAllLabelsButton.setSclass("planner-command show-labels clicked"); - } + if ( disabilityConfiguration.isLabelsEnabled() ) { + if ( isShowingLabels ) { + Clients.evalJavaScript("ganttz.TaskList.getInstance().hideAllTaskLabels()"); + showAllLabelsButton.setSclass("planner-command show-labels"); + } else { + Clients.evalJavaScript("ganttz.TaskList.getInstance().showAllTaskLabels()"); + showAllLabelsButton.setSclass("planner-command show-labels clicked"); + } - isShowingLabels = !isShowingLabels; + isShowingLabels = !isShowingLabels; + } } public void showAllResources() { Button showAllLabelsButton = (Button) getFellow("showAllResources"); - if ( isShowingResources ) { - Clients.evalJavaScript("ganttz.TaskList.getInstance().hideResourceTooltips()"); - showAllLabelsButton.setSclass("planner-command show-resources"); - } else { - Clients.evalJavaScript("ganttz.TaskList.getInstance().showResourceTooltips()"); - showAllLabelsButton.setSclass("planner-command show-resources clicked"); - } + if ( disabilityConfiguration.isResourcesEnabled() ) { + if ( isShowingResources ) { + Clients.evalJavaScript("ganttz.TaskList.getInstance().hideResourceTooltips()"); + showAllLabelsButton.setSclass("planner-command show-resources"); + } else { + Clients.evalJavaScript("ganttz.TaskList.getInstance().showResourceTooltips()"); + showAllLabelsButton.setSclass("planner-command show-resources clicked"); + } - isShowingResources = !isShowingResources; + isShowingResources = !isShowingResources; + + } } public void print() { @@ -752,7 +781,6 @@ public class Planner extends HtmlMacroComponent { public void setAreShownAdvancesByDefault(boolean shownAdvanceByDefault) { this.shownAdvanceByDefault = shownAdvanceByDefault; - this.isShowingAdvances = shownAdvanceByDefault; } public void setAreShownReportedHoursByDefault(boolean shownReportedHoursByDefault) { @@ -779,6 +807,30 @@ public class Planner extends HtmlMacroComponent { return areShownMoneyCostBarByDefault() || isShowingMoneyCostBar; } + public void setAreShownLabelsByDefault(boolean shownLabelsByDefault) { + this.shownLabelsByDefault = shownLabelsByDefault; + } + + public boolean areShownLabelsByDefault() { + return shownLabelsByDefault; + } + + public boolean showLabelsRightNow() { + return areShownLabelsByDefault() || isShowingLabels; + } + + public void setAreShownResourcesByDefault(boolean shownResourcesByDefault) { + this.shownResourcesByDefault = shownResourcesByDefault; + } + + public boolean areShownResourcesByDefault() { + return shownResourcesByDefault; + } + + public boolean showResourcesRightNow() { + return areShownResourcesByDefault() || isShowingResources; + } + public void expandAll() { Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON); if ( disabilityConfiguration.isExpandAllEnabled() ) { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/IDisabilityConfiguration.java b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/IDisabilityConfiguration.java index 6f5b50b38..19a28ee5e 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/IDisabilityConfiguration.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/IDisabilityConfiguration.java @@ -42,6 +42,10 @@ public interface IDisabilityConfiguration { public boolean isMoneyCostBarEnabled(); + public boolean isLabelsEnabled(); + + public boolean isResourcesEnabled(); + public boolean isExpandAllEnabled(); public boolean isFlattenTreeEnabled(); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java index e13f5bb88..e7464bd36 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java @@ -157,6 +157,10 @@ public class PlannerConfiguration implements IDisabilityConfiguration { private boolean moneyCostBarEnabled = true; + private boolean labelsEnabled = true; + + private boolean ResourcesEnabled = true; + private boolean expandAllEnabled = true; private boolean flattenTreeEnabled = true; @@ -167,6 +171,18 @@ public class PlannerConfiguration implements IDisabilityConfiguration { private boolean treeEditable = true; + private boolean showResourcesOn = false; + + private boolean showAdvancesOn = false; + + private boolean showReportedHoursOn = false; + + private boolean showLabelsOn = false; + + private boolean showMoneyCostBarOn = false; + + private boolean filterExcludeFinishedProject = false; + private IDetailItemModifier firstLevelModifiers = SeveralModifiers.empty(); private IDetailItemModifier secondLevelModifiers = SeveralModifiers.empty(); @@ -355,6 +371,24 @@ public class PlannerConfiguration implements IDisabilityConfiguration { return moneyCostBarEnabled; } + public void setLabelsEnabled(boolean labelsEnabled) { + this.labelsEnabled = labelsEnabled; + } + + @Override + public boolean isLabelsEnabled() { + return labelsEnabled; + } + + public void setResourcesEnabled(boolean ResourcesEnabled) { + this.ResourcesEnabled = ResourcesEnabled; + } + + @Override + public boolean isResourcesEnabled() { + return ResourcesEnabled; + } + public void setExpandAllEnabled(boolean expandAllEnabled) { this.expandAllEnabled = expandAllEnabled; } @@ -495,4 +529,52 @@ public class PlannerConfiguration implements IDisabilityConfiguration { this.scheduleBackwards = scheduleBackwards; } + public boolean isShowResourcesOn() { + return showResourcesOn; + } + + public void setShowResourcesOn(boolean showResourcesOn) { + this.showResourcesOn = showResourcesOn; + } + + public boolean isShowAdvancesOn() { + return showAdvancesOn; + } + + public void setShowAdvancesOn(boolean showAdvancesOn) { + this.showAdvancesOn = showAdvancesOn; + } + + public boolean isShowReportedHoursOn() { + return showReportedHoursOn; + } + + public void setShowReportedHoursOn(boolean showReportedHoursOn) { + this.showReportedHoursOn = showReportedHoursOn; + } + + public boolean isShowLabelsOn() { + return showLabelsOn; + } + + public void setShowLabelsOn(boolean showLabelsOn) { + this.showLabelsOn = showLabelsOn; + } + + public boolean isShowMoneyCostBarOn() { + return showMoneyCostBarOn; + } + + public void setShowMoneyCostBarOn(boolean showMoneyCostBarOn) { + this.showMoneyCostBarOn = showMoneyCostBarOn; + } + + public boolean isFilterExcludeFinishedProject() { + return filterExcludeFinishedProject; + } + + public void setFilterExcludeFinishedProject(boolean filterExcludeFinishedProject) { + this.filterExcludeFinishedProject = filterExcludeFinishedProject; + } + } 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 086156365..3c9a370ef 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java @@ -73,6 +73,10 @@ public abstract class Task implements ITaskFundamentalProperties { private PropertyChangeSupport moneyCostBarProperty = new PropertyChangeSupport(this); + private PropertyChangeSupport labelsProperty = new PropertyChangeSupport(this); + + private PropertyChangeSupport resourcesProperty = new PropertyChangeSupport(this); + private final ITaskFundamentalProperties fundamentalProperties; private boolean visible = true; @@ -85,6 +89,10 @@ public abstract class Task implements ITaskFundamentalProperties { private boolean showingMoneyCostBar = false; + private boolean showingLabels = false; + + private boolean showingResources = false; + private ConstraintViolationNotificator violationNotificator = ConstraintViolationNotificator.create(); private IDependenciesEnforcerHook dependenciesEnforcerHook = GanttDiagramGraph.doNothingHook(); @@ -231,6 +239,26 @@ public abstract class Task implements ITaskFundamentalProperties { return showingMoneyCostBar; } + public void setShowingResources(boolean showingResources) { + boolean previousValue = this.showingResources; + this.showingResources = showingResources; + resourcesProperty.firePropertyChange("showingResources", previousValue, this.showingResources); + } + + public boolean isShowingResources() { + return showingResources; + } + + public void setShowingLabels(boolean showingLabels) { + boolean previousValue = this.showingLabels; + this.showingLabels = showingLabels; + labelsProperty.firePropertyChange("showingLabels", previousValue, this.showingLabels); + } + + public boolean isShowingLabels() { + return showingLabels; + } + public String getName() { return fundamentalProperties.getName(); } diff --git a/libreplan-business/src/main/java/org/libreplan/business/common/AdHocTransactionService.java b/libreplan-business/src/main/java/org/libreplan/business/common/AdHocTransactionService.java index d33a40507..f4cee5e70 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/common/AdHocTransactionService.java +++ b/libreplan-business/src/main/java/org/libreplan/business/common/AdHocTransactionService.java @@ -103,6 +103,7 @@ public class AdHocTransactionService implements IAdHocTransactionService { }; } + @Override @Transactional public T runOnTransaction(IOnTransaction onTransaction) { return onTransaction.execute(); diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java index 109ef16bb..b114159f3 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/email/daos/EmailNotificationDAO.java @@ -23,8 +23,12 @@ import org.hibernate.criterion.Restrictions; import org.libreplan.business.common.daos.GenericDAOHibernate; import org.libreplan.business.email.entities.EmailNotification; import org.libreplan.business.email.entities.EmailTemplateEnum; +import org.libreplan.business.orders.entities.Order; +import org.libreplan.business.planner.entities.TaskElement; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +//import java.util.ArrayList; import java.util.List; /** @@ -50,6 +54,22 @@ public class EmailNotificationDAO .list(); } + @Override + public List getAllByProject(TaskElement taskElement) { + return getSession() + .createCriteria(EmailNotification.class) + .add(Restrictions.eq("project", taskElement)) + .list(); + } + + @Override + public List getAllByTask(TaskElement taskElement) { + return getSession() + .createCriteria(EmailNotification.class) + .add(Restrictions.eq("task", taskElement)) + .list(); + } + @Override public boolean deleteAll() { List notifications = list(EmailNotification.class); @@ -89,4 +109,26 @@ public class EmailNotificationDAO .uniqueResult() == null; } + @Override + public boolean deleteByProject(TaskElement taskElement) { + List notifications = getAllByProject(taskElement); + + for (Object item : notifications){ + getSession().delete(item); + } + + return getAllByProject(taskElement).isEmpty(); + } + + @Override + public boolean deleteByTask(TaskElement taskElement) { + List notifications = getAllByTask(taskElement); + + for (Object item : notifications){ + getSession().delete(item); + } + + return getAllByTask(taskElement).isEmpty(); + } + } diff --git a/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailNotificationDAO.java b/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailNotificationDAO.java index 92a32c886..881e7ff4e 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailNotificationDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/email/daos/IEmailNotificationDAO.java @@ -22,6 +22,8 @@ package org.libreplan.business.email.daos; import org.libreplan.business.common.daos.IGenericDAO; import org.libreplan.business.email.entities.EmailNotification; import org.libreplan.business.email.entities.EmailTemplateEnum; +import org.libreplan.business.orders.entities.Order; +import org.libreplan.business.planner.entities.TaskElement; import java.util.List; @@ -36,9 +38,18 @@ public interface IEmailNotificationDAO extends IGenericDAO getAllByType(EmailTemplateEnum enumeration); + List getAllByProject(TaskElement taskElement); + + List getAllByTask(TaskElement taskElement); + boolean deleteAll(); boolean deleteAllByType(EmailTemplateEnum enumeration); boolean deleteById(EmailNotification notification); + + boolean deleteByProject(TaskElement taskElement); + + boolean deleteByTask(TaskElement taskElement); + } diff --git a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/IOrderDAO.java b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/IOrderDAO.java index ca8cd9f62..7457879ce 100644 --- a/libreplan-business/src/main/java/org/libreplan/business/orders/daos/IOrderDAO.java +++ b/libreplan-business/src/main/java/org/libreplan/business/orders/daos/IOrderDAO.java @@ -86,7 +86,7 @@ public interface IOrderDAO extends IIntegrationEntityDAO { List getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState( String username, Scenario scenario, Date startDate, Date endDate, List