ItEr49S11CUEngadirModeloTraballoAOrganizacionTraballoItEr48S12: Add support for CriterionRequirements and HoursGroup in OrderElemenTemplate

* Copy CriterionRequirements and HoursGroup from OrderElement to OrderElementTemplate
* Copy back CriterionRequirements and HoursGroup from OrderElementTemplate to OrderElement
This commit is contained in:
Diego Pino Garcia 2010-02-22 12:02:14 +01:00 committed by Javier Moran Rua
parent 07cac13e47
commit 8e6ca35718
46 changed files with 3598 additions and 1117 deletions

View file

@ -20,141 +20,154 @@
package org.navalplanner.business.orders.entities;
import static org.navalplanner.business.i18n.I18nHelper._;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.sql.Template;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.ResourceEnum;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public class CriterionRequirementHandler implements
// <OrderElement, OrderLine, OrderLineGroup>
public abstract class CriterionRequirementHandler<T, S, R> implements
ICriterionRequirementHandler {
private static final CriterionRequirementHandler singleton = new CriterionRequirementHandler();
private CriterionRequirementHandler() {
}
public static CriterionRequirementHandler getInstance() {
return singleton;
}
// Operations to add a criterionRequirement
public void propagateDirectCriterionRequirementAddition(
OrderElement orderElement, CriterionRequirement directo) {
public void propagateDirectCriterionRequirementAddition(T orderElement,
CriterionRequirement directo) {
propagateIndirectCriterionRequirement(orderElement,
(DirectCriterionRequirement) directo);
}
private void propagateIndirectCriterionRequirement(
OrderElement orderElement,
CriterionRequirement directo) {
if (orderElement instanceof OrderLine) {
propagateIndirectCriterionRequirementToChildren(
(OrderLine) orderElement,
(DirectCriterionRequirement) directo);
protected void propagateIndirectCriterionRequirement(T orderElement,
CriterionRequirement direct) {
if (isOrderLine(orderElement)) {
propagateIndirectCriterionRequirementToOrderLineChildren(
toOrderLine(orderElement),
(DirectCriterionRequirement) direct);
} else {
propagateIndirectCriterionRequirementToChildren(
(OrderLineGroup) orderElement,
(DirectCriterionRequirement) directo);
propagateIndirectCriterionRequirementToOrderLineGroupChildren(
toOrderLineGroup(orderElement),
(DirectCriterionRequirement) direct);
}
}
void propagateIndirectCriterionRequirementToChildren(
OrderLineGroup orderLineGroup, DirectCriterionRequirement parent) {
protected void propagateIndirectCriterionRequirementToOrderLineGroupChildren(
R orderLineGroup, DirectCriterionRequirement parent) {
Criterion criterion = parent.getCriterion();
for (OrderElement child : orderLineGroup.getChildren()) {
for (T child : getOrderLineGroupChildren(orderLineGroup)) {
IndirectCriterionRequirement indirect = IndirectCriterionRequirement
.create(parent, criterion);
child.addIndirectCriterionRequirement(indirect);
addIndirectCriterionRequirement(child, indirect);
propagateIndirectCriterionRequirement(child, parent);
}
}
void propagateIndirectCriterionRequirementToChildren(OrderLine orderLine,
DirectCriterionRequirement parent) {
Criterion criterion = parent.getCriterion();
for (HoursGroup hoursGroup : orderLine.getHoursGroups()) {
protected void propagateIndirectCriterionRequirementToOrderLineChildren(
S orderLine, DirectCriterionRequirement parent) {
for (HoursGroup hoursGroup : getHoursGroups(orderLine)) {
hoursGroup.updateMyCriterionRequirements();
}
}
boolean canAddCriterionRequirement(OrderElement orderElement,
protected abstract boolean isOrderLine(T orderElement);
protected abstract S toOrderLine(T orderElement);
protected abstract R toOrderLineGroup(T orderElement);
protected abstract List<HoursGroup> getHoursGroups(S orderline);
protected abstract List<T> getOrderLineGroupChildren(R orderLineGroup);
public boolean canAddCriterionRequirement(T orderElement,
CriterionRequirement newRequirement) {
List<OrderElement> listOrderElements = orderElement.getAllChildren();
List<T> listOrderElements = getAllChildren(orderElement);
listOrderElements.add(orderElement);
for (OrderElement element : listOrderElements) {
for (T element : listOrderElements) {
if (existSameCriterionRequirement(element, newRequirement))
return false;
}
return true;
}
private boolean existSameCriterionRequirement(OrderElement orderElement,
CriterionRequirement newRequirement){
if (orderElement instanceof OrderLine) {
return existSameCriterionRequirementIntoOrderLine(
(OrderLine) orderElement,newRequirement);
protected abstract List<T> getAllChildren(T orderElement);
public boolean existSameCriterionRequirement(T orderElement,
CriterionRequirement newRequirement) {
if (isOrderLine(orderElement)) {
return existSameCriterionRequirementIntoOrderLine(toOrderLine(orderElement), newRequirement);
} else {
return existSameCriterionRequirementIntoOrderElement(
(OrderLineGroup) orderElement, newRequirement);
return existSameCriterionRequirementIntoOrderElement(orderElement,
newRequirement);
}
}
private boolean existSameCriterionRequirementIntoOrderElement(
OrderElement orderElement,
public boolean existSameCriterionRequirementIntoOrderLine(S orderLine,
CriterionRequirement newRequirement) {
Criterion criterion = newRequirement.getCriterion();
for (CriterionRequirement requirement : orderElement
.getCriterionRequirements()) {
if (requirement.getCriterion().equals(criterion))
return true;
}
return false;
}
boolean existSameCriterionRequirementIntoOrderLine(OrderLine orderLine,
CriterionRequirement newRequirement) {
if (existSameCriterionRequirementIntoOrderElement(orderLine,
if (existSameCriterionRequirementIntoOrderElement(toOrderElement(orderLine),
newRequirement)) {
return true;
}
for (HoursGroup hoursGroup : orderLine.getHoursGroups()) {
for (HoursGroup hoursGroup : getHoursGroups(orderLine)) {
if (hoursGroup.existSameCriterionRequirement(newRequirement))
return true;
}
return false;
}
protected abstract T toOrderElement(S orderLine);
public boolean existSameCriterionRequirementIntoOrderElement(
T orderElement, CriterionRequirement newRequirement) {
Criterion criterion = newRequirement.getCriterion();
for (CriterionRequirement requirement : getCriterionRequirements(orderElement)) {
if (requirement.getCriterion().equals(criterion))
return true;
}
return false;
}
protected abstract Set<CriterionRequirement> getCriterionRequirements(
T orderElement);
/*
* Operations to set the valid value of a criterion Requirements and the
* criterion Requirement of its children.
*/
public void propagateValidCriterionRequirement(OrderElement orderElement,
public void propagateValidCriterionRequirement(T orderElement,
DirectCriterionRequirement parent, boolean valid) {
if (orderElement instanceof OrderLine) {
setValidCriterionRequirementChildren((OrderLine) orderElement,
parent, valid);
if (isOrderLine(orderElement)) {
setValidCriterionRequirementChildrenAsOrderLine(
toOrderLine(orderElement), parent, valid);
} else {
setValidCriterionRequirementChildren((OrderLineGroup) orderElement,
parent, valid);
setValidCriterionRequirementChildrenAsOrderLineGroup(
toOrderLineGroup(orderElement), parent, valid);
}
}
protected void setValidCriterionRequirementChildren(
OrderLineGroup orderLineGroup,
DirectCriterionRequirement parent, boolean valid) {
for (OrderElement child : orderLineGroup.getChildren()) {
protected void setValidCriterionRequirementChildrenAsOrderLineGroup(
R orderLineGroup, DirectCriterionRequirement parent,
boolean valid) {
for (T child : getOrderLineGroupChildren(orderLineGroup)) {
IndirectCriterionRequirement indirect = findIndirectRequirementByParent(
child.getIndirectCriterionRequirement(), parent);
getIndirectCriterionRequirement(child), parent);
if (indirect != null) {
indirect.setValid(valid);
}
@ -162,9 +175,12 @@ public class CriterionRequirementHandler implements
}
}
protected void setValidCriterionRequirementChildren(OrderLine orderLine,
protected abstract Set<IndirectCriterionRequirement> getIndirectCriterionRequirement(
T orderElement);
protected void setValidCriterionRequirementChildrenAsOrderLine(S orderLine,
DirectCriterionRequirement parent, boolean valid) {
for (HoursGroup hoursGroup : orderLine.getHoursGroups()) {
for (HoursGroup hoursGroup : getHoursGroups(orderLine)) {
IndirectCriterionRequirement indirect = findIndirectRequirementByParent(
hoursGroup.getIndirectCriterionRequirement(), parent);
if (indirect != null) {
@ -177,31 +193,34 @@ public class CriterionRequirementHandler implements
* Operation to update the criterions requirements of the orderElement and
* its children
*/
public void propagateRemoveCriterionRequirement(OrderElement orderElement,
public void propagateRemoveCriterionRequirement(T orderElement,
DirectCriterionRequirement parent) {
if (orderElement instanceof OrderLine) {
removeIndirectCriterionRequirement((OrderLine) orderElement, parent);
if (isOrderLine(orderElement)) {
removeIndirectCriterionRequirementAsOrderLine(toOrderLine(orderElement), parent);
} else {
removeIndirectCriterionRequirement((OrderLineGroup) orderElement,
removeIndirectCriterionRequirement(toOrderLineGroup(orderElement),
parent);
}
}
protected void removeIndirectCriterionRequirement(
OrderLineGroup orderLineGroup, DirectCriterionRequirement parent) {
for (OrderElement child : orderLineGroup.getChildren()) {
R orderLineGroup, DirectCriterionRequirement parent) {
for (T child : getOrderLineGroupChildren(orderLineGroup)) {
IndirectCriterionRequirement indirect = findIndirectRequirementByParent(
child.getIndirectCriterionRequirement(), parent);
getIndirectCriterionRequirement(child), parent);
if (indirect != null) {
propagateRemoveCriterionRequirement(child, parent);
child.removeCriterionRequirement(indirect);
removeCriterionRequirement(child, indirect);
}
}
}
protected void removeIndirectCriterionRequirement(OrderLine orderLine,
protected abstract void removeCriterionRequirement(T orderElement,
CriterionRequirement criterionRequirement);
protected void removeIndirectCriterionRequirementAsOrderLine(S orderLine,
DirectCriterionRequirement parent) {
for (HoursGroup hoursGroup : orderLine.getHoursGroups()) {
for (HoursGroup hoursGroup : getHoursGroups(orderLine)) {
IndirectCriterionRequirement indirect = findIndirectRequirementByParent(
hoursGroup.getIndirectCriterionRequirement(), parent);
if (indirect != null) {
@ -210,62 +229,74 @@ public class CriterionRequirementHandler implements
}
}
public void removeDirectCriterionRequirement(T orderElement, DirectCriterionRequirement criterionRequirement){
propagateRemoveCriterionRequirement(orderElement, criterionRequirement);
removeCriterionRequirement(orderElement, criterionRequirement);
}
protected abstract List<HoursGroup> getOrderLineHoursGroups(S orderLine);
/*
* Operation to update the criterions requirements of the orderElement and
* its children
*/
public void propagateUpdateCriterionRequirements(OrderElement orderElement) {
public void propagateUpdateCriterionRequirements(T orderElement) {
if (orderElement instanceof OrderLine) {
updateCriterionRequirementsIntoOrderLine((OrderLine) orderElement);
updateCriterionRequirementsIntoOrderLine(toOrderLine(orderElement));
} else {
updateCriterionRequirementsIntoOrderLineGroup((OrderLineGroup) orderElement);
updateCriterionRequirementsIntoOrderLineGroup(toOrderLineGroup(orderElement));
}
}
private void updateCriterionRequirementsIntoOrderLineGroup(
OrderElement orderLineGroup) {
for (OrderElement child : orderLineGroup.getChildren()) {
child.updateMyCriterionRequirements();
R orderLineGroup) {
for (T child : getOrderLineGroupChildren(orderLineGroup)) {
updateMyCriterionRequirements(child);
propagateUpdateCriterionRequirements(child);
}
}
private void updateCriterionRequirementsIntoOrderLine(OrderLine orderLine) {
for (HoursGroup hoursGroup : orderLine.getHoursGroups()) {
protected abstract List<T> getChildren(T orderElement);
private void updateCriterionRequirementsIntoOrderLine(S orderLine) {
for (HoursGroup hoursGroup : getHoursGroups(orderLine)) {
hoursGroup.updateMyCriterionRequirements();
}
}
void transformDirectToIndirectIfNeeded(OrderElement orderElement,
void transformDirectToIndirectIfNeeded(T orderElement,
Set<IndirectCriterionRequirement> currents) {
for (DirectCriterionRequirement direct : orderElement
.getDirectCriterionRequirement()) {
for (DirectCriterionRequirement direct : getDirectCriterionRequirement(orderElement)) {
IndirectCriterionRequirement indirect = findIndirectRequirementByCriterion(
currents, direct.getCriterion());
if (indirect != null) {
orderElement.removeDirectCriterionRequirement(direct);
removeDirectCriterionRequirement(orderElement, direct);
}
}
}
void addNewsIndirects(OrderElement orderElement,
protected abstract Set<DirectCriterionRequirement> getDirectCriterionRequirement(
T orderElement);
void addNewsIndirects(T orderElement,
Set<IndirectCriterionRequirement> currents) {
Set<IndirectCriterionRequirement> indirects = orderElement
.getIndirectCriterionRequirement();
Set<IndirectCriterionRequirement> indirects = getIndirectCriterionRequirement(orderElement);
for (IndirectCriterionRequirement current : currents) {
if (!indirects.contains(current)) {
orderElement.basicAddCriterionRequirement(current);
basicAddCriterionRequirement(orderElement, current);
}
}
}
void removeOldIndirects(OrderElement orderElement,
protected abstract void basicAddCriterionRequirement(T orderElement,
CriterionRequirement criterionRequirement);
void removeOldIndirects(T orderElement,
Set<IndirectCriterionRequirement> currents) {
for (IndirectCriterionRequirement indirect : orderElement
.getIndirectCriterionRequirement()) {
for (IndirectCriterionRequirement indirect : getIndirectCriterionRequirement(orderElement)) {
if (!currents.contains(indirect)) {
orderElement.removeCriterionRequirement(indirect);
removeCriterionRequirement(orderElement, indirect);
}
}
}
@ -341,6 +372,7 @@ public class CriterionRequirementHandler implements
private IndirectCriterionRequirement findIndirectRequirementByParent(
Set<IndirectCriterionRequirement> indirects,
DirectCriterionRequirement newParent) {
for (IndirectCriterionRequirement requirement : indirects) {
if (requirement.getParent().equals(newParent)) {
return requirement;
@ -351,6 +383,7 @@ public class CriterionRequirementHandler implements
private IndirectCriterionRequirement findIndirectRequirementByCriterion(
Set<IndirectCriterionRequirement> indirects, Criterion criterion) {
for (IndirectCriterionRequirement requirement : indirects) {
if (requirement.getCriterion().equals(criterion)) {
return requirement;
@ -358,41 +391,57 @@ public class CriterionRequirementHandler implements
}
return null;
}
/*
* Operation to create and add to a orderElement new criterion requirements
* that it is copied of the criterion requirements of other orderElement
*/
protected void copyRequirementToOrderElement(OrderLine orderLine,
OrderLineGroup container) {
protected void copyRequirementToOrderLineGroup(S orderLine, R orderLineGroup) {
// copy the directCriterionRequirement
for (DirectCriterionRequirement newRequirement : copyDirectRequirements(orderLine
.getDirectCriterionRequirement())) {
container.basicAddCriterionRequirement(newRequirement);
for (DirectCriterionRequirement newRequirement :
copyDirectRequirements(getDirectCriterionRequirementFromOrderLine(orderLine))) {
basicAddCriterionRequirementIntoOrderLineGroup(orderLineGroup, newRequirement);
}
// copy the IndirectCriterionRequirement
for (IndirectCriterionRequirement newRequirement : copyIndirectRequirements(orderLine
.getIndirectCriterionRequirement())) {
container.basicAddCriterionRequirement(newRequirement);
for (IndirectCriterionRequirement newRequirement :
copyIndirectRequirements(getIndirectCriterionRequirementFromOrderLine(orderLine))) {
basicAddCriterionRequirementIntoOrderLineGroup(orderLineGroup, newRequirement);
}
}
protected void copyRequirementToOrderElement(OrderLineGroup orderLineGroup,
OrderLine leaf) {
protected abstract Set<DirectCriterionRequirement> getDirectCriterionRequirementFromOrderLine(S orderLine);
protected abstract Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLine(S orderLine);
protected abstract void basicAddCriterionRequirementIntoOrderLineGroup(
R orderLineGroup,
CriterionRequirement criterionRequirement);
protected void copyRequirementToOrderLine(R orderLineGroup, S orderLine) {
// copy the directCriterionRequirement
for (DirectCriterionRequirement newRequirement : copyDirectRequirements(orderLineGroup
.getDirectCriterionRequirement())) {
leaf.addDirectCriterionRequirement(newRequirement);
for (DirectCriterionRequirement newRequirement : copyDirectRequirements(
getDirectCriterionRequirementFromOrderLineGroup(orderLineGroup))) {
addDirectCriterionRequirementToOrderLine(orderLine, newRequirement);
}
// copy the IndirectCriterionRequirement
for (IndirectCriterionRequirement newRequirement : copyIndirectRequirements(orderLineGroup
.getIndirectCriterionRequirement())) {
leaf.addIndirectCriterionRequirement(newRequirement);
propagateIndirectCriterionRequirementToChildren(leaf,
for (IndirectCriterionRequirement newRequirement : copyIndirectRequirements(
getIndirectCriterionRequirementFromOrderLineGroup(orderLineGroup))) {
addIndirectCriterionRequirementToOrderLine(orderLine, newRequirement);
propagateIndirectCriterionRequirementToOrderLineChildren(orderLine,
newRequirement.getParent());
}
}
private Set<DirectCriterionRequirement> copyDirectRequirements(Set<DirectCriterionRequirement> collection){
protected abstract Set<DirectCriterionRequirement>
getDirectCriterionRequirementFromOrderLineGroup(R orderLineGroup);
protected abstract void addIndirectCriterionRequirementToOrderLine(S orderLine, IndirectCriterionRequirement indirect);
protected abstract Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLineGroup(R orderLineGroup);
private Set<DirectCriterionRequirement> copyDirectRequirements(
Set<DirectCriterionRequirement> collection) {
Set<DirectCriterionRequirement> result = new HashSet<DirectCriterionRequirement>();
for (DirectCriterionRequirement requirement : collection) {
DirectCriterionRequirement newRequirement = DirectCriterionRequirement
@ -415,8 +464,7 @@ public class CriterionRequirementHandler implements
}
Set<CriterionRequirement> getRequirementWithSameResourType(
Set<CriterionRequirement> requirements,
ResourceEnum resourceType) {
Set<CriterionRequirement> requirements, ResourceEnum resourceType) {
Set<CriterionRequirement> result = new HashSet<CriterionRequirement>();
for (CriterionRequirement requirement : requirements) {
ResourceEnum resourceTypeParent = requirement.getCriterion()
@ -427,4 +475,177 @@ public class CriterionRequirementHandler implements
}
return result;
}
}
/**
* Filters {@link DirectCriterionRequirement} from criterionRequirements
*
* @param criterionRequirements
* @return
*/
public Set<DirectCriterionRequirement> getDirectCriterionRequirement(
Set<CriterionRequirement> criterionRequirements) {
Set<DirectCriterionRequirement> list = new HashSet<DirectCriterionRequirement>();
for (CriterionRequirement criterionRequirement : criterionRequirements) {
if (criterionRequirement instanceof DirectCriterionRequirement) {
list.add((DirectCriterionRequirement) criterionRequirement);
}
}
return list;
}
public Set<IndirectCriterionRequirement> getIndirectCriterionRequirement(
Set<CriterionRequirement> criterionRequirements) {
Set<IndirectCriterionRequirement> list = new HashSet<IndirectCriterionRequirement>();
for (CriterionRequirement criterionRequirement : criterionRequirements) {
if (criterionRequirement instanceof IndirectCriterionRequirement) {
list.add((IndirectCriterionRequirement) criterionRequirement);
}
}
return list;
}
public void addCriterionRequirement(T orderElement,
CriterionRequirement criterionRequirement) {
if (criterionRequirement instanceof DirectCriterionRequirement) {
addDirectCriterionRequirement(orderElement, (DirectCriterionRequirement) criterionRequirement);
} else { // criterionRequirement instanceof IndirectCriterionRequirement
addIndirectCriterionRequirement(orderElement, (IndirectCriterionRequirement) criterionRequirement);
}
}
public void addDirectCriterionRequirement(T orderElement,
CriterionRequirement newRequirement) {
if (canAddCriterionRequirement(orderElement,
newRequirement)) {
basicAddCriterionRequirement(orderElement, newRequirement);
propagateDirectCriterionRequirementAddition(orderElement,
newRequirement);
} else {
final Criterion criterion = newRequirement.getCriterion();
throw new IllegalStateException(_(
" The {0} already exist into other order element",
criterion.getName()));
}
}
public void addIndirectCriterionRequirement(T orderElement,
IndirectCriterionRequirement criterionRequirement) {
basicAddCriterionRequirement(orderElement, criterionRequirement);
}
protected void addDirectCriterionRequirementToOrderLine(S orderLine, DirectCriterionRequirement direct) {
addDirectCriterionRequirement(toOrderElement(orderLine), direct);
}
public void updateMyCriterionRequirements(T orderElement) {
final T parent = getParent(orderElement);
Set<CriterionRequirement> requirementsParent = getCriterionRequirements(parent);
Set<IndirectCriterionRequirement> currentIndirects = getCurrentIndirectRequirements(
getIndirectCriterionRequirement(orderElement),
requirementsParent);
transformDirectToIndirectIfNeeded(orderElement, currentIndirects);
removeOldIndirects(orderElement, currentIndirects);
addNewsIndirects(orderElement, currentIndirects);
}
protected abstract T getParent(T orderElement);
/**
* Propagates {@link IndirectCriterionRequirement} for an
* {@link OrderElement} or {@link OrderElementTemplate} preserving its valid
* attribute
*
*/
public void copyIndirectCriterionRequirementFromOriginalToOrderLineGroupChildren(
R orderLineGroup,
DirectCriterionRequirement parent) {
copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren(
orderLineGroup, parent);
copyIndirectCriterionRequirementsFromOriginalToHoursGroup(
orderLineGroup, parent);
}
public abstract void copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren(
R orderLineGroup,
DirectCriterionRequirement parent);
public void copyIndirectCriterionRequirementsFromOriginalToHoursGroup(
R orderLineGroup,
DirectCriterionRequirement parent) {
final List<T> orderElements = getOrderLineGroupChildren(orderLineGroup);
final Criterion criterion = parent.getCriterion();
final Set<IndirectCriterionRequirement> originalIndirectCriterionRequirements = parent
.getOrigin().getChildren();
final Map<HoursGroup, Map<Criterion, Boolean>> mapHoursGroup =
createHoursGroupCriterionMap(originalIndirectCriterionRequirements);
for (T each: orderElements) {
IndirectCriterionRequirement indirect = IndirectCriterionRequirement
.create(parent, criterion);
if (isOrderLine(each)) {
for (HoursGroup hoursGroup: myHoursGroups(toOrderLine(each))) {
Map<Criterion, Boolean> criterionMap = mapHoursGroup.get(hoursGroup.getOrigin());
if (criterionMap != null) {
final Boolean valid = criterionMap.get(indirect.getCriterion());
indirect.setValid(valid);
}
hoursGroup.addCriterionRequirement(indirect);
}
}
if (isOrderLineGroup(each)) {
copyIndirectCriterionRequirementsFromOriginalToHoursGroup(
toOrderLineGroup(each), parent);
}
}
}
protected abstract boolean isOrderLineGroup(T orderElement);
protected abstract Collection<HoursGroup> myHoursGroups(S orderline);
/**
* Creates a mapping between {@link HoursGroup} and a tuple (criterion,
* boolean) from a list of {@link IndirectCriterionRequirement}
*
* The valid value of an {@link IndirectCriterionRequirement} can be later
* retrieve knowing its {@link HoursGroup} and its {@link Criterion}
*
* This data structure is used to keep the original valid value from
* {@link IndirectCriterionRequirement} when copying an {@link Order} to a
* {@link Template} or vice-versa
*
* @param indirects
* @return
*/
private Map<HoursGroup, Map<Criterion, Boolean>> createHoursGroupCriterionMap(
Set<IndirectCriterionRequirement> indirects) {
Map<HoursGroup, Map<Criterion, Boolean>> result =
new HashMap<HoursGroup, Map<Criterion, Boolean>>();
for (IndirectCriterionRequirement each: indirects) {
final HoursGroup hoursGroup = each.getHoursGroup();
if (hoursGroup != null) {
Map<Criterion, Boolean> value = result.get(hoursGroup);
if (value == null) {
value = new HashMap<Criterion, Boolean>();
}
value.put(each.getCriterion(), each.isValid());
result.put(hoursGroup, value);
}
}
return result;
}
}

View file

@ -0,0 +1,243 @@
/*
* 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.business.orders.entities;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class CriterionRequirementOrderElementHandler extends
CriterionRequirementHandler<OrderElement, OrderLine, OrderLineGroup> {
private static final CriterionRequirementOrderElementHandler singleton =
new CriterionRequirementOrderElementHandler();
private CriterionRequirementOrderElementHandler() {
}
public static CriterionRequirementOrderElementHandler getInstance() {
return singleton;
}
@Override
protected List<OrderElement> getOrderLineGroupChildren(OrderLineGroup orderLineGroup) {
return orderLineGroup.getChildren();
}
@Override
protected List<OrderElement> getAllChildren(OrderElement orderElement) {
return orderElement.getAllChildren();
}
@Override
protected List<OrderElement> getChildren(OrderElement orderElement) {
return orderElement.getChildren();
}
@Override
protected Set<CriterionRequirement> getCriterionRequirements(OrderElement orderElement) {
return orderElement.getCriterionRequirements();
}
@Override
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirement(OrderElement orderElement) {
return orderElement.getIndirectCriterionRequirement();
}
@Override
protected void removeCriterionRequirement(OrderElement orderElement,
CriterionRequirement criterionRequirement) {
orderElement.removeCriterionRequirement(criterionRequirement);
}
@Override
protected List<HoursGroup> getOrderLineHoursGroups(OrderLine orderLine) {
return orderLine.getHoursGroups();
}
@Override
protected Set<DirectCriterionRequirement> getDirectCriterionRequirement(OrderElement orderElement) {
return orderElement.getDirectCriterionRequirement();
}
@Override
protected void basicAddCriterionRequirement(OrderElement orderElement, CriterionRequirement criterionRequirement) {
orderElement.basicAddCriterionRequirement(criterionRequirement);
}
@Override
protected List<HoursGroup> getHoursGroups(OrderLine orderline) {
return orderline.getHoursGroups();
}
@Override
protected boolean isOrderLine(OrderElement orderElement) {
return (orderElement instanceof OrderLine);
}
@Override
protected OrderLine toOrderLine(OrderElement orderElement) {
return (OrderLine) orderElement;
}
@Override
protected OrderLineGroup toOrderLineGroup(OrderElement orderElement) {
return (OrderLineGroup) orderElement;
}
@Override
protected OrderElement toOrderElement(OrderLine orderLine) {
return (OrderElement) orderLine;
}
@Override
protected Set<DirectCriterionRequirement>
getDirectCriterionRequirementFromOrderLineGroup(OrderLineGroup orderLineGroup) {
return orderLineGroup.getDirectCriterionRequirement();
}
@Override
protected void addIndirectCriterionRequirementToOrderLine(OrderLine orderLine, IndirectCriterionRequirement indirect) {
orderLine.addIndirectCriterionRequirement(indirect);
}
@Override
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLineGroup(
OrderLineGroup orderLine) {
return orderLine.getIndirectCriterionRequirement();
}
@Override
protected Set<DirectCriterionRequirement> getDirectCriterionRequirementFromOrderLine(OrderLine orderLine) {
return orderLine.getDirectCriterionRequirement();
}
@Override
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLine(OrderLine orderLine) {
return orderLine.getIndirectCriterionRequirement();
}
@Override
protected void basicAddCriterionRequirementIntoOrderLineGroup(OrderLineGroup orderLineGroup, CriterionRequirement criterionRequirement) {
orderLineGroup.basicAddCriterionRequirement(criterionRequirement);
}
@Override
protected OrderElement getParent(OrderElement orderElement) {
return orderElement.getParent();
}
@Override
protected boolean isOrderLineGroup(OrderElement orderElement) {
return (orderElement instanceof OrderLineGroup);
}
@Override
protected Collection<HoursGroup> myHoursGroups(OrderLine orderline) {
return orderline.myHoursGroups();
}
/**
* For every OrderLineGroup, its {@link DirectCriterionRequirement} are
* copied to their children ({@link IndirectCriterionRequirement}). Every entry of
* {@link DirectCriterionRequirement} keeps a reference to its original
* (_origin_). Original {@link IndirectCriterionRequirement} can be accessed
* from _origin_.
*
* A unique IndirectCriterionRequirements can be referenced knowing two
* parameters: {@link OrderElement} or {@link OrderElementTemplate}, and
* {@link Criterion}. A map containing the original valid value of an
* indirect criterion is created, indexing by order element and criterion.
*
* Every order element keeps a reference to its template, and vice-versa. So
* when propagating a criterion it's possible to know the original value of
* valid via the map previously created
*/
@Override
public void copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren(
OrderLineGroup orderLineGroup, DirectCriterionRequirement parent) {
final List<OrderElement> orderElements = orderLineGroup.getChildren();
final Criterion criterion = parent.getCriterion();
final Set<IndirectCriterionRequirement> originalIndirectCriterionRequirements = parent
.getOrigin().getChildren();
final Map<OrderElementTemplate, Map<Criterion, Boolean>> mapTemplateCriterion =
createTemplateCriterionMap(originalIndirectCriterionRequirements);
for (OrderElement each : orderElements) {
Map<Criterion, Boolean> criterionMap = mapTemplateCriterion
.get(each.getTemplate());
if (criterionMap != null) {
IndirectCriterionRequirement indirect = IndirectCriterionRequirement
.create(parent, criterion);
indirect.setValid(criterionMap.get(criterion));
addIndirectCriterionRequirement(each, indirect);
}
if (isOrderLineGroup(each)) {
copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren(
toOrderLineGroup(each), parent);
}
}
}
/**
* Map containing {@link IndirectCriterionRequirement} valid attribute,
* indexing by {@link OrderElementTemplate} and {@link Criterion}
*
* @param indirects
* @return
*/
private Map<OrderElementTemplate, Map<Criterion, Boolean>> createTemplateCriterionMap(
Set<IndirectCriterionRequirement> indirects) {
Map<OrderElementTemplate, Map<Criterion, Boolean>> result =
new HashMap<OrderElementTemplate, Map<Criterion, Boolean>>();
for (IndirectCriterionRequirement each: indirects) {
final OrderElementTemplate template = each.getOrderElementTemplate();
if (template != null) {
Map<Criterion, Boolean> value = result.get(template);
if (value == null) {
value = new HashMap<Criterion, Boolean>();
}
value.put(each.getCriterion(), each.isValid());
result.put(template, value);
}
}
return result;
}
}

View file

@ -22,9 +22,11 @@ package org.navalplanner.business.orders.entities;
import static org.navalplanner.business.i18n.I18nHelper._;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -41,27 +43,13 @@ import org.navalplanner.business.requirements.entities.DirectCriterionRequiremen
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.ResourceEnum;
import org.navalplanner.business.templates.entities.OrderLineTemplate;
public class HoursGroup extends BaseEntity implements Cloneable,
ICriterionRequirable {
private static final Log LOG = LogFactory.getLog(HoursGroup.class);
public static HoursGroup create(OrderLine parentOrderLine) {
HoursGroup result = new HoursGroup(parentOrderLine);
result.setNewObject(true);
return result;
}
public static HoursGroup createUnvalidated(String name,
ResourceEnum resourceType, Integer workingHours) {
HoursGroup result = new HoursGroup();
result.setCode(name);
result.setResourceType(resourceType);
result.setWorkingHours(workingHours);
return create(result);
}
private String code;
private ResourceEnum resourceType = ResourceEnum.WORKER;
@ -74,20 +62,105 @@ public class HoursGroup extends BaseEntity implements Cloneable,
private Set<CriterionRequirement> criterionRequirements = new HashSet<CriterionRequirement>();
@NotNull
private OrderLine parentOrderLine;
protected CriterionRequirementHandler criterionRequirementHandler = CriterionRequirementHandler
.getInstance();
private OrderLineTemplate orderLineTemplate;
private HoursGroup origin;
protected CriterionRequirementOrderElementHandler criterionRequirementHandler =
CriterionRequirementOrderElementHandler.getInstance();
public static HoursGroup create(OrderLine parentOrderLine) {
HoursGroup result = new HoursGroup(parentOrderLine);
result.setNewObject(true);
return result;
}
public static HoursGroup create(OrderLineTemplate orderLineTemplate) {
HoursGroup result = new HoursGroup(orderLineTemplate);
result.setNewObject(true);
return result;
}
public static HoursGroup createUnvalidated(String code,
ResourceEnum resourceType, Integer workingHours) {
HoursGroup result = new HoursGroup();
result.setCode(code);
result.setResourceType(resourceType);
result.setWorkingHours(workingHours);
return create(result);
}
/**
* Returns a copy of hoursGroup, and sets parent as its parent
*
* @param hoursGroup
* @param parent
* @return
*/
public static HoursGroup copyFrom(HoursGroup hoursGroup, OrderLineTemplate parent) {
HoursGroup result = copyFrom(hoursGroup);
result.setCriterionRequirements(copyDirectCriterionRequirements(
result, parent, hoursGroup.getDirectCriterionRequirement()));
result.setOrderLineTemplate(parent);
result.setParentOrderLine(null);
return result;
}
private static Set<CriterionRequirement> copyDirectCriterionRequirements(
HoursGroup hoursGroup,
Object orderLine,
Collection<DirectCriterionRequirement> criterionRequirements) {
Set<CriterionRequirement> result = new HashSet<CriterionRequirement>();
for (DirectCriterionRequirement each: criterionRequirements) {
final DirectCriterionRequirement directCriterionRequirement = (DirectCriterionRequirement) each;
DirectCriterionRequirement newDirectCriterionRequirement = DirectCriterionRequirement
.copyFrom(directCriterionRequirement, hoursGroup);
newDirectCriterionRequirement.setHoursGroup(hoursGroup);
result.add(newDirectCriterionRequirement);
}
return result;
}
public static HoursGroup copyFrom(HoursGroup hoursGroup, OrderLine parent) {
HoursGroup result = copyFrom(hoursGroup);
result.setCriterionRequirements(copyDirectCriterionRequirements(
result, parent, hoursGroup.getDirectCriterionRequirement()));
result.setOrderLineTemplate(null);
result.setParentOrderLine(parent);
return result;
}
private static HoursGroup copyFrom(HoursGroup hoursGroup) {
HoursGroup result = createUnvalidated(
hoursGroup.getCode(),
hoursGroup.getResourceType(),
hoursGroup.getWorkingHours());
result.setCode(UUID.randomUUID().toString());
result.percentage = hoursGroup.getPercentage();
result.fixedPercentage = hoursGroup.isFixedPercentage();
result.origin = hoursGroup;
return result;
}
/**
* Constructor for hibernate. Do not use!
*/
public HoursGroup() {
}
private HoursGroup(OrderLine parentOrderLine) {
this.parentOrderLine = parentOrderLine;
this.setOrderLineTemplate(null);
}
private HoursGroup(OrderLineTemplate orderLineTemplate) {
this.orderLineTemplate = orderLineTemplate;
this.setParentOrderLine(null);
}
@NotEmpty(message = "code not specified")
@ -139,13 +212,18 @@ public class HoursGroup extends BaseEntity implements Cloneable,
this.percentage = proportion;
if (!parentOrderLine.isPercentageValid()) {
if (!isPercentageValidForParent()) {
this.percentage = oldPercentage;
throw new IllegalArgumentException(
_("Total percentage should be less than 100%"));
}
}
private boolean isPercentageValidForParent() {
return (parentOrderLine != null) ? parentOrderLine.isPercentageValid()
: orderLineTemplate.isPercentageValid();
}
public BigDecimal getPercentage() {
return percentage;
}
@ -231,10 +309,9 @@ public class HoursGroup extends BaseEntity implements Cloneable,
}
public void updateMyCriterionRequirements() {
OrderElement newParent = this.getParentOrderLine();
Set<CriterionRequirement> requirementsParent = criterionRequirementHandler
.getRequirementWithSameResourType(newParent
.getCriterionRequirements(), resourceType);
.getRequirementWithSameResourType(
getCriterionRequirementsFromParent(), resourceType);
Set<IndirectCriterionRequirement> currentIndirects = criterionRequirementHandler
.getCurrentIndirectRequirements(
getIndirectCriterionRequirement(), requirementsParent);
@ -242,6 +319,12 @@ public class HoursGroup extends BaseEntity implements Cloneable,
criterionRequirementHandler.addNewsIndirects(this, currentIndirects);
}
private Set<CriterionRequirement> getCriterionRequirementsFromParent() {
return (parentOrderLine != null) ? parentOrderLine
.getCriterionRequirements() : orderLineTemplate
.getCriterionRequirements();
}
public Set<IndirectCriterionRequirement> getIndirectCriterionRequirement() {
Set<IndirectCriterionRequirement> list = new HashSet<IndirectCriterionRequirement>();
for(CriterionRequirement criterionRequirement : criterionRequirements ){
@ -304,4 +387,20 @@ public class HoursGroup extends BaseEntity implements Cloneable,
}
}
public OrderLineTemplate getOrderLineTemplate() {
return orderLineTemplate;
}
public void setOrderLineTemplate(OrderLineTemplate orderLineTemplate) {
this.orderLineTemplate = orderLineTemplate;
}
public HoursGroup getOrigin() {
return origin;
}
public void setOrigin(HoursGroup origin) {
this.origin = origin;
}
}

View file

@ -0,0 +1,284 @@
/*
* This file is part of NavalPlan
*
* 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.business.orders.entities;
import static org.navalplanner.business.i18n.I18nHelper._;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
/**
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public abstract class HoursGroupHandler<T> implements IHoursGroupHandler<T> {
public boolean isTotalHoursValid(Integer total, final Set<HoursGroup> hoursGroups) {
if (total == null) {
return false;
}
Integer newTotal = 0;
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
newTotal += hoursGroup.getPercentage().multiply(
new BigDecimal(total).setScale(2)).toBigInteger()
.intValue();
}
}
if (newTotal.compareTo(total) > 0) {
return false;
}
return true;
}
public boolean isPercentageValid(final Set<HoursGroup> hoursGroups) {
BigDecimal newPercentage = new BigDecimal(0).setScale(2);
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
newPercentage = newPercentage.add(hoursGroup.getPercentage());
}
}
if (newPercentage.compareTo(new BigDecimal(1).setScale(2)) > 0) {
return false;
}
return true;
}
public Integer calculateTotalHours(Set<HoursGroup> hoursGroups) {
Integer result = 0;
for (HoursGroup hoursGroup : hoursGroups) {
Integer workingHours = hoursGroup.getWorkingHours();
if (workingHours != null) {
result += workingHours;
}
}
return result;
}
/**
* Calculates the total number of working hours in a set of
* {@link HoursGroup} taking into account just {@link HoursGroup} with
* NO_FIXED as policy.
* @param hoursGroups
* A {@link HoursGroup} set
* @return The sum of NO_FIXED {@link HoursGroup}
*/
private Integer calculateTotalHoursNoFixed(Set<HoursGroup> hoursGroups) {
Integer result = 0;
for (HoursGroup hoursGroup : hoursGroups) {
if (!hoursGroup.isFixedPercentage()) {
result += hoursGroup.getWorkingHours();
}
}
return result;
}
public void recalculateHoursGroups(T orderLine) {
Set<HoursGroup> hoursGroups = getHoursGroup(orderLine);
Integer total = calculateTotalHours(hoursGroups);
BigDecimal totalBigDecimal = new BigDecimal(total).setScale(2);
// For each HoursGroup with FIXED_PERCENTAGE, the workingHours are
// calculated
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
Integer workingHours = hoursGroup.getPercentage().multiply(
totalBigDecimal).toBigInteger().intValue();
hoursGroup.setWorkingHours(workingHours);
}
}
Integer newTotal = calculateTotalHours(hoursGroups);
// If the total was modified
if (!newTotal.equals(total)) {
Integer totalNoFixed = calculateTotalHoursNoFixed(hoursGroups);
// For each HoursGroup without FIXED_PERCENTAGE, the hours are
// proportionally shared
for (HoursGroup hoursGroup : hoursGroups) {
if (!hoursGroup.isFixedPercentage()) {
Integer hours = hoursGroup.getWorkingHours();
Integer newHours = (int) (((float) hours / totalNoFixed) * (total - (newTotal - totalNoFixed)));
hoursGroup.setWorkingHours(newHours);
}
}
}
newTotal = calculateTotalHours(hoursGroups);
// If there's still some remaining hours
if (newTotal.compareTo(total) < 0) {
// Add a new HourGroup with the remaining hours
HoursGroup hoursGroup = createHoursGroup(orderLine);
hoursGroup.updateMyCriterionRequirements();
hoursGroup.setWorkingHours(total - newTotal);
hoursGroups.add(hoursGroup);
}
// Then the percentages for the HoursGroup without FIXED_PERCENTAGE are
// recalculated.
for (HoursGroup hoursGroup : hoursGroups) {
if (!hoursGroup.isFixedPercentage()) {
if (totalBigDecimal.equals(new BigDecimal(0).setScale(2))) {
hoursGroup.setPercentage(new BigDecimal(0).setScale(2));
} else {
BigDecimal hoursBigDecimal = new BigDecimal(hoursGroup
.getWorkingHours()).setScale(2);
BigDecimal percentage = hoursBigDecimal.divide(
totalBigDecimal, BigDecimal.ROUND_DOWN);
hoursGroup.setPercentage(percentage);
}
}
}
}
protected abstract Set<HoursGroup> getHoursGroup(T orderLine);
protected abstract HoursGroup createHoursGroup(T orderLine);
private void updateHoursGroups(T orderLine, Integer workHours) {
final Set<HoursGroup> hoursGroups = getHoursGroup(orderLine);
Set<HoursGroup> newHoursGroups = new HashSet<HoursGroup>();
// Divide HourGroup depending on policy
Set<HoursGroup> fixedPercentageGroups = new HashSet<HoursGroup>();
Set<HoursGroup> noFixedGroups = new HashSet<HoursGroup>();
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
fixedPercentageGroups.add(hoursGroup);
} else {
noFixedGroups.add(hoursGroup);
}
}
// For every HourGroup with FIXED_PERCENTAGE, workingHours will be
// calculated
for (HoursGroup hoursGroup : fixedPercentageGroups) {
Integer hours = hoursGroup.getPercentage().multiply(
new BigDecimal(workHours).setScale(2)).toBigInteger()
.intValue();
hoursGroup.setWorkingHours(hours);
newHoursGroups.add(hoursGroup);
}
Integer newTotal = calculateTotalHours(newHoursGroups);
if (newTotal.compareTo(workHours) > 0) {
throw new RuntimeException("Unreachable code");
} else if (newTotal.compareTo(workHours) == 0) {
for (HoursGroup hoursGroup : noFixedGroups) {
hoursGroup.setWorkingHours(0);
newHoursGroups.add(hoursGroup);
}
} else if (newTotal.compareTo(workHours) < 0) {
// Proportional sharing
Integer oldNoFixed = calculateTotalHoursNoFixed(hoursGroups);
Integer newNoFixed = workHours - newTotal;
for (HoursGroup hoursGroup : noFixedGroups) {
Integer newHours;
if (oldNoFixed == 0) {
newHours = (int) ((float) newNoFixed / hoursGroups.size());
} else {
newHours = (int) ((float) hoursGroup.getWorkingHours()
/ oldNoFixed * newNoFixed);
}
hoursGroup.setWorkingHours(newHours);
newHoursGroups.add(hoursGroup);
}
}
// If there're remaining hours
newTotal = calculateTotalHours(newHoursGroups);
if (newTotal.compareTo(workHours) < 0) {
// Add a new HourGroup with the remaining hours
HoursGroup hoursGroup = createHoursGroup(orderLine);
hoursGroup.setWorkingHours(workHours - newTotal);
newHoursGroups.add(hoursGroup);
}
// Set the attribute with the new hours group calculated
setHoursGroups(orderLine, newHoursGroups);
// Re-calculate percentages
recalculateHoursGroups(orderLine);
}
protected abstract void setHoursGroups(T orderLine, Set<HoursGroup> hoursGroups);
/**
* Set the total working hours of the {@link OrderLine} taking into account
* the {@link HoursGroup} policies.
* @param workHours
* The desired value to set as total working hours
* @throws IllegalArgumentException
* If parameter is less than 0 or if it's not possible to set
* this value taking into account {@link HoursGroup} policies.
*/
@Override
public void setWorkHours(T orderLine, Integer workHours) throws IllegalArgumentException {
if (workHours == null) {
workHours = new Integer(0);
}
if (workHours < 0) {
throw new IllegalArgumentException(
_("workHours should be greater or equals to 0"));
}
if (hoursGroupsIsEmpty(orderLine)) {
HoursGroup hoursGroup = createHoursGroup(orderLine);
hoursGroup.setWorkingHours(workHours);
hoursGroup.setPercentage((new BigDecimal(1).setScale(2)));
hoursGroup.setCode(OrderLine.INITIAL_HOURS_GROUP_CODE);
addHoursGroup(orderLine, hoursGroup);
} else {
if (!isTotalHoursValid(workHours, getHoursGroup(orderLine))) {
throw new IllegalArgumentException(
_("\"workHours\" value is not valid, taking into "
+ "account the current list of HoursGroup"));
}
updateHoursGroups(orderLine, workHours);
}
}
protected abstract boolean hoursGroupsIsEmpty(T orderLine);
protected abstract void addHoursGroup(T orderLine, HoursGroup hoursGroup);
}

View file

@ -0,0 +1,68 @@
/*
* This file is part of NavalPlan
*
* 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.business.orders.entities;
import java.util.Set;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public class HoursGroupOrderLineHandler extends HoursGroupHandler<OrderLine> {
private static final HoursGroupOrderLineHandler singleton =
new HoursGroupOrderLineHandler();
private HoursGroupOrderLineHandler() {
}
public static HoursGroupOrderLineHandler getInstance() {
return singleton;
}
@Override
protected HoursGroup createHoursGroup(OrderLine orderLine) {
return HoursGroup.create(orderLine);
}
@Override
protected Set<HoursGroup> getHoursGroup(OrderLine orderLine) {
return orderLine.myHoursGroups();
}
@Override
protected void setHoursGroups(OrderLine orderLine,
Set<HoursGroup> hoursGroups) {
orderLine.setHoursGroups(hoursGroups);
}
@Override
protected void addHoursGroup(OrderLine orderLine, HoursGroup hoursGroup) {
orderLine.doAddHoursGroup(hoursGroup);
}
@Override
protected boolean hoursGroupsIsEmpty(OrderLine orderLine) {
return orderLine.getHoursGroups().isEmpty();
}
}

View file

@ -0,0 +1,76 @@
/*
* This file is part of NavalPlan
*
* 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.business.orders.entities;
import java.util.Set;
/**
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public interface IHoursGroupHandler<T> {
/**
* Calculates the total number of working hours in a set of
* {@link HoursGroup}.
* @param hoursGroups
* A {@link HoursGroup} set
* @return The sum of working hours
*/
Integer calculateTotalHours(Set<HoursGroup> hoursGroups);
/**
* Checks if the percentage is or not valid. That means, if the pertentage
* of all {@link HoursGroup} with FIXED_PERCENTAGE isn't more than 100%.
* This method is called from setPercentage at {@link HoursGroup} class.
* @return true if the percentage is valid
*/
boolean isPercentageValid(final Set<HoursGroup> hoursGroups);
/**
* Checks if the desired total number of hours is valid taking into account
* {@link HoursGroup} policy restrictions.
* @param total
* The desired value
* @return true if the value is valid
*/
boolean isTotalHoursValid(Integer total, final Set<HoursGroup> hoursGroups);
/**
* Re-calculates the working hours and percentages in the {@link HoursGroup}
* set of the current {@link OrderLine}, taking into account the policy of
* each {@link HoursGroup}.
*/
void recalculateHoursGroups(T orderLine);
/**
* Set the total working hours of the {@link OrderLine} taking into account
* the {@link HoursGroup} policies.
* @param workHours
* The desired value to set as total working hours
* @throws IllegalArgumentException
* If parameter is less than 0 or if it's not possible to set
* this value taking into account {@link HoursGroup} policies.
*/
void setWorkHours(T orderLine, Integer workHours) throws IllegalArgumentException;
}

View file

@ -59,7 +59,6 @@ import org.navalplanner.business.qualityforms.entities.TaskQualityForm;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.business.trees.ITreeNode;
@ -83,13 +82,12 @@ public abstract class OrderElement extends BaseEntity implements
private Set<TaskQualityForm> taskQualityForms = new HashSet<TaskQualityForm>();
private Set<CriterionRequirement> criterionRequirements = new HashSet<CriterionRequirement>();
protected OrderLineGroup parent;
protected CriterionRequirementHandler criterionRequirementHandler = CriterionRequirementHandler
.getInstance();
protected CriterionRequirementOrderElementHandler criterionRequirementHandler =
CriterionRequirementOrderElementHandler.getInstance();
private SchedulingState.Type schedulingStateType = Type.NO_SCHEDULED;
@ -576,32 +574,27 @@ public abstract class OrderElement extends BaseEntity implements
protected void removeCriterionRequirement(CriterionRequirement requirement) {
criterionRequirements.remove(requirement);
if(requirement instanceof IndirectCriterionRequirement){
if (requirement instanceof IndirectCriterionRequirement) {
((IndirectCriterionRequirement)requirement).getParent().
getChildren().remove((IndirectCriterionRequirement)requirement);
}
}
public void addDirectCriterionRequirement(
CriterionRequirement newRequirement) {
if (criterionRequirementHandler.canAddCriterionRequirement(this,
newRequirement)) {
basicAddCriterionRequirement(newRequirement);
criterionRequirementHandler
.propagateDirectCriterionRequirementAddition(this,
newRequirement);
} else {
Criterion criterion = newRequirement.getCriterion();
throw new IllegalStateException(_(
" The {0} already exist into other order element",
criterion
.getName()));
}
@Override
public void addCriterionRequirement(
CriterionRequirement criterionRequirement) {
criterionRequirementHandler.addCriterionRequirement(this, criterionRequirement);
}
void addIndirectCriterionRequirement(
public void addDirectCriterionRequirement(
CriterionRequirement criterionRequirement) {
criterionRequirementHandler.addDirectCriterionRequirement(this, criterionRequirement);
}
public void addIndirectCriterionRequirement(
IndirectCriterionRequirement criterionRequirement) {
basicAddCriterionRequirement(criterionRequirement);
criterionRequirementHandler.addIndirectCriterionRequirement(this,
criterionRequirement);
}
protected void basicAddCriterionRequirement(
@ -610,34 +603,11 @@ public abstract class OrderElement extends BaseEntity implements
this.criterionRequirements.add(criterionRequirement);
}
@Override
public void addCriterionRequirement(
CriterionRequirement criterionRequirement) {
if (criterionRequirement instanceof DirectCriterionRequirement) {
addDirectCriterionRequirement((DirectCriterionRequirement) criterionRequirement);
} else { // criterionRequirement instanceof IndirectCriterionRequirement
addIndirectCriterionRequirement((IndirectCriterionRequirement) criterionRequirement);
}
}
public void updateCriterionRequirements() {
updateMyCriterionRequirements();
criterionRequirementHandler.updateMyCriterionRequirements(this);
criterionRequirementHandler.propagateUpdateCriterionRequirements(this);
}
void updateMyCriterionRequirements() {
OrderElement newParent = this.getParent();
Set<CriterionRequirement> requirementsParent = newParent
.getCriterionRequirements();
Set<IndirectCriterionRequirement> currentIndirects = criterionRequirementHandler
.getCurrentIndirectRequirements(
getIndirectCriterionRequirement(), requirementsParent);
criterionRequirementHandler.transformDirectToIndirectIfNeeded(this,
currentIndirects);
criterionRequirementHandler.removeOldIndirects(this, currentIndirects);
criterionRequirementHandler.addNewsIndirects(this, currentIndirects);
}
public boolean canAddCriterionRequirement(
DirectCriterionRequirement newRequirement) {
return criterionRequirementHandler.canAddCriterionRequirement(this,
@ -645,13 +615,7 @@ public abstract class OrderElement extends BaseEntity implements
}
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirement() {
Set<IndirectCriterionRequirement> list = new HashSet<IndirectCriterionRequirement>();
for (CriterionRequirement criterionRequirement : criterionRequirements) {
if (criterionRequirement instanceof IndirectCriterionRequirement) {
list.add((IndirectCriterionRequirement) criterionRequirement);
}
}
return list;
return criterionRequirementHandler.getIndirectCriterionRequirement(criterionRequirements);
}
public void applyStartConstraintIfNeededTo(Task task) {
@ -670,13 +634,8 @@ public abstract class OrderElement extends BaseEntity implements
}
public Set<DirectCriterionRequirement> getDirectCriterionRequirement() {
Set<DirectCriterionRequirement> list = new HashSet<DirectCriterionRequirement>();
for (CriterionRequirement criterionRequirement : criterionRequirements) {
if (criterionRequirement instanceof DirectCriterionRequirement) {
list.add((DirectCriterionRequirement) criterionRequirement);
}
}
return list;
return criterionRequirementHandler
.getDirectCriterionRequirement(criterionRequirements);
}
public SchedulingState.Type getSchedulingStateType() {
@ -748,13 +707,7 @@ public abstract class OrderElement extends BaseEntity implements
}
public Order getOrder() {
Order order;
try {
order = parent.getOrder();
} catch (Exception e) {
throw new RuntimeException(e);
}
return order;
return parent.getOrder();
}
@Valid

View file

@ -20,8 +20,6 @@
package org.navalplanner.business.orders.entities;
import static org.navalplanner.business.i18n.I18nHelper._;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
@ -44,7 +42,10 @@ import org.navalplanner.business.templates.entities.OrderLineTemplate;
public class OrderLine extends OrderElement {
private static final String INITIAL_HOURS_GROUP_CODE = "HOURS-GROUP-CODE";
public static final String INITIAL_HOURS_GROUP_CODE = "HOURS-GROUP-CODE";
private HoursGroupOrderLineHandler hoursGroupOrderLineHandler = HoursGroupOrderLineHandler
.getInstance();
public static OrderLine create() {
OrderLine result = new OrderLine();
@ -77,7 +78,7 @@ public class OrderLine extends OrderElement {
@Override
public Integer getWorkHours() {
return calculateTotalHours(hoursGroups);
return hoursGroupOrderLineHandler.calculateTotalHours(hoursGroups);
}
@Override
@ -137,289 +138,49 @@ public class OrderLine extends OrderElement {
return new ArrayList<HoursGroup>(hoursGroups);
}
public Set<HoursGroup> myHoursGroups() {
return hoursGroups;
}
public void setHoursGroups(final Set<HoursGroup> hoursGroups) {
this.hoursGroups.clear();
this.hoursGroups.addAll(hoursGroups);
}
public void addHoursGroup(HoursGroup hoursGroup) {
hoursGroup.setParentOrderLine(this);
hoursGroup.updateMyCriterionRequirements();
hoursGroups.add(hoursGroup);
doAddHoursGroup(hoursGroup);
recalculateHoursGroups();
}
public void doAddHoursGroup(HoursGroup hoursGroup) {
hoursGroups.add(hoursGroup);
}
public void deleteHoursGroup(HoursGroup hoursGroup) {
hoursGroups.remove(hoursGroup);
recalculateHoursGroups();
}
/**
* Set the total working hours of the {@link OrderLine} taking into account
* the {@link HoursGroup} policies.
* @param workHours
* The desired value to set as total working hours
* @throws IllegalArgumentException
* If parameter is less than 0 or if it's not possible to set
* this value taking into account {@link HoursGroup} policies.
* Operations for manipulating {@link HoursGroup}
*/
public void setWorkHours(Integer workHours) throws IllegalArgumentException {
if (workHours == null) {
workHours = new Integer(0);
}
if (workHours < 0) {
throw new IllegalArgumentException(
_("workHours should be greater or equals to 0"));
}
if (hoursGroups.isEmpty()) {
HoursGroup hoursGroup = HoursGroup.create(this);
hoursGroup.setWorkingHours(workHours);
hoursGroup.setPercentage((new BigDecimal(1).setScale(2)));
hoursGroup.setCode(INITIAL_HOURS_GROUP_CODE);
hoursGroups.add(hoursGroup);
} else {
if (!isTotalHoursValid(workHours)) {
throw new IllegalArgumentException(
_("\"workHours\" value is not valid, taking into "
+ "account the current list of HoursGroup"));
}
updateHoursGroups(workHours);
}
hoursGroupOrderLineHandler.setWorkHours(this, workHours);
}
/**
* Makes the needed modifications in hoursGroups attribute in order to set
* the desired value of working hours. This method takes into account the
* different {@link HoursGroup} policies: If policy is FIXED_PERCENTAGE the
* new value is calculated for each {@link HoursGroup} with this policy.
* Using round down in order to avoid problems. Hours are proportionally
* distributed when there're {@link HoursGroup} with NO_FIXED policy.
* Finally, it creates new {@link HoursGroup} if the're some remaining hours
* (it could happen because of the round down used for operations).
* @param workHours
* The value to set as total working hours
*/
private void updateHoursGroups(Integer workHours) {
Set<HoursGroup> newHoursGroups = new HashSet<HoursGroup>();
// Divide HourGroup depending on policy
Set<HoursGroup> fixedPercentageGroups = new HashSet<HoursGroup>();
Set<HoursGroup> noFixedGroups = new HashSet<HoursGroup>();
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
fixedPercentageGroups.add(hoursGroup);
} else {
noFixedGroups.add(hoursGroup);
}
}
// For every HourGroup with FIXED_PERCENTAGE, workingHours will be
// calculated
for (HoursGroup hoursGroup : fixedPercentageGroups) {
Integer hours = hoursGroup.getPercentage().multiply(
new BigDecimal(workHours).setScale(2)).toBigInteger()
.intValue();
hoursGroup.setWorkingHours(hours);
newHoursGroups.add(hoursGroup);
}
Integer newTotal = calculateTotalHours(newHoursGroups);
if (newTotal.compareTo(workHours) > 0) {
throw new RuntimeException("Unreachable code");
} else if (newTotal.compareTo(workHours) == 0) {
for (HoursGroup hoursGroup : noFixedGroups) {
hoursGroup.setWorkingHours(0);
newHoursGroups.add(hoursGroup);
}
} else if (newTotal.compareTo(workHours) < 0) {
// Proportional sharing
Integer oldNoFixed = calculateTotalHoursNoFixed(hoursGroups);
Integer newNoFixed = workHours - newTotal;
for (HoursGroup hoursGroup : noFixedGroups) {
Integer newHours;
if (oldNoFixed == 0) {
newHours = (int) ((float) newNoFixed / hoursGroups.size());
} else {
newHours = (int) ((float) hoursGroup.getWorkingHours()
/ oldNoFixed * newNoFixed);
}
hoursGroup.setWorkingHours(newHours);
newHoursGroups.add(hoursGroup);
}
}
// If there're remaining hours
newTotal = calculateTotalHours(newHoursGroups);
if (newTotal.compareTo(workHours) < 0) {
// Add a new HourGroup with the remaining hours
HoursGroup hoursGroup = HoursGroup.create(this);
hoursGroup.setWorkingHours(workHours - newTotal);
newHoursGroups.add(hoursGroup);
}
// Set the attribute with the new hours group calculated
hoursGroups = newHoursGroups;
// Re-calculate percentages
recalculateHoursGroups();
}
/**
* Checks if the desired total number of hours is valid taking into account
* {@link HoursGroup} policy restrictions.
* @param total
* The desired value
* @return true if the value is valid
*/
public boolean isTotalHoursValid(Integer total) {
if (total == null) {
return false;
}
Integer newTotal = 0;
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
newTotal += hoursGroup.getPercentage().multiply(
new BigDecimal(total).setScale(2)).toBigInteger()
.intValue();
}
}
if (newTotal.compareTo(total) > 0) {
return false;
}
return true;
return hoursGroupOrderLineHandler.isTotalHoursValid(total, hoursGroups);
}
/**
* Checks if the percentage is or not valid. That means, if the pertentage
* of all {@link HoursGroup} with FIXED_PERCENTAGE isn't more than 100%.
* This method is called from setPercentage at {@link HoursGroup} class.
* @return true if the percentage is valid
*/
public boolean isPercentageValid() {
BigDecimal newPercentage = new BigDecimal(0).setScale(2);
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
newPercentage = newPercentage.add(hoursGroup.getPercentage());
}
}
if (newPercentage.compareTo(new BigDecimal(1).setScale(2)) > 0) {
return false;
}
return true;
return hoursGroupOrderLineHandler.isPercentageValid(hoursGroups);
}
/**
* Calculates the total number of working hours in a set of
* {@link HoursGroup}.
* @param hoursGroups
* A {@link HoursGroup} set
* @return The sum of working hours
*/
private Integer calculateTotalHours(Set<HoursGroup> hoursGroups) {
Integer result = 0;
for (HoursGroup hoursGroup : hoursGroups) {
Integer workingHours = hoursGroup.getWorkingHours();
if (workingHours != null) {
result += workingHours;
}
}
return result;
}
/**
* Calculates the total number of working hours in a set of
* {@link HoursGroup} taking into account just {@link HoursGroup} with
* NO_FIXED as policy.
* @param hoursGroups
* A {@link HoursGroup} set
* @return The sum of NO_FIXED {@link HoursGroup}
*/
private Integer calculateTotalHoursNoFixed(Set<HoursGroup> hoursGroups) {
Integer result = 0;
for (HoursGroup hoursGroup : hoursGroups) {
if (!hoursGroup.isFixedPercentage()) {
result += hoursGroup.getWorkingHours();
}
}
return result;
}
/**
* Re-calculates the working hours and percentages in the {@link HoursGroup}
* set of the current {@link OrderLine}, taking into account the policy of
* each {@link HoursGroup}.
*/
public void recalculateHoursGroups() {
Integer total = calculateTotalHours(hoursGroups);
BigDecimal totalBigDecimal = new BigDecimal(total).setScale(2);
// For each HoursGroup with FIXED_PERCENTAGE, the workingHours are
// calculated
for (HoursGroup hoursGroup : hoursGroups) {
if (hoursGroup.isFixedPercentage()) {
Integer workingHours = hoursGroup.getPercentage().multiply(
totalBigDecimal).toBigInteger().intValue();
hoursGroup.setWorkingHours(workingHours);
}
}
Integer newTotal = calculateTotalHours(hoursGroups);
// If the total was modified
if (!newTotal.equals(total)) {
Integer totalNoFixed = calculateTotalHoursNoFixed(hoursGroups);
// For each HoursGroup without FIXED_PERCENTAGE, the hours are
// proportionally shared
for (HoursGroup hoursGroup : hoursGroups) {
if (!hoursGroup.isFixedPercentage()) {
Integer hours = hoursGroup.getWorkingHours();
Integer newHours = (int) (((float) hours / totalNoFixed) * (total - (newTotal - totalNoFixed)));
hoursGroup.setWorkingHours(newHours);
}
}
}
newTotal = calculateTotalHours(hoursGroups);
// If there's still some remaining hours
if (newTotal.compareTo(total) < 0) {
// Add a new HourGroup with the remaining hours
HoursGroup hoursGroup = HoursGroup.create(this);
hoursGroup.updateMyCriterionRequirements();
hoursGroup.setWorkingHours(total - newTotal);
hoursGroups.add(hoursGroup);
}
// Then the percentages for the HoursGroup without FIXED_PERCENTAGE are
// recalculated.
for (HoursGroup hoursGroup : hoursGroups) {
if (!hoursGroup.isFixedPercentage()) {
if (totalBigDecimal.equals(new BigDecimal(0).setScale(2))) {
hoursGroup.setPercentage(new BigDecimal(0).setScale(2));
} else {
BigDecimal hoursBigDecimal = new BigDecimal(hoursGroup
.getWorkingHours()).setScale(2);
BigDecimal percentage = hoursBigDecimal.divide(
totalBigDecimal, BigDecimal.ROUND_DOWN);
hoursGroup.setPercentage(percentage);
}
}
}
hoursGroupOrderLineHandler.recalculateHoursGroups(this);
}
@Override
@ -480,7 +241,7 @@ public class OrderLine extends OrderElement {
}
protected void copyRequirementToOrderElement(OrderLineGroup container) {
criterionRequirementHandler.copyRequirementToOrderElement(this,
criterionRequirementHandler.copyRequirementToOrderLineGroup(this,
container);
}

View file

@ -778,7 +778,7 @@ public class OrderLineGroup extends OrderElement implements
}
protected void copyRequirementToOrderElement(OrderLine leaf) {
criterionRequirementHandler.copyRequirementToOrderElement(this, leaf);
criterionRequirementHandler.copyRequirementToOrderLine(this, leaf);
}
@Override

View file

@ -24,6 +24,7 @@ import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
/**
*
@ -31,11 +32,13 @@ import org.navalplanner.business.resources.entities.Criterion;
*/
public class CriterionRequirement extends BaseEntity{
private Criterion criterion;
private HoursGroup hoursGroup;
private OrderElement orderElement;
private Criterion criterion;
private OrderElementTemplate orderElementTemplate;
public CriterionRequirement(){
@ -46,9 +49,18 @@ public class CriterionRequirement extends BaseEntity{
}
public CriterionRequirement(Criterion criterion,
OrderElement orderElement,HoursGroup hoursGroup){
OrderElement orderElement, HoursGroup hoursGroup){
this.criterion = criterion;
this.orderElement = orderElement;
this.orderElementTemplate = null;
this.hoursGroup = hoursGroup;
}
public CriterionRequirement(Criterion criterion,
OrderElementTemplate orderElementTemplate, HoursGroup hoursGroup){
this.criterion = criterion;
this.orderElementTemplate = orderElementTemplate;
this.orderElement = null;
this.hoursGroup = hoursGroup;
}
@ -80,4 +92,12 @@ public class CriterionRequirement extends BaseEntity{
public boolean isValid() {
return true;
}
public OrderElementTemplate getOrderElementTemplate() {
return orderElementTemplate;
}
public void setOrderElementTemplate(OrderElementTemplate orderElementTemplate) {
this.orderElementTemplate = orderElementTemplate;
}
}

View file

@ -23,20 +23,63 @@ package org.navalplanner.business.requirements.entities;
import java.util.HashSet;
import java.util.Set;
import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
/**
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public class DirectCriterionRequirement extends CriterionRequirement{
private DirectCriterionRequirement origin;
private Set<IndirectCriterionRequirement> children =
new HashSet<IndirectCriterionRequirement>();
public static DirectCriterionRequirement copyFrom(
DirectCriterionRequirement criterionRequirement,
OrderElementTemplate orderElementTemplate) {
DirectCriterionRequirement result = copyFrom(criterionRequirement);
result.setOrigin(criterionRequirement);
result.setOrderElement(null);
result.setOrderElementTemplate(orderElementTemplate);
return result;
}
public static DirectCriterionRequirement copyFrom(
DirectCriterionRequirement criterionRequirement,
OrderElement orderElement) {
DirectCriterionRequirement result = copyFrom(criterionRequirement);
result.setOrigin(criterionRequirement);
result.setOrderElement(orderElement);
result.setOrderElementTemplate(null);
return result;
}
public static DirectCriterionRequirement copyFrom(
DirectCriterionRequirement criterionRequirement,
HoursGroup hoursGroup) {
DirectCriterionRequirement result = copyFrom(criterionRequirement);
result.setOrigin(criterionRequirement);
result.setHoursGroup(hoursGroup);
result.setOrderElement(null);
result.setOrderElementTemplate(null);
return result;
}
public static DirectCriterionRequirement copyFrom(
DirectCriterionRequirement criterionRequirement) {
DirectCriterionRequirement result = DirectCriterionRequirement.create();
result.setCriterion(criterionRequirement.getCriterion());
result.setHoursGroup(criterionRequirement.getHoursGroup());
return BaseEntity.create(result);
}
public static DirectCriterionRequirement create(){
DirectCriterionRequirement result = new DirectCriterionRequirement();
result.setNewObject(true);
@ -57,8 +100,8 @@ public class DirectCriterionRequirement extends CriterionRequirement{
return result;
}
protected DirectCriterionRequirement() {
public DirectCriterionRequirement(){
}
public DirectCriterionRequirement(Criterion criterion,
@ -70,12 +113,28 @@ public class DirectCriterionRequirement extends CriterionRequirement{
super(criterion);
}
public void addIndirectCriterionRequirement(IndirectCriterionRequirement indirect) {
children.add(indirect);
}
public void removeIndirectCriterionRequirement(IndirectCriterionRequirement indirect) {
children.remove(indirect);
}
public Set<IndirectCriterionRequirement> getChildren() {
return children;
}
public void setChildren(Set<IndirectCriterionRequirement>
children) {
public void setChildren(Set<IndirectCriterionRequirement> children) {
this.children = children;
}
public DirectCriterionRequirement getOrigin() {
return origin;
}
public void setOrigin(DirectCriterionRequirement origin) {
this.origin = origin;
}
}

View file

@ -22,34 +22,34 @@ package org.navalplanner.business.requirements.entities;
import org.apache.commons.lang.BooleanUtils;
import org.hibernate.validator.NotNull;
import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
/**
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public class IndirectCriterionRequirement extends CriterionRequirement{
private DirectCriterionRequirement parent;
private DirectCriterionRequirement parent;
private Boolean valid = true;
private Boolean valid = true;
public static IndirectCriterionRequirement create(DirectCriterionRequirement
parent,Criterion criterion) {
IndirectCriterionRequirement result = new IndirectCriterionRequirement(criterion);
result.setNewObject(true);
result.setParent(parent);
return result;
public static IndirectCriterionRequirement create(IndirectCriterionRequirement criterionRequirement) {
return create(criterionRequirement.getParent(), criterionRequirement.getCriterion());
}
public static IndirectCriterionRequirement create(DirectCriterionRequirement
parent, Criterion criterion,OrderElement orderElement,HoursGroup hoursGroup){
IndirectCriterionRequirement result = new IndirectCriterionRequirement(parent,criterion,
orderElement,hoursGroup);
public static IndirectCriterionRequirement create(
DirectCriterionRequirement parent, Criterion criterion) {
IndirectCriterionRequirement result = new IndirectCriterionRequirement(
criterion);
result.setNewObject(true);
result.setParent(parent);
return result;
}
@ -66,7 +66,12 @@ public class IndirectCriterionRequirement extends CriterionRequirement{
public IndirectCriterionRequirement(DirectCriterionRequirement parent,Criterion criterion,
OrderElement orderElement,HoursGroup hoursGroup){
super(criterion,orderElement,hoursGroup);
super(criterion, orderElement, hoursGroup);
}
public IndirectCriterionRequirement(DirectCriterionRequirement parent, Criterion criterion,
OrderElementTemplate orderElementTemplate, HoursGroup hoursGroup){
super(criterion, orderElementTemplate, hoursGroup);
}
@NotNull(message = "parent not specified")

View file

@ -0,0 +1,240 @@
/*
* This file is part of NavalPlan
*
* 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.business.templates.entities;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.orders.entities.CriterionRequirementHandler;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class CriterionRequirementTemplateHandler extends
CriterionRequirementHandler<OrderElementTemplate, OrderLineTemplate, OrderLineGroupTemplate>{
private static final CriterionRequirementTemplateHandler singleton =
new CriterionRequirementTemplateHandler();
private CriterionRequirementTemplateHandler() {
}
public static CriterionRequirementTemplateHandler getInstance() {
return singleton;
}
@Override
protected void addIndirectCriterionRequirementToOrderLine(
OrderLineTemplate orderLine, IndirectCriterionRequirement indirect) {
orderLine.addIndirectCriterionRequirement(indirect);
}
@Override
protected void basicAddCriterionRequirement(
OrderElementTemplate orderElement,
CriterionRequirement criterionRequirement) {
orderElement.basicAddCriterionRequirement(criterionRequirement);
}
@Override
protected void basicAddCriterionRequirementIntoOrderLineGroup(
OrderLineGroupTemplate orderLineGroup,
CriterionRequirement criterionRequirement) {
orderLineGroup.basicAddCriterionRequirement(criterionRequirement);
}
@Override
protected List<OrderElementTemplate> getAllChildren(
OrderElementTemplate orderElement) {
return orderElement.getAllChildren();
}
@Override
protected List<OrderElementTemplate> getChildren(
OrderElementTemplate orderElement) {
return orderElement.getChildren();
}
@Override
protected Set<CriterionRequirement> getCriterionRequirements(
OrderElementTemplate orderElement) {
return orderElement.getCriterionRequirements();
}
@Override
protected Set<DirectCriterionRequirement> getDirectCriterionRequirement(
OrderElementTemplate orderElement) {
return orderElement.getDirectCriterionRequirements();
}
@Override
protected Set<DirectCriterionRequirement> getDirectCriterionRequirementFromOrderLine(
OrderLineTemplate orderLine) {
return orderLine.getDirectCriterionRequirements();
}
@Override
protected Set<DirectCriterionRequirement> getDirectCriterionRequirementFromOrderLineGroup(
OrderLineGroupTemplate orderLineGroup) {
return orderLineGroup.getDirectCriterionRequirements();
}
@Override
protected List<HoursGroup> getHoursGroups(OrderLineTemplate orderline) {
return orderline.getHoursGroups();
}
@Override
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirement(
OrderElementTemplate orderElement) {
return orderElement.getIndirectCriterionRequirement();
}
@Override
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLine(
OrderLineTemplate orderLine) {
return orderLine.getIndirectCriterionRequirement();
}
@Override
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirementFromOrderLineGroup(
OrderLineGroupTemplate orderLineGroup) {
return orderLineGroup.getIndirectCriterionRequirement();
}
@Override
protected List<OrderElementTemplate> getOrderLineGroupChildren(
OrderLineGroupTemplate orderLineGroup) {
return orderLineGroup.getChildren();
}
@Override
protected List<HoursGroup> getOrderLineHoursGroups(
OrderLineTemplate orderLine) {
return orderLine.getHoursGroups();
}
@Override
protected OrderElementTemplate getParent(OrderElementTemplate orderElement) {
return orderElement.getParent();
}
@Override
protected boolean isOrderLine(OrderElementTemplate orderElement) {
return (orderElement instanceof OrderLineTemplate);
}
@Override
protected boolean isOrderLineGroup(OrderElementTemplate orderElement) {
return (orderElement instanceof OrderLineGroupTemplate);
}
@Override
protected void removeCriterionRequirement(
OrderElementTemplate orderElement,
CriterionRequirement criterionRequirement) {
orderElement.removeCriterionRequirement(criterionRequirement);
}
@Override
protected OrderElementTemplate toOrderElement(OrderLineTemplate orderLine) {
return (OrderElementTemplate) orderLine;
}
@Override
protected OrderLineTemplate toOrderLine(OrderElementTemplate orderElement) {
return (OrderLineTemplate) orderElement;
}
@Override
protected OrderLineGroupTemplate toOrderLineGroup(
OrderElementTemplate orderElement) {
return (OrderLineGroupTemplate) orderElement;
}
@Override
protected Collection<HoursGroup> myHoursGroups(OrderLineTemplate orderline) {
return orderline.myHoursGroups();
}
@Override
public void copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren(
OrderLineGroupTemplate orderLineGroup,
DirectCriterionRequirement parent) {
final List<OrderElementTemplate> orderElements = orderLineGroup.getChildren();
final Criterion criterion = parent.getCriterion();
final Set<IndirectCriterionRequirement> originalIndirectCriterionRequirements = parent
.getOrigin().getChildren();
final Map<OrderElement, Map<Criterion, Boolean>> mapTemplateCriterion =
createOrderElementCriterionMap(originalIndirectCriterionRequirements);
for (OrderElementTemplate each : orderElements) {
Map<Criterion, Boolean> criterionMap = mapTemplateCriterion
.get(each.getOrigin());
if (criterionMap != null) {
IndirectCriterionRequirement indirect = IndirectCriterionRequirement
.create(parent, criterion);
indirect.setValid(criterionMap.get(criterion));
addIndirectCriterionRequirement(each, indirect);
}
if (isOrderLineGroup(each)) {
copyIndirectCriterionRequirementsFromOriginalToOrderLineGroupChildren(
toOrderLineGroup(each), parent);
}
}
}
private Map<OrderElement, Map<Criterion, Boolean>> createOrderElementCriterionMap(
Set<IndirectCriterionRequirement> indirects) {
Map<OrderElement, Map<Criterion, Boolean>> result =
new HashMap<OrderElement, Map<Criterion, Boolean>>();
for (IndirectCriterionRequirement each: indirects) {
final OrderElement orderElement = each.getOrderElement();
if (orderElement != null) {
Map<Criterion, Boolean> value = result.get(orderElement);
if (value == null) {
value = new HashMap<Criterion, Boolean>();
}
value.put(each.getCriterion(), each.isValid());
result.put(orderElement, value);
}
}
return result;
}
}

View file

@ -0,0 +1,72 @@
/*
* This file is part of NavalPlan
*
* 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.business.templates.entities;
import java.util.Set;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.HoursGroupHandler;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class HoursGroupOrderLineTemplateHandler extends HoursGroupHandler<OrderLineTemplate> {
private static final HoursGroupOrderLineTemplateHandler singleton =
new HoursGroupOrderLineTemplateHandler();
private HoursGroupOrderLineTemplateHandler() {
}
public static HoursGroupOrderLineTemplateHandler getInstance() {
return singleton;
}
@Override
protected HoursGroup createHoursGroup(OrderLineTemplate orderLine) {
return HoursGroup.create(orderLine);
}
@Override
protected Set<HoursGroup> getHoursGroup(OrderLineTemplate orderLine) {
return orderLine.myHoursGroups();
}
@Override
protected void setHoursGroups(OrderLineTemplate orderLine,
Set<HoursGroup> hoursGroups) {
orderLine.setHoursGroups(hoursGroups);
}
@Override
protected void addHoursGroup(OrderLineTemplate orderLine, HoursGroup hoursGroup) {
orderLine.doAddHoursGroup(hoursGroup);
}
@Override
protected boolean hoursGroupsIsEmpty(OrderLineTemplate orderLine) {
return orderLine.getHoursGroups().isEmpty();
}
}

View file

@ -46,6 +46,8 @@ import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.materials.entities.MaterialAssignment;
import org.navalplanner.business.materials.entities.MaterialAssignmentTemplate;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.ICriterionRequirable;
import org.navalplanner.business.orders.entities.InfoComponent;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
@ -55,6 +57,9 @@ import org.navalplanner.business.orders.entities.SchedulingState.ITypeChangedLis
import org.navalplanner.business.orders.entities.SchedulingState.Type;
import org.navalplanner.business.qualityforms.entities.QualityForm;
import org.navalplanner.business.templates.daos.IOrderElementTemplateDAO;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.trees.ITreeNode;
/**
@ -62,11 +67,35 @@ import org.navalplanner.business.trees.ITreeNode;
*
*/
public abstract class OrderElementTemplate extends BaseEntity implements
ITreeNode<OrderElementTemplate> {
ICriterionRequirable, ITreeNode<OrderElementTemplate> {
private static final Log LOG = LogFactory
.getLog(OrderElementTemplate.class);
private SchedulingState.Type schedulingStateType;
private InfoComponent infoComponent;
private Integer startAsDaysFromBeginning;
private Integer deadlineAsDaysFromBeginning;
private OrderLineGroupTemplate parent;
private Set<CriterionRequirement> criterionRequirements = new HashSet<CriterionRequirement>();
private Set<MaterialAssignmentTemplate> materialAssignments = new HashSet<MaterialAssignmentTemplate>();
private Set<Label> labels = new HashSet<Label>();
private Set<QualityForm> qualityForms = new HashSet<QualityForm>();
private Set<AdvanceAssignmentTemplate> advanceAssignmentTemplates = new HashSet<AdvanceAssignmentTemplate>();
private SchedulingState schedulingState;
private OrderElement origin;
public static <T extends OrderElementTemplate> T create(T beingBuilt,
OrderElement origin) {
InfoComponent infoComponentCopied = origin.getInfoComponent().copy();
@ -77,6 +106,8 @@ public abstract class OrderElementTemplate extends BaseEntity implements
.getDeadline());
beingBuilt.materialAssignments = copyMaterialAssignmentsFrom(beingBuilt, origin
.getMaterialAssignments());
beingBuilt.criterionRequirements = copyDirectCriterionRequirements(
beingBuilt, origin.getDirectCriterionRequirement());
beingBuilt.labels = new HashSet<Label>(origin.getLabels());
beingBuilt.qualityForms = origin.getQualityForms();
beingBuilt.advanceAssignmentTemplates = copyDirectAdvanceAssignments(
@ -84,9 +115,32 @@ public abstract class OrderElementTemplate extends BaseEntity implements
beingBuilt.infoComponent = infoComponentCopied;
beingBuilt.schedulingStateType = origin.getSchedulingStateType();
assignDates(beingBuilt, fromBeginningToStart, fromBeginningToEnd);
beingBuilt.origin = origin;
return create(beingBuilt);
}
/**
*
* Copy only {@link DirectCriterionRequirement}
*
* @param beingBuilt
* @param criterionRequirements
* @return
*/
private static Set<CriterionRequirement> copyDirectCriterionRequirements(OrderElementTemplate beingBuilt,
Collection<DirectCriterionRequirement> criterionRequirements) {
Set<CriterionRequirement> result = new HashSet<CriterionRequirement>();
for (DirectCriterionRequirement each: criterionRequirements) {
final DirectCriterionRequirement directCriterionRequirement = (DirectCriterionRequirement) each;
DirectCriterionRequirement newDirectCriterionRequirement = DirectCriterionRequirement
.copyFrom(directCriterionRequirement, beingBuilt);
result.add(newDirectCriterionRequirement);
}
return result;
}
private static Set<AdvanceAssignmentTemplate> copyDirectAdvanceAssignments(
OrderElementTemplate beingBuilt,
Set<DirectAdvanceAssignment> directAdvanceAssignments) {
@ -142,6 +196,7 @@ public abstract class OrderElementTemplate extends BaseEntity implements
protected <T extends OrderElement> T setupElementParts(T orderElement) {
setupInfoComponent(orderElement);
setupDates(orderElement);
setupCriterionRequirements(orderElement);
setupMaterialAssignments(orderElement);
setupLabels(orderElement);
setupQualityForms(orderElement);
@ -177,6 +232,13 @@ public abstract class OrderElementTemplate extends BaseEntity implements
return localDate.plusDays(days).toDateTimeAtStartOfDay().toDate();
}
private void setupCriterionRequirements(OrderElement orderElement) {
for (DirectCriterionRequirement each : getDirectCriterionRequirements()) {
orderElement.addCriterionRequirement(DirectCriterionRequirement
.copyFrom(each, orderElement));
}
}
private void setupMaterialAssignments(OrderElement orderElement) {
for (MaterialAssignmentTemplate each : materialAssignments) {
orderElement.addMaterialAssignment(each
@ -212,26 +274,6 @@ public abstract class OrderElementTemplate extends BaseEntity implements
public abstract OrderElement createElement(OrderLineGroup parent);
private SchedulingState.Type schedulingStateType;
private InfoComponent infoComponent;
private Integer startAsDaysFromBeginning;
private Integer deadlineAsDaysFromBeginning;
private OrderLineGroupTemplate parent;
private Set<MaterialAssignmentTemplate> materialAssignments = new HashSet<MaterialAssignmentTemplate>();
private Set<Label> labels = new HashSet<Label>();
private Set<QualityForm> qualityForms = new HashSet<QualityForm>();
private Set<AdvanceAssignmentTemplate> advanceAssignmentTemplates = new HashSet<AdvanceAssignmentTemplate>();
private SchedulingState schedulingState;
public SchedulingState getSchedulingState() {
if (schedulingState == null) {
schedulingState = SchedulingState.createSchedulingState(
@ -425,10 +467,114 @@ public abstract class OrderElementTemplate extends BaseEntity implements
return template.getId().equals(getId());
} catch (InstanceNotFoundException e) {
return true;
} catch (NonUniqueResultException e) {
}
catch (NonUniqueResultException e) {
return false;
}
}
}
public List<OrderElementTemplate> getAllChildren() {
List<OrderElementTemplate> children = getChildrenTemplates();
List<OrderElementTemplate> result = new ArrayList<OrderElementTemplate>();
for (OrderElementTemplate orderElement : children) {
result.add(orderElement);
result.addAll(orderElement.getAllChildren());
}
return result;
}
@Valid
@Override
public Set<CriterionRequirement> getCriterionRequirements() {
return Collections.unmodifiableSet(criterionRequirements);
}
public abstract List<HoursGroup> getHoursGroups();
public abstract Integer getWorkHours();
/**
* Operations for manipulating CriterionRequirement
*/
protected CriterionRequirementTemplateHandler criterionRequirementHandler =
CriterionRequirementTemplateHandler.getInstance();
public void setValidCriterionRequirement(IndirectCriterionRequirement requirement, boolean valid){
requirement.setValid(valid);
criterionRequirementHandler.propagateValidCriterionRequirement(this,
requirement.getParent(), valid);
}
public void removeDirectCriterionRequirement(DirectCriterionRequirement criterionRequirement){
criterionRequirementHandler.propagateRemoveCriterionRequirement(this,
criterionRequirement);
removeCriterionRequirement(criterionRequirement);
}
protected void removeCriterionRequirement(CriterionRequirement requirement) {
criterionRequirements.remove(requirement);
if (requirement instanceof IndirectCriterionRequirement) {
((IndirectCriterionRequirement)requirement).getParent().
getChildren().remove((IndirectCriterionRequirement)requirement);
}
}
@Override
public void addCriterionRequirement(
CriterionRequirement criterionRequirement) {
criterionRequirementHandler.addCriterionRequirement(this,
criterionRequirement);
}
public void addDirectCriterionRequirement(
CriterionRequirement criterionRequirement) {
criterionRequirementHandler.addDirectCriterionRequirement(this, criterionRequirement);
}
public void addIndirectCriterionRequirement(
IndirectCriterionRequirement criterionRequirement) {
criterionRequirementHandler.addIndirectCriterionRequirement(this,
criterionRequirement);
}
protected void basicAddCriterionRequirement(
CriterionRequirement criterionRequirement) {
criterionRequirement.setOrderElementTemplate(this);
this.criterionRequirements.add(criterionRequirement);
}
public void updateCriterionRequirements() {
criterionRequirementHandler.updateMyCriterionRequirements(this);
criterionRequirementHandler.propagateUpdateCriterionRequirements(this);
}
public boolean canAddCriterionRequirement(
DirectCriterionRequirement newRequirement) {
return criterionRequirementHandler.canAddCriterionRequirement(this,
newRequirement);
}
protected Set<IndirectCriterionRequirement> getIndirectCriterionRequirement() {
return criterionRequirementHandler.getIndirectCriterionRequirement(criterionRequirements);
}
public Set<DirectCriterionRequirement> getDirectCriterionRequirements() {
return criterionRequirementHandler
.getDirectCriterionRequirement(criterionRequirements);
}
public Order getOrder() {
return (parent != null) ? parent.getOrder() : null;
}
public OrderElement getOrigin() {
return origin;
}
public void setOrigin(OrderElement origin) {
this.origin = origin;
}
}

View file

@ -25,10 +25,13 @@ import java.util.List;
import org.hibernate.validator.Valid;
import org.navalplanner.business.i18n.I18nHelper;
import org.navalplanner.business.orders.entities.CriterionRequirementOrderElementHandler;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLineGroup;
import org.navalplanner.business.orders.entities.SchedulingState;
import org.navalplanner.business.orders.entities.TreeNodeOnListWithSchedulingState;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.trees.ITreeParentNode;
/**
@ -38,6 +41,9 @@ import org.navalplanner.business.trees.ITreeParentNode;
public class OrderLineGroupTemplate extends OrderElementTemplate implements
ITreeParentNode<OrderElementTemplate> {
private final CriterionRequirementTemplateHandler criterionRequirementTemplateHandler = CriterionRequirementTemplateHandler
.getInstance();
private final class ChildrenManipulator extends
TreeNodeOnListWithSchedulingState<OrderElementTemplate> {
@ -93,10 +99,19 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
protected static <T extends OrderLineGroupTemplate> T create(T beingBuilt,
OrderLineGroup group) {
OrderElementTemplate.create(beingBuilt, group);
List<OrderElementTemplate> result = buildChildrenTemplates(beingBuilt,
group.getChildren());
beingBuilt.children = result;
return OrderElementTemplate.create(beingBuilt, group);
beingBuilt.copyIndirectRequirementsFromOriginalDirectRequirements();
return beingBuilt;
}
public void copyIndirectRequirementsFromOriginalDirectRequirements() {
for (DirectCriterionRequirement each: getDirectCriterionRequirements()) {
criterionRequirementTemplateHandler
.copyIndirectCriterionRequirementFromOriginalToOrderLineGroupChildren(this, each);
}
}
private static List<OrderElementTemplate> buildChildrenTemplates(
@ -175,23 +190,37 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
return false;
}
private CriterionRequirementOrderElementHandler criterionRequirementOrderElementHandler = CriterionRequirementOrderElementHandler
.getInstance();
protected <T extends OrderLineGroup> T setupGroupParts(T group) {
T parent = setupElementParts(group);
for (OrderElementTemplate each : children) {
each.createElement(parent);
}
copyIndirectCriterionRequirementFromOriginalToOrderLineGroupChildren(parent);
return parent;
}
private void copyIndirectCriterionRequirementFromOriginalToOrderLineGroupChildren(OrderLineGroup orderElement) {
for (DirectCriterionRequirement each: orderElement.getDirectCriterionRequirement()) {
criterionRequirementOrderElementHandler.copyIndirectCriterionRequirementFromOriginalToOrderLineGroupChildren(
orderElement, each);
}
}
@Override
public OrderLineGroup createElement() {
return setupGroupParts(setupSchedulingStateType(OrderLineGroup.create()));
OrderLineGroup orderLineGroup = OrderLineGroup.create();
orderLineGroup.initializeTemplate(this);
return setupGroupParts(setupSchedulingStateType(orderLineGroup));
}
@Override
public OrderElement createElement(OrderLineGroup parent) {
OrderLineGroup result = setupSchedulingStateType(OrderLineGroup
.create());
result.initializeTemplate(this);
parent.add(result);
return setupGroupParts(result);
}
@ -201,4 +230,22 @@ public class OrderLineGroupTemplate extends OrderElementTemplate implements
return I18nHelper._("Group");
}
@Override
public List<HoursGroup> getHoursGroups() {
List<HoursGroup> hoursGroups = new ArrayList<HoursGroup>();
for (OrderElementTemplate orderElement : children) {
hoursGroups.addAll(orderElement.getHoursGroups());
}
return hoursGroups;
}
@Override
public Integer getWorkHours() {
Integer result = 0;
for (OrderElementTemplate orderElement : getChildren()) {
result += orderElement.getWorkHours();
}
return result;
}
}

View file

@ -22,30 +22,65 @@ package org.navalplanner.business.templates.entities;
import static org.navalplanner.business.i18n.I18nHelper._;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.orders.entities.OrderLineGroup;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class OrderLineTemplate extends OrderElementTemplate {
@Valid
private Set<HoursGroup> hoursGroups = new HashSet<HoursGroup>();
private Integer lastHoursGroupSequenceCode = 0;
public static OrderLineTemplate create(OrderLine orderLine) {
OrderLineTemplate beingBuilt = new OrderLineTemplate();
beingBuilt.workHours = orderLine.getWorkHours();
copyHoursGroup(orderLine.getHoursGroups(), beingBuilt);
return create(beingBuilt, orderLine);
}
private static void copyHoursGroup(
final Collection<HoursGroup> hoursGroups,
OrderLineTemplate orderLineTemplate) {
for (HoursGroup each: hoursGroups) {
orderLineTemplate.addHoursGroup(HoursGroup.copyFrom(each,
orderLineTemplate));
}
}
public static OrderLineTemplate createNew() {
return createNew(new OrderLineTemplate());
}
private Integer workHours;
protected <T extends OrderElement> T setupElementParts(T orderElement) {
super.setupElementParts(orderElement);
setupHoursGroups((OrderLine) orderElement);
return orderElement;
}
private void setupHoursGroups(OrderLine orderLine) {
Set<HoursGroup> result = new HashSet<HoursGroup>();
for (HoursGroup each: getHoursGroups()) {
result.add(HoursGroup.copyFrom(each, orderLine));
}
orderLine.setHoursGroups(result);
}
@Override
public List<OrderElementTemplate> getChildrenTemplates() {
@ -84,6 +119,7 @@ public class OrderLineTemplate extends OrderElementTemplate {
public OrderElement createElement(OrderLineGroup parent) {
OrderLine line = setupSchedulingStateType(OrderLine
.createOrderLineWithUnfixedPercentage(getWorkHours()));
line.initializeTemplate(this);
parent.add(line);
return setupElementParts(line);
}
@ -93,11 +129,73 @@ public class OrderLineTemplate extends OrderElementTemplate {
return _("Line");
}
public int getWorkHours() {
if (workHours == null) {
return 0;
public Integer getWorkHours() {
return hoursGroupOrderLineTemplateHandler.calculateTotalHours(hoursGroups);
}
public void incrementLastHoursGroupSequenceCode() {
if(lastHoursGroupSequenceCode==null){
lastHoursGroupSequenceCode = 0;
}
return workHours;
lastHoursGroupSequenceCode++;
}
@NotNull(message = "last hours group sequence code not specified")
public Integer getLastHoursGroupSequenceCode() {
return lastHoursGroupSequenceCode;
}
/**
* Operations for manipulating {@link HoursGroup}
*/
@Override
public List<HoursGroup> getHoursGroups() {
return new ArrayList<HoursGroup>(hoursGroups);
}
public Set<HoursGroup> myHoursGroups() {
return hoursGroups;
}
public void setHoursGroups(final Set<HoursGroup> hoursGroups) {
this.hoursGroups.clear();
this.hoursGroups.addAll(hoursGroups);
}
public void addHoursGroup(HoursGroup hoursGroup) {
hoursGroup.setOrderLineTemplate(this);
hoursGroup.updateMyCriterionRequirements();
doAddHoursGroup(hoursGroup);
recalculateHoursGroups();
}
public void doAddHoursGroup(HoursGroup hoursGroup) {
hoursGroups.add(hoursGroup);
}
public void deleteHoursGroup(HoursGroup hoursGroup) {
hoursGroups.remove(hoursGroup);
recalculateHoursGroups();
}
private HoursGroupOrderLineTemplateHandler hoursGroupOrderLineTemplateHandler = HoursGroupOrderLineTemplateHandler
.getInstance();
public void setWorkHours(Integer workHours) throws IllegalArgumentException {
hoursGroupOrderLineTemplateHandler.setWorkHours(this, workHours);
}
public boolean isTotalHoursValid(Integer total) {
return hoursGroupOrderLineTemplateHandler.isTotalHoursValid(total, hoursGroups);
}
public boolean isPercentageValid() {
return hoursGroupOrderLineTemplateHandler.isPercentageValid(hoursGroups);
}
public void recalculateHoursGroups() {
hoursGroupOrderLineTemplateHandler.recalculateHoursGroups(this);
}
}

View file

@ -98,8 +98,8 @@
class="org.navalplanner.business.common.Registry"
factory-method="getInstance" />
<bean id="CriterionRequirementHandler"
class="org.navalplanner.business.orders.entities.CriterionRequirementHandler"
<bean id="CriterionRequirementOrderElementHandler"
class="org.navalplanner.business.orders.entities.CriterionRequirementOrderElementHandler"
factory-method="getInstance" />
</beans>

View file

@ -122,7 +122,14 @@
<version name="version" access="property" type="long" />
<property name="code" access="field" not-null="true" />
<property name="resourceType" access="field" />
<property name="resourceType" access="field" >
<type name="org.hibernate.type.EnumType">
<param name="enumClass">org.navalplanner.business.resources.entities.ResourceEnum</param>
<param name="type">12</param>
</type>
</property>
<property name="workingHours" access="field" not-null="true"/>
<property name="percentage" access="field" />
<property name="fixedPercentage" access="field" />
@ -133,8 +140,10 @@
</set>
<many-to-one name="parentOrderLine" column="PARENT_ORDER_LINE"
not-null="true"
class="org.navalplanner.business.orders.entities.OrderLine"/>
class="org.navalplanner.business.orders.entities.OrderLine" />
<many-to-one name="orderLineTemplate" column="ORDER_LINE_TEMPLATE"
class="org.navalplanner.business.templates.entities.OrderLineTemplate" />
</class>

View file

@ -8,12 +8,20 @@
<param name="max_lo">100</param>
</generator>
</id>
<discriminator column="CRITERION_REQUIREMENT_TYPE" type="string"/>
<version access="property" name="version" type="long"/>
<!-- Inverse navigation from CriterionRequirement to HoursGroup -->
<many-to-one class="org.navalplanner.business.orders.entities.HoursGroup" column="HOURS_GROUP_ID" name="hoursGroup"/>
<!-- Inverse navigation from CriterionRequirement to OrderElement -->
<many-to-one class="org.navalplanner.business.orders.entities.OrderElement" column="ORDER_ELEMENT_ID" name="orderElement"/>
<!-- Inverse navigation from CriterionRequirement to OrderTemplateElement -->
<many-to-one class="org.navalplanner.business.templates.entities.OrderElementTemplate" column="ORDER_ELEMENT_TEMPLATE_ID" name="orderElementTemplate"/>
<!-- Inverse navigation from CriterionRequirement to Criterion -->
<many-to-one class="org.navalplanner.business.resources.entities.Criterion" column="CRITERION_ID" name="criterion"/>
@ -24,9 +32,11 @@
<one-to-many class="IndirectCriterionRequirement"/>
</set>
</subclass>
<subclass discriminator-value="INDIRECT" name="IndirectCriterionRequirement">
<many-to-one class="DirectCriterionRequirement" column="parent" name="parent"/>
<property access="field" name="valid"/>
</subclass>
</class>
</hibernate-mapping>

View file

@ -25,6 +25,11 @@
<many-to-one name="parent" access="field" class="org.navalplanner.business.templates.entities.OrderLineGroupTemplate"/>
<set name="criterionRequirements" cascade="all-delete-orphan" inverse="true">
<key column="ORDER_ELEMENT_TEMPLATE_ID" not-null="true" />
<one-to-many class="org.navalplanner.business.requirements.entities.CriterionRequirement" />
</set>
<set name="materialAssignments" cascade="all-delete-orphan" inverse="true">
<key column="ORDER_ELEMENT_TEMPLATE_ID" not-null="true" />
<one-to-many class="org.navalplanner.business.materials.entities.MaterialAssignmentTemplate" />
@ -61,8 +66,14 @@
</joined-subclass>
<joined-subclass name="OrderLineTemplate">
<key column="ORDER_LINE_TEMPLATE_ID"></key>
<property name="workHours" />
<key column="ORDER_LINE_TEMPLATE_ID" />
<set name="hoursGroups" access="field" cascade="all-delete-orphan" inverse="true">
<key column="ORDER_LINE_TEMPLATE" />
<one-to-many class="org.navalplanner.business.orders.entities.HoursGroup" />
</set>
<property name="lastHoursGroupSequenceCode" access="field" />
</joined-subclass>
</class>

View file

@ -36,6 +36,8 @@ import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.resources.entities.ResourceEnum;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.business.templates.entities.OrderLineGroupTemplate;
/**
* Wrapper represents the handled data in the form of assigning criterion
@ -55,12 +57,24 @@ public class HoursGroupWrapper implements INewObject,
private OrderElement orderElement;
private OrderElementTemplate template;
private HoursGroup hoursGroup;
public HoursGroupWrapper(HoursGroup hoursGroup, OrderElement orderElement,
boolean newObject) {
this.newObject = newObject;
this.orderElement = orderElement;
this.template = null;
this.hoursGroup = hoursGroup;
initRequirementWrappers(hoursGroup);
}
public HoursGroupWrapper(HoursGroup hoursGroup, OrderElementTemplate template,
boolean newObject) {
this.newObject = newObject;
this.orderElement = null;
this.template = template;
this.hoursGroup = hoursGroup;
initRequirementWrappers(hoursGroup);
}
@ -133,16 +147,34 @@ public class HoursGroupWrapper implements INewObject,
}
public BigDecimal getPercentage() {
if (orderElement instanceof OrderLineGroup) {
return getPercentageInOrderLineGroup();
if (orderElementIsOrderLineGroup()) {
return getPercentageInOrderLineGroup(getWorkHours());
}
return hoursGroup.getPercentage().scaleByPowerOfTen(2);
}
private BigDecimal getPercentageInOrderLineGroup() {
private boolean orderElementIsOrderLineGroup() {
return getOrderElement() instanceof OrderLineGroup
|| getTemplate() instanceof OrderLineGroupTemplate;
}
private Integer getWorkHours() {
return (getOrderElement() != null) ? getOrderElement().getWorkHours()
: getTemplate().getWorkHours();
}
private OrderElement getOrderElement() {
return orderElement;
}
private OrderElementTemplate getTemplate() {
return template;
}
private BigDecimal getPercentageInOrderLineGroup(Integer workHours) {
BigDecimal workingHours = new BigDecimal(hoursGroup.getWorkingHours())
.setScale(2);
BigDecimal total = new BigDecimal(orderElement.getWorkHours())
BigDecimal total = new BigDecimal(workHours)
.setScale(2);
if (total.equals(new BigDecimal(0).setScale(2))) {
return new BigDecimal(0).setScale(2);
@ -180,12 +212,12 @@ public class HoursGroupWrapper implements INewObject,
public boolean isPercentageReadOnly() {
return (!hoursGroup.isFixedPercentage())
|| ((orderElement instanceof OrderLineGroup));
|| ((orderElementIsOrderLineGroup()));
}
public boolean isWorkingHoursReadOnly() {
return (hoursGroup.isFixedPercentage())
|| ((orderElement instanceof OrderLineGroup));
|| ((orderElementIsOrderLineGroup()));
}
/* Operations to manage the criterions requirements */

View file

@ -39,7 +39,6 @@ import org.navalplanner.business.externalcompanies.entities.ExternalCompany;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.orders.entities.OrderStatusEnum;
import org.navalplanner.business.templates.entities.OrderTemplate;
import org.navalplanner.business.users.entities.UserRole;
@ -53,6 +52,7 @@ 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.orders.criterionrequirements.AssignedCriterionRequirementToOrderElementController;
import org.navalplanner.web.orders.labels.AssignedLabelsToOrderElementController;
import org.navalplanner.web.orders.labels.LabelsAssignmentToOrderElementComponent;
import org.navalplanner.web.orders.materials.AssignedMaterialsToOrderElementController;
@ -127,9 +127,8 @@ public class OrderCRUDController extends GenericForwardComposer {
} else if (invalidValue.getBean() instanceof HoursGroup) {
Label result = new Label();
HoursGroup hoursGroup = (HoursGroup) invalidValue.getBean();
OrderLine parentOrderLine = hoursGroup.getParentOrderLine();
result.setValue(_("Hours Group at ")
+ parentOrderLine.getName() + ". "
+ getParentName(hoursGroup) + ". "
+ invalidValue.getPropertyName() + ": "
+ invalidValue.getMessage());
return result;
@ -137,6 +136,12 @@ public class OrderCRUDController extends GenericForwardComposer {
return MessagesForUser.createLabelFor(invalidValue);
}
}
private String getParentName(HoursGroup hoursGroup) {
return (hoursGroup.getParentOrderLine() != null) ? hoursGroup
.getParentOrderLine().getName() : hoursGroup
.getOrderLineTemplate().getName();
}
}
private static final org.apache.commons.logging.Log LOG = LogFactory

View file

@ -25,6 +25,8 @@ import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.orders.entities.OrderLineGroup;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.orders.criterionrequirements.AssignedCriterionRequirementToOrderElementController;
import org.navalplanner.web.orders.criterionrequirements.OrderElementCriterionRequirementComponent;
import org.navalplanner.web.orders.labels.AssignedLabelsToOrderElementController;
import org.navalplanner.web.orders.labels.LabelsAssignmentToOrderElementComponent;
import org.navalplanner.web.orders.materials.AssignedMaterialsToOrderElementController;
@ -71,7 +73,7 @@ public class OrderElementController extends GenericForwardComposer {
private AssignedTaskQualityFormsToOrderElementController assignedTaskQualityFormsController;
private Component orderElementCriterionRequirements;
private OrderElementCriterionRequirementComponent orderElementCriterionRequirements;
private AssignedCriterionRequirementToOrderElementController assignedCriterionRequirementController;
@ -79,6 +81,7 @@ public class OrderElementController extends GenericForwardComposer {
private AssignedMaterialsToOrderElementController assignedMaterialsController;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
@ -132,7 +135,7 @@ public class OrderElementController extends GenericForwardComposer {
throws Exception {
if (assignedCriterionRequirementController == null) {
assignedCriterionRequirementController = (AssignedCriterionRequirementToOrderElementController) orderElementCriterionRequirements
.getVariable("assignedCriterionRequirementController", true);
.getVariable("assignedCriterionRequirementController", true);
assignedCriterionRequirementController
.openWindow(orderElementModel);
} else {

View file

@ -50,6 +50,7 @@ import org.navalplanner.business.labels.daos.ILabelDAO;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.CriterionRequirementOrderElementHandler;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
@ -382,10 +383,8 @@ public class OrderModel implements IOrderModel {
private OrderElement createOrderElementFrom(OrderLineGroup parent,
OrderElementTemplate template) {
OrderElement result = parent != null ? template.createElement(parent)
: template.createElement();
result.initializeTemplate(template);
return result;
return (parent != null) ? template.createElement(parent) : template
.createElement();
}
private void setDefaultOrderCode() throws ConcurrentModificationException {

View file

@ -1,5 +1,5 @@
/*
* This file is part of NavalPlan
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
@ -18,7 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.orders;
package org.navalplanner.web.orders.criterionrequirements;
import static org.navalplanner.web.I18nHelper._;
@ -44,6 +44,9 @@ import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.MessagesForUser;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.NewDataSortableGrid;
import org.navalplanner.web.orders.CriterionRequirementWrapper;
import org.navalplanner.web.orders.HoursGroupWrapper;
import org.navalplanner.web.orders.OrderCRUDController;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.util.GenericForwardComposer;
@ -55,21 +58,20 @@ import org.zkoss.zul.Intbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listheader;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Row;
import org.zkoss.zul.Rows;
import org.zkoss.zul.Vbox;
/**
* Controller for showing OrderElement assigned labels
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public class AssignedCriterionRequirementToOrderElementController extends
public abstract class AssignedCriterionRequirementController<T, M> extends
GenericForwardComposer {
private static final org.apache.commons.logging.Log LOG = LogFactory
@ -79,81 +81,67 @@ public class AssignedCriterionRequirementToOrderElementController extends
private Component messagesContainer;
private IAssignedCriterionRequirementToOrderElementModel assignedCriterionRequirementToOrderElementModel;
private Vbox vboxCriterionRequirementsAndHoursGroups;
private Listbox hoursGroupsInOrderLineGroup;
List<ResourceEnum> listResourceTypes = new ArrayList<ResourceEnum>();
private List<ResourceEnum> listResourceTypes = new ArrayList<ResourceEnum>();
private NewDataSortableGrid listingRequirements;
private NewDataSortableGrid listHoursGroups;
protected NewDataSortableGrid listHoursGroups;
private Intbox orderElementTotalHours;
protected Intbox orderElementTotalHours;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
messagesForUser = new MessagesForUser(messagesContainer);
comp.setVariable("assignedCriterionRequirementController", this, true);
vboxCriterionRequirementsAndHoursGroups = (Vbox) comp;
// init the resorcesType
listResourceTypes.add(ResourceEnum.MACHINE);
listResourceTypes.add(ResourceEnum.WORKER);
}
public OrderElement getOrderElement() {
return assignedCriterionRequirementToOrderElementModel.getOrderElement();
}
public abstract T getElement();
public IOrderModel getOrderModel() {
return assignedCriterionRequirementToOrderElementModel.getOrderModel();
}
public abstract Set<CriterionType> getCriterionTypes();
public Set<CriterionType> getCriterionTypes() {
return assignedCriterionRequirementToOrderElementModel.getTypes();
}
public abstract void setOrderElement(T element);
public void setOrderElement(OrderElement orderElement) {
assignedCriterionRequirementToOrderElementModel.setOrderElement(orderElement);
}
public abstract void openWindow(M model);
public void openWindow(IOrderElementModel orderElementModel) {
assignedCriterionRequirementToOrderElementModel.setOrderModel(orderElementModel
.getOrderModel());
openWindow(orderElementModel.getOrderElement());
}
public void openWindow(OrderElement orderElement) {
assignedCriterionRequirementToOrderElementModel.init(orderElement);
Util.createBindingsFor(vboxCriterionRequirementsAndHoursGroups);
Util.reloadBindings(vboxCriterionRequirementsAndHoursGroups);
}
public abstract void confirm();
public boolean close() {
if (showInvalidValues()) {
return false;
}
assignedCriterionRequirementToOrderElementModel.confirm();
confirm();
return true;
}
public List<CriterionRequirementWrapper> criterionRequirementWrappers() {
return assignedCriterionRequirementToOrderElementModel.
getCriterionRequirementWrappers();
private boolean showInvalidValues() {
CriterionRequirementWrapper invalidWrapper = validateWrappers(criterionRequirementWrappers());
if (invalidWrapper != null) {
showInvalidValues(invalidWrapper);
return true;
}
CriterionRequirementWrapper invalidHoursGroupWrapper = validateHoursGroupWrappers();
if (invalidHoursGroupWrapper != null) {
showInvalidValuesInHoursGroups(invalidHoursGroupWrapper);
return true;
}
return false;
}
public List<CriterionWithItsType> getCriterionWithItsTypes(){
return assignedCriterionRequirementToOrderElementModel.getCriterionWithItsTypes();
}
public abstract List<CriterionRequirementWrapper> criterionRequirementWrappers();
public abstract List<CriterionWithItsType> getCriterionWithItsTypes();
public List<CriterionWithItsType> getCriterionWithItsTypesWorker() {
List<CriterionWithItsType> result = new ArrayList<CriterionWithItsType>();
for (CriterionWithItsType criterionAndType : assignedCriterionRequirementToOrderElementModel
.getCriterionWithItsTypes()) {
for (CriterionWithItsType criterionAndType : getCriterionWithItsTypes()) {
if (!criterionAndType.getCriterion().getType().getResource()
.equals(ResourceEnum.MACHINE)) {
result.add(criterionAndType);
@ -164,8 +152,7 @@ getCriterionRequirementWrappers();
public List<CriterionWithItsType> getCriterionWithItsTypesMachine() {
List<CriterionWithItsType> result = new ArrayList<CriterionWithItsType>();
for (CriterionWithItsType criterionAndType : assignedCriterionRequirementToOrderElementModel
.getCriterionWithItsTypes()) {
for (CriterionWithItsType criterionAndType : getCriterionWithItsTypes()) {
if (!criterionAndType.getCriterion().getType().getResource()
.equals(ResourceEnum.WORKER)) {
result.add(criterionAndType);
@ -178,51 +165,40 @@ getCriterionRequirementWrappers();
return listResourceTypes;
}
public void addCriterionRequirementWrapper() {
assignedCriterionRequirementToOrderElementModel
.assignCriterionRequirementWrapper();
reload();
}
public abstract void addCriterionRequirementWrapper();
public void remove(CriterionRequirementWrapper requirement){
assignedCriterionRequirementToOrderElementModel.
deleteCriterionRequirementWrapper(requirement);
reload();
}
public abstract void remove(CriterionRequirementWrapper requirement);
public void invalidate(CriterionRequirementWrapper requirement){
assignedCriterionRequirementToOrderElementModel.
setValidCriterionRequirementWrapper(requirement, false);
reload();
}
public abstract void invalidate(CriterionRequirementWrapper requirement);
public void validate(CriterionRequirementWrapper requirement){
assignedCriterionRequirementToOrderElementModel.
setValidCriterionRequirementWrapper(requirement, true);
reload();
}
public abstract void validate(CriterionRequirementWrapper requirement);
public void selectCriterionAndType(Listitem item,Bandbox bandbox,
protected abstract void changeCriterionAndType(
CriterionRequirementWrapper requirementWrapper,
CriterionWithItsType newCriterionAndType);
public void selectCriterionAndType(Listitem item, Bandbox bandbox,
CriterionRequirementWrapper requirementWrapper) {
if(item != null){
if (item != null) {
CriterionWithItsType newCriterionAndType = (CriterionWithItsType) item
.getValue();
try {
bandbox.close();
bandbox.setValue(newCriterionAndType.getNameAndType());
assignedCriterionRequirementToOrderElementModel
.changeCriterionAndType(requirementWrapper,
newCriterionAndType);
changeCriterionAndType(requirementWrapper, newCriterionAndType);
} catch (IllegalStateException e) {
showInvalidConstraint(bandbox, e);
requirementWrapper.setCriterionWithItsType(null);
}
Util.reloadBindings(listHoursGroups);
}else{
} else {
bandbox.setValue("");
}
}
protected abstract void updateCriterionsWithDiferentResourceType(
HoursGroupWrapper hoursGroupWrapper);
public void selectResourceType(Combobox combobox)
throws InterruptedException {
HoursGroupWrapper hoursGroupWrapper = (HoursGroupWrapper) ((Row) combobox
@ -239,8 +215,7 @@ setValidCriterionRequirementWrapper(requirement, true);
ResourceEnum resource = (ResourceEnum) combobox
.getSelectedItem().getValue();
hoursGroupWrapper.assignResourceType(resource);
assignedCriterionRequirementToOrderElementModel
.updateCriterionsWithDiferentResourceType(hoursGroupWrapper);
updateCriterionsWithDiferentResourceType(hoursGroupWrapper);
}
} catch (InterruptedException e) {
messagesForUser.showMessage(Level.ERROR, e.getMessage());
@ -260,30 +235,17 @@ setValidCriterionRequirementWrapper(requirement, true);
}
}
private boolean showInvalidValues() {
CriterionRequirementWrapper invalidWrapper = assignedCriterionRequirementToOrderElementModel
.validateWrappers(criterionRequirementWrappers());
if (invalidWrapper != null) {
showInvalidValues(invalidWrapper);
return true;
}
protected abstract CriterionRequirementWrapper validateWrappers(
List<CriterionRequirementWrapper> list);
CriterionRequirementWrapper invalidHoursGroupWrapper = assignedCriterionRequirementToOrderElementModel
.validateHoursGroupWrappers();
if (invalidHoursGroupWrapper != null) {
showInvalidValuesInHoursGroups(invalidHoursGroupWrapper);
return true;
}
return false;
}
protected abstract CriterionRequirementWrapper validateHoursGroupWrappers();
// Show invalid values inside listhoursGroup.
private void showInvalidValuesInHoursGroups(
CriterionRequirementWrapper requirementWrapper) {
if (listHoursGroups != null) {
List<Row> listRowsHoursGroup = (List<Row>) ((Rows) listHoursGroups
.getRows())
.getChildren();
.getRows()).getChildren();
for (Row row : listRowsHoursGroup) {
Rows listRequirementRows = getRequirementRows(row);
Row requirementRow = findRowOfCriterionRequirementWrapper(
@ -292,13 +254,15 @@ setValidCriterionRequirementWrapper(requirement, true);
}
}
}
/**
* Validates {@link CriterionRequirementWrapper} data constraints
*
* @param invalidValue
*/
private void showInvalidValues(
CriterionRequirementWrapper requirementWrapper) {
if(listingRequirements != null){
if (listingRequirements != null) {
// Find which listItem contains CriterionSatisfaction inside listBox
Row row = findRowOfCriterionRequirementWrapper(listingRequirements
.getRows(), requirementWrapper);
@ -318,6 +282,7 @@ setValidCriterionRequirementWrapper(requirement, true);
/**
* Locates which {@link row} is bound to {@link WorkReportLine} in rows
*
* @param Rows
* @param CriterionRequirementWrapper
* @return
@ -325,7 +290,7 @@ setValidCriterionRequirementWrapper(requirement, true);
private Row findRowOfCriterionRequirementWrapper(Rows rows,
CriterionRequirementWrapper requirementWrapper) {
List<Row> listRows = (List<Row>) rows.getChildren();
final List<Row> listRows = (List<Row>) rows.getChildren();
for (Row row : listRows) {
if (requirementWrapper.equals(row.getValue())) {
return row;
@ -334,7 +299,7 @@ setValidCriterionRequirementWrapper(requirement, true);
return null;
}
/**
/**
* Locates {@link Bandbox} criterion requirement in {@link row}
*
* @param row
@ -349,8 +314,7 @@ setValidCriterionRequirementWrapper(requirement, true);
return (Bandbox) ((Hbox) row.getChildren().get(0)).getChildren()
.get(2);
}
return (Bandbox)((Hbox) row.getChildren().get(0))
.getChildren().get(0);
return (Bandbox) ((Hbox) row.getChildren().get(0)).getChildren().get(0);
}
private Rows getRequirementRows(Row row) {
@ -368,6 +332,7 @@ setValidCriterionRequirementWrapper(requirement, true);
return (HoursGroupWrapper) ((Row) panel.getParent().getParent())
.getValue();
}
/*
* Operations to manage OrderElement's hoursGroups and to assign criterion
* requirements to this hoursGroups.
@ -377,27 +342,15 @@ setValidCriterionRequirementWrapper(requirement, true);
return !isEditableHoursGroup();
}
public boolean isEditableHoursGroup() {
if (getOrderElement() != null) {
if (getOrderElement() instanceof OrderLine)
return true;
}
return false;
}
public abstract boolean isEditableHoursGroup();
public abstract List<HoursGroupWrapper> getHoursGroupWrappers();
public List<HoursGroupWrapper> getHoursGroupWrappers() {
return assignedCriterionRequirementToOrderElementModel
.getHoursGroupsWrappers();
}
/**
* Adds a new {@link HoursGroup} to the current {@link OrderElement} The
* {@link OrderElement} should be a {@link OrderLine}
*/
public void addHoursGroup() {
assignedCriterionRequirementToOrderElementModel
.addNewHoursGroupWrapper();
Util.reloadBindings(listHoursGroups);
}
public abstract void addHoursGroup();
/**
* Deletes the selected {@link HoursGroup} for the current
@ -406,51 +359,64 @@ setValidCriterionRequirementWrapper(requirement, true);
*/
public void deleteHoursGroups(Component self) throws InterruptedException {
if (getHoursGroupWrappers().size() < 2) {
Messagebox.show(_("At least one HoursGroup is needed"), _("Error"), Messagebox.OK,
Messagebox.ERROR);
Messagebox.show(_("At least one HoursGroup is needed"), _("Error"),
Messagebox.OK, Messagebox.ERROR);
return;
}else{
HoursGroupWrapper hoursGroupWrapper = getHoursGroupWrapper(self);
if (hoursGroupWrapper != null) {
assignedCriterionRequirementToOrderElementModel
.deleteHoursGroupWrapper(hoursGroupWrapper);
Util.reloadBindings(listHoursGroups);
}
}
final HoursGroupWrapper hoursGroupWrapper = getHoursGroupWrapper(self);
if (hoursGroupWrapper != null) {
deleteHoursGroupWrapper(hoursGroupWrapper);
Util.reloadBindings(listHoursGroups);
}
}
protected abstract void deleteHoursGroupWrapper(HoursGroupWrapper hoursGroupWrapper);
private HoursGroupWrapper getHoursGroupWrapper(Component self) {
return ((HoursGroupWrapper) (((Row) (self.getParent().getParent()))
.getValue()));
}
public void addCriterionToHoursGroup(Component self) {
HoursGroupWrapper hoursGroupWrapper = getHoursGroupWrapper(self);
final HoursGroupWrapper hoursGroupWrapper = getHoursGroupWrapper(self);
if (hoursGroupWrapper != null) {
assignedCriterionRequirementToOrderElementModel
.addCriterionToHoursGroupWrapper(hoursGroupWrapper);
addCriterionToHoursGroupWrapper(hoursGroupWrapper);
Util.reloadBindings(listHoursGroups);
}
}
protected abstract void addCriterionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper);
public void addExceptionToHoursGroups(Component self) {
HoursGroupWrapper hoursGroupWrapper = getHoursGroupWrapper(self);
final HoursGroupWrapper hoursGroupWrapper = getHoursGroupWrapper(self);
if (hoursGroupWrapper != null) {
assignedCriterionRequirementToOrderElementModel
.addExceptionToHoursGroupWrapper(hoursGroupWrapper);
addExceptionToHoursGroupWrapper(hoursGroupWrapper);
Util.reloadBindings(listHoursGroups);
}
}
public void removeCriterionToHoursGroup(Component self){
protected abstract CriterionRequirementWrapper addExceptionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper);
public void removeCriterionToHoursGroup(Component self) {
try {
Row row = (Row) self.getParent().getParent();
CriterionRequirementWrapper requirementWrapper = (CriterionRequirementWrapper) row.getValue();
CriterionRequirementWrapper requirementWrapper = (CriterionRequirementWrapper) row
.getValue();
HoursGroupWrapper hoursGroupWrapper = getHoursGroupOfRequirementWrapper(row);
assignedCriterionRequirementToOrderElementModel
.deleteCriterionToHoursGroup(hoursGroupWrapper,
requirementWrapper);
deleteCriterionToHoursGroup(hoursGroupWrapper, requirementWrapper);
Util.reloadBindings(listHoursGroups);
} catch (Exception e) {
}
}
public abstract void deleteCriterionToHoursGroup(
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper);
public void selectCriterionToHoursGroup(Listitem item, Bandbox bandbox,
CriterionRequirementWrapper requirementWrapper) {
if (item != null) {
@ -463,10 +429,10 @@ setValidCriterionRequirementWrapper(requirement, true);
bandbox.close();
bandbox.setValue(criterionAndType.getNameAndType());
try{
assignedCriterionRequirementToOrderElementModel.selectCriterionToHoursGroup(hoursGroupWrapper,
requirementWrapper, criterionAndType);
}catch(IllegalStateException e){
try {
selectCriterionToHoursGroup(hoursGroupWrapper,
requirementWrapper, criterionAndType);
} catch (IllegalStateException e) {
requirementWrapper.setCriterionWithItsType(null);
showInvalidConstraint(bandbox, e);
}
@ -476,20 +442,16 @@ setValidCriterionRequirementWrapper(requirement, true);
}
}
protected abstract void selectCriterionToHoursGroup(
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper,
CriterionWithItsType criterionAndType);
private void showInvalidConstraint(Bandbox bandbox, IllegalStateException e) {
bandbox.setValue("");
throw new WrongValueException(bandbox, _(e.getMessage()));
}
private HoursGroupWrapper getHoursGroupWrapper(Component self) {
try {
return ((HoursGroupWrapper) (((Row) (self.getParent().getParent()))
.getValue()));
} catch (Exception e) {
return null;
}
}
/*
* Operations to manage the data hoursGroup, for example validate the
* percentage and its number of hours or set the fixed percentage
@ -497,8 +459,12 @@ setValidCriterionRequirementWrapper(requirement, true);
public void changeTotalHours() {
recalculateHoursGroup();
Util.reloadBindings(listHoursGroups);
Util.reloadBindings(orderElementTotalHours);
}
public abstract void recalculateHoursGroup();
public Constraint validateTotalHours() {
return new Constraint() {
@Override
@ -509,9 +475,9 @@ setValidCriterionRequirementWrapper(requirement, true);
orderElementTotalHours.setValue((Integer) value);
}
try {
if (getOrderElement() instanceof OrderLine) {
((OrderLine) getOrderElement())
.setWorkHours((Integer) value);
if (getElement() instanceof OrderLine) {
((OrderLine) getElement())
.setWorkHours((Integer) value);
}
} catch (IllegalArgumentException e) {
throw new WrongValueException(comp, _(e.getMessage()));
@ -536,14 +502,7 @@ setValidCriterionRequirementWrapper(requirement, true);
};
}
public void recalculateHoursGroup() {
((OrderLine) assignedCriterionRequirementToOrderElementModel
.getOrderElement()).recalculateHoursGroups();
Util.reloadBindings(listHoursGroups);
Util.reloadBindings(orderElementTotalHours);
}
/*Operations to return the agrouped list of hours Group */
/* Operations to return grouped list of hours Group */
/**
* Returns a {@link List} of {@link HoursGroup}. If the current element is
@ -551,20 +510,14 @@ setValidCriterionRequirementWrapper(requirement, true);
* this {@link OrderLine}. Otherwise, this method gets all the
* {@link HoursGroup} of all the children {@link OrderElement}, and
* aggregates them if they have the same {@link Criterion}.
*
* @return The {@link HoursGroup} list of the current {@link OrderElement}
*/
public List<HoursGroup> getHoursGroups() {
if ((getOrderElement() == null)
|| (assignedCriterionRequirementToOrderElementModel == null)) {
return new ArrayList<HoursGroup>();
}
// Creates a map in order to join HoursGroup with the same
// Criterions.
// Creates a map in order to join HoursGroup with the same Criterions
Map<Map<ResourceEnum, Set<Criterion>>, HoursGroup> map = new HashMap<Map<ResourceEnum, Set<Criterion>>, HoursGroup>();
List<HoursGroup> hoursGroups = getOrderElement().getHoursGroups();
List<HoursGroup> hoursGroups = getHoursGroups(getElement());
for (HoursGroup hoursGroup : hoursGroups) {
Map<ResourceEnum, Set<Criterion>> key = getKeyFor(hoursGroup);
@ -590,6 +543,8 @@ setValidCriterionRequirementWrapper(requirement, true);
return new ArrayList<HoursGroup>(map.values());
}
protected abstract List<HoursGroup> getHoursGroups(T orderElement);
private Map<ResourceEnum, Set<Criterion>> getKeyFor(HoursGroup hoursGroup) {
Map<ResourceEnum, Set<Criterion>> keys = new HashMap<ResourceEnum, Set<Criterion>>();
ResourceEnum resourceType = hoursGroup.getResourceType();
@ -608,13 +563,15 @@ setValidCriterionRequirementWrapper(requirement, true);
return key;
}
public abstract boolean isCodeAutogenerated();
private transient ListitemRenderer renderer = new HoursGroupListitemRender();
public ListitemRenderer getRenderer() {
return renderer;
return renderer;
}
public class HoursGroupListitemRender implements ListitemRenderer{
public class HoursGroupListitemRender implements ListitemRenderer {
@Override
public void render(Listitem item, Object data) throws Exception {
@ -623,7 +580,8 @@ setValidCriterionRequirementWrapper(requirement, true);
// Criterion Requirements hours Group
Listcell cellCriterionRequirements = new Listcell();
cellCriterionRequirements.setParent(item);
cellCriterionRequirements.appendChild( appendRequirements(hoursGroup));
cellCriterionRequirements
.appendChild(appendRequirements(hoursGroup));
// Type hours Group
Listcell cellType = new Listcell();
@ -635,46 +593,41 @@ setValidCriterionRequirementWrapper(requirement, true);
cellWorkingHours.setParent(item);
cellWorkingHours.appendChild(appendWorkingHours(hoursGroup));
}
}
private Label appendRequirements(final HoursGroup hoursGroup) {
Label requirementsLabel = new Label();
requirementsLabel.setMultiline(true);
requirementsLabel.setValue(getLabelRequirements(hoursGroup));
return requirementsLabel;
}
private Label appendRequirements(final HoursGroup hoursGroup) {
Label requirementsLabel = new Label();
requirementsLabel.setMultiline(true);
requirementsLabel.setValue(getLabelRequirements(hoursGroup));
return requirementsLabel;
}
private Label appendType(final HoursGroup hoursGroup) {
Label type = new Label();
type.setValue(hoursGroup.getResourceType().toString());
return type;
}
private Label appendWorkingHours(final HoursGroup hoursGroup) {
Listheader list = new Listheader();
Label workingHoursLabel = new Label();
workingHoursLabel
.setValue(String.valueOf(hoursGroup.getWorkingHours()));
return workingHoursLabel;
}
private String getLabelRequirements(HoursGroup hoursGroup) {
String label = "";
for (Criterion criterion : hoursGroup.getValidCriterions()) {
if (!label.equals("")) {
label = label.concat(", ");
private String getLabelRequirements(HoursGroup hoursGroup) {
String label = "";
for (Criterion criterion : hoursGroup.getValidCriterions()) {
if (!label.equals("")) {
label = label.concat(", ");
}
label = label.concat(criterion.getName());
}
label = label.concat(criterion.getName());
if (!label.equals("")) {
label = label.concat(".");
}
return label;
}
if (!label.equals("")) {
label = label.concat(".");
private Label appendType(final HoursGroup hoursGroup) {
Label type = new Label();
type.setValue(hoursGroup.getResourceType().toString());
return type;
}
return label;
private Label appendWorkingHours(final HoursGroup hoursGroup) {
Label workingHoursLabel = new Label();
workingHoursLabel.setValue(String.valueOf(hoursGroup
.getWorkingHours()));
return workingHoursLabel;
}
}
public boolean isCodeAutogenerated() {
return assignedCriterionRequirementToOrderElementModel
.isCodeAutogenerated();
}
}
}

View file

@ -1,5 +1,5 @@
/*
* This file is part of NavalPlan
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
@ -18,152 +18,60 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.orders;
package org.navalplanner.web.orders.criterionrequirements;
import static org.navalplanner.web.I18nHelper._;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.springframework.beans.factory.annotation.Autowired;
import org.navalplanner.web.orders.CriterionRequirementWrapper;
import org.navalplanner.web.orders.HoursGroupWrapper;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class AssignedCriterionRequirementToOrderElementModel implements
IAssignedCriterionRequirementToOrderElementModel{
public abstract class AssignedCriterionRequirementModel<T, M> implements
IAssignedCriterionRequirementModel<T, M> {
@Autowired
IOrderElementDAO orderElementDAO;
OrderElement orderElement;
IOrderModel orderModel;
private List<CriterionWithItsType> criterionWithItsTypes =
protected List<CriterionWithItsType> criterionWithItsTypes =
new ArrayList<CriterionWithItsType>();
private List<CriterionRequirementWrapper> criterionRequirementWrappers =
protected List<CriterionRequirementWrapper> criterionRequirementWrappers =
new ArrayList<CriterionRequirementWrapper>();
private List<HoursGroupWrapper> hoursGroupsWrappers = new ArrayList<HoursGroupWrapper>();
protected List<HoursGroupWrapper> hoursGroupsWrappers = new ArrayList<HoursGroupWrapper>();
@Override
public IOrderModel getOrderModel() {
return orderModel;
}
@Override
public OrderElement getOrderElement() {
return orderElement;
}
@Override
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
}
@Override
@Transactional(readOnly = true)
public void init(OrderElement orderElement) {
this.orderElement = orderElement;
if(orderElement != null){
reattachOrderElement();
initializeWrappers();
initializeCriterionWithItsType();
reloadHoursGroupWrappers();
}
}
private void reattachOrderElement() {
orderElementDAO.reattach(orderElement);
for(OrderElement child : orderElement.getAllChildren()){
child.getName();
reattachCriterionRequirement(child.getCriterionRequirements());
if(child instanceof OrderLine){
for(HoursGroup hoursGroup : child.getHoursGroups()){
hoursGroup.getWorkingHours();
reattachCriterionRequirement(hoursGroup.getCriterionRequirements());
}
}
}
}
private void reattachCriterionRequirement(Set<CriterionRequirement> list){
for(CriterionRequirement requirement : list){
requirement.getCriterion().getName();
requirement.getCriterion().getType().getName();
}
}
private void initializeWrappers() {
criterionRequirementWrappers = new ArrayList<CriterionRequirementWrapper>();
for(CriterionRequirement requirement :
orderElement.getCriterionRequirements()){
CriterionRequirementWrapper Wrapper = new CriterionRequirementWrapper(
requirement, null, false);
criterionRequirementWrappers.add(Wrapper);
}
}
private void initializeCriterionWithItsType() {
criterionWithItsTypes = new ArrayList<CriterionWithItsType>();
for(CriterionType type : getTypes()){
if(type.isEnabled()){
for (Criterion criterion : orderModel.getCriterionsFor(type)) {
if(criterion.isActive()){
CriterionWithItsType criterionAndType =
new CriterionWithItsType(type,criterion);
criterionWithItsTypes.add(criterionAndType);
}
}
}
}
}
@Override
public Set<CriterionType> getTypes() {
return getMapCriterions().keySet();
}
private Map<CriterionType, List<Criterion>> getMapCriterions(){
return orderModel.getMapCriterions();
}
public abstract Set<CriterionType> getTypes();
@Override
public List<CriterionWithItsType> getCriterionWithItsTypes(){
return criterionWithItsTypes;
}
public Integer getTotalHours() {
if (getOrderElement() != null) {
return getOrderElement().getWorkHours();
}
return 0;
}
public abstract Integer getTotalHours();
@Override
@Transactional(readOnly = true)
public void assignCriterionRequirementWrapper() {
if((orderModel != null) && (orderElement != null)){
if((getModel() != null) && (getElement() != null)){
CriterionRequirementWrapper newRequirementWrapper = createCriterionRequirementWreapper(null);
criterionRequirementWrappers.add(newRequirementWrapper);
}
@ -203,9 +111,11 @@ public class AssignedCriterionRequirementToOrderElementModel implements
CriterionRequirementWrapper requirementWrapper) {
DirectCriterionRequirement requirement = (DirectCriterionRequirement) requirementWrapper
.getCriterionRequirement();
orderElement.addDirectCriterionRequirement(requirement);
addDirectCriterionRequirement(requirement);
}
protected abstract void addDirectCriterionRequirement(DirectCriterionRequirement requirement);
@Override
public void deleteCriterionRequirementWrapper(
CriterionRequirementWrapper requirementWrapper) {
@ -218,23 +128,14 @@ public class AssignedCriterionRequirementToOrderElementModel implements
CriterionRequirementWrapper requirementWrapper) {
DirectCriterionRequirement requirement = (DirectCriterionRequirement) requirementWrapper
.getCriterionRequirement();
orderElement.removeDirectCriterionRequirement(requirement);
removeDirectCriterionRequirement(requirement);
}
@Override
@Transactional(readOnly = true)
public void confirm() throws ValidationException{
reattachOrderElement();
}
@Override
public void setOrderModel(IOrderModel orderModel) {
this.orderModel = orderModel;
}
protected abstract void removeDirectCriterionRequirement(DirectCriterionRequirement requirement);
@Override
public List<CriterionRequirementWrapper> getCriterionRequirementWrappers() {
if((orderModel != null)&&(getOrderElement() != null)){
if ((getModel() != null) && (getElement() != null)) {
return criterionRequirementWrappers;
}
return new ArrayList<CriterionRequirementWrapper>();
@ -246,12 +147,14 @@ public class AssignedCriterionRequirementToOrderElementModel implements
requirementWrapper.setValid(valid);
IndirectCriterionRequirement requirement = (IndirectCriterionRequirement) requirementWrapper
.getCriterionRequirement();
getOrderElement().setValidCriterionRequirement(requirement, valid);
setValidCriterionRequirement(requirement, valid);
if (requirementWrapper.getCriterionWithItsType() != null) {
updateExceptionInHoursGroups();
}
}
protected abstract void setValidCriterionRequirement(IndirectCriterionRequirement requirement, boolean valid);
public CriterionRequirementWrapper validateWrappers(
List<CriterionRequirementWrapper> list) {
for (CriterionRequirementWrapper requirementWrapper : list) {
@ -280,35 +183,17 @@ public class AssignedCriterionRequirementToOrderElementModel implements
*/
private OrderLine asOrderLine() {
if (getOrderElement() instanceof OrderLine) {
return (OrderLine) getOrderElement();
} else {
return null;
}
}
private void reloadHoursGroupWrappers() {
hoursGroupsWrappers = new ArrayList<HoursGroupWrapper>();
for (HoursGroup hoursGroup : orderElement.getHoursGroups()) {
if (!existIntohoursGroupsWrappers(hoursGroup)) {
addNewHoursGroupWrapper(hoursGroup, false);
}
}
return (getElement() instanceof OrderLine) ? (OrderLine) getElement() : null;
}
public void addNewHoursGroupWrapper() {
if ((orderModel != null) && (getOrderElement() != null)) {
if ((getModel() != null) && (getElement() != null)) {
HoursGroup newHoursGroup = createNewHoursGroup();
addNewHoursGroupWrapper(newHoursGroup, true);
}
}
private void addNewHoursGroupWrapper(HoursGroup newHoursGroup,
boolean newObject) {
HoursGroupWrapper newHoursGroupWrapper = new HoursGroupWrapper(
newHoursGroup, getOrderElement(), newObject);
hoursGroupsWrappers.add(newHoursGroupWrapper);
}
protected abstract void addNewHoursGroupWrapper(HoursGroup newHoursGroup, boolean newObject);
private HoursGroup createNewHoursGroup() {
if (asOrderLine() != null) {
@ -325,7 +210,7 @@ public class AssignedCriterionRequirementToOrderElementModel implements
}
public List<HoursGroupWrapper> getHoursGroupsWrappers() {
if ((orderModel != null) && (getOrderElement() != null)) {
if ((getModel() != null) && (getElement() != null)) {
return hoursGroupsWrappers;
}
return new ArrayList<HoursGroupWrapper>();
@ -339,15 +224,6 @@ public class AssignedCriterionRequirementToOrderElementModel implements
}
}
private boolean existIntohoursGroupsWrappers(HoursGroup hoursGroup) {
for (HoursGroupWrapper hoursGroupWrapper : hoursGroupsWrappers) {
if (hoursGroupWrapper.getHoursGroup().equals(hoursGroup)) {
return true;
}
}
return false;
}
/*
* Operation to manage the criterion Requirements for the hoursGroups. The
* operations is add new direct criterion requirement, delete criterion
@ -355,7 +231,7 @@ public class AssignedCriterionRequirementToOrderElementModel implements
*/
public void addCriterionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper) {
if ((orderModel != null) && (orderElement != null)) {
if ((getModel() != null) && (getElement() != null)) {
CriterionRequirementWrapper requirement = createCriterionRequirementWreapper(hoursGroupWrapper);
hoursGroupWrapper.assignCriterionRequirementWrapper(requirement);
}
@ -391,7 +267,7 @@ public class AssignedCriterionRequirementToOrderElementModel implements
public CriterionRequirementWrapper addExceptionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper) {
if ((orderModel != null) && (orderElement != null)) {
if ((getModel() != null) && (getElement() != null)) {
CriterionRequirementWrapper exceptionWrapper = new CriterionRequirementWrapper(
CriterionRequirementWrapper.INDIRECT);
exceptionWrapper.setNewException(true);
@ -405,8 +281,7 @@ public class AssignedCriterionRequirementToOrderElementModel implements
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper exception,
CriterionWithItsType criterionAndType) {
hoursGroupWrapper
.selectCriterionToExceptionRequirementWrapper(
hoursGroupWrapper.selectCriterionToExceptionRequirementWrapper(
exception, criterionAndType);
}
@ -446,12 +321,6 @@ public class AssignedCriterionRequirementToOrderElementModel implements
hoursGroupWrapper.updateListExceptionCriterionRequirementWrapper();
}
@Override
public boolean isCodeAutogenerated() {
if (orderElement != null) {
return orderElement.getOrder().isCodeAutogenerated();
}
return false;
}
public abstract boolean isCodeAutogenerated();
}

View file

@ -0,0 +1,211 @@
/*
* This file is part of NavalPlan
*
* 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.criterionrequirements;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.orders.CriterionRequirementWrapper;
import org.navalplanner.web.orders.HoursGroupWrapper;
import org.navalplanner.web.orders.IOrderElementModel;
/**
* Controller for showing OrderElement assigned labels
*
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public class AssignedCriterionRequirementToOrderElementController extends
AssignedCriterionRequirementController<OrderElement, IOrderElementModel> {
protected IAssignedCriterionRequirementToOrderElementModel assignedCriterionRequirementToOrderElementModel;
@Override
public OrderElement getElement() {
return getOrderElement();
}
public OrderElement getOrderElement() {
return assignedCriterionRequirementToOrderElementModel.getElement();
}
public Set<CriterionType> getCriterionTypes() {
return assignedCriterionRequirementToOrderElementModel.getTypes();
}
public void setOrderElement(OrderElement orderElement) {
assignedCriterionRequirementToOrderElementModel.setElement(orderElement);
}
public void openWindow(IOrderElementModel orderElementModel) {
assignedCriterionRequirementToOrderElementModel.setModel(orderElementModel.getOrderModel());
openWindow(orderElementModel.getOrderElement());
}
public void openWindow(OrderElement orderElement) {
assignedCriterionRequirementToOrderElementModel.init(orderElement);
Util.createBindingsFor(self);
Util.reloadBindings(self);
}
public void confirm() {
assignedCriterionRequirementToOrderElementModel.confirm();
}
public List<CriterionRequirementWrapper> criterionRequirementWrappers() {
return assignedCriterionRequirementToOrderElementModel
.getCriterionRequirementWrappers();
}
public List<CriterionWithItsType> getCriterionWithItsTypes() {
return assignedCriterionRequirementToOrderElementModel
.getCriterionWithItsTypes();
}
public void addCriterionRequirementWrapper() {
assignedCriterionRequirementToOrderElementModel
.assignCriterionRequirementWrapper();
reload();
}
public void remove(CriterionRequirementWrapper requirement) {
assignedCriterionRequirementToOrderElementModel
.deleteCriterionRequirementWrapper(requirement);
reload();
}
public void invalidate(CriterionRequirementWrapper requirement) {
assignedCriterionRequirementToOrderElementModel
.setValidCriterionRequirementWrapper(requirement, false);
reload();
}
public void validate(CriterionRequirementWrapper requirement) {
assignedCriterionRequirementToOrderElementModel
.setValidCriterionRequirementWrapper(requirement, true);
reload();
}
protected void changeCriterionAndType(
CriterionRequirementWrapper requirementWrapper,
CriterionWithItsType newCriterionAndType) {
assignedCriterionRequirementToOrderElementModel.changeCriterionAndType(
requirementWrapper, newCriterionAndType);
}
protected void updateCriterionsWithDiferentResourceType(
HoursGroupWrapper hoursGroupWrapper) {
assignedCriterionRequirementToOrderElementModel
.updateCriterionsWithDiferentResourceType(hoursGroupWrapper);
}
protected CriterionRequirementWrapper validateWrappers(
List<CriterionRequirementWrapper> list) {
return assignedCriterionRequirementToOrderElementModel
.validateWrappers(criterionRequirementWrappers());
}
protected CriterionRequirementWrapper validateHoursGroupWrappers() {
return assignedCriterionRequirementToOrderElementModel
.validateHoursGroupWrappers();
}
public List<HoursGroupWrapper> getHoursGroupWrappers() {
return assignedCriterionRequirementToOrderElementModel
.getHoursGroupsWrappers();
}
public void addHoursGroup() {
assignedCriterionRequirementToOrderElementModel
.addNewHoursGroupWrapper();
Util.reloadBindings(listHoursGroups);
}
protected void deleteHoursGroupWrapper(HoursGroupWrapper hoursGroupWrapper) {
assignedCriterionRequirementToOrderElementModel
.deleteHoursGroupWrapper(hoursGroupWrapper);
}
protected void addCriterionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper) {
assignedCriterionRequirementToOrderElementModel
.addCriterionToHoursGroupWrapper(hoursGroupWrapper);
}
protected CriterionRequirementWrapper addExceptionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper) {
return assignedCriterionRequirementToOrderElementModel
.addExceptionToHoursGroupWrapper(hoursGroupWrapper);
}
public void deleteCriterionToHoursGroup(
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper) {
assignedCriterionRequirementToOrderElementModel
.deleteCriterionToHoursGroup(hoursGroupWrapper,
requirementWrapper);
}
protected void selectCriterionToHoursGroup(
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper,
CriterionWithItsType criterionAndType) {
assignedCriterionRequirementToOrderElementModel
.selectCriterionToHoursGroup(hoursGroupWrapper,
requirementWrapper, criterionAndType);
}
public void recalculateHoursGroup() {
((OrderLine) assignedCriterionRequirementToOrderElementModel
.getElement()).recalculateHoursGroups();
}
public boolean isCodeAutogenerated() {
return assignedCriterionRequirementToOrderElementModel
.isCodeAutogenerated();
}
public List<HoursGroup> getHoursGroups() {
if ((getElement() == null)
|| (assignedCriterionRequirementToOrderElementModel == null)) {
return new ArrayList<HoursGroup>();
}
return super.getHoursGroups();
}
@Override
protected List<HoursGroup> getHoursGroups(OrderElement orderElement) {
return orderElement.getHoursGroups();
}
public boolean isEditableHoursGroup() {
return getElement() != null && getElement() instanceof OrderLine;
}
}

View file

@ -0,0 +1,206 @@
/*
* This file is part of NavalPlan
*
* 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.criterionrequirements;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.web.orders.CriterionRequirementWrapper;
import org.navalplanner.web.orders.HoursGroupWrapper;
import org.navalplanner.web.orders.IOrderModel;
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;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class AssignedCriterionRequirementToOrderElementModel extends
AssignedCriterionRequirementModel<OrderElement, IOrderModel> implements
IAssignedCriterionRequirementToOrderElementModel {
@Autowired
private IOrderElementDAO orderElementDAO;
private IOrderModel orderModel;
private OrderElement orderElement;
@Override
public IOrderModel getModel() {
return orderModel;
}
@Override
public OrderElement getElement() {
return orderElement;
}
@Override
public void setElement(OrderElement orderElement) {
this.orderElement = orderElement;
}
@Override
public void setModel(IOrderModel model) {
orderModel = model;
}
@Override
@Transactional(readOnly = true)
public void init(OrderElement element) {
setElement(element);
if(element != null){
reattachOrderElement();
initializeWrappers();
initializeCriterionWithItsType();
reloadHoursGroupWrappers();
}
}
private void reattachOrderElement() {
orderElementDAO.reattach(orderElement);
for (OrderElement child : orderElement.getAllChildren()) {
child.getName();
reattachCriterionRequirement(child.getCriterionRequirements());
if (child instanceof OrderLine) {
for (HoursGroup hoursGroup : child.getHoursGroups()) {
hoursGroup.getWorkingHours();
reattachCriterionRequirement(hoursGroup.getCriterionRequirements());
}
}
}
}
private void reattachCriterionRequirement(Set<CriterionRequirement> list){
for (CriterionRequirement requirement : list) {
requirement.getCriterion().getName();
requirement.getCriterion().getType().getName();
}
}
private void initializeWrappers() {
criterionRequirementWrappers = new ArrayList<CriterionRequirementWrapper>();
for(CriterionRequirement requirement :
orderElement.getCriterionRequirements()){
CriterionRequirementWrapper Wrapper = new CriterionRequirementWrapper(
requirement, null, false);
criterionRequirementWrappers.add(Wrapper);
}
}
private void initializeCriterionWithItsType() {
criterionWithItsTypes = new ArrayList<CriterionWithItsType>();
for(CriterionType type : getTypes()){
if (type.isEnabled()) {
for (Criterion criterion : getModel().getCriterionsFor(type)) {
if(criterion.isActive()){
CriterionWithItsType criterionAndType =
new CriterionWithItsType(type,criterion);
criterionWithItsTypes.add(criterionAndType);
}
}
}
}
}
private void reloadHoursGroupWrappers() {
hoursGroupsWrappers = new ArrayList<HoursGroupWrapper>();
for (HoursGroup hoursGroup : orderElement.getHoursGroups()) {
if (!existIntohoursGroupsWrappers(hoursGroup)) {
addNewHoursGroupWrapper(hoursGroup, false);
}
}
}
private boolean existIntohoursGroupsWrappers(HoursGroup hoursGroup) {
for (HoursGroupWrapper hoursGroupWrapper : hoursGroupsWrappers) {
if (hoursGroupWrapper.getHoursGroup().equals(hoursGroup)) {
return true;
}
}
return false;
}
@Override
@Transactional(readOnly = true)
public void confirm() throws ValidationException{
reattachOrderElement();
}
public Set<CriterionType> getTypes() {
return getMapCriterions().keySet();
}
private Map<CriterionType, List<Criterion>> getMapCriterions() {
return getModel().getMapCriterions();
}
public Integer getTotalHours() {
return (getElement() != null) ? getElement().getWorkHours() : 0;
}
protected void addDirectCriterionRequirement(DirectCriterionRequirement requirement) {
getElement().addDirectCriterionRequirement(requirement);
}
protected void removeDirectCriterionRequirement(DirectCriterionRequirement requirement) {
getElement().removeDirectCriterionRequirement(requirement);
}
protected void setValidCriterionRequirement(IndirectCriterionRequirement requirement, boolean valid) {
getElement().setValidCriterionRequirement(requirement, valid);
}
@Override
protected void addNewHoursGroupWrapper(HoursGroup newHoursGroup,
boolean newObject) {
HoursGroupWrapper newHoursGroupWrapper = new HoursGroupWrapper(
newHoursGroup, getElement(), newObject);
hoursGroupsWrappers.add(newHoursGroupWrapper);
}
@Override
public boolean isCodeAutogenerated() {
if (getElement() != null && getElement().getOrder() != null) {
return getElement().getOrder().isCodeAutogenerated();
}
return false;
}
}

View file

@ -0,0 +1,36 @@
/*
* 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.criterionrequirements;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.web.orders.IOrderElementModel;
import org.zkoss.zk.ui.HtmlMacroComponent;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public abstract class CriterionRequirementComponent extends HtmlMacroComponent {
public abstract AssignedCriterionRequirementController<?, ?> getController();
}

View file

@ -1,65 +1,40 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
* This file is part of NavalPlan
*
* 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;
package org.navalplanner.web.orders.criterionrequirements;
import java.util.List;
import java.util.Set;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.web.orders.CriterionRequirementWrapper;
import org.navalplanner.web.orders.HoursGroupWrapper;
/**
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public interface IAssignedCriterionRequirementToOrderElementModel {
IOrderModel getOrderModel();
OrderElement getOrderElement();
Set<CriterionType> getTypes();
void setOrderElement(OrderElement orderElement);
void init(OrderElement orderElement);
void assignCriterionRequirementWrapper();
void deleteCriterionRequirementWrapper(
CriterionRequirementWrapper requirement);
void confirm()throws ValidationException;
void setOrderModel(IOrderModel orderModel);
List<CriterionRequirementWrapper> getCriterionRequirementWrappers();
List<CriterionWithItsType> getCriterionWithItsTypes();
void changeCriterionAndType(
CriterionRequirementWrapper criterionRequirementWrapper,
CriterionWithItsType newCriterionAndType);
CriterionRequirementWrapper validateWrappers(
List<CriterionRequirementWrapper> list);
CriterionRequirementWrapper validateHoursGroupWrappers();
void setValidCriterionRequirementWrapper(
CriterionRequirementWrapper requirement, boolean valid);
// Operations to manage the hours Groups
public void addNewHoursGroupWrapper();
List<HoursGroupWrapper> getHoursGroupsWrappers();
void deleteHoursGroupWrapper(HoursGroupWrapper hoursGroupWrapper);
public interface IAssignedCriterionRequirementModel<T, M> {
void addCriterionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper);
@ -67,17 +42,58 @@ public interface IAssignedCriterionRequirementToOrderElementModel {
CriterionRequirementWrapper addExceptionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper);
void addNewHoursGroupWrapper();
void assignCriterionRequirementWrapper();
void changeCriterionAndType(
CriterionRequirementWrapper criterionRequirementWrapper,
CriterionWithItsType newCriterionAndType);
void confirm()throws ValidationException;
void deleteCriterionRequirementWrapper(
CriterionRequirementWrapper requirement);
void deleteCriterionToHoursGroup(HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper);
void deleteHoursGroupWrapper(HoursGroupWrapper hoursGroupWrapper);
List<CriterionRequirementWrapper> getCriterionRequirementWrappers();
List<CriterionWithItsType> getCriterionWithItsTypes();
T getElement();
List<HoursGroupWrapper> getHoursGroupsWrappers();
M getModel();
Set<CriterionType> getTypes();
void init(T element);
boolean isCodeAutogenerated();
void selectCriterionToHoursGroup(
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper exception,
CriterionWithItsType criterionAndType);
void deleteCriterionToHoursGroup(HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper);
void setElement(T element);
void setModel(M model);
void setValidCriterionRequirementWrapper(
CriterionRequirementWrapper requirement, boolean valid);
void updateCriterionsWithDiferentResourceType(
HoursGroupWrapper hoursGroupWrapper);
boolean isCodeAutogenerated();
CriterionRequirementWrapper validateHoursGroupWrappers();
CriterionRequirementWrapper validateWrappers(
List<CriterionRequirementWrapper> list);
}

View file

@ -0,0 +1,33 @@
/*
* This file is part of NavalPlan
*
* 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.criterionrequirements;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.web.orders.IOrderModel;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public interface IAssignedCriterionRequirementToOrderElementModel extends
IAssignedCriterionRequirementModel<OrderElement, IOrderModel> {
}

View file

@ -0,0 +1,40 @@
/*
* 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.criterionrequirements;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class OrderElementCriterionRequirementComponent extends
CriterionRequirementComponent {
private AssignedCriterionRequirementToOrderElementController controller =
new AssignedCriterionRequirementToOrderElementController();
@Override
public AssignedCriterionRequirementToOrderElementController getController() {
return controller;
}
}

View file

@ -22,6 +22,7 @@ package org.navalplanner.web.templates;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.templates.advances.AdvancesAssignmentComponent;
import org.navalplanner.web.templates.criterionrequirements.CriterionRequirementTemplateComponent;
import org.navalplanner.web.templates.labels.LabelsAssignmentToTemplateComponent;
import org.navalplanner.web.templates.materials.MaterialAssignmentTemplateComponent;
import org.navalplanner.web.templates.quality.QualityFormAssignerComponent;
@ -83,6 +84,7 @@ public class EditTemplateWindowController extends GenericForwardComposer {
}
bindAdvancesAssignment(template);
bindOrderElementLabels(template);
bindCriterionRequirements(template);
bindOrderElementMaterials(template);
bindAssignedQualityForms(template);
Util.reloadBindings(editTemplateWindow);
@ -106,6 +108,13 @@ public class EditTemplateWindowController extends GenericForwardComposer {
component.getController().openWindow(model);
}
private void bindCriterionRequirements(OrderElementTemplate template) {
CriterionRequirementTemplateComponent component = find(
"listOrderElementCriterionRequirements",
CriterionRequirementTemplateComponent.class);
component.getController().openWindow(model, template);
}
private void bindOrderElementMaterials(OrderElementTemplate template) {
MaterialAssignmentTemplateComponent component = find(
"listOrderElementMaterials",

View file

@ -20,11 +20,14 @@
package org.navalplanner.web.templates;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.qualityforms.entities.QualityForm;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.web.tree.EntitiesTree;
@ -48,7 +51,7 @@ public interface IOrderTemplatesModel {
boolean isTemplateTreeDisabled();
public void addLabelToConversation(Label label);
void addLabelToConversation(Label label);
List<Label> getLabels();
@ -57,4 +60,9 @@ public interface IOrderTemplatesModel {
OrderElementsOnConversation getOrderElementsOnConversation();
void validateTemplateName(String name) throws IllegalArgumentException;
List<Criterion> getCriterionsFor(CriterionType criterionType);
Map<CriterionType, List<Criterion>> getMapCriterions();
}

View file

@ -36,6 +36,7 @@ import org.navalplanner.web.common.entrypoints.IURLHandlerRegistry;
import org.navalplanner.web.common.entrypoints.URLHandler;
import org.navalplanner.web.planner.tabs.IGlobalViewEntryPoints;
import org.navalplanner.web.templates.advances.AdvancesAssignmentComponent;
import org.navalplanner.web.templates.criterionrequirements.CriterionRequirementTemplateComponent;
import org.navalplanner.web.templates.historicalAssignment.OrderElementHistoricalAssignmentComponent;
import org.navalplanner.web.templates.historicalStatistics.OrderElementHistoricalStatisticsComponent;
import org.navalplanner.web.templates.labels.LabelsAssignmentToTemplateComponent;
@ -114,6 +115,7 @@ public class OrderTemplatesController extends GenericForwardComposer implements
private void showEditWindow() {
bindAdvancesComponentWithCurrentTemplate();
bindMaterialsControllerWithCurrentTemplate();
bindCriterionRequirementControllerWithCurrentTemplate();
bindLabelsControllerWithCurrentTemplate();
bindQualityFormWithCurrentTemplate();
bindEditTemplateWindowWithController();
@ -139,6 +141,13 @@ public class OrderTemplatesController extends GenericForwardComposer implements
c.getController().openWindow(model.getTemplate());
}
private void bindCriterionRequirementControllerWithCurrentTemplate() {
CriterionRequirementTemplateComponent c = findAtEditWindow(
"listOrderElementCriterionRequirements",
CriterionRequirementTemplateComponent.class);
c.getController().openWindow(model);
}
private void bindLabelsControllerWithCurrentTemplate() {
LabelsAssignmentToTemplateComponent c = findAtEditWindow(
"listOrderElementLabels",

View file

@ -17,12 +17,16 @@
* 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.templates;
import static org.navalplanner.business.i18n.I18nHelper._;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.advance.entities.AdvanceAssignmentTemplate;
@ -30,11 +34,16 @@ import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.labels.daos.ILabelDAO;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.daos.IOrderElementDAO;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.qualityforms.daos.IQualityFormDAO;
import org.navalplanner.business.qualityforms.entities.QualityForm;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.resources.daos.ICriterionDAO;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.templates.daos.IOrderElementTemplateDAO;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.web.orders.QualityFormsOnConversation;
@ -47,17 +56,16 @@ import org.springframework.transaction.annotation.Transactional;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
*
* @author Diego Pino Garcia <dpino@igalia.com>
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class OrderTemplatesModel implements IOrderTemplatesModel {
@Autowired
private IOrderElementDAO orderElementDAO;
private static final Map<CriterionType, List<Criterion>> mapCriterions = new HashMap<CriterionType, List<Criterion>>();
@Autowired
private IOrderDAO orderDAO;
private IOrderElementDAO orderElementDAO;
@Autowired
private IOrderElementTemplateDAO dao;
@ -68,6 +76,12 @@ public class OrderTemplatesModel implements IOrderTemplatesModel {
@Autowired
private IQualityFormDAO qualityFormDAO;
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@Autowired
private ICriterionDAO criterionDAO;
@Autowired
private IAdHocTransactionService transaction;
@ -160,9 +174,33 @@ public class OrderTemplatesModel implements IOrderTemplatesModel {
private void loadAssociatedData(OrderElementTemplate template) {
loadAdvanceAssignments(template);
loadQualityForms(template);
loadCriterionRequirements(template);
getOrderElementsOnConversation().initialize(template);
}
private static void loadCriterionRequirements(OrderElementTemplate orderElement) {
orderElement.getHoursGroups().size();
for (HoursGroup hoursGroup : orderElement.getHoursGroups()) {
attachDirectCriterionRequirement(hoursGroup
.getDirectCriterionRequirement());
}
attachDirectCriterionRequirement(orderElement
.getDirectCriterionRequirements());
for (OrderElementTemplate child : orderElement.getChildren()) {
loadCriterionRequirements(child);
}
}
private static void attachDirectCriterionRequirement(
Set<DirectCriterionRequirement> requirements) {
for (DirectCriterionRequirement requirement : requirements) {
requirement.getChildren().size();
requirement.getCriterion().getName();
requirement.getCriterion().getType().getName();
}
}
private void loadQualityForms(OrderElementTemplate template) {
for (QualityForm each : template.getQualityForms()) {
each.getName();
@ -184,10 +222,23 @@ public class OrderTemplatesModel implements IOrderTemplatesModel {
}
private void initializeAcompanyingObjectsOnConversation() {
loadCriterions();
getLabelsOnConversation().initializeLabels();
getQualityFormsOnConversation().initialize();
}
private void loadCriterions() {
mapCriterions.clear();
List<CriterionType> criterionTypes = criterionTypeDAO
.getCriterionTypes();
for (CriterionType criterionType : criterionTypes) {
List<Criterion> criterions = new ArrayList<Criterion>(criterionDAO
.findByType(criterionType));
mapCriterions.put(criterionType, criterions);
}
}
@Override
public TemplatesTree getTemplatesTreeModel() {
return treeModel;
@ -228,4 +279,17 @@ public class OrderTemplatesModel implements IOrderTemplatesModel {
}
}
@Override
public List<Criterion> getCriterionsFor(CriterionType criterionType) {
return mapCriterions.get(criterionType);
}
@Override
public Map<CriterionType, List<Criterion>> getMapCriterions() {
final Map<CriterionType, List<Criterion>> result =
new HashMap<CriterionType, List<Criterion>>();
result.putAll(mapCriterions);
return result;
}
}

View file

@ -0,0 +1,219 @@
/*
* 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.templates.criterionrequirements;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.business.templates.entities.OrderLineTemplate;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.orders.CriterionRequirementWrapper;
import org.navalplanner.web.orders.HoursGroupWrapper;
import org.navalplanner.web.orders.criterionrequirements.AssignedCriterionRequirementController;
import org.navalplanner.web.templates.IOrderTemplatesModel;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class AssignedCriterionRequirementToTemplateController extends
AssignedCriterionRequirementController<OrderElementTemplate, IOrderTemplatesModel> {
protected IAssignedCriterionRequirementToTemplateModel assignedCriterionRequirementToTemplateModel;
@Override
public OrderElementTemplate getElement() {
return getOrderElement();
}
public OrderElementTemplate getOrderElement() {
return assignedCriterionRequirementToTemplateModel.getElement();
}
public Set<CriterionType> getCriterionTypes() {
return assignedCriterionRequirementToTemplateModel.getTypes();
}
public void setOrderElement(OrderElementTemplate orderElement) {
assignedCriterionRequirementToTemplateModel.setElement(orderElement);
}
public void openWindow(IOrderTemplatesModel orderTemplateModel, OrderElementTemplate template) {
assignedCriterionRequirementToTemplateModel.setModel(orderTemplateModel);
assignedCriterionRequirementToTemplateModel.init(template);
Util.reloadBindings(self);
}
public void openWindow(IOrderTemplatesModel orderTemplateModel) {
assignedCriterionRequirementToTemplateModel.setModel(orderTemplateModel);
openWindow(orderTemplateModel.getTemplate());
}
public void openWindow(OrderElementTemplate orderElement) {
assignedCriterionRequirementToTemplateModel.init(orderElement);
Util.createBindingsFor(self);
Util.reloadBindings(self);
}
public void confirm() {
assignedCriterionRequirementToTemplateModel.confirm();
}
public List<CriterionRequirementWrapper> criterionRequirementWrappers() {
return assignedCriterionRequirementToTemplateModel
.getCriterionRequirementWrappers();
}
public List<CriterionWithItsType> getCriterionWithItsTypes() {
return assignedCriterionRequirementToTemplateModel
.getCriterionWithItsTypes();
}
public void addCriterionRequirementWrapper() {
assignedCriterionRequirementToTemplateModel
.assignCriterionRequirementWrapper();
reload();
}
public void remove(CriterionRequirementWrapper requirement) {
assignedCriterionRequirementToTemplateModel
.deleteCriterionRequirementWrapper(requirement);
reload();
}
public void invalidate(CriterionRequirementWrapper requirement) {
assignedCriterionRequirementToTemplateModel
.setValidCriterionRequirementWrapper(requirement, false);
reload();
}
public void validate(CriterionRequirementWrapper requirement) {
assignedCriterionRequirementToTemplateModel
.setValidCriterionRequirementWrapper(requirement, true);
reload();
}
protected void changeCriterionAndType(
CriterionRequirementWrapper requirementWrapper,
CriterionWithItsType newCriterionAndType) {
assignedCriterionRequirementToTemplateModel.changeCriterionAndType(
requirementWrapper, newCriterionAndType);
}
protected void updateCriterionsWithDiferentResourceType(
HoursGroupWrapper hoursGroupWrapper) {
assignedCriterionRequirementToTemplateModel
.updateCriterionsWithDiferentResourceType(hoursGroupWrapper);
}
protected CriterionRequirementWrapper validateWrappers(
List<CriterionRequirementWrapper> list) {
return assignedCriterionRequirementToTemplateModel
.validateWrappers(criterionRequirementWrappers());
}
protected CriterionRequirementWrapper validateHoursGroupWrappers() {
return assignedCriterionRequirementToTemplateModel
.validateHoursGroupWrappers();
}
public List<HoursGroupWrapper> getHoursGroupWrappers() {
return assignedCriterionRequirementToTemplateModel
.getHoursGroupsWrappers();
}
public void addHoursGroup() {
assignedCriterionRequirementToTemplateModel
.addNewHoursGroupWrapper();
Util.reloadBindings(listHoursGroups);
}
protected void deleteHoursGroupWrapper(HoursGroupWrapper hoursGroupWrapper) {
assignedCriterionRequirementToTemplateModel
.deleteHoursGroupWrapper(hoursGroupWrapper);
}
protected void addCriterionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper) {
assignedCriterionRequirementToTemplateModel
.addCriterionToHoursGroupWrapper(hoursGroupWrapper);
}
protected CriterionRequirementWrapper addExceptionToHoursGroupWrapper(
HoursGroupWrapper hoursGroupWrapper) {
return assignedCriterionRequirementToTemplateModel
.addExceptionToHoursGroupWrapper(hoursGroupWrapper);
}
public void deleteCriterionToHoursGroup(
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper) {
assignedCriterionRequirementToTemplateModel
.deleteCriterionToHoursGroup(hoursGroupWrapper,
requirementWrapper);
}
protected void selectCriterionToHoursGroup(
HoursGroupWrapper hoursGroupWrapper,
CriterionRequirementWrapper requirementWrapper,
CriterionWithItsType criterionAndType) {
assignedCriterionRequirementToTemplateModel
.selectCriterionToHoursGroup(hoursGroupWrapper,
requirementWrapper, criterionAndType);
}
public void recalculateHoursGroup() {
((OrderLineTemplate) assignedCriterionRequirementToTemplateModel
.getElement()).recalculateHoursGroups();
}
public boolean isCodeAutogenerated() {
return assignedCriterionRequirementToTemplateModel
.isCodeAutogenerated();
}
public List<HoursGroup> getHoursGroups() {
if ((getElement() == null)
|| (assignedCriterionRequirementToTemplateModel == null)) {
return new ArrayList<HoursGroup>();
}
return super.getHoursGroups();
}
@Override
protected List<HoursGroup> getHoursGroups(OrderElementTemplate orderElement) {
return orderElement.getHoursGroups();
}
public boolean isEditableHoursGroup() {
return getElement() != null && getElement() instanceof OrderLineTemplate;
}
}

View file

@ -0,0 +1,209 @@
/*
* This file is part of NavalPlan
*
* 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.templates.criterionrequirements;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.requirements.entities.DirectCriterionRequirement;
import org.navalplanner.business.requirements.entities.IndirectCriterionRequirement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
import org.navalplanner.business.resources.entities.CriterionWithItsType;
import org.navalplanner.business.templates.daos.IOrderElementTemplateDAO;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.business.templates.entities.OrderLineTemplate;
import org.navalplanner.web.orders.CriterionRequirementWrapper;
import org.navalplanner.web.orders.HoursGroupWrapper;
import org.navalplanner.web.orders.criterionrequirements.AssignedCriterionRequirementModel;
import org.navalplanner.web.templates.IOrderTemplatesModel;
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;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class AssignedCriterionRequirementToTemplateModel extends
AssignedCriterionRequirementModel<OrderElementTemplate, IOrderTemplatesModel> implements
IAssignedCriterionRequirementToTemplateModel {
@Autowired
private IOrderElementTemplateDAO orderElementTemplateDAO;
private IOrderTemplatesModel orderTemplateModel;
private OrderElementTemplate orderElementTemplate;
@Override
public IOrderTemplatesModel getModel() {
return orderTemplateModel;
}
@Override
public OrderElementTemplate getElement() {
return orderElementTemplate;
}
@Override
public void setElement(OrderElementTemplate orderElementTemplate) {
this.orderElementTemplate = orderElementTemplate;
}
@Override
public void setModel(IOrderTemplatesModel model) {
orderTemplateModel = model;
}
@Override
@Transactional(readOnly = true)
public void init(OrderElementTemplate element) {
setElement(element);
if (element != null) {
reattachOrderElementTemplate();
initializeWrappers();
initializeCriterionWithItsType();
reloadHoursGroupWrappers();
}
}
private void reattachOrderElementTemplate() {
orderElementTemplateDAO.reattach(orderElementTemplate);
for (OrderElementTemplate each : orderElementTemplate.getAllChildren()) {
each.getName();
reattachCriterionRequirement(each.getCriterionRequirements());
if (each instanceof OrderLineTemplate) {
for (HoursGroup hoursGroup : each.getHoursGroups()) {
hoursGroup.getWorkingHours();
reattachCriterionRequirement(hoursGroup.getCriterionRequirements());
}
}
}
}
private void reattachCriterionRequirement(Set<CriterionRequirement> list){
for (CriterionRequirement requirement : list) {
requirement.getCriterion().getName();
requirement.getCriterion().getType().getName();
}
}
private void initializeWrappers() {
criterionRequirementWrappers = new ArrayList<CriterionRequirementWrapper>();
for(CriterionRequirement requirement :
orderElementTemplate.getCriterionRequirements()) {
CriterionRequirementWrapper Wrapper = new CriterionRequirementWrapper(
requirement, null, false);
criterionRequirementWrappers.add(Wrapper);
}
}
private void initializeCriterionWithItsType() {
criterionWithItsTypes = new ArrayList<CriterionWithItsType>();
for(CriterionType type : getTypes()){
if (type.isEnabled()) {
for (Criterion criterion : getModel().getCriterionsFor(type)) {
if(criterion.isActive()){
CriterionWithItsType criterionAndType =
new CriterionWithItsType(type,criterion);
criterionWithItsTypes.add(criterionAndType);
}
}
}
}
}
private void reloadHoursGroupWrappers() {
hoursGroupsWrappers = new ArrayList<HoursGroupWrapper>();
for (HoursGroup hoursGroup : orderElementTemplate.getHoursGroups()) {
if (!existIntohoursGroupsWrappers(hoursGroup)) {
addNewHoursGroupWrapper(hoursGroup, false);
}
}
}
protected boolean existIntohoursGroupsWrappers(HoursGroup hoursGroup) {
for (HoursGroupWrapper hoursGroupWrapper : hoursGroupsWrappers) {
if (hoursGroupWrapper.getHoursGroup().equals(hoursGroup)) {
return true;
}
}
return false;
}
@Override
@Transactional(readOnly = true)
public void confirm() throws ValidationException{
reattachOrderElementTemplate();
}
public Set<CriterionType> getTypes() {
return getMapCriterions().keySet();
}
private Map<CriterionType, List<Criterion>> getMapCriterions() {
return getModel().getMapCriterions();
}
public Integer getTotalHours() {
return (getElement() != null) ? getElement().getWorkHours() : 0;
}
protected void addDirectCriterionRequirement(DirectCriterionRequirement requirement) {
getElement().addDirectCriterionRequirement(requirement);
}
protected void removeDirectCriterionRequirement(DirectCriterionRequirement requirement) {
getElement().removeDirectCriterionRequirement(requirement);
}
protected void setValidCriterionRequirement(IndirectCriterionRequirement requirement, boolean valid) {
getElement().setValidCriterionRequirement(requirement, valid);
}
@Override
public boolean isCodeAutogenerated() {
if (getElement() != null && getElement().getOrder() != null) {
return getElement().getOrder().isCodeAutogenerated();
}
return false;
}
@Override
protected void addNewHoursGroupWrapper(HoursGroup newHoursGroup,
boolean newObject) {
HoursGroupWrapper newHoursGroupWrapper = new HoursGroupWrapper(
newHoursGroup, getElement(), newObject);
hoursGroupsWrappers.add(newHoursGroupWrapper);
}
}

View file

@ -0,0 +1,39 @@
/*
* 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.templates.criterionrequirements;
import org.navalplanner.web.orders.criterionrequirements.CriterionRequirementComponent;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class CriterionRequirementTemplateComponent extends CriterionRequirementComponent {
private AssignedCriterionRequirementToTemplateController controller =
new AssignedCriterionRequirementToTemplateController();
@Override
public AssignedCriterionRequirementToTemplateController getController() {
return controller;
}
}

View file

@ -0,0 +1,35 @@
/*
* This file is part of NavalPlan
*
* 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.templates.criterionrequirements;
import org.navalplanner.business.templates.entities.OrderElementTemplate;
import org.navalplanner.web.orders.criterionrequirements.IAssignedCriterionRequirementModel;
import org.navalplanner.web.templates.IOrderTemplatesModel;
/**
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public interface IAssignedCriterionRequirementToTemplateModel extends
IAssignedCriterionRequirementModel<OrderElementTemplate, IOrderTemplatesModel> {
}

View file

@ -22,16 +22,20 @@
<?component name="listOrderElementHours" inline="true" macroURI="_listOrderElementHours.zul"?>
<?component name="listOrderElementAdvances" inline="true" macroURI="_listOrderElementAdvances.zul"?>
<?component name="listOrderElementLabels" class="org.navalplanner.web.orders.labels.LabelsAssignmentToOrderElementComponent" macroURI="components/_listOrderElementLabels.zul"?>
<?component name="listOrderElementCriterionRequirements" inline="true" macroURI="_listOrderElementCriterionRequirements.zul"?>
<?component name="listOrderElementMaterials" class="org.navalplanner.web.orders.materials.OrderElementMaterialAssignmentsComponent"
<?component name="listOrderElementCriterionRequirements"
class="org.navalplanner.web.orders.criterionrequirements.OrderElementCriterionRequirementComponent"
macroURI="_listOrderElementCriterionRequirements.zul"?>
<?component name="listOrderElementMaterials"
class="org.navalplanner.web.orders.materials.OrderElementMaterialAssignmentsComponent"
macroURI="/orders/components/_listOrderElementMaterials.zul"?>
<?component name="listOrderElementTaskQualityForms" inline="true" macroURI="_listOrderElementTaskQualityForms.zul"?>
<window id="${arg.top_id}" title="${i18n:_('Edit order element')}"
width="950px" left="50px" top="50px"
closable="true" visible="false">
<tabbox height="620px" id="tabboxOrderElement">
<tabs>
<tabbox height="620px" id="tabboxOrderElement">
<tabs>
<tab id="tabDetails" label="${i18n:_('Details')}" selected="true"
onSelect="orderElementController.clearAll();"/>
<tab id="tabAssignedHours" label="${i18n:_('Assigned hours')}"
@ -47,6 +51,7 @@
<tab id="tabTaskQualityForm" label="${i18n:_('Task quality forms')}"
onSelect="orderElementController.setupAssignedTaskQualityFormsToOrderElementController();"/>
</tabs>
<tabpanels>
<tabpanel id="tabPanelDetails">
<orderElementDetails id="orderElementDetails" />
@ -70,9 +75,11 @@
<listOrderElementTaskQualityForms id="orderElementTaskQualityForms" fulfill="tabTaskQualityForm.onSelect"/>
</tabpanel>
</tabpanels>
</tabbox>
<hbox>
<button label="${i18n:_('Back')}" onClick="orderElementController.back()"
sclass="back-button global-action"/>
</hbox>
</tabbox>
<hbox>
<button label="${i18n:_('Back')}" onClick="orderElementController.back()"
sclass="back-button global-action"/>
</hbox>
</window>

View file

@ -23,8 +23,11 @@
<?component name="listOrderElementHours" inline="true" macroURI="_listOrderElementHours.zul"?>
<?component name="listOrderElementAdvances" inline="true" macroURI="_listOrderElementAdvances.zul"?>
<?component name="listOrderElementLabels" class="org.navalplanner.web.orders.labels.LabelsAssignmentToOrderElementComponent" macroURI="components/_listOrderElementLabels.zul"?>
<?component name="listOrderElementCriterionRequirements" inline="true" macroURI="_listOrderElementCriterionRequirements.zul"?>
<?component name="listOrderElementMaterials" class="org.navalplanner.web.orders.materials.OrderElementMaterialAssignmentsComponent"
<?component name="listOrderElementCriterionRequirements"
class="org.navalplanner.web.orders.criterionrequirements.OrderElementCriterionRequirementComponent"
macroURI="/orders/_listOrderElementCriterionRequirements.zul"?>
<?component name="listOrderElementMaterials"
class="org.navalplanner.web.orders.materials.OrderElementMaterialAssignmentsComponent"
macroURI="/orders/components/_listOrderElementMaterials.zul"?>
<?component name="listOrderElementTaskQualityForms" inline="true" macroURI="_listOrderElementTaskQualityForms.zul"?>
<?component name="listOrderElementAuthorizations" inline="true" macroURI="_listOrderElementAuthorizations.zul"?>
@ -44,7 +47,8 @@
<tab id="tabLabels" label="${i18n:_('Label')}"
onSelect = "controller.setupAssignedLabelsToOrderElementController();"/>
<tab id="tabRequirements" label="${i18n:_('Criterion Requirement')}"
onSelect = "controller.setupAssignedCriterionRequirementsToOrderElementController();"/>
onSelect = "controller.setupAssignedCriterionRequirementsToOrderElementController();"
onClick="controller.reloadHoursGroupOrder()" />
<tab id="tabMaterials" label="${i18n:_('Materials')}"
onSelect = "controller.setupAssignedMaterialsToOrderElementController();"/>
<tab id="tabTaskQualityForm" label="${i18n:_('Task quality forms')}"

View file

@ -21,24 +21,26 @@
<?component name="listHoursGroupCriterionRequirements" inline="true" macroURI="_listHoursGroupCriterionRequirement.zul"?>
<zk>
<zscript><![CDATA[
criterionRequirementsController = new org.navalplanner.web.orders.AssignedCriterionRequirementToOrderElementController();
criterionRequirementsController = self.controller;
]]>
</zscript>
<vbox id="${arg.id}"
apply="${criterionRequirementsController}">
<panel title="${i18n:_('Assigned Criterion Requirements')}" border="normal"
style="overflow:auto" width="99%">
<vbox apply="${criterionRequirementsController}">
<panel title="${i18n:_('Assigned criterion requirements')}" border="normal"
style="overflow:auto" >
<panelchildren>
<hbox align="center">
<separator bar="false" spacing="40px" orient="horizontal"/>
<separator bar="false" spacing="20px" orient="vertical"/>
<button onClick="criterionRequirementsController.addCriterionRequirementWrapper();"
label="${i18n:_('Add criterion requirement')}" />
<separator bar="false" spacing="40px" orient="vertical"/>
<button label="${i18n:_('Add')}"
tooltiptext="${i18n:_('Add criterion requirement')}"
style="margin-bottom: 5px"
onClick="criterionRequirementsController.addCriterionRequirementWrapper()" />
</hbox>
<newdatasortablegrid id="listingRequirements" mold="paging"
pageSize="4" fixedLayout="true"
model="@{criterionRequirementsController.criterionRequirementWrappers}">
<newdatasortablegrid id="listingRequirements"
model="@{criterionRequirementsController.criterionRequirementWrappers}"
mold="paging"
pageSize="10"
fixedLayout="true" >
<columns>
<newdatasortablecolumn label="${i18n:_('Criterion name')}" sort="auto(criterionAndType)" sortDirection="ascending"/>
<newdatasortablecolumn label="${i18n:_('Type')}" sort="auto(type)" width="100px" align="center"/>
@ -47,30 +49,36 @@ criterionRequirementsController = new org.navalplanner.web.orders.AssignedCriter
<rows>
<row self="@{each='criterionRequirementWrapper'}" value="@{criterionRequirementWrapper}">
<hbox>
<bandbox width="500px"
visible ="@{criterionRequirementWrapper.updatable}"
value = "@{criterionRequirementWrapper.criterionAndType}">
<bandpopup>
<listbox width="500px" height="150px" fixedLayout="true"
model="@{criterionRequirementsController.criterionWithItsTypes}"
onSelect="criterionRequirementsController.selectCriterionAndType(self.selectedItem,
self.parent.parent,self.parent.parent.parent.parent.value);">
<listhead>
<listheader label="Type" />
<listheader label="Criterion" />
</listhead>
<listitem self="@{each='criterionWithItsType'}" value="@{criterionWithItsType}">
<listcell label="@{criterionWithItsType.type.name}" />
<listcell label="@{criterionWithItsType.nameHierarchy}" />
</listitem>
</listbox>
</bandpopup>
</bandbox>
<label visible="@{criterionRequirementWrapper.unmodifiable}"
value="@{criterionRequirementWrapper.criterionAndType}"/>
<!-- Bandbox select criterion-and-type -->
<bandbox width="500px"
visible="@{criterionRequirementWrapper.updatable}"
value="@{criterionRequirementWrapper.criterionAndType}">
<bandpopup>
<listbox width="500px" height="150px" fixedLayout="true"
model="@{criterionRequirementsController.criterionWithItsTypes}"
onSelect="criterionRequirementsController.selectCriterionAndType(self.selectedItem,
self.parent.parent,self.parent.parent.parent.parent.value);">
<listhead>
<listheader label="Type" />
<listheader label="Criterion" />
</listhead>
<listitem self="@{each='criterionWithItsType'}" value="@{criterionWithItsType}">
<listcell label="@{criterionWithItsType.type.name}" />
<listcell label="@{criterionWithItsType.nameHierarchy}" />
</listitem>
</listbox>
</bandpopup>
</bandbox>
<!-- Assigned criterion-and-type -->
<label visible="@{criterionRequirementWrapper.unmodifiable}"
value="@{criterionRequirementWrapper.criterionAndType}"/>
</hbox>
<!-- Criterion assignment type (direct, indirect) -->
<label value="@{criterionRequirementWrapper.type}"/>
<!-- Operations -->
<hbox>
<button visible = "@{criterionRequirementWrapper.direct}"
sclass="icono" image="/common/img/ico_borrar1.png"
@ -94,110 +102,123 @@ criterionRequirementsController = new org.navalplanner.web.orders.AssignedCriter
</panel>
<separator bar="false" spacing="80px" orient="vertical"/>
<panel title="${i18n:_('Total Hours OrderElement')}" border="normal"
width="180px" >
<!-- Total hours order element -->
<panel title="${i18n:_('Total hours order element')}"
style="overflow:auto" >
<panelchildren>
<hbox align="center">
<separator bar="false" spacing="40px" orient="horizontal"/>
<separator bar="false" spacing="20px" orient="vertical"/>
<intbox id="orderElementTotalHours"
visible = "@{criterionRequirementsController.editableHoursGroup}"
value = "@{criterionRequirementsController.orderElement.workHours}"
onChange="criterionRequirementsController.changeTotalHours();"
readonly = "@{criterionRequirementsController.readOnly}"
constraint = "@{criterionRequirementsController.validateTotalHours}"/>
<label value = "@{criterionRequirementsController.orderElement.workHours}"
visible = "@{criterionRequirementsController.readOnly}" />
<separator bar="false" spacing="20px" orient="vertical"/>
</hbox>
</panelchildren>
<grid fixedLayout="true">
<columns>
<column width="200px" />
<column />
</columns>
<rows>
<row>
<label
value="${i18n:_('Total hours order element')}:" />
<hbox align="center">
<intbox id="orderElementTotalHours"
visible="@{criterionRequirementsController.editableHoursGroup}"
value="@{criterionRequirementsController.orderElement.workHours}"
onChange="criterionRequirementsController.changeTotalHours();"
readonly="@{criterionRequirementsController.readOnly}"
constraint="@{criterionRequirementsController.validateTotalHours}"/>
<label value="@{criterionRequirementsController.orderElement.workHours}"
visible="@{criterionRequirementsController.readOnly}" />
</hbox>
</row>
</rows>
</grid>
</panelchildren>
</panel>
<separator bar="false" spacing="80px" orient="vertical"/>
<div id= "messagesContainer">
</div>
<div id="messagesContainer" />
<!-- List Hours Groups in OrdeLineGroup -->
<panel title="${i18n:_('Hours group')}"
visible = "@{criterionRequirementsController.readOnly}">
<panelchildren>
<listbox id="hoursGroupsInOrderLineGroup" multiple="true"
model="@{criterionRequirementsController.hoursGroups}"
itemRenderer="@{criterionRequirementsController.renderer}">
<listhead>
<listheader label="${i18n:_('Criterion Requirements')}" width = "500px"/>
<listheader label="${i18n:_('Type')}" align="center" width = "150px" />
<listheader label="${i18n:_('Hours')}" align="center" width = "150px" />
</listhead>
</listbox>
</panelchildren>
visible="@{criterionRequirementsController.readOnly}"
style="overflow: auto" >
<panelchildren>
<listbox id="hoursGroupsInOrderLineGroup" multiple="true"
model="@{criterionRequirementsController.hoursGroups}"
itemRenderer="@{criterionRequirementsController.renderer}">
<listhead>
<listheader label="${i18n:_('Criterion Requirements')}" width="500px"/>
<listheader label="${i18n:_('Type')}" align="center" width="150px" />
<listheader label="${i18n:_('Hours')}" align="center" width="150px" />
</listhead>
</listbox>
</panelchildren>
</panel>
<!--Manage Hours Groups in OrdeLine-->
<panel title="${i18n:_('Hours Group')}" border="normal" width="99%"
visible = "@{criterionRequirementsController.editableHoursGroup}">
<panel title="${i18n:_('Hours Group')}" border="normal"
visible="@{criterionRequirementsController.editableHoursGroup}">
<panelchildren>
<hbox align="center">
<separator bar="false" spacing="40px" orient="horizontal"/>
<separator bar="false" spacing="20px" orient="vertical"/>
<button id="buttonAddHoursGroup"
label="${i18n:_('Add new hours group')}"
onClick="criterionRequirementsController.addHoursGroup()" />
<separator bar="false" spacing="20px" orient="vertical"/>
</hbox>
<newdatasortablegrid id = "listHoursGroups" mold="paging" pageSize="4" fixedLayout="true"
model="@{criterionRequirementsController.hoursGroupWrappers}">
<columns>
<newdatasortablecolumn width="25px" sort="auto"/>
<newdatasortablecolumn label="Code" width="160px" sort="auto(code)" sortDirection="ascending" align="center"/>
<newdatasortablecolumn label="Type" width="130px" align="center"/>
<newdatasortablecolumn label="Hours" width="120px" align="center"/>
<newdatasortablecolumn label="%" width="100px" align="center"/>
<newdatasortablecolumn label="Fixed %" width="50px" align="center"/>
<newdatasortablecolumn label="Operations" align="center"/>
</columns>
<rows>
<row self="@{each='hoursGroupWrapper'}" value="@{hoursGroupWrapper}">
<detail open="true">
<listHoursGroupCriterionRequirements/>
<separator bar="false" spacing="40px" orient="vertical"/>
</detail>
<textbox value="@{hoursGroupWrapper.code}"
readonly = "@{criterionRequirementsController.readOnly}"
disabled = "@{criterionRequirementsController.isCodeAutogenerated}" />
<combobox id="comboboxTypeHoursGroup" width="80px"
value = "@{hoursGroupWrapper.resourceType}"
onChange = "criterionRequirementsController.selectResourceType(self);"
model = "@{criterionRequirementsController.resourceTypes}"
disabled = "@{criterionRequirementsController.readOnly}">
</combobox>
<intbox value="@{hoursGroupWrapper.workingHours}"
readonly ="@{hoursGroupWrapper.workingHoursReadOnly}"
onChange = "criterionRequirementsController.recalculateHoursGroup()"/>
<decimalbox scale = "2" value="@{hoursGroupWrapper.percentage}"
constraint = "@{criterionRequirementsController.validatePercentage}"
readonly ="@{hoursGroupWrapper.percentageReadOnly}"
onChange = "criterionRequirementsController.recalculateHoursGroup()"/>
<checkbox checked="@{hoursGroupWrapper.fixedPercentage}"
onCheck = "criterionRequirementsController.recalculateHoursGroup()"/>
<hbox>
<button id="buttonDeleteHoursGroup"
sclass="icono" image="/common/img/ico_borrar1.png"
hoverImage="/common/img/ico_borrar.png"
tooltiptext="${i18n:_('Delete')}"
onClick="criterionRequirementsController.deleteHoursGroups(self)" />
<button id="buttonAddCriterion"
label="${i18n:_('Add Criterion')}"
onClick="criterionRequirementsController.addCriterionToHoursGroup(self)" />
<button id="buttonAddException"
disabled = "@{hoursGroupWrapper.dontExistValidCriterions}"
label="${i18n:_('Add Exception')}"
onClick="criterionRequirementsController.addExceptionToHoursGroups(self)" />
</hbox>
</row>
</rows>
</newdatasortablegrid>
<hbox align="center">
<button id="buttonAddHoursGroup"
label="${i18n:_('Add')}"
tooltiptext="${i18n:_('Add new hours group')}"
style="margin-bottom: 5px"
onClick="criterionRequirementsController.addHoursGroup()" />
</hbox>
<newdatasortablegrid id="listHoursGroups"
model="@{criterionRequirementsController.hoursGroupWrappers}"
mold="paging"
pageSize="4"
fixedLayout="true">
<columns>
<newdatasortablecolumn width="25px" sort="auto"/>
<newdatasortablecolumn label="Code" width="160px" sort="auto(code)" sortDirection="ascending" align="center"/>
<newdatasortablecolumn label="Type" width="130px" align="center"/>
<newdatasortablecolumn label="Hours" width="120px" align="center"/>
<newdatasortablecolumn label="%" width="100px" align="center"/>
<newdatasortablecolumn label="Fixed %" width="50px" align="center"/>
<newdatasortablecolumn label="Operations" align="center"/>
</columns>
<rows>
<row self="@{each='hoursGroupWrapper'}" value="@{hoursGroupWrapper}">
<detail open="true">
<listHoursGroupCriterionRequirements/>
<separator bar="false" spacing="40px" orient="vertical"/>
</detail>
<textbox value="@{hoursGroupWrapper.code}"
readonly="@{criterionRequirementsController.readOnly}"
disabled="@{criterionRequirementsController.isCodeAutogenerated}" />
<combobox id="comboboxTypeHoursGroup" width="80px"
value="@{hoursGroupWrapper.resourceType}"
onChange="criterionRequirementsController.selectResourceType(self);"
model="@{criterionRequirementsController.resourceTypes}"
disabled="@{criterionRequirementsController.readOnly}">
</combobox>
<intbox value="@{hoursGroupWrapper.workingHours}"
readonly="@{hoursGroupWrapper.workingHoursReadOnly}"
onChange="criterionRequirementsController.recalculateHoursGroup()"/>
<decimalbox scale="2" value="@{hoursGroupWrapper.percentage}"
constraint="@{criterionRequirementsController.validatePercentage}"
readonly="@{hoursGroupWrapper.percentageReadOnly}"
onChange="criterionRequirementsController.recalculateHoursGroup()"/>
<checkbox checked="@{hoursGroupWrapper.fixedPercentage}"
onCheck="criterionRequirementsController.recalculateHoursGroup()"/>
<hbox>
<button id="buttonDeleteHoursGroup"
sclass="icono" image="/common/img/ico_borrar1.png"
hoverImage="/common/img/ico_borrar.png"
tooltiptext="${i18n:_('Delete')}"
onClick="criterionRequirementsController.deleteHoursGroups(self)" />
<button id="buttonAddCriterion"
label="${i18n:_('Add Criterion')}"
onClick="criterionRequirementsController.addCriterionToHoursGroup(self)" />
<button id="buttonAddException"
disabled = "@{hoursGroupWrapper.dontExistValidCriterions}"
label="${i18n:_('Add Exception')}"
onClick="criterionRequirementsController.addExceptionToHoursGroups(self)" />
</hbox>
</row>
</rows>
</newdatasortablegrid>
</panelchildren>
</panel>
</vbox>
</zk>
</zk>

View file

@ -17,18 +17,37 @@
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/>.
-->
<?component name="advancesAssignment" class="org.navalplanner.web.templates.advances.AdvancesAssignmentComponent" macroURI="/templates/_advances.zul"?>
<?component name="listOrderElementLabels" class="org.navalplanner.web.templates.labels.LabelsAssignmentToTemplateComponent" macroURI="/orders/components/_listOrderElementLabels.zul"?>
<?component name="listOrderElementMaterials" class="org.navalplanner.web.templates.materials.MaterialAssignmentTemplateComponent"
<?component name="advancesAssignment"
class="org.navalplanner.web.templates.advances.AdvancesAssignmentComponent"
macroURI="/templates/_advances.zul"?>
<?component name="listOrderElementLabels"
class="org.navalplanner.web.templates.labels.LabelsAssignmentToTemplateComponent"
macroURI="/orders/components/_listOrderElementLabels.zul"?>
<?component name="listOrderElementMaterials"
class="org.navalplanner.web.templates.materials.MaterialAssignmentTemplateComponent"
macroURI="/orders/components/_listOrderElementMaterials.zul"?>
<?component name="assignedQualityForms" class="org.navalplanner.web.templates.quality.QualityFormAssignerComponent" macroURI="/templates/_assignedQualityForms.zul" ?>
<?component name="listOrderElementCriterionRequirements"
class="org.navalplanner.web.templates.criterionrequirements.CriterionRequirementTemplateComponent"
macroURI="/orders/_listOrderElementCriterionRequirements.zul"?>
<?component name="assignedQualityForms"
class="org.navalplanner.web.templates.quality.QualityFormAssignerComponent"
macroURI="/templates/_assignedQualityForms.zul" ?>
<window id="editTemplateWindow" title="${i18n:_('Edit order element')}"
width="950px" left="50px" top="50px"
closable="false" visible="false">
closable="true" onClose="self.visible = false; event.stopPropagation()"
visible="false" >
<tabbox height="620px" id="tabboxOrderElement">
<tabs>
<tab label="${i18n:_('Advances')}" />
<tab label="${i18n:_('Labels')}" />
<tab label="${i18n:_('Criterion requirement')}" />
<tab label="${i18n:_('Materials')}" />
<tab label="${i18n:_('Quality Forms')}" />
</tabs>
@ -39,6 +58,9 @@
<tabpanel>
<listOrderElementLabels id="listOrderElementLabels"/>
</tabpanel>
<tabpanel>
<listOrderElementCriterionRequirements id="listOrderElementCriterionRequirements"/>
</tabpanel>
<tabpanel>
<listOrderElementMaterials id="listOrderElementMaterials"/>
</tabpanel>
@ -47,7 +69,9 @@
</tabpanel>
</tabpanels>
</tabbox>
<hbox>
<button id="backButton" label="${i18n:_('Back')}" sclass="back-button global-action"/>
</hbox>
</window>
</window>

View file

@ -28,8 +28,12 @@
<?component name="schedulingStateToggler" class="org.navalplanner.web.orders.SchedulingStateToggler" macroURI="/common/components/schedulingStateToggler.zul"?>
<?component name="list" inline="true" macroURI="_list.zul"?>
<?component name="orderElementTree" macroURI="/orders/components/_orderElementTree.zul"
class="org.navalplanner.web.templates.TemplatesTreeComponent"?>
<?component name="listOrderElementMaterials" class="org.navalplanner.web.templates.materials.MaterialAssignmentTemplateComponent"
class="org.navalplanner.web.templates.TemplatesTreeComponent"?>
<?component name="listOrderElementCriterionRequirements"
class="org.navalplanner.web.templates.criterionrequirements.CriterionRequirementTemplateComponent"
macroURI="/orders/_listOrderElementCriterionRequirements.zul"?>
<?component name="listOrderElementMaterials"
class="org.navalplanner.web.templates.materials.MaterialAssignmentTemplateComponent"
macroURI="/orders/components/_listOrderElementMaterials.zul"?>
<?component name="listOrderElementLabels" class="org.navalplanner.web.templates.labels.LabelsAssignmentToTemplateComponent" macroURI="/orders/components/_listOrderElementLabels.zul"?>
<?component name="assignedQualityForms" class="org.navalplanner.web.templates.quality.QualityFormAssignerComponent" macroURI="/templates/_assignedQualityForms.zul" ?>
@ -54,6 +58,7 @@
<tab label="${i18n:_('Template Tree')}" disabled="@{templateController.templateTreeDisabled}"/>
<tab label="${i18n:_('Advances')}" />
<tab label="${i18n:_('Labels')}" />
<tab id="tabRequirements" label="${i18n:_('Criterion Requirement')}" />
<tab label="${i18n:_('Materials')}" />
<tab label="${i18n:_('Quality Forms')}" />
<tab label="${i18n:_('Assignment log')}" />
@ -100,6 +105,9 @@
<tabpanel>
<listOrderElementLabels id="listOrderElementLabels"/>
</tabpanel>
<tabpanel>
<listOrderElementCriterionRequirements id="listOrderElementCriterionRequirements"/>
</tabpanel>
<tabpanel>
<listOrderElementMaterials id="listOrderElementMaterials"/>
</tabpanel>