Add filtering of finished projects

User preference setting to default filtering of finished projects from planning
and company views.
* Still needs work to investigate and update resource views
This commit is contained in:
lmann99 2017-04-17 22:14:49 -04:00
parent b7fd49b881
commit b43d48e439
18 changed files with 181 additions and 19 deletions

View file

@ -181,6 +181,8 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
private boolean showMoneyCostBarOn = false;
private boolean filterExcludeFinishedProject = false;
private IDetailItemModifier firstLevelModifiers = SeveralModifiers.empty();
private IDetailItemModifier secondLevelModifiers = SeveralModifiers.empty();
@ -567,4 +569,12 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
this.showMoneyCostBarOn = showMoneyCostBarOn;
}
public boolean isFilterExcludeFinishedProject() {
return filterExcludeFinishedProject;
}
public void setFilterExcludeFinishedProject(boolean filterExcludeFinishedProject) {
this.filterExcludeFinishedProject = filterExcludeFinishedProject;
}
}

View file

@ -86,7 +86,7 @@ public interface IOrderDAO extends IIntegrationEntityDAO<Order> {
List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
String username, Scenario scenario, Date startDate, Date endDate,
List<Label> labels, List<Criterion> criteria,
ExternalCompany customer, OrderStatusEnum state);
ExternalCompany customer, OrderStatusEnum state, Boolean excludeFinishedProject);
/**
* Returns the order filtered by the name.

View file

@ -231,9 +231,10 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements IOrderDAO {
List<Label> labels,
List<Criterion> criteria,
ExternalCompany customer,
OrderStatusEnum state) {
OrderStatusEnum state,
Boolean excludeFinishedProject) {
List<Long> ordersIdsFiltered = getOrdersIdsFiltered(user, labels, criteria, customer, state);
List<Long> ordersIdsFiltered = getOrdersIdsFiltered(user, labels, criteria, customer, state, excludeFinishedProject);
if (ordersIdsFiltered != null && ordersIdsFiltered.isEmpty()) {
return Collections.emptyList();
}
@ -354,7 +355,8 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements IOrderDAO {
List<Label> labels,
List<Criterion> criteria,
ExternalCompany customer,
OrderStatusEnum state) {
OrderStatusEnum state,
Boolean excludeFinishedProject) {
List<Long> ordersIdsByReadAuthorization = getOrdersIdsByReadAuthorization(user);
@ -405,6 +407,15 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements IOrderDAO {
where += "o.state = :state ";
}
if (excludeFinishedProject != null && excludeFinishedProject == true) {
if (where.isEmpty()) {
where += "WHERE ";
} else {
where += "AND ";
}
where += "o.state <> '" + OrderStatusEnum.FINISHED.getIndex() + "'";
}
// If not restrictions by labels, criteria, customer or state
if (where.isEmpty()) {
return ordersIdsByReadAuthorization;
@ -550,7 +561,8 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements IOrderDAO {
List<Label> labels,
List<Criterion> criteria,
ExternalCompany customer,
OrderStatusEnum state) {
OrderStatusEnum state,
Boolean excludeFinishedProject) {
User user;
try {
@ -559,7 +571,7 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements IOrderDAO {
throw new RuntimeException(e);
}
return existsInScenario(getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
user, startDate, endDate, labels, criteria, customer, state), scenario);
user, startDate, endDate, labels, criteria, customer, state, excludeFinishedProject), scenario);
}
private List<Order> existsInScenario(List<Order> orders, Scenario scenario) {

View file

@ -93,6 +93,8 @@ public class User extends BaseEntity implements IHumanIdentifiable{
private Integer projectsFilterPeriodTo;
private Boolean projectsFilterFinishedOn = false;
private Criterion resourcesLoadFilterCriterion = null;
private Integer resourcesLoadFilterPeriodSince;
@ -444,6 +446,14 @@ public class User extends BaseEntity implements IHumanIdentifiable{
projectsFilterPeriodTo = period;
}
public boolean isProjectsFilterFinishedOn() {
return projectsFilterFinishedOn;
}
public void setProjectsFilterFinishedOn(boolean projectsFilterFinishedOn) {
this.projectsFilterFinishedOn = projectsFilterFinishedOn;
}
public Integer getResourcesLoadFilterPeriodSince() {
return resourcesLoadFilterPeriodSince;
}

View file

@ -39,6 +39,13 @@
</addColumn>
</changeSet>
<changeSet id="add-new-columns-projects-filter-finished" author="lmann">
<comment>Add columns to store user default setting of filter finished projects in views</comment>
<addColumn tableName="user_table">
<column name="projects_filter_finished_on" type="BOOLEAN" />
</addColumn>
</changeSet>
<changeSet id="set-default-value-show-reported-hours" author="lmann">
<addDefaultValue tableName="user_table"
columnName="show_reported_hours_on"
@ -89,4 +96,14 @@
columnDataType="BOOLEAN" />
</changeSet>
<changeSet id="set-default-value-projects-filter-finished" author="lmann">
<addDefaultValue tableName="user_table"
columnName="projects_filter_finished_on"
defaultValueBoolean="FALSE" />
<addNotNullConstraint tableName="user_table"
columnName="projects_filter_finished_on"
defaultNullValue="FALSE"
columnDataType="BOOLEAN" />
</changeSet>
</databaseChangeLog>

View file

@ -66,6 +66,8 @@
<property name="projectsFilterPeriodTo" column="projects_filter_period_to"/>
<property name="projectsFilterFinishedOn" column="projects_filter_finished_on"/>
<property name="resourcesLoadFilterPeriodSince" column="resources_load_filter_period_since"/>
<property name="resourcesLoadFilterPeriodTo" column="resources_load_filter_period_to"/>

View file

@ -50,6 +50,11 @@ public class FilterUtils {
return (String) Sessions.getCurrent().getAttribute("companyFilterOrderName");
}
public static Boolean readExcludeFinishedProjects() {
Boolean res = (Boolean) Sessions.getCurrent().getAttribute("companyFilterFinished");
return res;
}
public static List<FilterPair> readProjectsParameters() {
return (List<FilterPair>) Sessions.getCurrent().getAttribute("companyFilterLabel");
}
@ -76,6 +81,15 @@ public class FilterUtils {
Sessions.getCurrent().setAttribute("companyFilterOrderName", name);
}
public static void writeExcludeFinishedProjects(Boolean excludeFinishedProject) {
Sessions.getCurrent().setAttribute("companyFilterFinished", excludeFinishedProject);
Sessions.getCurrent().setAttribute("companyFilterFinishedChanged", true);
}
public static boolean hasExcludeFinishedProjects() {
return Sessions.getCurrent().hasAttribute("companyFilterFinishedChanged");
}
public static void writeProjectsParameters(List<FilterPair> parameters) {
Sessions.getCurrent().setAttribute("companyFilterLabel", parameters);
}
@ -83,12 +97,14 @@ public class FilterUtils {
public static void writeProjectsFilter(Date startDate,
Date endDate,
List<FilterPair> parameters,
String projectName) {
String projectName,
Boolean excludeFinishedProject) {
writeProjectsStartDate(startDate);
writeProjectsEndDate(endDate);
writeProjectsParameters(parameters);
writeProjectsName(projectName);
writeExcludeFinishedProjects(excludeFinishedProject);
}
public static void writeProjectFilterChanged(boolean changed) {
@ -159,6 +175,10 @@ public class FilterUtils {
return (String) Sessions.getCurrent().getAttribute(order.getCode() + "-tasknameFilter");
}
public static String readOrderStatus(Order order) {
return (String) Sessions.getCurrent().getAttribute(order.getCode() + "-orderStatus");
}
public static List<FilterPair> readOrderParameters(Order order) {
return (List<FilterPair>) Sessions.getCurrent().getAttribute(order.getCode() + "-labelsandcriteriaFilter");
}

View file

@ -91,7 +91,7 @@ public interface IOrderModel extends IIntegrationEntityModel {
List<Order> getOrders(Date startDate, Date endDate, List<Label> labels,
List<Criterion> criteria, ExternalCompany customer,
OrderStatusEnum state);
OrderStatusEnum state, Boolean excludeFinishedProject);
void initEdit(Order order, Desktop desktop);

View file

@ -78,6 +78,7 @@ import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.SelectEvent;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Column;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
@ -220,6 +221,8 @@ public class OrderCRUDController extends GenericForwardComposer {
private Textbox filterProjectName;
private Checkbox filterExcludeFinishedProject;
private Runnable onUp;
private boolean readOnly = true;
@ -248,6 +251,8 @@ public class OrderCRUDController extends GenericForwardComposer {
filterProjectName = (Textbox) filterComponent.getFellow("filterProjectName");
filterExcludeFinishedProject = (Checkbox) filterComponent.getFellow("filterExcludeFinishedProject");
checkCreationPermissions();
setupGlobalButtons();
initializeFilter();
@ -291,6 +296,8 @@ public class OrderCRUDController extends GenericForwardComposer {
filterProjectName.setValue(FilterUtils.readProjectsName());
filterExcludeFinishedProject.setValue(FilterUtils.readExcludeFinishedProjects());
loadLabels();
FilterUtils.writeProjectPlanningFilterChanged(false);
@ -802,6 +809,7 @@ public class OrderCRUDController extends GenericForwardComposer {
List<Criterion> criteria = new ArrayList<>();
ExternalCompany customer = null;
OrderStatusEnum state = null;
//Boolean excludeFinishedProject = false;
for (FilterPair filterPair : (List<FilterPair>) bdFilters.getSelectedElements()) {
OrderFilterEnum type = (OrderFilterEnum) filterPair.getType();
@ -837,7 +845,7 @@ public class OrderCRUDController extends GenericForwardComposer {
}
return orderModel.getOrders(
filterStartDate.getValue(), filterFinishDate.getValue(), labels, criteria, customer, state);
filterStartDate.getValue(), filterFinishDate.getValue(), labels, criteria, customer, state, filterExcludeFinishedProject.isChecked());
}
private OnlyOneVisible getVisibility() {
@ -1438,7 +1446,8 @@ public class OrderCRUDController extends GenericForwardComposer {
filterStartDate.getValue(),
filterFinishDate.getValue(),
getSelectedBandboxAsTaskGroupFilters(),
filterProjectName.getValue());
filterProjectName.getValue(),
filterExcludeFinishedProject.getValue());
}
private List<FilterPair> getSelectedBandboxAsTaskGroupFilters() {
@ -1769,6 +1778,7 @@ public class OrderCRUDController extends GenericForwardComposer {
filterStartDate.setValue(FilterUtils.readProjectsStartDate());
filterFinishDate.setValue(FilterUtils.readProjectsEndDate());
filterProjectName.setValue(FilterUtils.readProjectsName());
filterExcludeFinishedProject.setValue(FilterUtils.readExcludeFinishedProjects());
loadLabels();
}

View file

@ -241,13 +241,13 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
@Transactional(readOnly = true)
public List<Order> getOrders(Date startDate, Date endDate,
List<Label> labels, List<Criterion> criteria,
ExternalCompany customer, OrderStatusEnum state) {
ExternalCompany customer, OrderStatusEnum state, Boolean excludeFinishedProject) {
getLabelsOnConversation().reattachLabels();
List<Order> orders = orderDAO
.getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
SecurityUtils.getSessionUserLoginName(),
scenarioManager.getCurrent(), startDate, endDate,
labels, criteria, customer, state);
labels, criteria, customer, state, excludeFinishedProject);
initializeOrders(orders);

View file

@ -56,12 +56,15 @@ public class TaskGroupPredicate implements IPredicate {
private String name;
private Boolean excludeFinishedProject;
public TaskGroupPredicate(List<FilterPair> filters, Date startDate,
Date finishDate, String name) {
Date finishDate, String name, Boolean excludeFinishedProject) {
this.filters = filters;
this.startDate = startDate;
this.finishDate = finishDate;
this.name = name;
this.excludeFinishedProject = excludeFinishedProject;
}
@Override
@ -166,6 +169,15 @@ public class TaskGroupPredicate implements IPredicate {
return false;
}
private boolean acceptFinishedProject(FilterPair filter, TaskGroup taskGroup) {
Label filterLabel = (Label) filter.getValue();
Order order = (Order) taskGroup.getOrderElement();
if (order.getState() != OrderStatusEnum.FINISHED) {
return true;
}
return false;
}
private boolean acceptExternalCompany(FilterPair filter, TaskGroup taskGroup) {
Order order = (Order) taskGroup.getOrderElement();
ExternalCompany filterCustomer = (ExternalCompany) filter.getValue();
@ -300,4 +312,8 @@ public class TaskGroupPredicate implements IPredicate {
return false;
}
}
public Boolean getExcludeFinishedProjects() {
return excludeFinishedProject;
}
}

View file

@ -91,6 +91,8 @@ public class CompanyPlanningController implements Composer {
private Textbox filterProjectName;
private Checkbox filterExcludeFinishedProject;
private BandboxMultipleSearch bdFilters;
private ICommandOnTask<TaskElement> doubleClickCommand;
@ -135,6 +137,7 @@ public class CompanyPlanningController implements Composer {
filterStartDate = (Datebox) filterComponent.getFellow("filterStartDate");
filterFinishDate = (Datebox) filterComponent.getFellow("filterFinishDate");
filterProjectName = (Textbox) filterComponent.getFellow("filterProjectName");
filterExcludeFinishedProject = (Checkbox) filterComponent.getFellow("filterExcludeFinishedProject");
bdFilters = (BandboxMultipleSearch) filterComponent.getFellow("bdFilters");
bdFilters.setFinder("taskGroupsMultipleFiltersFinder");
@ -179,6 +182,8 @@ public class CompanyPlanningController implements Composer {
.toDate());
}
filterProjectName.setValue(FilterUtils.readProjectsName());
filterExcludeFinishedProject.setChecked(user.isProjectsFilterFinishedOn());
}
}
@ -311,6 +316,10 @@ public class CompanyPlanningController implements Composer {
filterStartDate.setValue(FilterUtils.readProjectsStartDate());
filterFinishDate.setValue(FilterUtils.readProjectsEndDate());
filterProjectName.setValue(FilterUtils.readProjectsName());
Boolean excludeFinishedProjects = FilterUtils.readExcludeFinishedProjects();
if ( excludeFinishedProjects != null ) {
filterExcludeFinishedProject.setChecked(excludeFinishedProjects);
}
loadPredefinedBandboxFilter();
}
@ -319,7 +328,8 @@ public class CompanyPlanningController implements Composer {
filterStartDate.getValue(),
filterFinishDate.getValue(),
bdFilters.getSelectedElements(),
filterProjectName.getValue());
filterProjectName.getValue(),
filterExcludeFinishedProject.isChecked());
FilterUtils.writeProjectPlanningFilterChanged(true);
filterByPredicate(createPredicate());
@ -333,6 +343,7 @@ public class CompanyPlanningController implements Composer {
List<FilterPair> listFilters = (List<FilterPair>) bdFilters.getSelectedElements();
Date startDate = filterStartDate.getValue();
Date finishDate = filterFinishDate.getValue();
Boolean excludeFinishedProject = filterExcludeFinishedProject.isChecked();
String name = filterProjectName.getValue();
@ -354,7 +365,7 @@ public class CompanyPlanningController implements Composer {
return predicate;
}
return new TaskGroupPredicate(listFilters, startDate, finishDate, name);
return new TaskGroupPredicate(listFilters, startDate, finishDate, name, excludeFinishedProject);
}
private void filterByPredicate(TaskGroupPredicate predicate) {

View file

@ -164,6 +164,8 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
private LocalDate filterFinishDate;
private Boolean filterExcludeFinishedProject;
private static final class TaskElementNavigator implements IStructureNavigator<TaskElement> {
@Override
@ -204,6 +206,9 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
boolean expandPlanningViewChart = user.isExpandCompanyPlanningViewCharts();
configuration.setExpandPlanningViewCharts(expandPlanningViewChart);
boolean projectsFilterFinished = user.isProjectsFilterFinishedOn();
configuration.setFilterExcludeFinishedProject(projectsFilterFinished);
final Tabbox chartComponent = new Tabbox();
chartComponent.setOrient("vertical");
chartComponent.setHeight("200px");
@ -710,6 +715,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
Date startDate = predicate.getStartDate();
Date endDate = predicate.getFinishDate();
Boolean excludeFinishedProject = predicate.getExcludeFinishedProjects();
List<org.libreplan.business.labels.entities.Label> labels = new ArrayList<>();
List<Criterion> criteria = new ArrayList<>();
ExternalCompany customer = null;
@ -750,7 +756,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
return orderDAO.getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
username, currentScenario, startDate, endDate, labels, criteria, customer, state);
username, currentScenario, startDate, endDate, labels, criteria, customer, state, excludeFinishedProject);
}
@Override
@ -760,6 +766,12 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
Date startDate = FilterUtils.readProjectsStartDate();
Date endDate = FilterUtils.readProjectsEndDate();
String name = FilterUtils.readProjectsName();
Boolean projectsFinished = FilterUtils.readExcludeFinishedProjects();
if ( projectsFinished == null ) {
User user = getUser();
projectsFinished = user.isProjectsFilterFinishedOn();
}
boolean calculateStartDate = startDate == null;
boolean calculateEndDate = endDate == null;
@ -794,8 +806,9 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
filterStartDate = startDate != null ? LocalDate.fromDateFields(startDate) : null;
filterFinishDate = endDate != null ? LocalDate.fromDateFields(endDate) : null;
//filterExcludeFinishedProject = projectsFinished != null ? projectsFinished : false;
return new TaskGroupPredicate(null, startDate, endDate, name);
return new TaskGroupPredicate(null, startDate, endDate, name, projectsFinished);
}
private static <T> List<T> notNull(T... values) {
@ -904,4 +917,12 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
return user;
}
public Boolean getFilterExcludeFinishedProject() {
return filterExcludeFinishedProject;
}
public void setFilterExcludeFinishedProject(Boolean filterExcludeFinishedProject) {
this.filterExcludeFinishedProject = filterExcludeFinishedProject;
}
}

View file

@ -120,4 +120,8 @@ public interface ISettingsModel {
boolean isShowMoneyCostBarOn();
void setShowMoneyCostBarOn(boolean showMoneyCostBarOn);
boolean isProjectsFilterFinishedOn();
void setProjectsFilterFinishedOn(boolean projectsFilterFinishedOn);
}

View file

@ -353,4 +353,13 @@ public class SettingsController extends GenericForwardComposer {
public void setShowMoneyCostBarOn(boolean showMoneyCostBarOn) {
settingsModel.setShowMoneyCostBarOn(showMoneyCostBarOn);
}
public boolean isProjectsFilterFinishedOn() {
return settingsModel.isProjectsFilterFinishedOn();
}
public void setProjectsFilterFinishedOn(boolean projectsFilterFinishedOn) {
settingsModel.setProjectsFilterFinishedOn(projectsFilterFinishedOn);
}
}

View file

@ -360,4 +360,15 @@ public class SettingsModel implements ISettingsModel {
public void setShowMoneyCostBarOn(boolean showMoneyCostBarOn) {
user.setShowMoneyCostBarOn(showMoneyCostBarOn);
}
@Override
public boolean isProjectsFilterFinishedOn() {
return user.isProjectsFilterFinishedOn();
}
@Override
public void setProjectsFilterFinishedOn(boolean projectsFilterFinishedOn) {
user.setProjectsFilterFinishedOn(projectsFilterFinishedOn);
}
}

View file

@ -172,6 +172,9 @@
value="@{settingsController.projectsFilterPeriodTo}"
width="50px"
constraint="@{settingsController.checkMonthsMaxValue}"/>
<checkbox id="projectsFilterFinishedOn"
label="${i18n:_('Exclude finished projects')}"
checked="@{settingsController.projectsFilterFinishedOn}"/>
</hbox>
</row>

View file

@ -24,7 +24,8 @@
tooltiptext="${i18n:_('Select required criteria set and press filter button')}"/>
<textbox id="filterProjectName" width="100px"
onChange="orderFilterController.onApplyFilter()" />
onChange="orderFilterController.onApplyFilter()"
onOK="orderFilterController.onApplyFilter()" />
<label value=" ${i18n:_('with')}" />
@ -41,6 +42,11 @@
<datebox id="filterFinishDate" constraint = "@{orderFilterController.checkConstraintFinishDate}"
onChange="orderFilterController.onApplyFilter()"/>
<label value=" ${i18n:_('Exclude finished projects')}" />
<checkbox id="filterExcludeFinishedProject"
onChange="orderFilterController.onApplyFilter()"/>
<button mold="trendy" image="/common/img/ico_filter.png" style="margin-top: -4px"
tooltiptext="${i18n:_('Apply filtering to tasks satisfying required criteria')}"
onClick="orderFilterController.onApplyFilter()"/>