ItEr46S19CUProcuraOrganizacionsTraballoItEr40S22: Added multiple search filter to order elements tree.
This commit is contained in:
parent
017b90e5a6
commit
b093094831
8 changed files with 299 additions and 48 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 <mrego@igalia.com>
|
||||
*/
|
||||
public class OrderElementPredicate implements IPredicate {
|
||||
|
||||
private List<FilterPair> filters;
|
||||
|
||||
private Date startDate;
|
||||
|
||||
private Date finishDate;
|
||||
|
||||
public OrderElementPredicate(List<FilterPair> 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<OrderElement> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<OrderElement> {
|
|||
|
||||
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<OrderElement> {
|
|||
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<String, String>());
|
||||
"/orders/_orderElementTreeFilter.zul", filter,
|
||||
new HashMap<String, String>());
|
||||
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<OrderElement> {
|
|||
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<OrderElement> {
|
|||
|
||||
/**
|
||||
* 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<FilterPair> listFilters = (List<FilterPair>) 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<OrderElement> {
|
|||
*/
|
||||
public void clear() {
|
||||
selectDefaultTab();
|
||||
bdFilter.clear();
|
||||
bdFilters2.clear();
|
||||
predicate = null;
|
||||
}
|
||||
|
||||
|
|
@ -539,4 +559,42 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
|||
}
|
||||
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"));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ import org.navalplanner.web.tree.EntitiesTree;
|
|||
public class OrderElementTreeModel extends EntitiesTree<OrderElement> {
|
||||
|
||||
public OrderElementTreeModel(OrderElement root,
|
||||
List<OrderElement> rootChildren) {
|
||||
super(OrderElement.class, root, rootChildren);
|
||||
List<OrderElement> orderElements) {
|
||||
super(OrderElement.class, root, orderElements);
|
||||
}
|
||||
|
||||
public OrderElementTreeModel(OrderElement root) {
|
||||
|
|
|
|||
|
|
@ -517,12 +517,10 @@ public class OrderModel implements IOrderModel {
|
|||
IPredicate predicate) {
|
||||
// Iterate through orderElements from order
|
||||
List<OrderElement> orderElements = new ArrayList<OrderElement>();
|
||||
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)) {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -56,14 +56,32 @@ public abstract class EntitiesTree<T extends ITreeNode<T>> {
|
|||
}
|
||||
}
|
||||
|
||||
private static <T extends ITreeNode<T>> MutableTreeModel<T> createFilteredTreeFrom(
|
||||
Class<T> type, T tree, List<T> elements) {
|
||||
MutableTreeModel<T> treeModel = MutableTreeModel.create(type, tree);
|
||||
T parent = treeModel.getRoot();
|
||||
addFilteredChildren(treeModel, parent, elements);
|
||||
return treeModel;
|
||||
}
|
||||
|
||||
private static <T extends ITreeNode<T>> void addFilteredChildren(
|
||||
MutableTreeModel<T> treeModel, T parent, List<T> children) {
|
||||
for (T each : children) {
|
||||
if ((each.getParent() != null) && (each.getParent().equals(parent))) {
|
||||
treeModel.add(parent, each);
|
||||
addFilteredChildren(treeModel, each, children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MutableTreeModel<T> tree;
|
||||
|
||||
protected EntitiesTree(Class<T> type, T root) {
|
||||
tree = createTreeFrom(type, root);
|
||||
}
|
||||
|
||||
protected EntitiesTree(Class<T> type, T root, List<T> rootChildren) {
|
||||
tree = createTreeFrom(type, root, rootChildren);
|
||||
protected EntitiesTree(Class<T> type, T root, List<T> elements) {
|
||||
tree = createFilteredTreeFrom(type, root, elements);
|
||||
}
|
||||
|
||||
public TreeModel asTree() {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
<hbox align="right" style="margin-left:700px;">
|
||||
<!-- Filter by label -->
|
||||
<label value="${i18n:_('Filter by label:')}" />
|
||||
<bandboxSearch id="bdFilter" widthBandbox="185px" widthListbox="200px"
|
||||
finder="LabelBandboxFinder"
|
||||
model="@{treeController.labels}"/>
|
||||
<button label="${i18n:_('Filter')}" style="margin-top: -4px"
|
||||
onClick="treeController.onApplyFilter(event)"/>
|
||||
<hbox align="center" sclass="filtering-area">
|
||||
<label value="${i18n:_('Filter by')}"
|
||||
tooltiptext="${i18n:_('Select required criteria set and press filter button')}"/>
|
||||
<bandboxMultipleSearch id="bdFilters2" widthBandbox="385px" widthListbox="400px"
|
||||
finder="multipleFiltersFinder"/>
|
||||
<label value="${i18n:_('from')}"/>
|
||||
<datebox id="filterStartDate2" constraint = "@{treeController.checkConstraintStartDate}"/>
|
||||
<label value="${i18n:_('to')}"/>
|
||||
<datebox id="filterFinishDate2" constraint = "@{treeController.checkConstraintFinishDate}"/>
|
||||
<button label="${i18n:_('Filter')}" style="margin-top: -4px"
|
||||
tooltiptext="${i18n:_('Apply filtering to order elements satisfying required critera')}"
|
||||
onClick="treeController.onApplyFilter()"/>
|
||||
</hbox>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue