/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolóxico de Galicia * Copyright (C) 2010-2012 Igalia, S.L. * * 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.libreplan.web.orders; import static org.libreplan.web.I18nHelper._; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import org.apache.commons.lang3.Validate; import org.libreplan.business.advance.entities.AdvanceMeasurement; import org.libreplan.business.advance.entities.DirectAdvanceAssignment; import org.libreplan.business.advance.entities.IndirectAdvanceAssignment; import org.libreplan.business.calendars.daos.IBaseCalendarDAO; import org.libreplan.business.calendars.entities.BaseCalendar; import org.libreplan.business.common.IntegrationEntity; import org.libreplan.business.common.daos.IConfigurationDAO; import org.libreplan.business.common.entities.Configuration; import org.libreplan.business.common.entities.EntityNameEnum; import org.libreplan.business.common.exceptions.InstanceNotFoundException; import org.libreplan.business.externalcompanies.daos.IExternalCompanyDAO; import org.libreplan.business.externalcompanies.entities.EndDateCommunication; import org.libreplan.business.externalcompanies.entities.ExternalCompany; import org.libreplan.business.labels.daos.ILabelDAO; import org.libreplan.business.labels.entities.Label; import org.libreplan.business.orders.daos.IOrderDAO; import org.libreplan.business.orders.daos.IOrderElementDAO; 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.PositionConstraintType; import org.libreplan.business.qualityforms.daos.IQualityFormDAO; import org.libreplan.business.qualityforms.entities.QualityForm; import org.libreplan.business.requirements.entities.DirectCriterionRequirement; import org.libreplan.business.resources.daos.ICriterionDAO; import org.libreplan.business.resources.daos.ICriterionTypeDAO; import org.libreplan.business.resources.entities.Criterion; import org.libreplan.business.resources.entities.CriterionType; import org.libreplan.business.scenarios.IScenarioManager; import org.libreplan.business.scenarios.daos.IOrderVersionDAO; import org.libreplan.business.scenarios.daos.IScenarioDAO; import org.libreplan.business.scenarios.entities.OrderVersion; import org.libreplan.business.scenarios.entities.Scenario; import org.libreplan.business.templates.daos.IOrderElementTemplateDAO; import org.libreplan.business.templates.entities.OrderElementTemplate; import org.libreplan.business.templates.entities.OrderTemplate; import org.libreplan.business.users.daos.IOrderAuthorizationDAO; import org.libreplan.business.users.daos.IUserDAO; import org.libreplan.business.users.entities.OrderAuthorization; import org.libreplan.business.users.entities.OrderAuthorizationType; import org.libreplan.business.users.entities.User; import org.libreplan.business.users.entities.UserRole; import org.libreplan.web.calendars.BaseCalendarModel; import org.libreplan.web.common.IntegrationEntityModel; import org.libreplan.web.common.concurrentdetection.OnConcurrentModification; import org.libreplan.web.logs.IIssueLogModel; import org.libreplan.web.logs.IRiskLogModel; import org.libreplan.web.orders.files.IOrderFileModel; import org.libreplan.web.orders.labels.LabelsOnConversation; import org.libreplan.web.planner.order.ISaveCommand.IBeforeSaveActions; import org.libreplan.web.planner.order.PlanningStateCreator; import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState; import org.libreplan.web.security.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.zkoss.ganttz.IPredicate; import org.zkoss.zk.ui.Desktop; /** * Model for UI operations related to {@link Order}. * <br /> * @author Óscar González Fernández <ogonzalez@igalia.com> * @author Diego Pino García <dpino@igalia.com> * @author Jacobo Aragunde Pérez <jaragunde@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com> */ @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) @OnConcurrentModification(goToPage = "/planner/index.zul;orders_list") public class OrderModel extends IntegrationEntityModel implements IOrderModel { @Autowired private ICriterionTypeDAO criterionTypeDAO; @Autowired private IExternalCompanyDAO externalCompanyDAO; private final Map<CriterionType, List<Criterion>> mapCriterions = new HashMap<>(); private List<ExternalCompany> externalCompanies = new ArrayList<>(); @Autowired private IOrderDAO orderDAO; @Autowired private PlanningStateCreator planningStateCreator; private PlanningState planningState; private OrderElementTreeModel orderElementTreeModel; @Autowired private IOrderElementModel orderElementModel; @Autowired private ICriterionDAO criterionDAO; @Autowired private ILabelDAO labelDAO; @Autowired private IQualityFormDAO qualityFormDAO; @Autowired private IOrderElementDAO orderElementDAO; @Autowired private IOrderElementTemplateDAO templateDAO; @Autowired private IBaseCalendarDAO baseCalendarDAO; @Autowired private IConfigurationDAO configurationDAO; @Autowired private IUserDAO userDAO; @Autowired private IOrderAuthorizationDAO orderAuthorizationDAO; @Autowired private IScenarioDAO scenarioDAO; @Autowired private IScenarioManager scenarioManager; @Autowired private IOrderVersionDAO orderVersionDAO; @Autowired private IOrderFileModel orderFileModel; @Autowired private IRiskLogModel riskLogModel; @Autowired private IIssueLogModel issueLogModel; private List<Order> orderList = new ArrayList<>(); @Override @Transactional(readOnly = true) public List<Label> getLabels() { return getLabelsOnConversation().getLabels(); } private LabelsOnConversation labelsOnConversation; private LabelsOnConversation getLabelsOnConversation() { if ( labelsOnConversation == null ) { labelsOnConversation = new LabelsOnConversation(labelDAO); } return labelsOnConversation; } private QualityFormsOnConversation qualityFormsOnConversation; private QualityFormsOnConversation getQualityFormsOnConversation() { if ( qualityFormsOnConversation == null ) { qualityFormsOnConversation = new QualityFormsOnConversation(qualityFormDAO); } return qualityFormsOnConversation; } @Override public List<QualityForm> getQualityForms() { return getQualityFormsOnConversation().getQualityForms(); } @Override public void addLabel(Label label) { getLabelsOnConversation().addLabel(label); } @Override @Transactional(readOnly = true) public List<Order> getOrders() { getLabelsOnConversation().reattachLabels(); List<Order> orders = orderDAO.getOrdersByReadAuthorizationByScenario( SecurityUtils.getSessionUserLoginName(), scenarioManager.getCurrent()); initializeOrders(orders); 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); if (order.getCustomer() != null) { order.getCustomer().getName(); } order.getAdvancePercentage(); for (Label label : order.getLabels()) { label.getName(); } order.getScenarios().size(); } this.orderList = list; } private void loadCriterions() { mapCriterions.clear(); List<CriterionType> criterionTypes = criterionTypeDAO.getCriterionTypes(); for (CriterionType criterionType : criterionTypes) { List<Criterion> criterions = new ArrayList<>(criterionDAO.findByType(criterionType)); mapCriterions.put(criterionType, criterions); } } @Override public Map<CriterionType, List<Criterion>> getMapCriterions(){ final Map<CriterionType, List<Criterion>> result = new HashMap<>(); result.putAll(mapCriterions); return result; } @Override @Transactional(readOnly = true) public void initEdit(Order orderToEdit, Desktop desktop) { Validate.notNull(orderToEdit); loadNeededDataForConversation(); this.planningState = planningStateCreator.retrieveOrCreate(desktop, orderToEdit, planningState1 -> planningState1.reattach()); Order order = this.planningState.getOrder(); this.orderElementTreeModel = new OrderElementTreeModel(order); forceLoadAdvanceAssignmentsAndMeasurements(order); forceLoadCriterionRequirements(order); forceLoadCalendar(this.getCalendar()); forceLoadCustomer(order.getCustomer()); forceLoadDeliveringDates(order); forceLoadLabels(order); forceLoadMaterialAssignments(order); forceLoadTaskQualityForms(order); forceLoadEndDateCommunicationToCustomer(order); initOldCodes(); } private void forceLoadEndDateCommunicationToCustomer(Order order) { if ( order != null ) { order.getEndDateCommunicationToCustomer().size(); } } private void forceLoadDeliveringDates(Order order){ order.getDeliveringDates().size(); } private void forceLoadLabels(OrderElement orderElement) { orderElement.getLabels().size(); for (OrderElement each : orderElement.getChildren()) { forceLoadLabels(each); } } private void forceLoadMaterialAssignments(OrderElement orderElement) { orderElement.getMaterialAssignments().size(); for (OrderElement each : orderElement.getChildren()) { forceLoadMaterialAssignments(each); } } private void forceLoadTaskQualityForms(OrderElement orderElement) { orderElement.getTaskQualityForms().size(); for (OrderElement each : orderElement.getChildren()) { forceLoadTaskQualityForms(each); } } private void forceLoadCustomer(ExternalCompany customer) { if (customer != null) { customer.getName(); } } private void loadNeededDataForConversation() { loadCriterions(); initializeCacheLabels(); getQualityFormsOnConversation().initialize(); loadExternalCompaniesAreClient(); } private void reattachNeededDataForConversation() { reattachCriterions(); reattachLabels(); getQualityFormsOnConversation().reattach(); } private void initializeCacheLabels() { getLabelsOnConversation().initializeLabels(); } private static void forceLoadCriterionRequirements(OrderElement orderElement) { orderElement.getHoursGroups().size(); for (HoursGroup hoursGroup : orderElement.getHoursGroups()) { attachDirectCriterionRequirement(hoursGroup.getDirectCriterionRequirement()); } attachDirectCriterionRequirement(orderElement.getDirectCriterionRequirement()); for (OrderElement child : orderElement.getChildren()) { forceLoadCriterionRequirements(child); } } private static void attachDirectCriterionRequirement(Set<DirectCriterionRequirement> requirements) { for (DirectCriterionRequirement requirement : requirements) { requirement.getChildren().size(); requirement.getCriterion().getName(); requirement.getCriterion().getType().getName(); } } private void forceLoadAdvanceAssignmentsAndMeasurements(OrderElement orderElement) { for (DirectAdvanceAssignment directAdvanceAssignment : orderElement.getDirectAdvanceAssignments()) { directAdvanceAssignment.getAdvanceType().getUnitName(); for (AdvanceMeasurement advanceMeasurement : directAdvanceAssignment.getAdvanceMeasurements()) { advanceMeasurement.getValue(); } } if (orderElement instanceof OrderLineGroup) { for (IndirectAdvanceAssignment indirectAdvanceAssignment : orderElement.getIndirectAdvanceAssignments()) { indirectAdvanceAssignment.getAdvanceType().getUnitName(); } for (OrderElement child : orderElement.getChildren()) { forceLoadAdvanceAssignmentsAndMeasurements(child); } } } @Override @Transactional(readOnly = true) public void prepareForCreate(Desktop desktop) { loadNeededDataForConversation(); this.planningState = planningStateCreator.createOn(desktop, Order.create()); planningState.getOrder().setInitDate(new Date()); initializeOrder(); initializeCode(); initializeCalendar(); } private void initializeOrder() { this.orderElementTreeModel = new OrderElementTreeModel(planningState.getOrder()); } private void initializeCode() { setDefaultCode(); planningState.getOrder().setCodeAutogenerated(true); } private void initializeCalendar() { this.planningState.getOrder().setCalendar(getDefaultCalendar()); } @Override @Transactional(readOnly = true) public void prepareCreationFrom(OrderTemplate template, Desktop desktop) { loadNeededDataForConversation(); Order newOrder = createOrderFrom((OrderTemplate) templateDAO.findExistingEntity(template.getId())); newOrder.setCode(getOrder().getCode()); newOrder.setCodeAutogenerated(true); newOrder.setName(getOrder().getName()); newOrder.setCustomer(getOrder().getCustomer()); newOrder.setCalendar(getCalendar()); newOrder.setInitDate(getOrder().getInitDate()); if ( getOrder().getDeadline() != null ) { newOrder.setDeadline(getOrder().getDeadline()); } planningState = planningStateCreator.createOn(desktop, newOrder); forceLoadAdvanceAssignmentsAndMeasurements(planningState.getOrder()); initializeOrder(); } private Order createOrderFrom(OrderTemplate template) { return template.createOrder(scenarioManager.getCurrent()); } private OrderElement createOrderElementFrom(OrderLineGroup parent, OrderElementTemplate template) { Validate.notNull(parent); return template.createElement(parent); } @Override @Transactional(readOnly = true) public OrderElement createFrom(OrderLineGroup parent, OrderElementTemplate template) { reattachNeededDataForConversation(); OrderElement result = createOrderElementFrom(parent, templateDAO.findExistingEntity(template.getId())); if ( isCodeAutogenerated() ) { setAllCodeToNull(result); } forceLoadAdvanceAssignmentsAndMeasurements(result); return result; } private void setAllCodeToNull(OrderElement result) { result.setCode(null); for (OrderElement each : result.getChildren()) { setAllCodeToNull(each); } } @Override public void save() { save(false); } @Override public void save(boolean showSaveMessage) { IBeforeSaveActions beforeSaveActions = () -> { reattachCalendar(); reattachCriterions(); }; if ( showSaveMessage ) { this.planningState.getSaveCommand().save(beforeSaveActions); } else { this.planningState.getSaveCommand().save(beforeSaveActions, null); } } private void reattachCalendar() { if ( planningState.getOrder().getCalendar() == null ) { return; } BaseCalendar calendar = planningState.getOrder().getCalendar(); baseCalendarDAO.reattachUnmodifiedEntity(calendar); } private void reattachCriterions() { for (List<Criterion> list : mapCriterions.values()) { for (Criterion criterion : list) { criterionDAO.reattachUnmodifiedEntity(criterion); } } } @Override public Order getOrder() { return planningState.getOrder(); } @Override @Transactional public void remove(Order detachedOrder) { Order order = orderDAO.findExistingEntity(detachedOrder.getId()); removeFiles(order); removeLogs(order); removeVersions(order); if ( order.hasNoVersions() ) { removeOrderFromDB(order); } } private void removeLogs(Order order) { riskLogModel.getByParent(order).forEach(riskLog -> riskLogModel.remove(riskLog)); issueLogModel.getByParent(order).forEach(issueLog -> issueLogModel.remove(issueLog)); } private void removeFiles(Order order) { orderFileModel.findByParent(order).forEach(orderFile -> orderFileModel.delete(orderFile)); } private void removeVersions(Order order) { Map<Long, OrderVersion> versionsRemovedById = new HashMap<>(); List<Scenario> currentAndDerived = currentAndDerivedScenarios(); for (Scenario each : currentAndDerived) { OrderVersion versionRemoved = order.disassociateFrom(each); if ( versionRemoved != null ) { versionsRemovedById.put(versionRemoved.getId(), versionRemoved); } } for (OrderVersion each : versionsRemovedById.values()) { if ( !order.isVersionUsed(each) ) { removeOrderVersionAt(each, currentAndDerived); removeOrderVersionFromDB(each); } } } private void removeOrderVersionAt(OrderVersion orderVersion, Collection<? extends Scenario> currentAndDerived) { for (Scenario each : currentAndDerived) { each.removeVersion(orderVersion); } } private List<Scenario> currentAndDerivedScenarios() { List<Scenario> scenariosToBeDisassociatedFrom = new ArrayList<>(); Scenario currentScenario = scenarioManager.getCurrent(); scenariosToBeDisassociatedFrom.add(currentScenario); scenariosToBeDisassociatedFrom.addAll(scenarioDAO.getDerivedScenarios(currentScenario)); return scenariosToBeDisassociatedFrom; } private void removeOrderVersionFromDB(OrderVersion currentOrderVersion) { try { orderVersionDAO.remove(currentOrderVersion.getId()); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } } private void removeOrderFromDB(Order order) { try { orderDAO.remove(order.getId()); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } } @Override public OrderElementTreeModel getOrderElementTreeModel() { return orderElementTreeModel; } @Override @Transactional(readOnly = true) public OrderElementTreeModel getOrderElementsFilteredByPredicate(IPredicate predicate) { // Iterate through orderElements from order List<OrderElement> orderElements = new ArrayList<>(); for (OrderElement orderElement : planningState.getOrder().getAllOrderElements()) { if (!orderElement.isNewObject()) { reattachOrderElement(orderElement); } // Accepts predicate, add it to list of orderElements if (predicate.accepts(orderElement)) { orderElements.add(orderElement); } } // Return list of filtered elements return new OrderElementTreeModel(planningState.getOrder(), orderElements); } private void reattachLabels() { getLabelsOnConversation().reattachLabels(); } private void reattachOrderElement(OrderElement orderElement) { orderElementDAO.reattach(orderElement); } @Override @Transactional(readOnly = true) public IOrderElementModel getOrderElementModel(OrderElement orderElement) { reattachCriterions(); orderElementModel.setCurrent(orderElement, this); return orderElementModel; } @Override public List<Criterion> getCriterionsFor(CriterionType criterionType) { return mapCriterions.get(criterionType); } @Override public void setPlanningState(PlanningState planningState) { this.planningState = planningState; } @Override @Transactional(readOnly = true) public List<BaseCalendar> getBaseCalendars() { List<BaseCalendar> result = baseCalendarDAO.getBaseCalendars(); for (BaseCalendar each : result) { BaseCalendarModel.forceLoadBaseCalendar(each); } return result; } @Override @Transactional(readOnly = true) public BaseCalendar getDefaultCalendar() { Configuration configuration = configurationDAO.getConfiguration(); if (configuration == null) { return null; } BaseCalendar defaultCalendar = configuration.getDefaultCalendar(); forceLoadCalendar(defaultCalendar); return defaultCalendar; } private void forceLoadCalendar(BaseCalendar calendar) { BaseCalendarModel.forceLoadBaseCalendar(calendar); } @Override public BaseCalendar getCalendar() { if (planningState == null) { return null; } return planningState.getOrder().getCalendar(); } @Override public void setCalendar(BaseCalendar calendar) { if (planningState != null) { planningState.getOrder().setCalendar(calendar); } } @Override public boolean isCodeAutogenerated() { if (planningState == null) { return false; } return planningState.getOrder().isCodeAutogenerated(); } @Override public List<ExternalCompany> getExternalCompaniesAreClient() { return externalCompanies; } private void loadExternalCompaniesAreClient() { this.externalCompanies = externalCompanyDAO.getExternalCompaniesAreClient(); Collections.sort(this.externalCompanies); } @Override public void setExternalCompany(ExternalCompany externalCompany) { if (this.getOrder() != null) { Order order = getOrder(); order.setCustomer(externalCompany); } } @Override @Transactional(readOnly = true) public String gettooltipText(Order order) { orderDAO.reattachUnmodifiedEntity(order); StringBuilder result = new StringBuilder(); result.append(_("Progress") + ": ").append(getEstimatedAdvance(order)).append("% , "); result.append(_("Hours invested")).append(": ").append(getHoursAdvancePercentage(order)).append("%\n"); if (!getDescription(order).equals("")) { result.append(" , " + _("Description") + ": " + getDescription(order) + "\n"); } String labels = buildLabelsText(order); if (!labels.equals("")) { result.append(" , " + _("Labels") + ": " + labels); } return result.toString(); } private String getDescription(Order order) { if (order.getDescription() != null) { return order.getDescription(); } return ""; } private BigDecimal getEstimatedAdvance(Order order) { return order.getAdvancePercentage().multiply(new BigDecimal(100)); } private BigDecimal getHoursAdvancePercentage(Order order) { BigDecimal result; if (order != null) { result = orderElementDAO.getHoursAdvancePercentage(order); } else { result = new BigDecimal(0); } return result.multiply(new BigDecimal(100)); } private String buildLabelsText(Order order) { StringBuilder result = new StringBuilder(); Set<Label> labels = order.getLabels(); if (!labels.isEmpty()) { for (Label label : labels) { result.append(label.getName()).append(","); } result.delete(result.length() - 1, result.length()); } return result.toString(); } /** * Operation to filter the order list. */ @Override @Transactional(readOnly = true) public List<Order> getFilterOrders(OrderPredicate predicate) { reattachLabels(); List<Order> filterOrderList = new ArrayList<>(); for (Order order : orderList) { orderDAO.reattach(order); if (predicate.accepts(order)) { filterOrderList.add(order); } } return filterOrderList; } @Override @Transactional(readOnly = true) public boolean userCanRead(Order order, String loginName) { if (SecurityUtils.isSuperuserOrUserInRoles( UserRole.ROLE_READ_ALL_PROJECTS, UserRole.ROLE_EDIT_ALL_PROJECTS)) { return true; } if (order.isNewObject() & SecurityUtils .isSuperuserOrUserInRoles(UserRole.ROLE_CREATE_PROJECTS)) { return true; } try { User user = userDAO.findByLoginName(loginName); for(OrderAuthorization authorization : orderAuthorizationDAO.listByOrderUserAndItsProfiles(order, user)) { if(authorization.getAuthorizationType() == OrderAuthorizationType.READ_AUTHORIZATION || authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) { return true; } } } catch(InstanceNotFoundException e) { // This case shouldn't happen, because it would mean that there isn't a logged user //anyway, if it happenned we don't allow the user to pass } return false; } @Override @Transactional(readOnly = true) public boolean userCanWrite(Order order) { return SecurityUtils.loggedUserCanWrite(order); } @Override @Transactional(readOnly = true) public boolean isAlreadyInUse(OrderElement orderElement) { return orderElementDAO.isAlreadyInUseThisOrAnyOfItsChildren(orderElement); } @Override @Transactional(readOnly = true) public boolean isAlreadyInUseAndIsOnlyInCurrentScenario(Order order) { return isAlreadyInUse(order) && (order.getScenarios().size() == 1); } @Override @Transactional(readOnly = true) public void useSchedulingDataForCurrentScenario(Order order) { orderDAO.reattach(order); order.useSchedulingDataFor(scenarioManager.getCurrent()); } @Override public EntityNameEnum getEntityName() { return EntityNameEnum.ORDER; } @Override public Set<IntegrationEntity> getChildren() { Set<IntegrationEntity> children = new HashSet<>(); if (planningState != null) { children.addAll(planningState.getOrder().getOrderElements()); } return children; } @Override public IntegrationEntity getCurrentEntity() { return this.planningState.getOrder(); } @Override public PlanningState getPlanningState() { return planningState; } @Override @Transactional(readOnly = true) public boolean hasImputedExpenseSheetsThisOrAnyOfItsChildren(OrderElement order) { if (order.isNewObject()) { return false; } try { return orderElementDAO.hasImputedExpenseSheetThisOrAnyOfItsChildren(order.getId()); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } } public void removeAskedEndDate(EndDateCommunication endDate) { Order order = getOrder(); if (getOrder() != null && endDate != null) { order.removeAskedEndDate(endDate); } } @Override public SortedSet<EndDateCommunication> getEndDates() { Order order = getOrder(); if (getOrder() != null) { return order.getEndDateCommunicationToCustomer(); } return new TreeSet<>(); } @Override public void addAskedEndDate(Date value) { if (getOrder() != null) { Order order = getOrder(); EndDateCommunication askedEndDate = EndDateCommunication.create(new Date(), value, null); order.addAskedEndDate(askedEndDate); } } @Override public boolean alreadyExistsRepeatedEndDate(Date value) { if (getOrder() != null) { Order order = getOrder(); if (order.getEndDateCommunicationToCustomer().isEmpty()) { return false; } EndDateCommunication endDateCommunicationToCustomer = order.getEndDateCommunicationToCustomer().first(); Date currentEndDate = endDateCommunicationToCustomer.getEndDate(); return (currentEndDate.compareTo(value) == 0); } return false; } public boolean isAnyTaskWithConstraint(PositionConstraintType type) { return !((planningState == null) || (planningState.getRootTask() == null)) && planningState.getRootTask().isAnyTaskWithConstraint(type); } @Override @Transactional(readOnly = true) public boolean isOnlyChildAndParentAlreadyInUseByHoursOrExpenses(OrderElement orderElement) { try { OrderLineGroup parent = orderElement.getParent(); if (!parent.isOrder() && !parent.isNewObject() && parent.getChildren().size() == 1) { if (orderElementDAO.isAlreadyInUse(parent)) { return true; } if (orderElementDAO.hasImputedExpenseSheet(parent.getId())) { return true; } } return false; } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } } @Override @Transactional(readOnly = true) public User getUser() { User user; try { user = this.userDAO.findByLoginName(SecurityUtils .getSessionUserLoginName()); } catch (InstanceNotFoundException e) { throw new RuntimeException(e); } // Attach filter bandbox elements if (user.getProjectsFilterLabel() != null) { user.getProjectsFilterLabel().getFinderPattern(); } return user; } }