diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java
index d6dc25de3..aebff5db5 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java
@@ -70,11 +70,8 @@ public interface IOrderModel {
IOrderElementModel getOrderElementModel(OrderElement orderElement);
/**
- * Iterates through order.orderElements, and checks if orderElement holds
- * predicate. In case it's true, add orderElement and all its children to
- * filtered orderElements list
- *
- * @return
+ * Iterates through all the orderElements of an order, and checks if
+ * orderElement holds predicate. In case it is true, adds orderElement.
*/
OrderElementTreeModel getOrderElementsFilteredByPredicate(IPredicate predicate);
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementPredicate.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementPredicate.java
new file mode 100644
index 000000000..c35030c91
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementPredicate.java
@@ -0,0 +1,176 @@
+/*
+ * This file is part of ###PROJECT_NAME###
+ *
+ * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
+ * Desenvolvemento Tecnolóxico de Galicia
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.navalplanner.web.orders;
+
+import java.util.Date;
+import java.util.List;
+
+import org.navalplanner.business.labels.entities.Label;
+import org.navalplanner.business.orders.entities.OrderElement;
+import org.navalplanner.business.requirements.entities.CriterionRequirement;
+import org.navalplanner.business.resources.entities.Criterion;
+import org.navalplanner.web.common.components.finders.FilterPair;
+
+/**
+ * Checks if {@link OrderElement} matches with the different filters.
+ *
+ * @author Manuel Rego Casasnovas
+ */
+public class OrderElementPredicate implements IPredicate {
+
+ private List filters;
+
+ private Date startDate;
+
+ private Date finishDate;
+
+ public OrderElementPredicate(List filters, Date startDate,
+ Date finishDate) {
+ this.filters = filters;
+ this.startDate = startDate;
+ this.finishDate = finishDate;
+ }
+
+ @Override
+ public boolean accepts(Object object) {
+ final OrderElement orderElement = (OrderElement) object;
+ return accepts(orderElement) || accepts(orderElement.getAllChildren());
+ }
+
+ private boolean accepts(OrderElement orderElement) {
+ if (orderElement == null) {
+ return false;
+ }
+ if (acceptFilters(orderElement) && acceptFiltersDates(orderElement)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean accepts(List orderElements) {
+ for (OrderElement orderElement : orderElements) {
+ if (accepts(orderElement)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean acceptFilters(OrderElement orderElement) {
+ if ((filters == null) || (filters.isEmpty())) {
+ return true;
+ }
+ for (FilterPair filter : filters) {
+ if (!acceptFilter(filter, orderElement)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean acceptFilter(FilterPair filter, OrderElement orderElement) {
+ switch (filter.getType()) {
+ case Criterion:
+ return acceptCriterion(filter, orderElement);
+ case Label:
+ return acceptLabel(filter, orderElement);
+ }
+ return false;
+ }
+
+ private boolean acceptCriterion(FilterPair filter, OrderElement orderElement) {
+ Criterion filterCriterion = (Criterion) filter.getValue();
+ return existCriterionInOrderElement(filterCriterion, orderElement);
+ }
+
+ private boolean existCriterionInOrderElement(Criterion filterCriterion,
+ OrderElement orderElement) {
+ for (CriterionRequirement criterionRequirement : orderElement
+ .getCriterionRequirements()) {
+ if(criterionRequirement.getCriterion().getId().equals(filterCriterion.getId())){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean acceptLabel(FilterPair filter, OrderElement orderElement) {
+ Label filterLabel = (Label) filter.getValue();
+ return existLabelInOrderElement(filterLabel, orderElement);
+ }
+
+ private boolean existLabelInOrderElement(Label filterLabel,
+ OrderElement order) {
+ for(Label label : order.getLabels()){
+ if(label.getId().equals(filterLabel.getId())){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean acceptFiltersDates(OrderElement orderElement) {
+ return (acceptStartDate(orderElement.getInitDate()) && (acceptFinishDate(orderElement
+ .getDeadline())));
+ }
+
+ private boolean acceptStartDate(Date initDate) {
+ if ((initDate == null) && (startDate == null)) {
+ return true;
+ }
+ return isInTheRangeFilterDates(initDate);
+ }
+
+ private boolean acceptFinishDate(Date deadLine) {
+ if ((deadLine == null) && (finishDate == null)) {
+ return true;
+ }
+ return isInTheRangeFilterDates(deadLine);
+ }
+
+ private boolean isInTheRangeFilterDates(Date date) {
+ // Check if date is into interval between the startdate and finish date
+ return (isGreaterToStartDate(date, startDate) && isLowerToFinishDate(
+ date, finishDate));
+ }
+
+ private boolean isGreaterToStartDate(Date date, Date startDate) {
+ if (startDate == null) {
+ return true;
+ }
+
+ if (date != null && (date.compareTo(startDate) >= 0)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isLowerToFinishDate(Date date, Date finishDate) {
+ if (finishDate == null) {
+ return true;
+ }
+ if (date != null && (date.compareTo(finishDate) <= 0)) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java
index 738b17b49..287289570 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java
@@ -43,6 +43,7 @@ import org.navalplanner.web.common.Util.Getter;
import org.navalplanner.web.common.Util.Setter;
import org.navalplanner.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
+import org.navalplanner.web.common.components.finders.FilterPair;
import org.navalplanner.web.orders.assigntemplates.TemplateFinderPopup;
import org.navalplanner.web.orders.assigntemplates.TemplateFinderPopup.IOnResult;
import org.navalplanner.web.templates.IOrderTemplatesControllerEntryPoints;
@@ -54,7 +55,6 @@ import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
-import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Hbox;
@@ -78,15 +78,11 @@ public class OrderElementTreeController extends TreeController {
private Hbox orderFilter;
- private BandboxSearch bdFilter;
+ private BandboxMultipleSearch bdFilters2;
- private Datebox filterStartDate;
+ private Datebox filterStartDate2;
- private Datebox filterFinishDate;
-
- private BandboxMultipleSearch bdFilters;
-
- private Checkbox checkIncludeOrderElements;
+ private Datebox filterFinishDate2;
private OrderElementTreeitemRenderer renderer = new OrderElementTreeitemRenderer();
@@ -194,13 +190,17 @@ public class OrderElementTreeController extends TreeController {
super.doAfterCompose(comp);
// Configuration of the order elements filter
- orderFilter.setVisible(false);
- filter.setVisible(true);
Component filterComponent = Executions.createComponents(
- "/orders/_orderElementTreeFilter.zul",
- filter, new HashMap());
+ "/orders/_orderElementTreeFilter.zul", filter,
+ new HashMap());
filterComponent.setVariable("treeController", this, true);
- bdFilter = (BandboxSearch) filterComponent.getFellow("bdFilter");
+ bdFilters2 = (BandboxMultipleSearch) filterComponent
+ .getFellow("bdFilters2");
+ filterStartDate2 = (Datebox) filterComponent
+ .getFellow("filterStartDate2");
+ filterFinishDate2 = (Datebox) filterComponent
+ .getFellow("filterFinishDate2");
+
templateFinderPopup = (TemplateFinderPopup) comp
.getFellow("templateFinderPopupAtTree");
}
@@ -404,8 +404,8 @@ public class OrderElementTreeController extends TreeController {
final OrderElement currentOrderElement) {
addCell(createEditButton(currentOrderElement, item),
createTemplateButton(currentOrderElement),
- createUpButton(item,currentOrderElement),
createDownButton(item,currentOrderElement),
+ createUpButton(item,currentOrderElement),
createUnindentButton(item, currentOrderElement),
createIndentButton(item, currentOrderElement),
createRemoveButton(currentOrderElement));
@@ -448,21 +448,41 @@ public class OrderElementTreeController extends TreeController {
/**
* Apply filter to order elements in current order
- * @param event
*/
- public void onApplyFilter(Event event) {
- org.navalplanner.business.labels.entities.Label label = getSelectedLabel();
- if (label == null) {
- label = org.navalplanner.business.labels.entities.Label.create("");
- }
- // Create predicate and filter order elements by predicate
- predicate = new LabelOrderElementPredicate(label);
- filterByPredicate();
+ public void onApplyFilter() {
+ OrderElementPredicate predicate = createPredicate();
+ this.predicate = predicate;
+
+ if (predicate != null) {
+ filterByPredicate(predicate);
+ } else {
+ showAllOrderElements();
+ }
}
- private org.navalplanner.business.labels.entities.Label getSelectedLabel() {
- return (org.navalplanner.business.labels.entities.Label) bdFilter
- .getSelectedElement();
+ private OrderElementPredicate createPredicate() {
+ List listFilters = (List) bdFilters2
+ .getSelectedElements();
+ Date startDate = filterStartDate2.getValue();
+ Date finishDate = filterFinishDate2.getValue();
+
+ if (listFilters.isEmpty() && startDate == null && finishDate == null) {
+ return null;
+ }
+ return new OrderElementPredicate(listFilters, startDate, finishDate);
+ }
+
+ private void filterByPredicate(OrderElementPredicate predicate) {
+ OrderElementTreeModel orderElementTreeModel = orderModel
+ .getOrderElementsFilteredByPredicate(predicate);
+ tree.setModel(orderElementTreeModel.asTree());
+ tree.invalidate();
+ }
+
+ public void showAllOrderElements() {
+ this.predicate = null;
+ tree.setModel(orderModel.getOrderElementTreeModel().asTree());
+ tree.invalidate();
}
@Override
@@ -476,7 +496,7 @@ public class OrderElementTreeController extends TreeController {
*/
public void clear() {
selectDefaultTab();
- bdFilter.clear();
+ bdFilters2.clear();
predicate = null;
}
@@ -539,4 +559,42 @@ public class OrderElementTreeController extends TreeController {
}
return null;
}
+
+ /**
+ * Operations to filter the orders by multiple filters
+ */
+ public Constraint checkConstraintFinishDate() {
+ return new Constraint() {
+ @Override
+ public void validate(Component comp, Object value)
+ throws WrongValueException {
+ Date finishDate = (Date) value;
+ if ((finishDate != null)
+ && (filterStartDate2.getValue() != null)
+ && (finishDate.compareTo(filterStartDate2.getValue()) < 0)) {
+ filterFinishDate2.setValue(null);
+ throw new WrongValueException(comp,
+ _("must be greater than start date"));
+ }
+ }
+ };
+ }
+
+ public Constraint checkConstraintStartDate() {
+ return new Constraint() {
+ @Override
+ public void validate(Component comp, Object value)
+ throws WrongValueException {
+ Date startDate = (Date) value;
+ if ((startDate != null)
+ && (filterFinishDate2.getValue() != null)
+ && (startDate.compareTo(filterFinishDate2.getValue()) > 0)) {
+ filterStartDate2.setValue(null);
+ throw new WrongValueException(comp,
+ _("must be lower than finish date"));
+ }
+ }
+ };
+ }
+
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java
index 417ad8e79..14424ca05 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java
@@ -39,8 +39,8 @@ import org.navalplanner.web.tree.EntitiesTree;
public class OrderElementTreeModel extends EntitiesTree {
public OrderElementTreeModel(OrderElement root,
- List rootChildren) {
- super(OrderElement.class, root, rootChildren);
+ List orderElements) {
+ super(OrderElement.class, root, orderElements);
}
public OrderElementTreeModel(OrderElement root) {
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java
index 4ca87d0f1..47172223a 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java
@@ -517,12 +517,10 @@ public class OrderModel implements IOrderModel {
IPredicate predicate) {
// Iterate through orderElements from order
List orderElements = new ArrayList();
- for (OrderElement orderElement : order.getOrderElements()) {
+ for (OrderElement orderElement : order.getAllOrderElements()) {
if (!orderElement.isNewObject()) {
reattachOrderElement(orderElement);
}
- reattachLabels();
- initializeLabels(orderElement.getLabels());
// Accepts predicate, add it to list of orderElements
if (predicate.accepts(orderElement)) {
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java
index 857a9abae..93d3cbeb5 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java
@@ -64,8 +64,8 @@ public class TemplatesTreeController extends
protected void addOperationsCell(Treeitem item,
OrderElementTemplate currentElement) {
addCell(createEditButton(currentElement),
- createUpButton(item, currentElement),
createDownButton(item, currentElement),
+ createUpButton(item, currentElement),
createUnindentButton(item, currentElement),
createIndentButton(item, currentElement),
createRemoveButton(currentElement));
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/EntitiesTree.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/EntitiesTree.java
index e4b3d4835..8943c3132 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/EntitiesTree.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/EntitiesTree.java
@@ -56,14 +56,32 @@ public abstract class EntitiesTree> {
}
}
+ private static > MutableTreeModel createFilteredTreeFrom(
+ Class type, T tree, List elements) {
+ MutableTreeModel treeModel = MutableTreeModel.create(type, tree);
+ T parent = treeModel.getRoot();
+ addFilteredChildren(treeModel, parent, elements);
+ return treeModel;
+ }
+
+ private static > void addFilteredChildren(
+ MutableTreeModel treeModel, T parent, List children) {
+ for (T each : children) {
+ if ((each.getParent() != null) && (each.getParent().equals(parent))) {
+ treeModel.add(parent, each);
+ addFilteredChildren(treeModel, each, children);
+ }
+ }
+ }
+
private MutableTreeModel tree;
protected EntitiesTree(Class type, T root) {
tree = createTreeFrom(type, root);
}
- protected EntitiesTree(Class type, T root, List rootChildren) {
- tree = createTreeFrom(type, root, rootChildren);
+ protected EntitiesTree(Class type, T root, List elements) {
+ tree = createFilteredTreeFrom(type, root, elements);
}
public TreeModel asTree() {
diff --git a/navalplanner-webapp/src/main/webapp/orders/_orderElementTreeFilter.zul b/navalplanner-webapp/src/main/webapp/orders/_orderElementTreeFilter.zul
index 63af646a2..f0b946d0c 100644
--- a/navalplanner-webapp/src/main/webapp/orders/_orderElementTreeFilter.zul
+++ b/navalplanner-webapp/src/main/webapp/orders/_orderElementTreeFilter.zul
@@ -1,9 +1,13 @@
-
-
-
-
-
+
+
+
+
+
+
+
+