New query in OrderDAO to get projects filtered

The new query receives several params from the filters (dates, labels, criteria,
customer and state) and returns the filtered orders.

For the moment it's only used to get the initial list of orders for the projects
list window.

FEA: ItEr77S15FilteringEnhancements
This commit is contained in:
Manuel Rego Casasnovas 2013-02-04 13:32:06 +01:00
parent 58ad890227
commit 86e1d77791
5 changed files with 275 additions and 1 deletions

View file

@ -26,8 +26,11 @@ import java.util.List;
import org.libreplan.business.common.daos.IIntegrationEntityDAO;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.externalcompanies.entities.ExternalCompany;
import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.reports.dtos.CostExpenseSheetDTO;
import org.libreplan.business.reports.dtos.OrderCostsPerResourceDTO;
@ -79,6 +82,11 @@ public interface IOrderDAO extends IIntegrationEntityDAO<Order> {
List<Order> getOrdersByReadAuthorizationByScenario(String username,
Scenario scenario);
List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
String username, Scenario scenario, Date startDate, Date endDate,
List<Label> labels, List<Criterion> criteria,
ExternalCompany customer, OrderStatusEnum state);
/**
* Returns the order filtered by the name. If name is blank (whitespace,
* empty ("") or null, it throws <code>InstanceNotFoundException</code>.

View file

@ -38,6 +38,8 @@ import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.costcategories.daos.CostCategoryDAO;
import org.libreplan.business.costcategories.daos.ITypeOfWorkHoursDAO;
import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
import org.libreplan.business.externalcompanies.entities.ExternalCompany;
import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderStatusEnum;
@ -214,6 +216,191 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
}
}
private List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
User user, Date startDate, Date endDate, List<Label> labels,
List<Criterion> criteria, ExternalCompany customer,
OrderStatusEnum state) {
List<Long> ordersIdsFiltered = getOrdersIdsFiltered(user, labels,
criteria, customer, state);
if (ordersIdsFiltered != null && ordersIdsFiltered.isEmpty()) {
return Collections.emptyList();
}
List<Long> ordersIdsByDates = getOrdersIdsByDates(startDate, endDate);
if (ordersIdsByDates != null && ordersIdsByDates.isEmpty()) {
return Collections.emptyList();
}
Criteria c = getSession().createCriteria(Order.class);
if (ordersIdsFiltered != null) {
c.add(Restrictions.in("id", ordersIdsFiltered));
}
if (ordersIdsByDates != null) {
c.add(Restrictions.in("id", ordersIdsByDates));
}
c.addOrder(org.hibernate.criterion.Order.desc("initDate"));
c.addOrder(org.hibernate.criterion.Order.asc("infoComponent.name"));
return c.list();
}
/**
* If both params are <code>null</code> it returns <code>null</code>.
* Otherwise it filters the list of tasks to return the ones wihtout parent
* between the dates.
*/
private List<Long> getOrdersIdsByDates(Date startDate, Date endDate) {
if (startDate == null && endDate == null) {
return null;
}
String strQuery = "SELECT t.taskSource.schedulingData.orderElement.id "
+ "FROM TaskElement t "
+ "WHERE t.parent IS NULL ";
if (startDate != null) {
strQuery += "AND t.startDate.date >= :startDate ";
}
if (endDate != null) {
strQuery += "AND t.endDate.date <= :endDate ";
}
Query query = getSession().createQuery(strQuery);
if (startDate != null) {
query.setParameter("startDate", LocalDate.fromDateFields(startDate));
}
if (endDate != null) {
query.setParameter("endDate", LocalDate.fromDateFields(endDate));
}
return query.list();
}
/**
* If user has permissions over all orders and not filters are passed it
* returns <code>null</code>. Otherwise, it returns the list of orders
* identifiers for which the user has read permissions and the filters pass.
*/
private List<Long> getOrdersIdsFiltered(User user, List<Label> labels,
List<Criterion> criteria, ExternalCompany customer,
OrderStatusEnum state) {
List<Long> ordersIdsByReadAuthorization = getOrdersIdsByReadAuthorization(user);
String strQuery = "SELECT o.id ";
strQuery += "FROM Order o ";
String where = "";
if (labels != null && !labels.isEmpty()) {
for (int i = 0; i < labels.size(); i++) {
if (where.isEmpty()) {
where += "WHERE ";
} else {
where += "AND ";
}
where += ":label" + i + " IN elements(o.labels) ";
}
}
if (criteria != null && !criteria.isEmpty()) {
strQuery += "JOIN o.criterionRequirements cr ";
if (where.isEmpty()) {
where += "WHERE ";
} else {
where += "AND ";
}
where += "cr.criterion IN (:criteria) ";
where += "AND cr.class = DirectCriterionRequirement ";
where += "GROUP BY o.id ";
where += "HAVING count(o.id) = :criteriaSize ";
}
if (customer != null) {
if (where.isEmpty()) {
where += "WHERE ";
} else {
where += "AND ";
}
where += "o.customer = :customer ";
}
if (state != null) {
if (where.isEmpty()) {
where += "WHERE ";
} else {
where += "AND ";
}
where += "o.state = :state ";
}
// If not restrictions by labels, criteria, customer or state
if (where.isEmpty()) {
return ordersIdsByReadAuthorization;
}
if (ordersIdsByReadAuthorization != null
&& !ordersIdsByReadAuthorization.isEmpty()) {
if (where.isEmpty()) {
where += "WHERE ";
} else {
where += "AND ";
}
where += "o.id = :ids ";
}
strQuery += where;
Query query = getSession().createQuery(strQuery);
if (labels != null && !labels.isEmpty()) {
int i = 0;
for (Label label : labels) {
query.setParameter("label" + i, label);
i++;
}
}
if (criteria != null && !criteria.isEmpty()) {
query.setParameterList("criteria", criteria);
query.setParameter("criteriaSize", (long) criteria.size());
}
if (customer != null) {
query.setParameter("customer", customer);
}
if (state != null) {
query.setParameter("state", state);
}
if (ordersIdsByReadAuthorization != null
&& !ordersIdsByReadAuthorization.isEmpty()) {
query.setParameterList("ids", ordersIdsByReadAuthorization);
}
return query.list();
}
/**
* If user has permissions over all orders it returns <code>null</code>.
* Otherwise, it returns the list of orders identifiers for which the user
* has read permissions.
*/
private List<Long> getOrdersIdsByReadAuthorization(User user) {
if (user.isInRole(UserRole.ROLE_SUPERUSER)
|| user.isInRole(UserRole.ROLE_READ_ALL_PROJECTS)
|| user.isInRole(UserRole.ROLE_EDIT_ALL_PROJECTS)) {
return null;
} else {
String strQuery = "SELECT oa.order.id "
+ "FROM OrderAuthorization oa "
+ "WHERE oa.user = :user "
+ "OR oa.profile IN (:profiles) ";
Query query = getSession().createQuery(strQuery);
query.setParameter("user", user);
query.setParameterList("profiles", user.getProfiles());
return query.list();
}
}
@Override
public List<Order> getOrdersByWriteAuthorization(User user) {
if (user.isInRole(UserRole.ROLE_SUPERUSER)
@ -278,6 +465,23 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return existsInScenario(getOrdersByReadAuthorization(user), scenario);
}
@Override
public List<Order> getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
String username, Scenario scenario, Date startDate, Date endDate,
List<Label> labels, List<Criterion> criteria,
ExternalCompany customer, OrderStatusEnum state) {
User user;
try {
user = userDAO.findByLoginName(username);
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
}
return existsInScenario(
getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
user, startDate, endDate, labels, criteria, customer,
state), scenario);
}
private List<Order> existsInScenario(List<Order> orders, Scenario scenario) {
List<Order> result = new ArrayList<Order>();
for (Order each : orders) {

View file

@ -33,6 +33,7 @@ import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderLineGroup;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.entities.PositionConstraintType;
import org.libreplan.business.qualityforms.entities.QualityForm;
import org.libreplan.business.resources.entities.Criterion;
@ -87,6 +88,10 @@ public interface IOrderModel extends IIntegrationEntityModel {
List<Order> getOrders();
List<Order> getOrders(Date startDate, Date endDate, List<Label> labels,
List<Criterion> criteria, ExternalCompany customer,
OrderStatusEnum state);
void initEdit(Order order, Desktop desktop);
void prepareForCreate(Desktop desktop);

View file

@ -23,6 +23,8 @@ package org.libreplan.web.orders;
import static org.libreplan.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.HashMap;
@ -49,6 +51,7 @@ import org.libreplan.business.orders.entities.Order.SchedulingMode;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.entities.PositionConstraintType;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.templates.entities.OrderTemplate;
import org.libreplan.business.users.daos.IUserDAO;
import org.libreplan.business.users.entities.User;
@ -63,6 +66,7 @@ import org.libreplan.web.common.Util.ReloadStrategy;
import org.libreplan.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.libreplan.web.common.components.bandboxsearch.BandboxSearch;
import org.libreplan.web.common.components.finders.FilterPair;
import org.libreplan.web.common.components.finders.OrderFilterEnum;
import org.libreplan.web.orders.criterionrequirements.AssignedCriterionRequirementToOrderElementController;
import org.libreplan.web.orders.labels.AssignedLabelsToOrderElementController;
import org.libreplan.web.orders.labels.LabelsAssignmentToOrderElementComponent;
@ -694,7 +698,43 @@ public class OrderCRUDController extends GenericForwardComposer {
}
public List<Order> getOrders() {
return orderModel.getOrders();
List<org.libreplan.business.labels.entities.Label> labels = new ArrayList<org.libreplan.business.labels.entities.Label>();
List<Criterion> criteria = new ArrayList<Criterion>();
ExternalCompany customer = null;
OrderStatusEnum state = null;
for (FilterPair filterPair : (List<FilterPair>) bdFilters
.getSelectedElements()) {
OrderFilterEnum type = (OrderFilterEnum) filterPair.getType();
switch (type) {
case Label:
labels.add((org.libreplan.business.labels.entities.Label) filterPair
.getValue());
break;
case Criterion:
criteria.add((Criterion) filterPair.getValue());
break;
case ExternalCompany:
if (customer != null) {
// It's impossible to have an Order associated to more than
// 1 customer
return Collections.emptyList();
}
customer = (ExternalCompany) filterPair.getValue();
break;
case State:
if (state != null) {
// It's impossible to have an Order associated with more
// than 1 state
return Collections.emptyList();
}
state = (OrderStatusEnum) filterPair.getValue();
break;
}
}
return orderModel.getOrders(filterStartDate.getValue(),
filterFinishDate.getValue(), labels, criteria, customer, state);
}
private OnlyOneVisible getVisibility() {

View file

@ -58,6 +58,7 @@ import org.libreplan.business.orders.entities.HoursGroup;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderLineGroup;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.entities.IMoneyCostCalculator;
import org.libreplan.business.planner.entities.PositionConstraintType;
import org.libreplan.business.qualityforms.daos.IQualityFormDAO;
@ -222,6 +223,22 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
return orders;
}
@Override
@Transactional(readOnly = true)
public List<Order> getOrders(Date startDate, Date endDate,
List<Label> labels, List<Criterion> criteria,
ExternalCompany customer, OrderStatusEnum state) {
getLabelsOnConversation().reattachLabels();
List<Order> orders = orderDAO
.getOrdersByReadAuthorizationBetweenDatesByLabelsCriteriaCustomerAndState(
SecurityUtils.getSessionUserLoginName(),
scenarioManager.getCurrent(), startDate, endDate,
labels, criteria, customer, state);
initializeOrders(orders);
return orders;
}
private void initializeOrders(List<Order> list) {
for (Order order : list) {
orderDAO.reattachUnmodifiedEntity(order);