Added test for BAC value.

Code refactoring.
(cherry picked from commit 0f00d11)
This commit is contained in:
Vova Perebykivskiy 2016-04-15 19:30:05 +03:00 committed by Dgray16
parent 0763cbfe02
commit 529d3b738e
75 changed files with 2235 additions and 2585 deletions

View file

@ -33,11 +33,10 @@ import org.zkoss.zk.ui.event.Event;
public class CommandOnTaskContextualized<T> { public class CommandOnTaskContextualized<T> {
public static <T> CommandOnTaskContextualized<T> create( public static <T> CommandOnTaskContextualized<T> create(ICommandOnTask<T> commandOnTask,
ICommandOnTask<T> commandOnTask, IDomainAndBeansMapper<T> mapper, IDomainAndBeansMapper<T> mapper, IContext<T> context) {
IContext<T> context) {
return new CommandOnTaskContextualized<T>(commandOnTask, mapper, return new CommandOnTaskContextualized<T>(commandOnTask, mapper, context);
context);
} }
private final ICommandOnTask<T> commandOnTask; private final ICommandOnTask<T> commandOnTask;
@ -46,16 +45,17 @@ public class CommandOnTaskContextualized<T> {
private final IDomainAndBeansMapper<T> mapper; private final IDomainAndBeansMapper<T> mapper;
private CommandOnTaskContextualized(ICommandOnTask<T> commandOnTask, private CommandOnTaskContextualized(ICommandOnTask<T> commandOnTask, IDomainAndBeansMapper<T> mapper,
IDomainAndBeansMapper<T> mapper, IContext<T> context) { IContext<T> context) {
this.commandOnTask = commandOnTask; this.commandOnTask = commandOnTask;
this.mapper = mapper; this.mapper = mapper;
this.context = context; this.context = context;
} }
public void doAction(TaskComponent taskComponent) { public void doAction(TaskComponent taskComponent) {
doAction(ContextRelativeToOtherComponent.makeRelativeTo(context, doAction(
taskComponent), domainObjectFor(taskComponent.getTask())); ContextRelativeToOtherComponent.makeRelativeTo(context, taskComponent),
domainObjectFor(taskComponent.getTask()));
} }
public void doAction(Task task) { public void doAction(Task task) {
@ -67,8 +67,9 @@ public class CommandOnTaskContextualized<T> {
} }
private void doAction(IContext<T> context, T domainObject) { private void doAction(IContext<T> context, T domainObject) {
IContextWithPlannerTask<T> contextWithTask = ContextWithPlannerTask IContextWithPlannerTask<T> contextWithTask =
.create(context, mapper.findAssociatedBean(domainObject)); ContextWithPlannerTask.create(context, mapper.findAssociatedBean(domainObject));
commandOnTask.doAction(contextWithTask, domainObject); commandOnTask.doAction(contextWithTask, domainObject);
} }

View file

@ -119,8 +119,7 @@ public class TaskList extends XulElement implements AfterCompose {
return result; return result;
} }
public List<DependencyComponent> asDependencyComponents( public List<DependencyComponent> asDependencyComponents(Collection<? extends Dependency> dependencies) {
Collection<? extends Dependency> dependencies) {
List<DependencyComponent> result = new ArrayList<DependencyComponent>(); List<DependencyComponent> result = new ArrayList<DependencyComponent>();
for (Dependency dependency : dependencies) { for (Dependency dependency : dependencies) {
result.add(new DependencyComponent(taskComponentByTask result.add(new DependencyComponent(taskComponentByTask
@ -134,13 +133,12 @@ public class TaskList extends XulElement implements AfterCompose {
return asDependencyComponents(Arrays.asList(dependency)).get(0); return asDependencyComponents(Arrays.asList(dependency)).get(0);
} }
private synchronized void addTaskComponent(TaskRow beforeThis, private synchronized void addTaskComponent(TaskRow beforeThis, final TaskComponent taskComponent, boolean relocate) {
final TaskComponent taskComponent, boolean relocate) {
insertBefore(taskComponent.getRow(), beforeThis); insertBefore(taskComponent.getRow(), beforeThis);
addContextMenu(taskComponent); addContextMenu(taskComponent);
addListenerForTaskComponentEditForm(taskComponent); addListenerForTaskComponentEditForm(taskComponent);
taskComponent.afterCompose(); taskComponent.afterCompose();
if (relocate) { if ( relocate ) {
getGanttPanel().adjustZoomColumnsHeight(); getGanttPanel().adjustZoomColumnsHeight();
} }
} }
@ -168,9 +166,8 @@ public class TaskList extends XulElement implements AfterCompose {
return null; return null;
} }
private void addListenerForTaskComponentEditForm( private void addListenerForTaskComponentEditForm(final TaskComponent taskComponent) {
final TaskComponent taskComponent) { if ( doubleClickCommand == null ) {
if (doubleClickCommand == null) {
return; return;
} }
taskComponent.addEventListener("onDoubleClick", new EventListener() { taskComponent.addEventListener("onDoubleClick", new EventListener() {
@ -292,25 +289,23 @@ public class TaskList extends XulElement implements AfterCompose {
private Map<TaskComponent, Menupopup> contextMenus = new HashMap<TaskComponent, Menupopup>(); private Map<TaskComponent, Menupopup> contextMenus = new HashMap<TaskComponent, Menupopup>();
private Menupopup getContextMenuFor(TaskComponent taskComponent) { private Menupopup getContextMenuFor(TaskComponent taskComponent) {
if (contextMenus.get(taskComponent) == null) { if ( contextMenus.get(taskComponent) == null ) {
MenuBuilder<TaskComponent> menuBuilder = MenuBuilder.on(getPage(), MenuBuilder<TaskComponent> menuBuilder = MenuBuilder.on(getPage(), getTaskComponents());
getTaskComponents());
if (disabilityConfiguration.isAddingDependenciesEnabled()) { if ( disabilityConfiguration.isAddingDependenciesEnabled() ) {
menuBuilder.item(_("Add Dependency"), menuBuilder.item(_("Add Dependency"), "/common/img/ico_dependency.png",
"/common/img/ico_dependency.png",
new ItemAction<TaskComponent>() { new ItemAction<TaskComponent>() {
@Override @Override
public void onEvent(TaskComponent choosen, public void onEvent(TaskComponent choosen, Event event) {
Event event) {
choosen.addDependency(); choosen.addDependency();
} }
}); });
} }
for (CommandOnTaskContextualized<?> command : commandsOnTasksContextualized) { for (CommandOnTaskContextualized<?> command : commandsOnTasksContextualized) {
if (command.accepts(taskComponent)) { if ( command.accepts(taskComponent) ) {
menuBuilder.item(command.getName(), command.getIcon(), menuBuilder.item(command.getName(), command.getIcon(), command.toItemAction());
command.toItemAction());
} }
} }
Menupopup result = menuBuilder.createWithoutSettingContext(); Menupopup result = menuBuilder.createWithoutSettingContext();
@ -358,22 +353,21 @@ public class TaskList extends XulElement implements AfterCompose {
getGanttPanel().getDependencyList().redrawDependencies(); getGanttPanel().getDependencyList().redrawDependencies();
} }
private void reload(List<Task> tasks, List<Task> tasksPendingToAdd, private void reload(List<Task> tasks, List<Task> tasksPendingToAdd, boolean relocate) {
boolean relocate) {
for (Task task : tasks) { for (Task task : tasks) {
if (visibleTasks.contains(task)) { if ( visibleTasks.contains(task) ) {
addPendingTasks(tasksPendingToAdd, rowFor(task), addPendingTasks(tasksPendingToAdd, rowFor(task), relocate);
relocate);
} }
final boolean isShown = visibleTasks.contains(task); final boolean isShown = visibleTasks.contains(task);
if (predicate.accepts(task) != isShown) {
if (isShown) { if ( predicate.accepts(task) != isShown ) {
if ( isShown ) {
makeDisappear(task); makeDisappear(task);
} else { } else {
tasksPendingToAdd.add(task); tasksPendingToAdd.add(task);
} }
} }
if (task instanceof TaskContainer) { if ( task instanceof TaskContainer ) {
reload(task.getTasks(), tasksPendingToAdd, relocate); reload(task.getTasks(), tasksPendingToAdd, relocate);
} }
} }
@ -391,9 +385,8 @@ public class TaskList extends XulElement implements AfterCompose {
return taskComponent == null ? null : taskComponent.getRow(); return taskComponent == null ? null : taskComponent.getRow();
} }
private void addPendingTasks(List<Task> tasksPendingToAdd, private void addPendingTasks(List<Task> tasksPendingToAdd, TaskRow insertBefore, boolean relocate) {
TaskRow insertBefore, boolean relocate) { if ( tasksPendingToAdd.isEmpty() ) {
if (tasksPendingToAdd.isEmpty()) {
return; return;
} }
for (TaskComponent each : createAndPublishComponentsIfNeeded(tasksPendingToAdd)) { for (TaskComponent each : createAndPublishComponentsIfNeeded(tasksPendingToAdd)) {

View file

@ -29,8 +29,7 @@ package org.libreplan.business;
*/ */
public class BusinessGlobalNames { public class BusinessGlobalNames {
public final static String BUSINESS_SPRING_CONFIG_FILE = public final static String BUSINESS_SPRING_CONFIG_FILE = "classpath:/libreplan-business-spring-config.xml";
"classpath:/libreplan-business-spring-config.xml";
private BusinessGlobalNames () {} private BusinessGlobalNames () {}

View file

@ -28,30 +28,22 @@ import org.libreplan.business.common.Registry;
public enum PredefinedAdvancedTypes { public enum PredefinedAdvancedTypes {
CHILDREN("children", new BigDecimal(100), new BigDecimal(0.01), true, CHILDREN("children", new BigDecimal(100), new BigDecimal(0.01), true, false),
false), PERCENTAGE("percentage", new BigDecimal(100), new BigDecimal(0.01), true, false),
PERCENTAGE( UNITS("units", new BigDecimal(Integer.MAX_VALUE), new BigDecimal(1), false, false),
"percentage", new BigDecimal(100), new BigDecimal(0.01), true, SUBCONTRACTOR("subcontractor", new BigDecimal(100), new BigDecimal(0.01), true, false),
false), TIMESHEETS("timesheets", new BigDecimal(100), new BigDecimal(0.01), true, false, true);
UNITS("units", new BigDecimal(Integer.MAX_VALUE),
new BigDecimal(1), false, false),
SUBCONTRACTOR("subcontractor",
new BigDecimal(100), new BigDecimal(0.01), true, false),
TIMESHEETS("timesheets",
new BigDecimal(100), new BigDecimal(0.01), true, false, true);
private PredefinedAdvancedTypes(String name, BigDecimal defaultMaxValue, private PredefinedAdvancedTypes(String name, BigDecimal defaultMaxValue, BigDecimal precision, boolean percentage,
BigDecimal precision, boolean percentage, boolean qualityForm) { boolean qualityForm) {
this(name, defaultMaxValue, precision, percentage, qualityForm, false); this(name, defaultMaxValue, precision, percentage, qualityForm, false);
} }
private PredefinedAdvancedTypes(String name, BigDecimal defaultMaxValue, private PredefinedAdvancedTypes(String name, BigDecimal defaultMaxValue, BigDecimal precision, boolean percentage,
BigDecimal precision, boolean percentage, boolean qualityForm, boolean qualityForm, boolean readOnly) {
boolean readOnly) {
this.name = name; this.name = name;
this.defaultMaxValue = defaultMaxValue.setScale(4, this.defaultMaxValue = defaultMaxValue.setScale(4, BigDecimal.ROUND_HALF_UP);
BigDecimal.ROUND_HALF_UP);
this.unitPrecision = precision.setScale(4, BigDecimal.ROUND_HALF_UP); this.unitPrecision = precision.setScale(4, BigDecimal.ROUND_HALF_UP);
this.percentage = percentage; this.percentage = percentage;
this.qualityForm = qualityForm; this.qualityForm = qualityForm;
@ -71,8 +63,10 @@ public enum PredefinedAdvancedTypes {
private final boolean readOnly; private final boolean readOnly;
public AdvanceType createType() { public AdvanceType createType() {
AdvanceType advanceType = AdvanceType.create(name, defaultMaxValue,
false, unitPrecision, true, percentage, qualityForm); AdvanceType advanceType =
AdvanceType.create(name, defaultMaxValue, false, unitPrecision, true, percentage, qualityForm);
advanceType.setReadOnly(readOnly); advanceType.setReadOnly(readOnly);
return advanceType; return advanceType;
} }

View file

@ -53,8 +53,7 @@ import org.springframework.transaction.annotation.Transactional;
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class BaseCalendarDAO extends IntegrationEntityDAO<BaseCalendar> public class BaseCalendarDAO extends IntegrationEntityDAO<BaseCalendar> implements IBaseCalendarDAO {
implements IBaseCalendarDAO {
@Override @Override
public List<BaseCalendar> getBaseCalendars() { public List<BaseCalendar> getBaseCalendars() {
@ -65,10 +64,9 @@ public class BaseCalendarDAO extends IntegrationEntityDAO<BaseCalendar>
} }
private void removeResourceCalendarInstances(List<BaseCalendar> list) { private void removeResourceCalendarInstances(List<BaseCalendar> list) {
for (Iterator<BaseCalendar> iterator = list.iterator(); iterator for (Iterator<BaseCalendar> iterator = list.iterator(); iterator.hasNext();) {
.hasNext();) {
BaseCalendar baseCalendar = iterator.next(); BaseCalendar baseCalendar = iterator.next();
if (baseCalendar instanceof ResourceCalendar) { if ( baseCalendar instanceof ResourceCalendar ) {
iterator.remove(); iterator.remove();
} }
} }

View file

@ -56,11 +56,9 @@ import org.libreplan.business.workingday.ResourcesPerDay;
* some exceptions of its parent calendar. * some exceptions of its parent calendar.
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
public class BaseCalendar extends IntegrationEntity implements ICalendar, public class BaseCalendar extends IntegrationEntity implements ICalendar, IHumanIdentifiable, Comparable<BaseCalendar> {
IHumanIdentifiable, Comparable<BaseCalendar> {
private static final Capacity DEFAULT_VALUE = Capacity.zero() private static final Capacity DEFAULT_VALUE = Capacity.zero().overAssignableWithoutLimit();
.overAssignableWithoutLimit();
public static BaseCalendar create() { public static BaseCalendar create() {
return create(new BaseCalendar(CalendarData.create())); return create(new BaseCalendar(CalendarData.create()));
@ -84,7 +82,7 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar,
private static void resetDefaultCapacities(BaseCalendar calendar) { private static void resetDefaultCapacities(BaseCalendar calendar) {
CalendarData calendarData = calendar.getLastCalendarData(); CalendarData calendarData = calendar.getLastCalendarData();
if (calendarData != null) { if ( calendarData != null ) {
CalendarData.resetDefaultCapacities(calendarData); CalendarData.resetDefaultCapacities(calendarData);
} }
} }

View file

@ -61,7 +61,7 @@ public abstract class BaseEntity implements INewObject {
Collection<? extends T> entities) { Collection<? extends T> entities) {
Map<Long, Set<T>> result = new HashMap<Long, Set<T>>(); Map<Long, Set<T>> result = new HashMap<Long, Set<T>>();
for (T each : entities) { for (T each : entities) {
if (!result.containsKey(each.getId())) { if ( !result.containsKey(each.getId()) ) {
result.put(each.getId(), new HashSet<T>()); result.put(each.getId(), new HashSet<T>());
} }
result.get(each.getId()).add(each); result.get(each.getId()).add(each);
@ -71,8 +71,7 @@ public abstract class BaseEntity implements INewObject {
private static final Log LOG = LogFactory.getLog(BaseEntity.class); private static final Log LOG = LogFactory.getLog(BaseEntity.class);
private static final ValidatorFactory validatorFactory = Validation private static final ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
.buildDefaultValidatorFactory();
private static final Validator validator = validatorFactory.getValidator(); private static final Validator validator = validatorFactory.getValidator();
@ -134,9 +133,8 @@ public abstract class BaseEntity implements INewObject {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void validate() throws ValidationException { public void validate() throws ValidationException {
Set<ConstraintViolation<BaseEntity>> violations = validator Set<ConstraintViolation<BaseEntity>> violations = validator.validate(this);
.validate(this); if ( !violations.isEmpty() ) {
if (!violations.isEmpty()) {
throw new ValidationException(violations); throw new ValidationException(violations);
} }
} }
@ -153,8 +151,7 @@ public abstract class BaseEntity implements INewObject {
} }
public String getExtraInformation() { public String getExtraInformation() {
return "[ id: " + getId() + ", newObject: " return "[ id: " + getId() + ", newObject: " + isNewObject() + "]";
+ isNewObject() + "]";
} }
} }

View file

@ -82,7 +82,7 @@ public class Flagged<T, F> {
public boolean isFlaggedWithSomeOf(F... flags) { public boolean isFlaggedWithSomeOf(F... flags) {
for (F each : flags) { for (F each : flags) {
if (this.isFlaggedWith(each)) { if ( this.isFlaggedWith(each) ) {
return true; return true;
} }
} }

View file

@ -38,13 +38,12 @@ import org.springframework.transaction.annotation.Transactional;
*/ */
@Repository @Repository
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
public class ConfigurationDAO extends GenericDAOHibernate<Configuration, Long> public class ConfigurationDAO extends GenericDAOHibernate<Configuration, Long> implements IConfigurationDAO {
implements IConfigurationDAO {
@Override @Override
public Configuration getConfiguration() { public Configuration getConfiguration() {
List<Configuration> list = list(Configuration.class); List<Configuration> list = list(Configuration.class);
if (list.isEmpty()) { if ( list.isEmpty() ) {
return null; return null;
} }
return list.get(0); return list.get(0);
@ -59,10 +58,8 @@ public class ConfigurationDAO extends GenericDAOHibernate<Configuration, Long>
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW) @Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveChangedDefaultPassword(String user, boolean change) { public void saveChangedDefaultPassword(String user, boolean change) {
user = user.substring(0, 1).toUpperCase() user = user.substring(0, 1).toUpperCase() + user.substring(1).toLowerCase();
+ user.substring(1).toLowerCase(); String sql = "UPDATE Configuration e SET e.changedDefault" + user + "Password = :change";
String sql = "UPDATE Configuration e SET e.changedDefault" + user
+ "Password = :change";
Query query = getSession().createQuery(sql); Query query = getSession().createQuery(sql);
query.setParameter("change", change); query.setParameter("change", change);
query.executeUpdate(); query.executeUpdate();

View file

@ -58,8 +58,7 @@ import org.springframework.transaction.annotation.Transactional;
* @param <PK> * @param <PK>
* Primary key class * Primary key class
*/ */
public class GenericDAOHibernate<E extends BaseEntity, public class GenericDAOHibernate<E extends BaseEntity, PK extends Serializable> implements IGenericDAO<E, PK> {
PK extends Serializable> implements IGenericDAO<E, PK> {
private Class<E> entityClass; private Class<E> entityClass;
@ -68,8 +67,8 @@ public class GenericDAOHibernate<E extends BaseEntity,
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public GenericDAOHibernate() { public GenericDAOHibernate() {
this.entityClass = (Class<E>) ((ParameterizedType) getClass() this.entityClass =
.getGenericSuperclass()).getActualTypeArguments()[0]; (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
} }
public GenericDAOHibernate(Class<E> entityClass) { public GenericDAOHibernate(Class<E> entityClass) {
@ -101,7 +100,7 @@ public class GenericDAOHibernate<E extends BaseEntity,
} }
public void reattachUnmodifiedEntity(E entity) { public void reattachUnmodifiedEntity(E entity) {
if (Hibernate.isInitialized(entity) && entity.isNewObject()) { if ( Hibernate.isInitialized(entity) && entity.isNewObject() ) {
return; return;
} }
getSession().lock(entity, LockMode.NONE); getSession().lock(entity, LockMode.NONE);
@ -125,14 +124,14 @@ public class GenericDAOHibernate<E extends BaseEntity,
Method getIdMethod = entityClass.getMethod("getId"); Method getIdMethod = entityClass.getMethod("getId");
id = (Serializable) getIdMethod.invoke(entity); id = (Serializable) getIdMethod.invoke(entity);
if (id == null) { if ( id == null ) {
return; return;
} }
Method getVersionMethod = entityClass.getMethod("getVersion"); Method getVersionMethod = entityClass.getMethod("getVersion");
versionValueInMemory = (Long) getVersionMethod.invoke(entity); versionValueInMemory = (Long) getVersionMethod.invoke(entity);
if (versionValueInMemory == null) { if ( versionValueInMemory == null ) {
return; return;
} }
@ -142,14 +141,14 @@ public class GenericDAOHibernate<E extends BaseEntity,
/* Check version. */ /* Check version. */
Long versionValueInDB = (Long) getSession().createCriteria(entityClass) Long versionValueInDB = (Long) getSession().createCriteria(entityClass)
.add(Restrictions.idEq(id)).setProjection( .add(Restrictions.idEq(id))
Projections.property("version")).uniqueResult(); .setProjection(Projections.property("version")).uniqueResult();
if (versionValueInDB == null) { if ( versionValueInDB == null ) {
return; return;
} }
if (!versionValueInMemory.equals(versionValueInDB)) { if ( !versionValueInMemory.equals(versionValueInDB) ) {
throw new StaleObjectStateException(entityClass.getName(), id); throw new StaleObjectStateException(entityClass.getName(), id);
} }
@ -171,7 +170,7 @@ public class GenericDAOHibernate<E extends BaseEntity,
E entity = (E) getSession().get(entityClass, id); E entity = (E) getSession().get(entityClass, id);
if (entity == null) { if ( entity == null ) {
throw new InstanceNotFoundException(id, entityClass.getName()); throw new InstanceNotFoundException(id, entityClass.getName());
} }

View file

@ -47,8 +47,7 @@ import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.ResourceEnum; import org.libreplan.business.resources.entities.ResourceEnum;
import org.libreplan.business.templates.entities.OrderLineTemplate; import org.libreplan.business.templates.entities.OrderLineTemplate;
public class HoursGroup extends IntegrationEntity implements Cloneable, public class HoursGroup extends IntegrationEntity implements Cloneable, ICriterionRequirable {
ICriterionRequirable {
private static final Log LOG = LogFactory.getLog(HoursGroup.class); private static final Log LOG = LogFactory.getLog(HoursGroup.class);
@ -197,22 +196,19 @@ public class HoursGroup extends IntegrationEntity implements Cloneable,
* if the new sum of percentages in the parent {@link OrderLine} * if the new sum of percentages in the parent {@link OrderLine}
* surpasses one * surpasses one
*/ */
public void setPercentage(BigDecimal proportion) public void setPercentage(BigDecimal proportion) throws IllegalArgumentException {
throws IllegalArgumentException {
BigDecimal oldPercentage = this.percentage; BigDecimal oldPercentage = this.percentage;
this.percentage = proportion; this.percentage = proportion;
if (!isPercentageValidForParent()) { if ( !isPercentageValidForParent() ) {
this.percentage = oldPercentage; this.percentage = oldPercentage;
throw new IllegalArgumentException( throw new IllegalArgumentException(_("Total percentage should be less than 100%"));
_("Total percentage should be less than 100%"));
} }
} }
private boolean isPercentageValidForParent() { private boolean isPercentageValidForParent() {
return (parentOrderLine != null) ? parentOrderLine.isPercentageValid() return (parentOrderLine != null) ? parentOrderLine.isPercentageValid() : orderLineTemplate.isPercentageValid();
: orderLineTemplate.isPercentageValid();
} }
public BigDecimal getPercentage() { public BigDecimal getPercentage() {
@ -243,7 +239,7 @@ public class HoursGroup extends IntegrationEntity implements Cloneable,
criterions.add(criterionRequirement.getCriterion()); criterions.add(criterionRequirement.getCriterion());
} }
for (IndirectCriterionRequirement requirement : getIndirectCriterionRequirement()) { for (IndirectCriterionRequirement requirement : getIndirectCriterionRequirement()) {
if (requirement.isValid()) { if ( requirement.isValid() ) {
criterions.add(requirement.getCriterion()); criterions.add(requirement.getCriterion());
} }
} }
@ -252,11 +248,11 @@ public class HoursGroup extends IntegrationEntity implements Cloneable,
@Override @Override
public void addCriterionRequirement(CriterionRequirement requirement) { public void addCriterionRequirement(CriterionRequirement requirement) {
if (!isValidResourceType(requirement)) { if ( !isValidResourceType(requirement) ) {
throw new IllegalStateException( throw new IllegalStateException(
"Criterion cannot be assigned to this Hours Group. Criterion Resource Type is of a different type"); "Criterion cannot be assigned to this Hours Group. Criterion Resource Type is of a different type");
} }
if (existSameCriterionRequirement(requirement)) { if ( existSameCriterionRequirement(requirement) ) {
throw new IllegalStateException( throw new IllegalStateException(
"Criterion cannot be assigned to this Hours Group. Criterion already exist within Hours Group"); "Criterion cannot be assigned to this Hours Group. Criterion already exist within Hours Group");
@ -265,10 +261,8 @@ public class HoursGroup extends IntegrationEntity implements Cloneable,
criterionRequirements.add(requirement); criterionRequirements.add(requirement);
} }
public boolean canAddCriterionRequirement( public boolean canAddCriterionRequirement(CriterionRequirement newRequirement) {
CriterionRequirement newRequirement) { if ( (isValidResourceType(newRequirement)) && (!existSameCriterionRequirement(newRequirement)) ) {
if ((isValidResourceType(newRequirement))
&& (!existSameCriterionRequirement(newRequirement))) {
return false; return false;
} }
return true; return true;
@ -277,10 +271,8 @@ public class HoursGroup extends IntegrationEntity implements Cloneable,
@Override @Override
public void removeCriterionRequirement(CriterionRequirement requirement) { public void removeCriterionRequirement(CriterionRequirement requirement) {
criterionRequirements.remove(requirement); criterionRequirements.remove(requirement);
if (requirement instanceof IndirectCriterionRequirement) { if ( requirement instanceof IndirectCriterionRequirement ) {
((IndirectCriterionRequirement) requirement).getParent() ((IndirectCriterionRequirement) requirement).getParent().getChildren().remove(requirement);
.getChildren().remove(
(IndirectCriterionRequirement) requirement);
} }
requirement.setCriterion(null); requirement.setCriterion(null);
requirement.setHoursGroup(null); requirement.setHoursGroup(null);

View file

@ -328,7 +328,7 @@ public class Order extends OrderLineGroup implements Comparable {
for (OrderElement orderElement : getAllChildren()) { for (OrderElement orderElement : getAllChildren()) {
TaskElement taskElement = orderElement.getAssociatedTaskElement(); TaskElement taskElement = orderElement.getAssociatedTaskElement();
if (taskElement != null) { if ( taskElement != null ) {
result.add(taskElement); result.add(taskElement);
} }
} }
@ -340,7 +340,7 @@ public class Order extends OrderLineGroup implements Comparable {
public List<TaskElement> getAssociatedTasks() { public List<TaskElement> getAssociatedTasks() {
ArrayList<TaskElement> result = new ArrayList<TaskElement>(); ArrayList<TaskElement> result = new ArrayList<TaskElement>();
TaskGroup taskGroup = getAssociatedTaskElement(); TaskGroup taskGroup = getAssociatedTaskElement();
if (taskGroup != null) { if ( taskGroup != null ) {
result.addAll(taskGroup.getChildren()); result.addAll(taskGroup.getChildren());
} }
return result; return result;
@ -353,15 +353,13 @@ public class Order extends OrderLineGroup implements Comparable {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@AssertTrue(message = "the project must have a start date") @AssertTrue(message = "the project must have a start date")
private boolean isIfSchedulingModeIsForwardOrderMustHaveStartDateConstraint() { private boolean isIfSchedulingModeIsForwardOrderMustHaveStartDateConstraint() {
return getSchedulingMode() != SchedulingMode.FORWARD return getSchedulingMode() != SchedulingMode.FORWARD || getInitDate() != null;
|| getInitDate() != null;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@AssertTrue(message = "the project must have a deadline") @AssertTrue(message = "the project must have a deadline")
private boolean isIfSchedulingModeIsBackwardsOrderMustHaveDeadlineConstraint() { private boolean isIfSchedulingModeIsBackwardsOrderMustHaveDeadlineConstraint() {
return getSchedulingMode() != SchedulingMode.BACKWARDS return getSchedulingMode() != SchedulingMode.BACKWARDS || getDeadline() != null;
|| getDeadline() != null;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View file

@ -142,7 +142,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
private SchedulingDataForVersion.Data current = null; private SchedulingDataForVersion.Data current = null;
public SchedulingDataForVersion.Data getCurrentSchedulingData() { public SchedulingDataForVersion.Data getCurrentSchedulingData() {
if (current == null) { if ( current == null ) {
throw new IllegalStateException( throw new IllegalStateException(
"in order to use scheduling state related data " "in order to use scheduling state related data "
+ "useSchedulingDataFor(OrderVersion orderVersion) " + "useSchedulingDataFor(OrderVersion orderVersion) "
@ -151,19 +151,15 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
return current; return current;
} }
private void schedulingDataNowPointsTo(DeepCopy deepCopy, private void schedulingDataNowPointsTo(DeepCopy deepCopy, OrderVersion version) {
OrderVersion version) { current = getCurrentSchedulingData().pointsTo(deepCopy, version, schedulingVersionFor(version));
current = getCurrentSchedulingData().pointsTo(deepCopy, version,
schedulingVersionFor(version));
for (OrderElement each : getChildren()) { for (OrderElement each : getChildren()) {
each.schedulingDataNowPointsTo(deepCopy, version); each.schedulingDataNowPointsTo(deepCopy, version);
} }
} }
protected void addNeededReplaces(DeepCopy deepCopy, protected void addNeededReplaces(DeepCopy deepCopy, OrderVersion newOrderVersion) {
OrderVersion newOrderVersion) { SchedulingDataForVersion currentVersion = getCurrentSchedulingData().getVersion();
SchedulingDataForVersion currentVersion = getCurrentSchedulingData()
.getVersion();
SchedulingDataForVersion newSchedulingVersion = schedulingVersionFor(newOrderVersion); SchedulingDataForVersion newSchedulingVersion = schedulingVersionFor(newOrderVersion);
deepCopy.replace(currentVersion, newSchedulingVersion); deepCopy.replace(currentVersion, newSchedulingVersion);
for (OrderElement each : getChildren()) { for (OrderElement each : getChildren()) {
@ -172,7 +168,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
} }
public SchedulingState getSchedulingState() { public SchedulingState getSchedulingState() {
if (schedulingState == null) { if ( schedulingState == null ) {
ensureSchedulingStateInitializedFromTop(); ensureSchedulingStateInitializedFromTop();
initializeSchedulingState(); // maybe this order element was added initializeSchedulingState(); // maybe this order element was added
// later // later
@ -189,11 +185,10 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
} }
private SchedulingState initializeSchedulingState() { private SchedulingState initializeSchedulingState() {
if (schedulingState != null) { if ( schedulingState != null ) {
return schedulingState; return schedulingState;
} }
return schedulingState = SchedulingState.createSchedulingState( return schedulingState = SchedulingState.createSchedulingState(getSchedulingStateType(), getChildrenStates(),
getSchedulingStateType(), getChildrenStates(),
getCurrentSchedulingData().onTypeChangeListener()); getCurrentSchedulingData().onTypeChangeListener());
} }
@ -227,11 +222,10 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
useSchedulingDataFor(orderVersion, true); useSchedulingDataFor(orderVersion, true);
} }
public void useSchedulingDataFor(OrderVersion orderVersion, public void useSchedulingDataFor(OrderVersion orderVersion, boolean recursive) {
boolean recursive) {
Validate.notNull(orderVersion); Validate.notNull(orderVersion);
SchedulingDataForVersion schedulingVersion = schedulingVersionFor(orderVersion); SchedulingDataForVersion schedulingVersion = schedulingVersionFor(orderVersion);
if (recursive) { if ( recursive ) {
for (OrderElement each : getChildren()) { for (OrderElement each : getChildren()) {
each.useSchedulingDataFor(orderVersion); each.useSchedulingDataFor(orderVersion);
} }
@ -520,7 +514,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
} }
public TaskElement getAssociatedTaskElement() { public TaskElement getAssociatedTaskElement() {
if (getTaskSource() == null) { if ( getTaskSource() == null ) {
return null; return null;
} else { } else {
return getTaskSource().getTask(); return getTaskSource().getTask();
@ -541,7 +535,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
} }
public void setName(String name) { public void setName(String name) {
if (name != null && name.length() > 255) { if ( name != null && name.length() > 255 ) {
name = name.substring(0, 255); name = name.substring(0, 255);
} }
this.getInfoComponent().setName(name); this.getInfoComponent().setName(name);
@ -718,32 +712,28 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
* @throws DuplicateValueTrueReportGlobalAdvanceException * @throws DuplicateValueTrueReportGlobalAdvanceException
* @throws DuplicateAdvanceAssignmentForOrderElementException * @throws DuplicateAdvanceAssignmentForOrderElementException
*/ */
public void addAdvanceAssignment( public void addAdvanceAssignment(DirectAdvanceAssignment newAdvanceAssignment)
DirectAdvanceAssignment newAdvanceAssignment) throws DuplicateValueTrueReportGlobalAdvanceException, DuplicateAdvanceAssignmentForOrderElementException {
throws DuplicateValueTrueReportGlobalAdvanceException,
DuplicateAdvanceAssignmentForOrderElementException {
checkNoOtherGlobalAdvanceAssignment(newAdvanceAssignment);
checkAncestorsNoOtherAssignmentWithSameAdvanceType(this,
newAdvanceAssignment);
checkChildrenNoOtherAssignmentWithSameAdvanceType(this,
newAdvanceAssignment);
if (getReportGlobalAdvanceAssignment() == null) { checkNoOtherGlobalAdvanceAssignment(newAdvanceAssignment);
checkAncestorsNoOtherAssignmentWithSameAdvanceType(this, newAdvanceAssignment);
checkChildrenNoOtherAssignmentWithSameAdvanceType(this, newAdvanceAssignment);
if ( getReportGlobalAdvanceAssignment() == null ) {
newAdvanceAssignment.setReportGlobalAdvance(true); newAdvanceAssignment.setReportGlobalAdvance(true);
} }
newAdvanceAssignment.setOrderElement(this); newAdvanceAssignment.setOrderElement(this);
this.directAdvanceAssignments.add(newAdvanceAssignment); this.directAdvanceAssignments.add(newAdvanceAssignment);
if (this.getParent() != null) { if ( this.getParent() != null ) {
addChildrenAdvanceInParents(this.getParent()); addChildrenAdvanceInParents(this.getParent());
this.getParent().addIndirectAdvanceAssignment( this.getParent().addIndirectAdvanceAssignment(newAdvanceAssignment.createIndirectAdvanceFor(this.getParent()));
newAdvanceAssignment.createIndirectAdvanceFor(this.getParent()));
} }
} }
public void addChildrenAdvanceInParents(OrderLineGroup parent) { public void addChildrenAdvanceInParents(OrderLineGroup parent) {
if ((parent != null) && (!parent.existChildrenAdvance())) { if ( (parent != null) && (!parent.existChildrenAdvance()) ) {
parent.addChildrenAdvanceOrderLineGroup(); parent.addChildrenAdvanceOrderLineGroup();
addChildrenAdvanceInParents(parent.getParent()); addChildrenAdvanceInParents(parent.getParent());
} }
@ -751,7 +741,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
} }
public void removeChildrenAdvanceInParents(OrderLineGroup parent) { public void removeChildrenAdvanceInParents(OrderLineGroup parent) {
if ((parent != null) && (parent.existChildrenAdvance()) if ( (parent != null) && (parent.existChildrenAdvance() )
&& (!itsChildsHasAdvances(parent))) { && (!itsChildsHasAdvances(parent))) {
parent.removeChildrenAdvanceOrderLineGroup(); parent.removeChildrenAdvanceOrderLineGroup();
removeChildrenAdvanceInParents(parent.getParent()); removeChildrenAdvanceInParents(parent.getParent());
@ -760,25 +750,26 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
private boolean itsChildsHasAdvances(OrderElement orderElement) { private boolean itsChildsHasAdvances(OrderElement orderElement) {
for (OrderElement child : orderElement.getChildren()) { for (OrderElement child : orderElement.getChildren()) {
if ((!child.getIndirectAdvanceAssignments().isEmpty())
|| (!child.getDirectAdvanceAssignments().isEmpty())) { if ( (!child.getIndirectAdvanceAssignments().isEmpty()) ||
(!child.getDirectAdvanceAssignments().isEmpty()) ) {
return true; return true;
} }
if (itsChildsHasAdvances(child)) { if ( itsChildsHasAdvances(child) ) {
return true; return true;
} }
} }
return false; return false;
} }
protected void checkNoOtherGlobalAdvanceAssignment( protected void checkNoOtherGlobalAdvanceAssignment(DirectAdvanceAssignment newAdvanceAssignment)
DirectAdvanceAssignment newAdvanceAssignment)
throws DuplicateValueTrueReportGlobalAdvanceException { throws DuplicateValueTrueReportGlobalAdvanceException {
if (!newAdvanceAssignment.getReportGlobalAdvance()) {
if ( !newAdvanceAssignment.getReportGlobalAdvance() ) {
return; return;
} }
for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) { for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) {
if (directAdvanceAssignment.getReportGlobalAdvance()) { if ( directAdvanceAssignment.getReportGlobalAdvance() ) {
throw new DuplicateValueTrueReportGlobalAdvanceException( throw new DuplicateValueTrueReportGlobalAdvanceException(
_("Cannot spread two progress in the same task"), _("Cannot spread two progress in the same task"),
this, OrderElement.class); this, OrderElement.class);
@ -1022,14 +1013,14 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
public TaskElement getTaskElement() { public TaskElement getTaskElement() {
TaskSource taskSource = getTaskSource(); TaskSource taskSource = getTaskSource();
if (taskSource == null) { if ( taskSource == null ) {
return null; return null;
} }
return taskSource.getTask(); return taskSource.getTask();
} }
public Set<TaskElement> getTaskElements() { public Set<TaskElement> getTaskElements() {
if (getTaskSource() == null) { if ( getTaskSource() == null ) {
return Collections.emptySet(); return Collections.emptySet();
} }
return Collections.singleton(getTaskSource().getTask()); return Collections.singleton(getTaskSource().getTask());
@ -1053,8 +1044,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
return result; return result;
} }
private void schedulingDataForVersionFromBottomToTop( private void schedulingDataForVersionFromBottomToTop(List<SchedulingDataForVersion> result) {
List<SchedulingDataForVersion> result) {
for (OrderElement each : getChildren()) { for (OrderElement each : getChildren()) {
each.schedulingDataForVersionFromBottomToTop(result); each.schedulingDataForVersionFromBottomToTop(result);
} }
@ -1065,7 +1055,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
for (OrderElement each : getChildren()) { for (OrderElement each : getChildren()) {
each.taskSourcesFromBottomToTop(result); each.taskSourcesFromBottomToTop(result);
} }
if (getTaskSource() != null) { if ( getTaskSource() != null ) {
result.add(getTaskSource()); result.add(getTaskSource());
} }
} }
@ -1486,16 +1476,16 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
} }
public void setCodeAutogenerated(Boolean codeAutogenerated) { public void setCodeAutogenerated(Boolean codeAutogenerated) {
if (getOrder().equals(this)) { if ( getOrder().equals(this) ) {
super.setCodeAutogenerated(codeAutogenerated); super.setCodeAutogenerated(codeAutogenerated);
} }
} }
public Boolean isCodeAutogenerated() { public Boolean isCodeAutogenerated() {
if (getOrder().equals(this)) { if ( getOrder().equals(this) ) {
return super.isCodeAutogenerated(); return super.isCodeAutogenerated();
} }
return getOrder() != null ? getOrder().isCodeAutogenerated() : false; return (getOrder() != null) ? getOrder().isCodeAutogenerated() : false;
} }
@AssertTrue(message = "a quality form cannot be assigned twice to the same task") @AssertTrue(message = "a quality form cannot be assigned twice to the same task")
@ -1503,7 +1493,7 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
Set<QualityForm> qualityForms = new HashSet<QualityForm>(); Set<QualityForm> qualityForms = new HashSet<QualityForm>();
for (TaskQualityForm each : taskQualityForms) { for (TaskQualityForm each : taskQualityForms) {
QualityForm qualityForm = each.getQualityForm(); QualityForm qualityForm = each.getQualityForm();
if (qualityForms.contains(qualityForm)) { if ( qualityForms.contains(qualityForm) ) {
return false; return false;
} }
qualityForms.add(qualityForm); qualityForms.add(qualityForm);
@ -1511,11 +1501,9 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
return true; return true;
} }
public void removeDirectAdvancesInList( public void removeDirectAdvancesInList(Set<DirectAdvanceAssignment> directAdvanceAssignments) {
Set<DirectAdvanceAssignment> directAdvanceAssignments) {
for (DirectAdvanceAssignment each : directAdvanceAssignments) { for (DirectAdvanceAssignment each : directAdvanceAssignments) {
removeAdvanceAssignment(getAdvanceAssignmentByType(each removeAdvanceAssignment(getAdvanceAssignmentByType(each.getAdvanceType()));
.getAdvanceType()));
} }
for (OrderElement each : getChildren()) { for (OrderElement each : getChildren()) {
@ -1528,31 +1516,29 @@ public abstract class OrderElement extends IntegrationEntity implements ICriteri
result.addAll(directAdvanceAssignments); result.addAll(directAdvanceAssignments);
if (getParent() != null) { if ( getParent() != null ) {
result.addAll(getParent() result.addAll(getParent().getDirectAdvanceAssignmentsAndAllInAncest());
.getDirectAdvanceAssignmentsAndAllInAncest());
} }
return result; return result;
} }
protected void updateSpreadAdvance() { protected void updateSpreadAdvance() {
if (getReportGlobalAdvanceAssignment() == null) { if ( getReportGlobalAdvanceAssignment() == null ) {
// Set PERCENTAGE type as spread if any // Set PERCENTAGE type as spread if any
String type = PredefinedAdvancedTypes.PERCENTAGE.getTypeName(); String type = PredefinedAdvancedTypes.PERCENTAGE.getTypeName();
for (DirectAdvanceAssignment each : directAdvanceAssignments) { for (DirectAdvanceAssignment each : directAdvanceAssignments) {
if (each.getAdvanceType() != null if ( each.getAdvanceType() != null &&
&& each.getAdvanceType().getType() != null each.getAdvanceType().getType() != null &&
&& each.getAdvanceType().getType().equals(type)) { each.getAdvanceType().getType().equals(type) ) {
each.setReportGlobalAdvance(true); each.setReportGlobalAdvance(true);
return; return;
} }
} }
// Otherwise, set first advance assignment // Otherwise, set first advance assignment
if (!directAdvanceAssignments.isEmpty()) { if ( !directAdvanceAssignments.isEmpty() ) {
directAdvanceAssignments.iterator().next() directAdvanceAssignments.iterator().next().setReportGlobalAdvance(true);
.setReportGlobalAdvance(true);
return; return;
} }
} }

View file

@ -45,8 +45,7 @@ import org.libreplan.business.templates.entities.OrderLineTemplate;
public class OrderLine extends OrderElement { public class OrderLine extends OrderElement {
private HoursGroupOrderLineHandler hoursGroupOrderLineHandler = HoursGroupOrderLineHandler private HoursGroupOrderLineHandler hoursGroupOrderLineHandler = HoursGroupOrderLineHandler.getInstance();
.getInstance();
public static OrderLine create() { public static OrderLine create() {
OrderLine result = new OrderLine(); OrderLine result = new OrderLine();
@ -59,8 +58,7 @@ public class OrderLine extends OrderElement {
return orderLine; return orderLine;
} }
public static OrderLine createUnvalidatedWithUnfixedPercentage(String code, public static OrderLine createUnvalidatedWithUnfixedPercentage(String code, int hours) {
int hours) {
OrderLine orderLine = createOrderLineWithUnfixedPercentage(hours); OrderLine orderLine = createOrderLineWithUnfixedPercentage(hours);
return create(orderLine, code); return create(orderLine, code);
} }
@ -400,4 +398,8 @@ public class OrderLine extends OrderElement {
return convertedToContainer; return convertedToContainer;
} }
@Override
public void setParent(OrderLineGroup parent) {
super.setParent(parent);
}
} }

View file

@ -67,15 +67,12 @@ import org.libreplan.business.trees.ITreeParentNode;
* *
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
*/ */
public class OrderLineGroup extends OrderElement implements public class OrderLineGroup extends OrderElement implements ITreeParentNode<OrderElement> {
ITreeParentNode<OrderElement> {
private final class ChildrenManipulator extends private final class ChildrenManipulator extends TreeNodeOnListWithSchedulingState<OrderElement> {
TreeNodeOnListWithSchedulingState<OrderElement> {
private ChildrenManipulator(OrderLineGroup parent, private ChildrenManipulator(List<OrderElement> children) {
List<OrderElement> children) {
super(children); super(children);
} }
@ -91,9 +88,8 @@ public class OrderLineGroup extends OrderElement implements
@Override @Override
protected SchedulingState getSchedulingStateFrom(OrderElement node) { protected SchedulingState getSchedulingStateFrom(OrderElement node) {
if (!node.isSchedulingDataInitialized()) { if ( !node.isSchedulingDataInitialized() ) {
node.useSchedulingDataFor(getCurrentSchedulingData() node.useSchedulingDataFor(getCurrentSchedulingData().getOriginOrderVersion());
.getOriginOrderVersion());
} }
return node.getSchedulingState(); return node.getSchedulingState();
} }
@ -114,7 +110,7 @@ public class OrderLineGroup extends OrderElement implements
removeChildTask(removedChild); removeChildTask(removedChild);
} }
updateCriterionRequirements(); updateCriterionRequirements();
if (!removedChild.isNewObject()) { if ( !removedChild.isNewObject() ) {
getOrder().markAsNeededToRecalculateSumChargedEfforts(); getOrder().markAsNeededToRecalculateSumChargedEfforts();
getOrder().markAsNeededToRecalculateSumExpenses(); getOrder().markAsNeededToRecalculateSumExpenses();
} }
@ -123,8 +119,7 @@ public class OrderLineGroup extends OrderElement implements
private void removeChildTask(OrderElement removedChild) { private void removeChildTask(OrderElement removedChild) {
TaskSource taskSource = removedChild.getTaskSource(); TaskSource taskSource = removedChild.getTaskSource();
TaskElement childTask = taskSource.getTask(); TaskElement childTask = taskSource.getTask();
TaskGroup group = (TaskGroup) getThis().getTaskSource() TaskGroup group = (TaskGroup) getThis().getTaskSource().getTask();
.getTask();
group.remove(childTask); group.remove(childTask);
childTask.detachDependencies(); childTask.detachDependencies();
} }
@ -184,8 +179,7 @@ public class OrderLineGroup extends OrderElement implements
public void addChildrenAdvanceOrderLineGroup() { public void addChildrenAdvanceOrderLineGroup() {
boolean spread = (getReportGlobalAdvanceAssignment() == null); boolean spread = (getReportGlobalAdvanceAssignment() == null);
IndirectAdvanceAssignment indirectAdvanceAssignment = IndirectAdvanceAssignment IndirectAdvanceAssignment indirectAdvanceAssignment = IndirectAdvanceAssignment.create(spread);
.create(spread);
AdvanceType advanceType = PredefinedAdvancedTypes.CHILDREN.getType(); AdvanceType advanceType = PredefinedAdvancedTypes.CHILDREN.getType();
indirectAdvanceAssignment.setAdvanceType(advanceType); indirectAdvanceAssignment.setAdvanceType(advanceType);
indirectAdvanceAssignment.setOrderElement(this); indirectAdvanceAssignment.setOrderElement(this);
@ -194,8 +188,7 @@ public class OrderLineGroup extends OrderElement implements
public void removeChildrenAdvanceOrderLineGroup() { public void removeChildrenAdvanceOrderLineGroup() {
for (IndirectAdvanceAssignment advance : getIndirectAdvanceAssignments()) { for (IndirectAdvanceAssignment advance : getIndirectAdvanceAssignments()) {
if (advance.getAdvanceType().getUnitName().equals( if ( advance.getAdvanceType().getUnitName().equals(PredefinedAdvancedTypes.CHILDREN.getTypeName()) ) {
PredefinedAdvancedTypes.CHILDREN.getTypeName())) {
indirectAdvanceAssignments.remove(advance); indirectAdvanceAssignments.remove(advance);
updateSpreadAdvance(); updateSpreadAdvance();
} }
@ -204,22 +197,21 @@ public class OrderLineGroup extends OrderElement implements
@Override @Override
protected void updateSpreadAdvance() { protected void updateSpreadAdvance() {
if (getReportGlobalAdvanceAssignment() == null) { if ( getReportGlobalAdvanceAssignment() == null ) {
// Set CHILDREN type as spread if any // Set CHILDREN type as spread if any
String type = PredefinedAdvancedTypes.CHILDREN.getTypeName(); String type = PredefinedAdvancedTypes.CHILDREN.getTypeName();
for (IndirectAdvanceAssignment each : indirectAdvanceAssignments) { for (IndirectAdvanceAssignment each : indirectAdvanceAssignments) {
if (each.getAdvanceType() != null if ( each.getAdvanceType() != null &&
&& each.getAdvanceType().getType() != null each.getAdvanceType().getType() != null &&
&& each.getAdvanceType().getType().equals(type)) { each.getAdvanceType().getType().equals(type) ) {
each.setReportGlobalAdvance(true); each.setReportGlobalAdvance(true);
return; return;
} }
} }
// Otherwise, set first indirect advance assignment // Otherwise, set first indirect advance assignment
if (!indirectAdvanceAssignments.isEmpty()) { if ( !indirectAdvanceAssignments.isEmpty() ) {
indirectAdvanceAssignments.iterator().next() indirectAdvanceAssignments.iterator().next().setReportGlobalAdvance(true);
.setReportGlobalAdvance(true);
return; return;
} }
@ -289,46 +281,38 @@ public class OrderLineGroup extends OrderElement implements
} }
private void addIndirectAdvanceAssignments(OrderElement orderElement) { private void addIndirectAdvanceAssignments(OrderElement orderElement) {
orderElement orderElement.removeDirectAdvancesInList(getDirectAdvanceAssignmentsAndAllInAncest());
.removeDirectAdvancesInList(getDirectAdvanceAssignmentsAndAllInAncest());
for (DirectAdvanceAssignment directAdvanceAssignment : orderElement.directAdvanceAssignments) { for (DirectAdvanceAssignment directAdvanceAssignment : orderElement.directAdvanceAssignments) {
IndirectAdvanceAssignment indirectAdvanceAssignment = IndirectAdvanceAssignment IndirectAdvanceAssignment indirectAdvanceAssignment = IndirectAdvanceAssignment.create();
.create(); indirectAdvanceAssignment.setAdvanceType(directAdvanceAssignment.getAdvanceType());
indirectAdvanceAssignment.setAdvanceType(directAdvanceAssignment
.getAdvanceType());
indirectAdvanceAssignment.setOrderElement(this); indirectAdvanceAssignment.setOrderElement(this);
this.addIndirectAdvanceAssignment(indirectAdvanceAssignment); this.addIndirectAdvanceAssignment(indirectAdvanceAssignment);
} }
if (orderElement instanceof OrderLineGroup) { if ( orderElement instanceof OrderLineGroup ) {
for (IndirectAdvanceAssignment indirectAdvanceAssignment : ((OrderLineGroup) orderElement) for (IndirectAdvanceAssignment indirectAdvanceAssignment : orderElement.getIndirectAdvanceAssignments()) {
.getIndirectAdvanceAssignments()) {
this.addIndirectAdvanceAssignment(indirectAdvanceAssignment); this.addIndirectAdvanceAssignment(indirectAdvanceAssignment);
} }
} }
if (!indirectAdvanceAssignments.isEmpty()) { if ( !indirectAdvanceAssignments.isEmpty() ) {
addChildrenAdvanceOrderLineGroup(); addChildrenAdvanceOrderLineGroup();
} }
} }
private void removeIndirectAdvanceAssignments(OrderElement orderElement) { private void removeIndirectAdvanceAssignments(OrderElement orderElement) {
for (DirectAdvanceAssignment directAdvanceAssignment : orderElement.directAdvanceAssignments) { for (DirectAdvanceAssignment directAdvanceAssignment : orderElement.directAdvanceAssignments) {
this.removeIndirectAdvanceAssignment(directAdvanceAssignment this.removeIndirectAdvanceAssignment(directAdvanceAssignment.getAdvanceType());
.getAdvanceType());
} }
if (orderElement instanceof OrderLineGroup) { if (orderElement instanceof OrderLineGroup) {
for (IndirectAdvanceAssignment indirectAdvanceAssignment : ((OrderLineGroup) orderElement) for (IndirectAdvanceAssignment indirectAdvanceAssignment : orderElement.getIndirectAdvanceAssignments()) {
.getIndirectAdvanceAssignments()) { this.removeIndirectAdvanceAssignment(indirectAdvanceAssignment.getAdvanceType());
this.removeIndirectAdvanceAssignment(indirectAdvanceAssignment
.getAdvanceType());
} }
} }
if (children.isEmpty() && (indirectAdvanceAssignments.size() == 1) if ( children.isEmpty() && (indirectAdvanceAssignments.size() == 1) && existChildrenAdvance() ) {
&& existChildrenAdvance()) {
removeChildrenAdvanceOrderLineGroup(); removeChildrenAdvanceOrderLineGroup();
} }
} }
@ -339,7 +323,7 @@ public class OrderLineGroup extends OrderElement implements
} }
private ChildrenManipulator getManipulator() { private ChildrenManipulator getManipulator() {
return new ChildrenManipulator(this, children); return new ChildrenManipulator(children);
} }
@Override @Override
@ -369,8 +353,8 @@ public class OrderLineGroup extends OrderElement implements
return result; return result;
} }
private static Set<DirectAdvanceAssignment> copyDirectAdvanceAssignments( private static Set<DirectAdvanceAssignment> copyDirectAdvanceAssignments(OrderElement origin,
OrderElement origin, OrderElement destination) { OrderElement destination) {
Set<DirectAdvanceAssignment> result = new HashSet<DirectAdvanceAssignment>(); Set<DirectAdvanceAssignment> result = new HashSet<DirectAdvanceAssignment>();
for (DirectAdvanceAssignment each : origin.directAdvanceAssignments) { for (DirectAdvanceAssignment each : origin.directAdvanceAssignments) {
result.add(DirectAdvanceAssignment.copy(each, destination)); result.add(DirectAdvanceAssignment.copy(each, destination));
@ -378,8 +362,7 @@ public class OrderLineGroup extends OrderElement implements
return result; return result;
} }
private static Set<MaterialAssignment> copyMaterialAssignments( private static Set<MaterialAssignment> copyMaterialAssignments(OrderElement origin, OrderElement destination) {
OrderElement origin, OrderElement destination) {
Set<MaterialAssignment> result = new HashSet<MaterialAssignment>(); Set<MaterialAssignment> result = new HashSet<MaterialAssignment>();
for (MaterialAssignment each : origin.materialAssignments) { for (MaterialAssignment each : origin.materialAssignments) {
result.add(MaterialAssignment.copy(each, destination)); result.add(MaterialAssignment.copy(each, destination));
@ -387,8 +370,7 @@ public class OrderLineGroup extends OrderElement implements
return result; return result;
} }
private static Set<Label> copyLabels( private static Set<Label> copyLabels(OrderElement origin, OrderElement destination) {
OrderElement origin, OrderElement destination) {
Set<Label> result = new HashSet<Label>(); Set<Label> result = new HashSet<Label>();
for (Label each : origin.labels) { for (Label each : origin.labels) {
destination.addLabel(each); destination.addLabel(each);
@ -397,8 +379,7 @@ public class OrderLineGroup extends OrderElement implements
return result; return result;
} }
private static Set<TaskQualityForm> copyTaskQualityForms( private static Set<TaskQualityForm> copyTaskQualityForms(OrderElement origin, OrderElement destination) {
OrderElement origin, OrderElement destination) {
Set<TaskQualityForm> result = new HashSet<TaskQualityForm>(); Set<TaskQualityForm> result = new HashSet<TaskQualityForm>();
for (TaskQualityForm each : origin.taskQualityForms) { for (TaskQualityForm each : origin.taskQualityForms) {
result.add(TaskQualityForm.copy(each, destination)); result.add(TaskQualityForm.copy(each, destination));
@ -451,8 +432,8 @@ public class OrderLineGroup extends OrderElement implements
@Override @Override
public BigDecimal getAdvancePercentage(LocalDate date) { public BigDecimal getAdvancePercentage(LocalDate date) {
for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) { for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) {
if (directAdvanceAssignment.getReportGlobalAdvance()) { if ( directAdvanceAssignment.getReportGlobalAdvance() ) {
if (date == null) { if ( date == null ) {
return directAdvanceAssignment.getAdvancePercentage(); return directAdvanceAssignment.getAdvancePercentage();
} }
return directAdvanceAssignment.getAdvancePercentage(date); return directAdvanceAssignment.getAdvancePercentage(date);
@ -460,16 +441,20 @@ public class OrderLineGroup extends OrderElement implements
} }
for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) { for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) {
if (indirectAdvanceAssignment.getReportGlobalAdvance()) { if ( indirectAdvanceAssignment.getReportGlobalAdvance() ) {
if (indirectAdvanceAssignment.getAdvanceType().getUnitName()
.equals(PredefinedAdvancedTypes.CHILDREN.getTypeName())) { if ( indirectAdvanceAssignment.getAdvanceType().getUnitName().equals(
if (date == null) { PredefinedAdvancedTypes.CHILDREN.getTypeName()) ) {
if ( date == null ) {
return getAdvancePercentageChildren(); return getAdvancePercentageChildren();
} }
return getAdvancePercentageChildren(date); return getAdvancePercentageChildren(date);
} else { } else {
DirectAdvanceAssignment directAdvanceAssignment = calculateFakeDirectAdvanceAssignment(indirectAdvanceAssignment); DirectAdvanceAssignment directAdvanceAssignment =
if (date == null) { calculateFakeDirectAdvanceAssignment(indirectAdvanceAssignment);
if ( date == null ) {
return directAdvanceAssignment.getAdvancePercentage(); return directAdvanceAssignment.getAdvancePercentage();
} }
return directAdvanceAssignment.getAdvancePercentage(date); return directAdvanceAssignment.getAdvancePercentage(date);
@ -489,20 +474,18 @@ public class OrderLineGroup extends OrderElement implements
Integer hours = getWorkHours(); Integer hours = getWorkHours();
BigDecimal result = new BigDecimal(0); BigDecimal result = new BigDecimal(0);
if (hours > 0) { if ( hours > 0 ) {
for (OrderElement orderElement : children) { for (OrderElement orderElement : children) {
BigDecimal childPercentage; BigDecimal childPercentage;
if (date == null) { if ( date == null ) {
childPercentage = orderElement.getAdvancePercentage(); childPercentage = orderElement.getAdvancePercentage();
} else { } else {
childPercentage = orderElement.getAdvancePercentage(date); childPercentage = orderElement.getAdvancePercentage(date);
} }
Integer childHours = orderElement.getWorkHours(); Integer childHours = orderElement.getWorkHours();
result = result.add(childPercentage.multiply(new BigDecimal( result = result.add(childPercentage.multiply(new BigDecimal(childHours)));
childHours)));
} }
result = result.divide(new BigDecimal(hours).setScale(2), 4, result = result.divide(new BigDecimal(hours).setScale(2), 4, RoundingMode.DOWN);
RoundingMode.DOWN);
} }
@ -512,52 +495,47 @@ public class OrderLineGroup extends OrderElement implements
@Override @Override
public DirectAdvanceAssignment calculateFakeDirectAdvanceAssignment( public DirectAdvanceAssignment calculateFakeDirectAdvanceAssignment(
IndirectAdvanceAssignment indirectAdvanceAssignment) { IndirectAdvanceAssignment indirectAdvanceAssignment) {
if (indirectAdvanceAssignment.getAdvanceType().getUnitName().equals(
PredefinedAdvancedTypes.CHILDREN.getTypeName())) { if ( indirectAdvanceAssignment.getAdvanceType().getUnitName().equals(
PredefinedAdvancedTypes.CHILDREN.getTypeName()) ) {
return calculateFakeDirectAdvanceAssignmentChildren(indirectAdvanceAssignment); return calculateFakeDirectAdvanceAssignmentChildren(indirectAdvanceAssignment);
} else { } else {
Set<DirectAdvanceAssignment> directAdvanceAssignments = getAllDirectAdvanceAssignments(indirectAdvanceAssignment Set<DirectAdvanceAssignment> directAdvanceAssignments =
.getAdvanceType()); getAllDirectAdvanceAssignments(indirectAdvanceAssignment.getAdvanceType());
return mergeAdvanceAssignments(new ArrayList<DirectAdvanceAssignment>(
directAdvanceAssignments)); return mergeAdvanceAssignments(new ArrayList<DirectAdvanceAssignment>(directAdvanceAssignments));
} }
} }
private DirectAdvanceAssignment calculateFakeDirectAdvanceAssignmentChildren( private DirectAdvanceAssignment calculateFakeDirectAdvanceAssignmentChildren(
IndirectAdvanceAssignment indirectAdvanceAssignment) { IndirectAdvanceAssignment indirectAdvanceAssignment) {
DirectAdvanceAssignment newDirectAdvanceAssignment = DirectAdvanceAssignment
.create(); DirectAdvanceAssignment newDirectAdvanceAssignment = DirectAdvanceAssignment.create();
newDirectAdvanceAssignment.setFake(true); newDirectAdvanceAssignment.setFake(true);
newDirectAdvanceAssignment.setMaxValue(new BigDecimal(100)); newDirectAdvanceAssignment.setMaxValue(new BigDecimal(100));
newDirectAdvanceAssignment.setAdvanceType(indirectAdvanceAssignment newDirectAdvanceAssignment.setAdvanceType(indirectAdvanceAssignment.getAdvanceType());
.getAdvanceType());
newDirectAdvanceAssignment.setOrderElement(this); newDirectAdvanceAssignment.setOrderElement(this);
Set<DirectAdvanceAssignment> directAdvanceAssignments = new HashSet<DirectAdvanceAssignment>(); Set<DirectAdvanceAssignment> directAdvanceAssignments = new HashSet<DirectAdvanceAssignment>();
for (OrderElement orderElement : children) { for (OrderElement orderElement : children) {
directAdvanceAssignments.addAll(orderElement directAdvanceAssignments.addAll(orderElement.getAllDirectAdvanceAssignmentsReportGlobal());
.getAllDirectAdvanceAssignmentsReportGlobal());
} }
List<AdvanceMeasurement> advanceMeasurements = new ArrayList<AdvanceMeasurement>(); List<AdvanceMeasurement> advanceMeasurements = new ArrayList<AdvanceMeasurement>();
for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) { for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) {
advanceMeasurements.addAll(directAdvanceAssignment advanceMeasurements.addAll(directAdvanceAssignment.getAdvanceMeasurements());
.getAdvanceMeasurements());
} }
List<LocalDate> measurementDates = getMeasurementDates(advanceMeasurements); List<LocalDate> measurementDates = getMeasurementDates(advanceMeasurements);
SortedSet<AdvanceMeasurement> newAdvanceMeasurements = new TreeSet<AdvanceMeasurement>( SortedSet<AdvanceMeasurement> newAdvanceMeasurements = new TreeSet<AdvanceMeasurement>(new AdvanceMeasurementComparator());
new AdvanceMeasurementComparator());
for (LocalDate localDate : measurementDates) { for (LocalDate localDate : measurementDates) {
BigDecimal value = getAdvancePercentageChildren(localDate) BigDecimal value = getAdvancePercentageChildren(localDate).multiply(new BigDecimal(100));
.multiply(new BigDecimal(100)); AdvanceMeasurement advanceMeasurement = AdvanceMeasurement.create(localDate, value);
AdvanceMeasurement advanceMeasurement = AdvanceMeasurement.create(
localDate, value);
advanceMeasurement.setAdvanceAssignment(newDirectAdvanceAssignment); advanceMeasurement.setAdvanceAssignment(newDirectAdvanceAssignment);
newAdvanceMeasurements.add(advanceMeasurement); newAdvanceMeasurements.add(advanceMeasurement);
} }
newDirectAdvanceAssignment newDirectAdvanceAssignment.setAdvanceMeasurements(newAdvanceMeasurements);
.setAdvanceMeasurements(newAdvanceMeasurements);
return newDirectAdvanceAssignment; return newDirectAdvanceAssignment;
} }
@ -847,49 +825,42 @@ public class OrderLineGroup extends OrderElement implements
} }
@Override @Override
public Set<DirectAdvanceAssignment> getAllDirectAdvanceAssignments( public Set<DirectAdvanceAssignment> getAllDirectAdvanceAssignments(AdvanceType advanceType) {
AdvanceType advanceType) {
Set<DirectAdvanceAssignment> result = new HashSet<DirectAdvanceAssignment>(); Set<DirectAdvanceAssignment> result = new HashSet<DirectAdvanceAssignment>();
for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) { for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) {
if (directAdvanceAssignment.getAdvanceType().getUnitName().equals(advanceType.getUnitName())) { if ( directAdvanceAssignment.getAdvanceType().getUnitName().equals(advanceType.getUnitName()) ) {
result.add(directAdvanceAssignment); result.add(directAdvanceAssignment);
return result; return result;
} }
} }
for (OrderElement orderElement : children) { for (OrderElement orderElement : children) {
result result.addAll(orderElement.getAllDirectAdvanceAssignments(advanceType));
.addAll(orderElement
.getAllDirectAdvanceAssignments(advanceType));
} }
return result; return result;
} }
@Override @Override
public Set<IndirectAdvanceAssignment> getAllIndirectAdvanceAssignments( public Set<IndirectAdvanceAssignment> getAllIndirectAdvanceAssignments(AdvanceType advanceType) {
AdvanceType advanceType) {
Set<IndirectAdvanceAssignment> result = new HashSet<IndirectAdvanceAssignment>(); Set<IndirectAdvanceAssignment> result = new HashSet<IndirectAdvanceAssignment>();
IndirectAdvanceAssignment indirectAdvanceAssignment = getIndirectAdvanceAssignment(advanceType); IndirectAdvanceAssignment indirectAdvanceAssignment = getIndirectAdvanceAssignment(advanceType);
if(indirectAdvanceAssignment != null){ if( indirectAdvanceAssignment != null ){
result.add(indirectAdvanceAssignment); result.add(indirectAdvanceAssignment);
} }
for (OrderElement orderElement : children) { for (OrderElement orderElement : children) {
result.addAll(orderElement result.addAll(orderElement.getAllIndirectAdvanceAssignments(advanceType));
.getAllIndirectAdvanceAssignments(advanceType));
} }
return result; return result;
} }
public IndirectAdvanceAssignment getIndirectAdvanceAssignment( public IndirectAdvanceAssignment getIndirectAdvanceAssignment(AdvanceType advanceType) {
AdvanceType advanceType) {
for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) { for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) {
if (indirectAdvanceAssignment.getAdvanceType().getUnitName() if ( indirectAdvanceAssignment.getAdvanceType().getUnitName().equals(advanceType.getUnitName()) ) {
.equals(advanceType.getUnitName())) {
return indirectAdvanceAssignment; return indirectAdvanceAssignment;
} }
} }
@ -901,14 +872,13 @@ public class OrderLineGroup extends OrderElement implements
Set<DirectAdvanceAssignment> result = new HashSet<DirectAdvanceAssignment>(); Set<DirectAdvanceAssignment> result = new HashSet<DirectAdvanceAssignment>();
for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) { for (DirectAdvanceAssignment directAdvanceAssignment : directAdvanceAssignments) {
if (directAdvanceAssignment.getReportGlobalAdvance()) { if ( directAdvanceAssignment.getReportGlobalAdvance() ) {
result.add(directAdvanceAssignment); result.add(directAdvanceAssignment);
} }
} }
for (OrderElement orderElement : children) { for (OrderElement orderElement : children) {
result.addAll(orderElement result.addAll(orderElement.getAllDirectAdvanceAssignmentsReportGlobal());
.getAllDirectAdvanceAssignmentsReportGlobal());
} }
return result; return result;
@ -932,43 +902,38 @@ public class OrderLineGroup extends OrderElement implements
return Collections.unmodifiableSet(indirectAdvanceAssignments); return Collections.unmodifiableSet(indirectAdvanceAssignments);
} }
public void addIndirectAdvanceAssignment( public void addIndirectAdvanceAssignment(IndirectAdvanceAssignment indirectAdvanceAssignment) {
IndirectAdvanceAssignment indirectAdvanceAssignment) {
if ((!existsIndirectAdvanceAssignmentWithTheSameType(indirectAdvanceAssignment if ( (!existsIndirectAdvanceAssignmentWithTheSameType(indirectAdvanceAssignment.getAdvanceType())) &&
.getAdvanceType())) (!existsDirectAdvanceAssignmentWithTheSameType(indirectAdvanceAssignment.getAdvanceType())) ) {
&& (!existsDirectAdvanceAssignmentWithTheSameType(indirectAdvanceAssignment
.getAdvanceType()))) {
indirectAdvanceAssignments.add(indirectAdvanceAssignment); indirectAdvanceAssignments.add(indirectAdvanceAssignment);
} }
if (parent != null) { if ( parent != null ) {
parent.addIndirectAdvanceAssignment(indirectAdvanceAssignment parent.addIndirectAdvanceAssignment(indirectAdvanceAssignment.createIndirectAdvanceFor(parent));
.createIndirectAdvanceFor(parent));
} }
} }
public void removeIndirectAdvanceAssignment(AdvanceType advanceType) { public void removeIndirectAdvanceAssignment(AdvanceType advanceType) {
DirectAdvanceAssignment tempAdavanceAssignmet = DirectAdvanceAssignment DirectAdvanceAssignment tempAdavanceAssignmet = DirectAdvanceAssignment.create();
.create();
tempAdavanceAssignmet.setAdvanceType(advanceType); tempAdavanceAssignmet.setAdvanceType(advanceType);
try { try {
checkChildrenNoOtherAssignmentWithSameAdvanceType(this, checkChildrenNoOtherAssignmentWithSameAdvanceType(this, tempAdavanceAssignmet);
tempAdavanceAssignmet);
String unitName = advanceType.getUnitName(); String unitName = advanceType.getUnitName();
IndirectAdvanceAssignment toRemove = null; IndirectAdvanceAssignment toRemove = null;
for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) { for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) {
if (unitName.equals(indirectAdvanceAssignment.getAdvanceType() if ( unitName.equals(indirectAdvanceAssignment.getAdvanceType().getUnitName()) ) {
.getUnitName())) {
toRemove = indirectAdvanceAssignment; toRemove = indirectAdvanceAssignment;
} }
} }
if (toRemove != null) { if ( toRemove != null ) {
indirectAdvanceAssignments.remove(toRemove); indirectAdvanceAssignments.remove(toRemove);
updateSpreadAdvance(); updateSpreadAdvance();
} }
if (parent != null) { if ( parent != null ) {
parent.removeIndirectAdvanceAssignment(advanceType); parent.removeIndirectAdvanceAssignment(advanceType);
} }
} catch (DuplicateAdvanceAssignmentForOrderElementException e) { } catch (DuplicateAdvanceAssignmentForOrderElementException e) {
@ -978,12 +943,10 @@ public class OrderLineGroup extends OrderElement implements
} }
} }
public boolean existsIndirectAdvanceAssignmentWithTheSameType( public boolean existsIndirectAdvanceAssignmentWithTheSameType(AdvanceType type) {
AdvanceType type) {
String unitName = type.getUnitName(); String unitName = type.getUnitName();
for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) { for (IndirectAdvanceAssignment indirectAdvanceAssignment : indirectAdvanceAssignments) {
if (unitName.equals(indirectAdvanceAssignment.getAdvanceType() if ( unitName.equals(indirectAdvanceAssignment.getAdvanceType().getUnitName()) ) {
.getUnitName())) {
return true; return true;
} }
} }
@ -991,17 +954,17 @@ public class OrderLineGroup extends OrderElement implements
} }
@Override @Override
protected void checkNoOtherGlobalAdvanceAssignment( protected void checkNoOtherGlobalAdvanceAssignment(DirectAdvanceAssignment newAdvanceAssignment)
DirectAdvanceAssignment newAdvanceAssignment)
throws DuplicateValueTrueReportGlobalAdvanceException { throws DuplicateValueTrueReportGlobalAdvanceException {
if (!newAdvanceAssignment.getReportGlobalAdvance()) {
if ( !newAdvanceAssignment.getReportGlobalAdvance() ) {
return; return;
} }
Set<AdvanceAssignment> advanceAssignments = new HashSet<AdvanceAssignment>(); Set<AdvanceAssignment> advanceAssignments = new HashSet<AdvanceAssignment>();
advanceAssignments.addAll(directAdvanceAssignments); advanceAssignments.addAll(directAdvanceAssignments);
advanceAssignments.addAll(indirectAdvanceAssignments); advanceAssignments.addAll(indirectAdvanceAssignments);
for (AdvanceAssignment advanceAssignment : advanceAssignments) { for (AdvanceAssignment advanceAssignment : advanceAssignments) {
if (advanceAssignment.getReportGlobalAdvance()) { if ( advanceAssignment.getReportGlobalAdvance() ) {
throw new DuplicateValueTrueReportGlobalAdvanceException( throw new DuplicateValueTrueReportGlobalAdvanceException(
_("Cannot spread two progress in the same task"), _("Cannot spread two progress in the same task"),
this, OrderElement.class); this, OrderElement.class);

View file

@ -39,10 +39,8 @@ public class SchedulingDataForVersion extends BaseEntity {
public static class Data { public static class Data {
private static Data from(SchedulingDataForVersion version, private static Data from(SchedulingDataForVersion version, OrderVersion orderVersion) {
OrderVersion orderVersion) { return new Data(orderVersion, version, version.getTaskSource(), version.getSchedulingStateType());
return new Data(orderVersion, version, version
.getTaskSource(), version.getSchedulingStateType());
} }
private SchedulingDataForVersion originVersion; private SchedulingDataForVersion originVersion;
@ -58,9 +56,10 @@ public class SchedulingDataForVersion extends BaseEntity {
private final Type initialSchedulingStateType; private final Type initialSchedulingStateType;
private Data(OrderVersion orderVersion, private Data(OrderVersion orderVersion,
SchedulingDataForVersion version, SchedulingDataForVersion version,
TaskSource taskSource, TaskSource taskSource,
Type schedulingStateType) { Type schedulingStateType) {
Validate.notNull(schedulingStateType); Validate.notNull(schedulingStateType);
this.originOrderVersion = orderVersion; this.originOrderVersion = orderVersion;
this.originVersion = version; this.originVersion = version;
@ -77,8 +76,7 @@ public class SchedulingDataForVersion extends BaseEntity {
return schedulingStateType; return schedulingStateType;
} }
private void setSchedulingStateType( private void setSchedulingStateType(SchedulingState.Type schedulingStateType) {
SchedulingState.Type schedulingStateType) {
this.schedulingStateType = schedulingStateType; this.schedulingStateType = schedulingStateType;
hasPendingChanges = true; hasPendingChanges = true;
} }
@ -109,14 +107,12 @@ public class SchedulingDataForVersion extends BaseEntity {
} }
public void requestedCreationOf(TaskSource taskSource) { public void requestedCreationOf(TaskSource taskSource) {
Validate.isTrue(this.getTaskSource() == null, Validate.isTrue(this.getTaskSource() == null, "there must be no task source");
"there must be no task source");
this.setTaskSource(taskSource); this.setTaskSource(taskSource);
} }
public void replaceCurrentTaskSourceWith(TaskSource newTaskSource) { public void replaceCurrentTaskSourceWith(TaskSource newTaskSource) {
Validate.isTrue(this.getTaskSource() != null, Validate.isTrue(this.getTaskSource() != null, "there must be a task source to replace");
"there must be a task source to replace");
this.setTaskSource(newTaskSource); this.setTaskSource(newTaskSource);
} }
@ -162,8 +158,7 @@ public class SchedulingDataForVersion extends BaseEntity {
} }
private static Type defaultTypeFor(OrderElement orderElement) { private static Type defaultTypeFor(OrderElement orderElement) {
return orderElement.isLeaf() ? Type.SCHEDULING_POINT return orderElement.isLeaf() ? Type.SCHEDULING_POINT : Type.NO_SCHEDULED;
: Type.NO_SCHEDULED;
} }
@NotNull @NotNull
@ -193,7 +188,8 @@ public class SchedulingDataForVersion extends BaseEntity {
void removeSpuriousDayAssignments(Scenario scenario) { void removeSpuriousDayAssignments(Scenario scenario) {
TaskSource taskSource = getTaskSource(); TaskSource taskSource = getTaskSource();
if (taskSource != null) {
if ( taskSource != null ) {
TaskElement task = taskSource.getTask(); TaskElement task = taskSource.getTask();
task.removeDayAssignmentsFor(scenario); task.removeDayAssignmentsFor(scenario);
} }

View file

@ -74,7 +74,7 @@ public abstract class TreeNodeOnListWithSchedulingState<T extends ITreeNode<T>>
protected void removeFromPreviousSchedulingState(T node) { protected void removeFromPreviousSchedulingState(T node) {
SchedulingState schedulingState = getSchedulingStateFrom(node); SchedulingState schedulingState = getSchedulingStateFrom(node);
if (!schedulingState.isRoot()) { if ( !schedulingState.isRoot() ) {
schedulingState.getParent().removeChild(schedulingState); schedulingState.getParent().removeChild(schedulingState);
} }
} }

View file

@ -68,8 +68,7 @@ public class AssignedEffortForResource {
* @return A {@link IAssignedEffortForResource} that calculates the load * @return A {@link IAssignedEffortForResource} that calculates the load
* associated for all allocations but the provided ones. * associated for all allocations but the provided ones.
*/ */
public static IAssignedEffortForResource effortDiscounting( public static IAssignedEffortForResource effortDiscounting(Collection<? extends BaseEntity> allocations) {
Collection<? extends BaseEntity> allocations) {
return new AssignedEffortDiscounting(allocations); return new AssignedEffortDiscounting(allocations);
} }

View file

@ -51,10 +51,11 @@ public class CompanyEarnedValueCalculator extends EarnedValueCalculator implemen
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkScheduled(AvailabilityTimeLine.Interval interval) { public SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkScheduled(AvailabilityTimeLine.Interval interval) {
Map<TaskElement, SortedMap<LocalDate, BigDecimal>> estimatedCostPerTask = databaseSnapshots
.snapshotEstimatedCostPerTask(); Map<TaskElement, SortedMap<LocalDate, BigDecimal>> estimatedCostPerTask =
Collection<TaskElement> list = filterTasksByDate( databaseSnapshots.snapshotEstimatedCostPerTask();
estimatedCostPerTask.keySet(), interval);
Collection<TaskElement> list = filterTasksByDate(estimatedCostPerTask.keySet(), interval);
SortedMap<LocalDate, BigDecimal> estimatedCost = new TreeMap<LocalDate, BigDecimal>(); SortedMap<LocalDate, BigDecimal> estimatedCost = new TreeMap<LocalDate, BigDecimal>();
for (TaskElement each : list) { for (TaskElement each : list) {
@ -63,25 +64,21 @@ public class CompanyEarnedValueCalculator extends EarnedValueCalculator implemen
return accumulateResult(estimatedCost); return accumulateResult(estimatedCost);
} }
private List<TaskElement> filterTasksByDate( private List<TaskElement> filterTasksByDate(Collection<TaskElement> tasks, AvailabilityTimeLine.Interval interval) {
Collection<TaskElement> tasks,
AvailabilityTimeLine.Interval interval) {
List<TaskElement> result = new ArrayList<TaskElement>(); List<TaskElement> result = new ArrayList<TaskElement>();
for(TaskElement task : tasks) { for(TaskElement task : tasks) {
if (interval.includes(task.getStartAsLocalDate()) if ( interval.includes(task.getStartAsLocalDate()) || interval.includes(task.getEndAsLocalDate()) ) {
|| interval.includes(task.getEndAsLocalDate())) {
result.add(task); result.add(task);
} }
} }
return result; return result;
} }
private List<WorkReportLine> filterWorkReportLinesByDate( private List<WorkReportLine> filterWorkReportLinesByDate(Collection<WorkReportLine> lines,
Collection<WorkReportLine> lines, AvailabilityTimeLine.Interval interval) {
AvailabilityTimeLine.Interval interval) {
List<WorkReportLine> result = new ArrayList<WorkReportLine>(); List<WorkReportLine> result = new ArrayList<WorkReportLine>();
for(WorkReportLine line: lines) { for(WorkReportLine line: lines) {
if (interval.includes(line.getLocalDate())) { if ( interval.includes(line.getLocalDate()) ) {
result.add(line); result.add(line);
} }
} }
@ -89,13 +86,13 @@ public class CompanyEarnedValueCalculator extends EarnedValueCalculator implemen
} }
private void addCost(SortedMap<LocalDate, BigDecimal> currentCost, private void addCost(SortedMap<LocalDate, BigDecimal> currentCost,
SortedMap<LocalDate, BigDecimal> additionalCost) { SortedMap<LocalDate, BigDecimal> additionalCost) {
for (LocalDate day : additionalCost.keySet()) { for (LocalDate day : additionalCost.keySet()) {
if (!currentCost.containsKey(day)) { if ( !currentCost.containsKey(day) ) {
currentCost.put(day, BigDecimal.ZERO); currentCost.put(day, BigDecimal.ZERO);
} }
currentCost.put(day, currentCost.get(day).add( currentCost.put(day, currentCost.get(day).add(additionalCost.get(day)));
additionalCost.get(day)));
} }
} }

View file

@ -73,10 +73,11 @@ public class GenericResourceAllocation extends
public static Map<Set<Criterion>, List<GenericResourceAllocation>> byCriterions( public static Map<Set<Criterion>, List<GenericResourceAllocation>> byCriterions(
Collection<GenericResourceAllocation> genericAllocations) { Collection<GenericResourceAllocation> genericAllocations) {
Map<Set<Criterion>, List<GenericResourceAllocation>> result = new HashMap<Set<Criterion>, List<GenericResourceAllocation>>(); Map<Set<Criterion>, List<GenericResourceAllocation>> result = new HashMap<Set<Criterion>, List<GenericResourceAllocation>>();
for (GenericResourceAllocation genericResourceAllocation : genericAllocations) { for (GenericResourceAllocation genericResourceAllocation : genericAllocations) {
Set<Criterion> criterions = genericResourceAllocation.getCriterions(); Set<Criterion> criterions = genericResourceAllocation.getCriterions();
if(! result.containsKey(criterions)){ if( !result.containsKey(criterions) ){
result.put(criterions, new ArrayList<GenericResourceAllocation>()); result.put(criterions, new ArrayList<GenericResourceAllocation>());
} }
result.get(criterions).add(genericResourceAllocation); result.get(criterions).add(genericResourceAllocation);
@ -128,8 +129,8 @@ public class GenericResourceAllocation extends
return first.getType().getResource(); return first.getType().getResource();
} }
public static GenericResourceAllocation create(Task task, public static GenericResourceAllocation create(Task task, ResourceEnum resourceType,
ResourceEnum resourceType, Collection<? extends Criterion> criterions) { Collection<? extends Criterion> criterions) {
Validate.notNull(resourceType); Validate.notNull(resourceType);
GenericResourceAllocation result = new GenericResourceAllocation(task); GenericResourceAllocation result = new GenericResourceAllocation(task);
result.criterions = new HashSet<Criterion>(criterions); result.criterions = new HashSet<Criterion>(criterions);
@ -208,8 +209,7 @@ public class GenericResourceAllocation extends
public GenericAllocation(List<Resource> resources) { public GenericAllocation(List<Resource> resources) {
this.resources = resources; this.resources = resources;
hoursDistributor = new EffortDistributor(resources, hoursDistributor = new EffortDistributor(resources, getAssignedEffortForResource(),
getAssignedEffortForResource(),
new ResourcesSatisfyingCriterionsSelector()); new ResourcesSatisfyingCriterionsSelector());
} }
@ -227,8 +227,7 @@ public class GenericResourceAllocation extends
@Override @Override
protected AvailabilityTimeLine getResourcesAvailability() { protected AvailabilityTimeLine getResourcesAvailability() {
return AvailabilityCalculator.buildSumOfAvailabilitiesFor( return AvailabilityCalculator.buildSumOfAvailabilitiesFor(getCriterions(), resources);
getCriterions(), resources);
} }
@Override @Override

View file

@ -24,10 +24,14 @@ package org.libreplan.business.planner.entities;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.List; import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.Date;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.libreplan.business.advance.entities.AdvanceMeasurement; import org.libreplan.business.advance.entities.AdvanceMeasurement;
@ -44,6 +48,7 @@ import org.springframework.stereotype.Component;
* Cost calulator in terms of hours. * Cost calulator in terms of hours.
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
@Component @Component
@Scope(BeanDefinition.SCOPE_SINGLETON) @Scope(BeanDefinition.SCOPE_SINGLETON)
@ -58,16 +63,17 @@ public class HoursCostCalculator implements ICostCalculator {
} }
@Override @Override
public SortedMap<LocalDate, BigDecimal> getAdvanceCost(Task task, public SortedMap<LocalDate, BigDecimal> getAdvanceCost(Task task, LocalDate filterStartDate,
LocalDate filterStartDate, LocalDate filterEndDate) { LocalDate filterEndDate) {
DirectAdvanceAssignment advanceAssignment = (task.getOrderElement() != null) ? task DirectAdvanceAssignment advanceAssignment =
.getOrderElement().getReportGlobalAdvanceAssignment() : null; (task.getOrderElement() != null) ? task.getOrderElement().getReportGlobalAdvanceAssignment() : null;
if (advanceAssignment == null) { if ( advanceAssignment == null ) {
return new TreeMap<LocalDate, BigDecimal>(); return new TreeMap<LocalDate, BigDecimal>();
} }
return calculateHoursPerDay(task.getHoursSpecifiedAtOrder(), return calculateHoursPerDay(
task.getHoursSpecifiedAtOrder(),
advanceAssignment.getAdvanceMeasurements(), advanceAssignment.getAdvanceMeasurements(),
filterStartDate, filterEndDate); filterStartDate, filterEndDate);
} }
@ -76,16 +82,17 @@ public class HoursCostCalculator implements ICostCalculator {
Integer totalHours, Integer totalHours,
SortedSet<AdvanceMeasurement> advanceMeasurements, SortedSet<AdvanceMeasurement> advanceMeasurements,
LocalDate filterStartDate, LocalDate filterEndDate) { LocalDate filterStartDate, LocalDate filterEndDate) {
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>(); SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
for (AdvanceMeasurement advanceMeasurement : advanceMeasurements) { for (AdvanceMeasurement advanceMeasurement : advanceMeasurements) {
LocalDate day = advanceMeasurement.getDate(); LocalDate day = advanceMeasurement.getDate();
if(((filterStartDate == null) || day.compareTo(filterStartDate) >= 0) && if( ((filterStartDate == null) || day.compareTo(filterStartDate) >= 0) &&
((filterEndDate == null) || day.compareTo(filterEndDate) <= 0)) { ((filterEndDate == null) || day.compareTo(filterEndDate) <= 0) ) {
BigDecimal cost = advanceMeasurement.getValue().setScale(2) BigDecimal cost = advanceMeasurement.getValue().setScale(2)
.multiply(new BigDecimal(totalHours)) .multiply(new BigDecimal(totalHours))
.divide(new BigDecimal(100), .divide(new BigDecimal(100), new MathContext(2, RoundingMode.HALF_UP));
new MathContext(2, RoundingMode.HALF_UP));
result.put(day, cost); result.put(day, cost);
} }
} }
@ -98,37 +105,101 @@ public class HoursCostCalculator implements ICostCalculator {
return getEstimatedCost(task, null, null); return getEstimatedCost(task, null, null);
} }
/**
* BCWS values are calculating here.
* MAX(BCWS) equals addition of all dayAssignments.
*/
@Override @Override
public SortedMap<LocalDate, BigDecimal> getEstimatedCost(Task task, public SortedMap<LocalDate, BigDecimal> getEstimatedCost(
LocalDate filterStartDate, LocalDate filterEndDate) { Task task,
if (task.isSubcontracted()) { LocalDate filterStartDate,
LocalDate filterEndDate) {
if ( task.isSubcontracted() ) {
return getAdvanceCost(task); return getAdvanceCost(task);
} }
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>(); SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
List<DayAssignment> dayAssignments = task List<DayAssignment> dayAssignments = task.getDayAssignments(FilterType.WITHOUT_DERIVED);
.getDayAssignments(FilterType.WITHOUT_DERIVED); if ( dayAssignments.isEmpty() ) {
if (dayAssignments.isEmpty()) {
return result; return result;
} }
int additionOfAllAssignmentsMinutes = 0;
for (DayAssignment dayAssignment : dayAssignments) { for (DayAssignment dayAssignment : dayAssignments) {
LocalDate day = dayAssignment.getDay(); LocalDate day = dayAssignment.getDay();
if(((filterStartDate == null) || day.compareTo(filterStartDate) >= 0) && if( ( (filterStartDate == null) || day.compareTo(filterStartDate) >= 0) &&
((filterEndDate == null) || day.compareTo(filterEndDate) <= 0)) { ( (filterEndDate == null) || day.compareTo(filterEndDate) <= 0) ) {
BigDecimal cost = new BigDecimal(dayAssignment.getHours());
if (!result.containsKey(day)) { String currentTime = dayAssignment.getDuration().toFormattedString();
SimpleDateFormat format1 = new SimpleDateFormat("hh:mm");
SimpleDateFormat format2 = new SimpleDateFormat("hh");
Date date = null;
try {
if ( isParsableWithFormat1(currentTime) )
date = format1.parse(currentTime);
else if ( isParsableWithFormat2(currentTime) )
date = format2.parse(currentTime);
} catch (ParseException e) {
e.printStackTrace();
}
Time time = new Time(date.getTime());
BigDecimal hours = new BigDecimal(time.getHours());
additionOfAllAssignmentsMinutes += time.getMinutes();
if ( !result.containsKey(day) ) {
result.put(day, BigDecimal.ZERO); result.put(day, BigDecimal.ZERO);
} }
result.put(day, result.get(day).add(cost));
/**
* On last day assignment app will check addition of minutes of all assignments.
* If it is between 30 and 60 - add 1 hour to the last value of result.
* If it is more than 60 then divide on 60 and calculate hours.
* E.G. 120 minutes / 60 = 2 hours.
*/
if ( dayAssignment.equals(dayAssignments.get(dayAssignments.size() - 1)) ){
if ( additionOfAllAssignmentsMinutes >= 30 && additionOfAllAssignmentsMinutes <= 60 )
hours = BigDecimal.valueOf(hours.intValue() + 1);
if ( additionOfAllAssignmentsMinutes > 60 )
hours = BigDecimal.valueOf(hours.intValue() + (additionOfAllAssignmentsMinutes / 60));
}
result.put(day, result.get(day).add(hours));
} }
} }
return result; return result;
} }
private boolean isParsableWithFormat1(String input){
boolean parsable = true;
try {
SimpleDateFormat format = new SimpleDateFormat("hh:mm");
format.parse(input);
} catch (ParseException e) {
parsable = false;
}
return parsable;
}
private boolean isParsableWithFormat2(String input){
boolean parsable = true;
try {
SimpleDateFormat format = new SimpleDateFormat("hh");
format.parse(input);
} catch (ParseException e) {
parsable = false;
}
return parsable;
}
@Override @Override
public SortedMap<LocalDate, BigDecimal> getWorkReportCost(Task task) { public SortedMap<LocalDate, BigDecimal> getWorkReportCost(Task task) {
if (task.isSubcontracted()) { if (task.isSubcontracted()) {

View file

@ -32,13 +32,10 @@ import org.libreplan.business.calendars.entities.AvailabilityTimeLine;
*/ */
public interface ICompanyEarnedValueCalculator extends IEarnedValueCalculator { public interface ICompanyEarnedValueCalculator extends IEarnedValueCalculator {
SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkScheduled( SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkScheduled(AvailabilityTimeLine.Interval interval);
AvailabilityTimeLine.Interval interval);
SortedMap<LocalDate, BigDecimal> calculateActualCostWorkPerformed( SortedMap<LocalDate, BigDecimal> calculateActualCostWorkPerformed(AvailabilityTimeLine.Interval interval);
AvailabilityTimeLine.Interval interval);
SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkPerformed( SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkPerformed(AvailabilityTimeLine.Interval interval);
AvailabilityTimeLine.Interval interval);
} }

View file

@ -52,21 +52,19 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
@Transactional(readOnly = true) @Transactional(readOnly = true)
@Override @Override
public SortedMap<LocalDate, BigDecimal> calculateActualCostWorkPerformed( public SortedMap<LocalDate, BigDecimal> calculateActualCostWorkPerformed(Order order) {
Order order) {
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>(); SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
for (TaskElement taskElement : getAllTaskElements(order)) { for (TaskElement taskElement : getAllTaskElements(order)) {
if (taskElement instanceof Task) { if ( taskElement instanceof Task ) {
addCost(result, getWorkReportCost((Task) taskElement)); addCost(result, getWorkReportCost((Task) taskElement));
} }
} }
return accumulateResult(result); return accumulateResult(result);
} }
private SortedMap<LocalDate, BigDecimal> accumulateResult( private SortedMap<LocalDate, BigDecimal> accumulateResult(SortedMap<LocalDate, BigDecimal> map) {
SortedMap<LocalDate, BigDecimal> map) {
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>(); SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
if (map.isEmpty()) { if ( map.isEmpty() ) {
return result; return result;
} }
@ -80,13 +78,13 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
} }
private void addCost(SortedMap<LocalDate, BigDecimal> currentCost, private void addCost(SortedMap<LocalDate, BigDecimal> currentCost,
SortedMap<LocalDate, BigDecimal> additionalCost) { SortedMap<LocalDate, BigDecimal> additionalCost) {
for (LocalDate day : additionalCost.keySet()) { for (LocalDate day : additionalCost.keySet()) {
if (!currentCost.containsKey(day)) { if ( !currentCost.containsKey(day) ) {
currentCost.put(day, BigDecimal.ZERO); currentCost.put(day, BigDecimal.ZERO);
} }
currentCost.put(day, currentCost.put(day, currentCost.get(day).add(additionalCost.get(day)));
currentCost.get(day).add(additionalCost.get(day)));
} }
} }
@ -104,17 +102,15 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
@Transactional(readOnly = true) @Transactional(readOnly = true)
public BigDecimal getBudgetAtCompletion(Order order) { public BigDecimal getBudgetAtCompletion(Order order) {
SortedMap<LocalDate, BigDecimal> budgedtedCost = calculateBudgetedCostWorkScheduled(order); SortedMap<LocalDate, BigDecimal> budgedtedCost = calculateBudgetedCostWorkScheduled(order);
return !budgedtedCost.isEmpty() ? budgedtedCost.get(budgedtedCost return !budgedtedCost.isEmpty() ? budgedtedCost.get(budgedtedCost.lastKey()) : BigDecimal.ZERO;
.lastKey()) : BigDecimal.ZERO;
} }
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkScheduled( public SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkScheduled(Order order) {
Order order) {
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>(); SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
for (TaskElement taskElement : getAllTaskElements(order)) { for (TaskElement taskElement : getAllTaskElements(order)) {
if (taskElement instanceof Task) { if ( taskElement instanceof Task ) {
addCost(result, getEstimatedCost((Task) taskElement)); addCost(result, getEstimatedCost((Task) taskElement));
} }
} }
@ -132,21 +128,20 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
return getValueAt(budgetedCost, date); return getValueAt(budgetedCost, date);
} }
private BigDecimal getValueAt(SortedMap<LocalDate, BigDecimal> map, private BigDecimal getValueAt(SortedMap<LocalDate, BigDecimal> map, LocalDate date) {
LocalDate date) { if ( map.isEmpty() ) {
if (map.isEmpty()) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
BigDecimal result = map.get(date); BigDecimal result = map.get(date);
if (result != null) { if ( result != null ) {
return result; return result;
} }
for (LocalDate each : map.keySet()) { for (LocalDate each : map.keySet()) {
if (date.isBefore(each)) { if ( date.isBefore(each) ) {
return map.get(each); return map.get(each);
} }
} }
if (date.isAfter(map.lastKey())) { if ( date.isAfter(map.lastKey()) ) {
return map.get(map.lastKey()); return map.get(map.lastKey());
} }
return BigDecimal.ZERO; return BigDecimal.ZERO;
@ -154,11 +149,10 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkPerformed( public SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkPerformed(Order order) {
Order order) {
SortedMap<LocalDate, BigDecimal> estimatedCost = new TreeMap<LocalDate, BigDecimal>(); SortedMap<LocalDate, BigDecimal> estimatedCost = new TreeMap<LocalDate, BigDecimal>();
for (TaskElement taskElement : getAllTaskElements(order)) { for (TaskElement taskElement : getAllTaskElements(order)) {
if (taskElement instanceof Task) { if ( taskElement instanceof Task ) {
addCost(estimatedCost, getAdvanceCost((Task) taskElement)); addCost(estimatedCost, getAdvanceCost((Task) taskElement));
} }
} }
@ -170,9 +164,8 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
} }
@Override @Override
public BigDecimal getCostPerformanceIndex(BigDecimal budgetedCost, public BigDecimal getCostPerformanceIndex(BigDecimal budgetedCost, BigDecimal actualCost) {
BigDecimal actualCost) { if ( BigDecimal.ZERO.compareTo(actualCost) == 0 ) {
if (BigDecimal.ZERO.compareTo(actualCost) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
return budgetedCost.setScale(4) return budgetedCost.setScale(4)
@ -182,15 +175,13 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
} }
@Override @Override
public BigDecimal getCostVariance(BigDecimal budgetedCost, public BigDecimal getCostVariance(BigDecimal budgetedCost, BigDecimal actualCost) {
BigDecimal actualCost) {
return budgetedCost.subtract(actualCost); return budgetedCost.subtract(actualCost);
} }
@Override @Override
public BigDecimal getEstimateAtCompletion(BigDecimal budgetAtCompletion, public BigDecimal getEstimateAtCompletion(BigDecimal budgetAtCompletion, BigDecimal costPerformanceIndex) {
BigDecimal costPerformanceIndex) { if ( BigDecimal.ZERO.compareTo(costPerformanceIndex) == 0 ) {
if (BigDecimal.ZERO.compareTo(costPerformanceIndex) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
return budgetAtCompletion.setScale(2) return budgetAtCompletion.setScale(2)
@ -199,8 +190,7 @@ public class OrderEarnedValueCalculator extends EarnedValueCalculator implements
} }
@Override @Override
public BigDecimal getEstimateToComplete(BigDecimal estimateAtCompletion, public BigDecimal getEstimateToComplete(BigDecimal estimateAtCompletion, BigDecimal actualCostWorkPerformed) {
BigDecimal actualCostWorkPerformed) {
return estimateAtCompletion.subtract(actualCostWorkPerformed); return estimateAtCompletion.subtract(actualCostWorkPerformed);
} }

View file

@ -46,6 +46,7 @@ import org.libreplan.business.workingday.EffortDuration;
public class SpecificDayAssignment extends DayAssignment { public class SpecificDayAssignment extends DayAssignment {
private abstract class ParentState { private abstract class ParentState {
abstract SpecificResourceAllocation getResourceAllocation(); abstract SpecificResourceAllocation getResourceAllocation();
abstract ParentState setParent( abstract ParentState setParent(
@ -66,11 +67,9 @@ public class SpecificDayAssignment extends DayAssignment {
} }
@Override @Override
ParentState setParent( ParentState setParent(SpecificResourceAllocation specificResourceAllocation) {
SpecificResourceAllocation specificResourceAllocation) { if ( parent != null && parent != specificResourceAllocation ) {
if (parent != null && parent != specificResourceAllocation) { throw new IllegalStateException("the allocation cannot be changed once it has been set");
throw new IllegalStateException(
"the allocation cannot be changed once it has been set");
} }
this.parent = specificResourceAllocation; this.parent = specificResourceAllocation;
return this; return this;
@ -121,9 +120,9 @@ public class SpecificDayAssignment extends DayAssignment {
} }
public static Set<SpecificDayAssignment> copy( public static Set<SpecificDayAssignment> copy(SpecificDayAssignmentsContainer container,
SpecificDayAssignmentsContainer container, Collection<? extends SpecificDayAssignment> specificDaysAssignment) {
Collection<? extends SpecificDayAssignment> specificDaysAssignment) {
Set<SpecificDayAssignment> result = new HashSet<SpecificDayAssignment>(); Set<SpecificDayAssignment> result = new HashSet<SpecificDayAssignment>();
for (SpecificDayAssignment s : specificDaysAssignment) { for (SpecificDayAssignment s : specificDaysAssignment) {
SpecificDayAssignment created = copyFromWithoutParent(s); SpecificDayAssignment created = copyFromWithoutParent(s);
@ -135,16 +134,15 @@ public class SpecificDayAssignment extends DayAssignment {
return result; return result;
} }
private static SpecificDayAssignment copyFromWithoutParent( private static SpecificDayAssignment copyFromWithoutParent(SpecificDayAssignment assignment) {
SpecificDayAssignment assignment) { SpecificDayAssignment copy = create(assignment.getDay(), assignment.getDuration(), assignment.getResource());
SpecificDayAssignment copy = create(assignment.getDay(),
assignment.getDuration(), assignment.getResource());
copy.setConsolidated(assignment.isConsolidated()); copy.setConsolidated(assignment.isConsolidated());
return copy; return copy;
} }
public static List<SpecificDayAssignment> copyToAssignmentsWithoutParent( public static List<SpecificDayAssignment> copyToAssignmentsWithoutParent(
Collection<? extends SpecificDayAssignment> assignments) { Collection<? extends SpecificDayAssignment> assignments) {
List<SpecificDayAssignment> result = new ArrayList<SpecificDayAssignment>(); List<SpecificDayAssignment> result = new ArrayList<SpecificDayAssignment>();
for (SpecificDayAssignment each : assignments) { for (SpecificDayAssignment each : assignments) {
result.add(copyFromWithoutParent(each)); result.add(copyFromWithoutParent(each));

View file

@ -38,14 +38,12 @@ import org.libreplan.business.workingday.IntraDayDate;
* for a {@link ResourceAllocation} at a {@link Scenario} <br /> * for a {@link ResourceAllocation} at a {@link Scenario} <br />
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*/ */
public class SpecificDayAssignmentsContainer extends BaseEntity implements public class SpecificDayAssignmentsContainer extends BaseEntity
IDayAssignmentsContainer<SpecificDayAssignment> { implements IDayAssignmentsContainer<SpecificDayAssignment> {
public static SpecificDayAssignmentsContainer create( public static SpecificDayAssignmentsContainer create(SpecificResourceAllocation specificResourceAllocation,
SpecificResourceAllocation specificResourceAllocation, Scenario scenario) {
Scenario scenario) { return create(new SpecificDayAssignmentsContainer(specificResourceAllocation, scenario));
return create(new SpecificDayAssignmentsContainer(specificResourceAllocation,
scenario));
} }
private SpecificResourceAllocation resourceAllocation; private SpecificResourceAllocation resourceAllocation;
@ -71,8 +69,7 @@ public class SpecificDayAssignmentsContainer extends BaseEntity implements
return new HashSet<SpecificDayAssignment>(dayAssignments); return new HashSet<SpecificDayAssignment>(dayAssignments);
} }
private SpecificDayAssignmentsContainer( private SpecificDayAssignmentsContainer(SpecificResourceAllocation resourceAllocation, Scenario scenario) {
SpecificResourceAllocation resourceAllocation, Scenario scenario) {
Validate.notNull(resourceAllocation); Validate.notNull(resourceAllocation);
Validate.notNull(scenario); Validate.notNull(scenario);
this.resourceAllocation = resourceAllocation; this.resourceAllocation = resourceAllocation;
@ -112,8 +109,7 @@ public class SpecificDayAssignmentsContainer extends BaseEntity implements
dayAssignments.addAll(copyToThisContainer(assignments)); dayAssignments.addAll(copyToThisContainer(assignments));
} }
private Set<SpecificDayAssignment> copyToThisContainer( private Set<SpecificDayAssignment> copyToThisContainer(Collection<? extends SpecificDayAssignment> assignments) {
Collection<? extends SpecificDayAssignment> assignments) {
return SpecificDayAssignment.copy(this, assignments); return SpecificDayAssignment.copy(this, assignments);
} }

View file

@ -60,12 +60,10 @@ import org.libreplan.business.workingday.ResourcesPerDay;
* Represents the relation between {@link Task} and a specific {@link Worker}. * Represents the relation between {@link Task} and a specific {@link Worker}.
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
*/ */
public class SpecificResourceAllocation extends public class SpecificResourceAllocation extends ResourceAllocation<SpecificDayAssignment> implements IAllocatable {
ResourceAllocation<SpecificDayAssignment> implements IAllocatable {
public static SpecificResourceAllocation create(Task task) { public static SpecificResourceAllocation create(Task task) {
return create(new SpecificResourceAllocation( return create(new SpecificResourceAllocation(task));
task));
} }
/** /**
@ -80,11 +78,9 @@ public class SpecificResourceAllocation extends
* @param task * @param task
* @return * @return
*/ */
public static SpecificResourceAllocation createForLimiting(Resource resource, public static SpecificResourceAllocation createForLimiting(Resource resource, Task task) {
Task task) {
assert resource.isLimitingResource(); assert resource.isLimitingResource();
SpecificResourceAllocation result = create(new SpecificResourceAllocation( SpecificResourceAllocation result = create(new SpecificResourceAllocation(task));
task));
result.setResource(resource); result.setResource(resource);
result.setResourcesPerDayToAmount(1); result.setResourcesPerDayToAmount(1);
return result; return result;
@ -96,42 +92,35 @@ public class SpecificResourceAllocation extends
private Set<SpecificDayAssignmentsContainer> specificDayAssignmentsContainers = new HashSet<SpecificDayAssignmentsContainer>(); private Set<SpecificDayAssignmentsContainer> specificDayAssignmentsContainers = new HashSet<SpecificDayAssignmentsContainer>();
@Valid @Valid
private Set<SpecificDayAssignmentsContainer> getSpecificDayAssignmentsContainers() { public Set<SpecificDayAssignmentsContainer> getSpecificDayAssignmentsContainers() {
return new HashSet<SpecificDayAssignmentsContainer>( return new HashSet<SpecificDayAssignmentsContainer>(specificDayAssignmentsContainers);
specificDayAssignmentsContainers);
} }
public static SpecificResourceAllocation createForTesting( public static SpecificResourceAllocation createForTesting(ResourcesPerDay resourcesPerDay, Task task) {
ResourcesPerDay resourcesPerDay, Task task) { return create(new SpecificResourceAllocation(resourcesPerDay, task));
return create(new SpecificResourceAllocation(
resourcesPerDay, task));
} }
public SpecificResourceAllocation() { public SpecificResourceAllocation() {
} }
@Override @Override
protected SpecificDayAssignmentsContainer retrieveOrCreateContainerFor( protected SpecificDayAssignmentsContainer retrieveOrCreateContainerFor(Scenario scenario) {
Scenario scenario) {
SpecificDayAssignmentsContainer retrieved = retrieveContainerFor(scenario); SpecificDayAssignmentsContainer retrieved = retrieveContainerFor(scenario);
if (retrieved != null) { if ( retrieved != null ) {
return retrieved; return retrieved;
} }
SpecificDayAssignmentsContainer result = SpecificDayAssignmentsContainer SpecificDayAssignmentsContainer result = SpecificDayAssignmentsContainer.create(this, scenario);
.create(this, scenario);
specificDayAssignmentsContainers.add(result); specificDayAssignmentsContainers.add(result);
return result; return result;
} }
@Override @Override
protected SpecificDayAssignmentsContainer retrieveContainerFor( protected SpecificDayAssignmentsContainer retrieveContainerFor(Scenario scenario) {
Scenario scenario) {
Map<Scenario, SpecificDayAssignmentsContainer> containers = containersByScenario(); Map<Scenario, SpecificDayAssignmentsContainer> containers = containersByScenario();
return containers.get(scenario); return containers.get(scenario);
} }
private SpecificResourceAllocation(ResourcesPerDay resourcesPerDay, private SpecificResourceAllocation(ResourcesPerDay resourcesPerDay, Task task) {
Task task) {
super(resourcesPerDay, task); super(resourcesPerDay, task);
} }
@ -165,15 +154,12 @@ public class SpecificResourceAllocation extends
} }
@Override @Override
public IAllocateResourcesPerDay resourcesPerDayUntil( public IAllocateResourcesPerDay resourcesPerDayUntil(IntraDayDate endExclusive) {
IntraDayDate endExclusive) { return new SpecificAssignmentsAllocator().resourcesPerDayUntil(endExclusive);
return new SpecificAssignmentsAllocator()
.resourcesPerDayUntil(endExclusive);
} }
@Override @Override
public IAllocateResourcesPerDay resourcesPerDayFromEndUntil( public IAllocateResourcesPerDay resourcesPerDayFromEndUntil(IntraDayDate start) {
IntraDayDate start) {
SpecificAssignmentsAllocator allocator = new SpecificAssignmentsAllocator(); SpecificAssignmentsAllocator allocator = new SpecificAssignmentsAllocator();
return allocator.resourcesPerDayFromEndUntil(start); return allocator.resourcesPerDayFromEndUntil(start);
} }
@ -192,10 +178,8 @@ public class SpecificResourceAllocation extends
AssignmentsAllocator { AssignmentsAllocator {
@Override @Override
public List<SpecificDayAssignment> distributeForDay(PartialDay day, public List<SpecificDayAssignment> distributeForDay(PartialDay day, EffortDuration effort) {
EffortDuration effort) { return Arrays.asList(SpecificDayAssignment.create(day.getDate(), effort, resource));
return Arrays.asList(SpecificDayAssignment.create(day.getDate(),
effort, resource));
} }
@Override @Override
@ -221,29 +205,23 @@ public class SpecificResourceAllocation extends
} }
@Override @Override
public IAllocateEffortOnInterval onIntervalWithinTask(IntraDayDate start, public IAllocateEffortOnInterval onIntervalWithinTask(IntraDayDate start, IntraDayDate end) {
IntraDayDate end) { return new SpecificAssignmentsAllocator().onIntervalWithinTask(start, end);
return new SpecificAssignmentsAllocator().onIntervalWithinTask(start,
end);
} }
@Override @Override
public IAllocateEffortOnInterval onInterval(LocalDate startInclusive, public IAllocateEffortOnInterval onInterval(LocalDate startInclusive, LocalDate endExclusive) {
LocalDate endExclusive) { return new SpecificAssignmentsAllocator().onInterval(startInclusive, endExclusive);
return new SpecificAssignmentsAllocator().onInterval(startInclusive,
endExclusive);
} }
@Override @Override
public IAllocateEffortOnInterval onInterval(IntraDayDate start, public IAllocateEffortOnInterval onInterval(IntraDayDate start, IntraDayDate end) {
IntraDayDate end) {
return new SpecificAssignmentsAllocator().onInterval(start, end); return new SpecificAssignmentsAllocator().onInterval(start, end);
} }
@Override @Override
protected ICalendar getCalendarGivenTaskCalendar(ICalendar taskCalendar) { protected ICalendar getCalendarGivenTaskCalendar(ICalendar taskCalendar) {
return CombinedWorkHours.minOf(taskCalendar, getResource() return CombinedWorkHours.minOf(taskCalendar, getResource().getCalendar());
.getCalendar());
} }
@Override @Override
@ -327,39 +305,35 @@ public class SpecificResourceAllocation extends
* @param effortForNotConsolidatedPart * @param effortForNotConsolidatedPart
* @param endExclusive * @param endExclusive
*/ */
public void allocateWholeAllocationKeepingProportions( public void allocateWholeAllocationKeepingProportions(EffortDuration effortForNotConsolidatedPart,
EffortDuration effortForNotConsolidatedPart, IntraDayDate end) { IntraDayDate end) {
AllocationInterval interval = new AllocationInterval(
getIntraDayStartDate(), end);
List<DayAssignment> nonConsolidatedAssignments = interval AllocationInterval interval = new AllocationInterval(getIntraDayStartDate(), end);
.getNoConsolidatedAssignmentsOnInterval();
ProportionalDistributor distributor = ProportionalDistributor
.create(asSeconds(nonConsolidatedAssignments));
EffortDuration[] effortsPerDay = asEfforts(distributor List<DayAssignment> nonConsolidatedAssignments = interval.getNoConsolidatedAssignmentsOnInterval();
.distribute(effortForNotConsolidatedPart.getSeconds())); ProportionalDistributor distributor = ProportionalDistributor.create(asSeconds(nonConsolidatedAssignments));
allocateTheWholeAllocation(
interval, EffortDuration[] effortsPerDay = asEfforts(distributor.distribute(effortForNotConsolidatedPart.getSeconds()));
assignmentsForEfforts(nonConsolidatedAssignments, effortsPerDay)); allocateTheWholeAllocation(interval, assignmentsForEfforts(nonConsolidatedAssignments, effortsPerDay));
} }
private EffortDuration[] asEfforts(int[] secondsArray) { private EffortDuration[] asEfforts(int[] secondsArray) {
EffortDuration[] result = new EffortDuration[secondsArray.length]; EffortDuration[] result = new EffortDuration[secondsArray.length];
for (int i = 0; i < result.length; i++) { for (int i = 0; i < result.length; i++) {
result[i] = EffortDuration.seconds(secondsArray[i]); result[i] = EffortDuration.seconds(secondsArray[i]);
} }
return result; return result;
} }
private List<SpecificDayAssignment> assignmentsForEfforts( private List<SpecificDayAssignment> assignmentsForEfforts(List<DayAssignment> assignments,
List<DayAssignment> assignments, EffortDuration[] newEffortsPerDay) { EffortDuration[] newEffortsPerDay) {
List<SpecificDayAssignment> result = new ArrayList<SpecificDayAssignment>(); List<SpecificDayAssignment> result = new ArrayList<SpecificDayAssignment>();
int i = 0; int i = 0;
for (DayAssignment each : assignments) { for (DayAssignment each : assignments) {
EffortDuration durationForAssignment = newEffortsPerDay[i++]; EffortDuration durationForAssignment = newEffortsPerDay[i++];
result.add(SpecificDayAssignment.create(each.getDay(), result.add(SpecificDayAssignment.create(each.getDay(), durationForAssignment, resource));
durationForAssignment, resource));
} }
return result; return result;
} }
@ -367,35 +341,32 @@ public class SpecificResourceAllocation extends
private int[] asSeconds(List<DayAssignment> assignments) { private int[] asSeconds(List<DayAssignment> assignments) {
int[] result = new int[assignments.size()]; int[] result = new int[assignments.size()];
int i = 0; int i = 0;
for (DayAssignment each : assignments) { for (DayAssignment each : assignments) {
result[i++] = each.getDuration().getSeconds(); result[i++] = each.getDuration().getSeconds();
} }
return result; return result;
} }
public void overrideConsolidatedDayAssignments( public void overrideConsolidatedDayAssignments(SpecificResourceAllocation origin) {
SpecificResourceAllocation origin) { if ( origin != null ) {
if (origin != null) { List<SpecificDayAssignment> originAssignments = origin.getConsolidatedAssignments();
List<SpecificDayAssignment> originAssignments = origin resetAssignmentsTo(SpecificDayAssignment.copyToAssignmentsWithoutParent(originAssignments));
.getConsolidatedAssignments();
resetAssignmentsTo(SpecificDayAssignment
.copyToAssignmentsWithoutParent(originAssignments));
} }
} }
@Override @Override
public EffortDuration getAssignedEffort(Criterion criterion, public EffortDuration getAssignedEffort(Criterion criterion, final IntraDayDate startInclusive,
final IntraDayDate startInclusive, final IntraDayDate endExclusive) { final IntraDayDate endExclusive) {
return EffortDuration.sum( return EffortDuration.sum(getIntervalsRelatedWith(criterion, startInclusive.getDate(),
getIntervalsRelatedWith(criterion, startInclusive.getDate(), endExclusive.asExclusiveEnd()), new IEffortFrom<Interval>() {
endExclusive.asExclusiveEnd()),
new IEffortFrom<Interval>() {
@Override @Override
public EffortDuration from(Interval each) { public EffortDuration from(Interval each) {
FixedPoint intervalStart = (FixedPoint) each.getStart(); FixedPoint intervalStart = (FixedPoint) each.getStart();
FixedPoint intervalEnd = (FixedPoint) each.getEnd(); FixedPoint intervalEnd = (FixedPoint) each.getEnd();
return getAssignedDuration( return getAssignedDuration(
IntraDayDate.convert(intervalStart.getDate(), startInclusive), IntraDayDate.convert(intervalStart.getDate(), startInclusive),
IntraDayDate.convert(intervalEnd.getDate(), endExclusive)); IntraDayDate.convert(intervalEnd.getDate(), endExclusive));
@ -403,34 +374,32 @@ public class SpecificResourceAllocation extends
}); });
} }
private List<Interval> getIntervalsRelatedWith(Criterion criterion, private List<Interval> getIntervalsRelatedWith(Criterion criterion, LocalDate startInclusive,
LocalDate startInclusive, LocalDate endExclusive) { LocalDate endExclusive) {
Interval queryInterval = AvailabilityTimeLine.Interval.create(
startInclusive, endExclusive); Interval queryInterval = AvailabilityTimeLine.Interval.create(startInclusive, endExclusive);
List<Interval> result = new ArrayList<Interval>(); List<Interval> result = new ArrayList<Interval>();
for (Interval each : getIntervalsThisAllocationInterferesWith(criterion)) { for (Interval each : getIntervalsThisAllocationInterferesWith(criterion)) {
if (queryInterval.overlaps(each)) { if ( queryInterval.overlaps(each) ) {
result.add(queryInterval.intersect(each)); result.add(queryInterval.intersect(each));
} }
} }
return result; return result;
} }
private List<Interval> getIntervalsThisAllocationInterferesWith( private List<Interval> getIntervalsThisAllocationInterferesWith(Criterion criterion) {
Criterion criterion) { AvailabilityTimeLine availability =
AvailabilityTimeLine availability = AvailabilityCalculator AvailabilityCalculator.getCriterionsAvailabilityFor(Collections.singleton(criterion), resource);
.getCriterionsAvailabilityFor(Collections.singleton(criterion),
resource);
availability.invalidUntil(getStartDate()); availability.invalidUntil(getStartDate());
availability.invalidFrom(getEndDate()); availability.invalidFrom(getEndDate());
return availability.getValidPeriods(); return availability.getValidPeriods();
} }
public boolean interferesWith(Criterion criterion, public boolean interferesWith(Criterion criterion, LocalDate startInclusive, LocalDate endExclusive) {
LocalDate startInclusive, LocalDate endExclusive) { List<Interval> intervalsRelatedWith = getIntervalsRelatedWith(criterion, startInclusive, endExclusive);
List<Interval> intervalsRelatedWith = getIntervalsRelatedWith(
criterion, startInclusive, endExclusive);
return !intervalsRelatedWith.isEmpty(); return !intervalsRelatedWith.isEmpty();
} }

View file

@ -155,7 +155,7 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
private Set<ResourceAllocation<?>> resourceAllocations = new HashSet<ResourceAllocation<?>>(); private Set<ResourceAllocation<?>> resourceAllocations = new HashSet<ResourceAllocation<?>>();
@Valid @Valid
private Set<ResourceAllocation<?>> getResourceAlloations() { private Set<ResourceAllocation<?>> getResourceAllocations() {
return new HashSet<ResourceAllocation<?>>(resourceAllocations); return new HashSet<ResourceAllocation<?>>(resourceAllocations);
} }
@ -238,11 +238,10 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
public Set<ResourceAllocation<?>> getSatisfiedResourceAllocations() { public Set<ResourceAllocation<?>> getSatisfiedResourceAllocations() {
Set<ResourceAllocation<?>> result = new HashSet<ResourceAllocation<?>>(); Set<ResourceAllocation<?>> result = new HashSet<ResourceAllocation<?>>();
if (isLimiting()) { if ( isLimiting() ) {
result.addAll(getLimitingResourceAllocations()); result.addAll(getLimitingResourceAllocations());
} else { } else {
result.addAll(ResourceAllocation result.addAll(ResourceAllocation.getSatisfied(resourceAllocations));
.getSatisfied(resourceAllocations));
} }
return Collections.unmodifiableSet(result); return Collections.unmodifiableSet(result);
} }
@ -282,31 +281,27 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
} }
public LimitingResourceQueueElement getAssociatedLimitingResourceQueueElementIfAny() { public LimitingResourceQueueElement getAssociatedLimitingResourceQueueElementIfAny() {
if (!isLimiting()) { if ( !isLimiting() ) {
throw new IllegalStateException("this is not a limiting task"); throw new IllegalStateException("this is not a limiting task");
} }
return getAssociatedLimitingResourceAllocation() return getAssociatedLimitingResourceAllocation().getLimitingResourceQueueElement();
.getLimitingResourceQueueElement();
} }
public boolean isLimitingAndHasDayAssignments() { public boolean isLimitingAndHasDayAssignments() {
ResourceAllocation<?> resourceAllocation = getAssociatedLimitingResourceAllocation(); ResourceAllocation<?> resourceAllocation = getAssociatedLimitingResourceAllocation();
return resourceAllocation != null return resourceAllocation != null && resourceAllocation.isLimitingAndHasDayAssignments();
&& resourceAllocation.isLimitingAndHasDayAssignments();
} }
public void addResourceAllocation(ResourceAllocation<?> resourceAllocation) { public void addResourceAllocation(ResourceAllocation<?> resourceAllocation) {
addResourceAllocation(resourceAllocation, true); addResourceAllocation(resourceAllocation, true);
} }
public void addResourceAllocation(ResourceAllocation<?> resourceAllocation, public void addResourceAllocation(ResourceAllocation<?> resourceAllocation, boolean generateDayAssignments) {
boolean generateDayAssignments) { if ( !resourceAllocation.getTask().equals(this) ) {
if (!resourceAllocation.getTask().equals(this)) { throw new IllegalArgumentException("the resourceAllocation's task must be this task");
throw new IllegalArgumentException(
"the resourceAllocation's task must be this task");
} }
resourceAllocations.add(resourceAllocation); resourceAllocations.add(resourceAllocation);
if (generateDayAssignments) { if ( generateDayAssignments ) {
resourceAllocation.associateAssignmentsToResource(); resourceAllocation.associateAssignmentsToResource();
} }
} }
@ -795,18 +790,15 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
new WithPotentiallyNewResources(searcher)); new WithPotentiallyNewResources(searcher));
} }
private void reassign(Scenario onScenario, Direction direction, private void reassign(Scenario onScenario, Direction direction, WithPotentiallyNewResources strategy) {
WithPotentiallyNewResources strategy) {
try { try {
this.lastAllocationDirection = direction; this.lastAllocationDirection = direction;
if (isLimiting()) { if ( isLimiting() ) {
return; return;
} }
List<ModifiedAllocation> copied = ModifiedAllocation.copy(onScenario, List<ModifiedAllocation> copied = ModifiedAllocation.copy(onScenario, getResourceAllocations());
getResourceAlloations()); List<ResourceAllocation<?>> toBeModified = ModifiedAllocation.modified(copied);
List<ResourceAllocation<?>> toBeModified = ModifiedAllocation if ( toBeModified.isEmpty() ) {
.modified(copied);
if (toBeModified.isEmpty()) {
return; return;
} }
setCustomAssignedEffortForResource(copied); setCustomAssignedEffortForResource(copied);
@ -814,12 +806,12 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
updateDerived(copied); updateDerived(copied);
List<ResourceAllocation<?>> newAllocations = emptyList(), removedAllocations = emptyList(); List<ResourceAllocation<?>> newAllocations = emptyList(), removedAllocations = emptyList();
mergeAllocation(onScenario, getIntraDayStartDate(),
getIntraDayEndDate(), workableDays, calculatedValue, mergeAllocation(onScenario, getIntraDayStartDate(), getIntraDayEndDate(), workableDays, calculatedValue,
newAllocations, copied, removedAllocations); newAllocations, copied, removedAllocations);
} catch (Exception e) { } catch (Exception e) {
LOG.error("reassignment for task: " + this LOG.error("reassignment for task: " + this + " couldn't be completed", e);
+ " couldn't be completed", e);
} }
} }
@ -1186,7 +1178,7 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
if (this.currentStatus != null) { if (this.currentStatus != null) {
return this.currentStatus == TaskStatusEnum.IN_PROGRESS; return this.currentStatus == TaskStatusEnum.IN_PROGRESS;
} else { } else {
boolean advanceBetweenZeroAndOne = this.advancePertentageIsGreaterThanZero() && boolean advanceBetweenZeroAndOne = this.advancePercentageIsGreaterThanZero() &&
!advancePercentageIsOne(); !advancePercentageIsOne();
boolean outcome = advanceBetweenZeroAndOne || this.hasAttachedWorkReports(); boolean outcome = advanceBetweenZeroAndOne || this.hasAttachedWorkReports();
if (outcome == true) { if (outcome == true) {
@ -1197,19 +1189,18 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
} }
public boolean isReadyToStart() { public boolean isReadyToStart() {
if (!this.advancePercentageIsZero() || this.hasAttachedWorkReports()) { if ( !this.advancePercentageIsZero() || this.hasAttachedWorkReports() ) {
return false; return false;
} }
Set<Dependency> dependencies = getDependenciesWithThisDestinationAndAllParents(); Set<Dependency> dependencies = getDependenciesWithThisDestinationAndAllParents();
for (Dependency dependency: dependencies) { for (Dependency dependency: dependencies) {
Type dependencyType = dependency.getType(); Type dependencyType = dependency.getType();
if (dependencyType.equals(Type.END_START)) { if ( dependencyType.equals(Type.END_START) ) {
if (!dependency.getOrigin().isFinished()) { if ( !dependency.getOrigin().isFinished() ) {
return false; return false;
} }
} else if (dependencyType.equals(Type.START_START)) { } else if ( dependencyType.equals(Type.START_START) ) {
if (!dependency.getOrigin().isFinished() && if ( !dependency.getOrigin().isFinished() && !dependency.getOrigin().isInProgress() ) {
!dependency.getOrigin().isInProgress()) {
return false; return false;
} }
} }
@ -1218,19 +1209,18 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
} }
public boolean isBlocked() { public boolean isBlocked() {
if (!this.advancePercentageIsZero() || this.hasAttachedWorkReports()) { if ( !this.advancePercentageIsZero() || this.hasAttachedWorkReports() ) {
return false; return false;
} }
Set<Dependency> dependencies = getDependenciesWithThisDestinationAndAllParents(); Set<Dependency> dependencies = getDependenciesWithThisDestinationAndAllParents();
for (Dependency dependency: dependencies) { for (Dependency dependency: dependencies) {
Type dependencyType = dependency.getType(); Type dependencyType = dependency.getType();
if (dependencyType.equals(Type.END_START)) { if ( dependencyType.equals(Type.END_START) ) {
if (!dependency.getOrigin().isFinished()) { if ( !dependency.getOrigin().isFinished() ) {
return true; return true;
} }
} else if (dependencyType.equals(Type.START_START)) { } else if ( dependencyType.equals(Type.START_START) ) {
if (!dependency.getOrigin().isFinished() && if ( !dependency.getOrigin().isFinished() && !dependency.getOrigin().isInProgress() ) {
!dependency.getOrigin().isInProgress()) {
return true; return true;
} }
} }
@ -1238,7 +1228,7 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
return false; return false;
} }
private boolean advancePertentageIsGreaterThanZero() { private boolean advancePercentageIsGreaterThanZero() {
return this.getAdvancePercentage().compareTo(BigDecimal.ZERO) > 0; return this.getAdvancePercentage().compareTo(BigDecimal.ZERO) > 0;
} }
@ -1270,4 +1260,13 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
return getPositionConstraint().getConstraintType().equals(type); return getPositionConstraint().getConstraintType().equals(type);
} }
@Override
public void setParent(TaskGroup taskGroup) {
super.setParent(taskGroup);
}
@Override
public void setTaskSource(TaskSource taskSource) {
super.setTaskSource(taskSource);
}
} }

View file

@ -135,14 +135,13 @@ public abstract class TaskElement extends BaseEntity {
return this.getEndAsLocalDate(); return this.getEndAsLocalDate();
} }
protected static <T extends TaskElement> T create(T taskElement, protected static <T extends TaskElement> T create(T taskElement, TaskSource taskSource) {
TaskSource taskSource) {
taskElement.setTaskSource(taskSource); taskElement.setTaskSource(taskSource);
taskElement.updateDeadlineFromOrderElement(); taskElement.updateDeadlineFromOrderElement();
taskElement.setName(taskElement.getOrderElement().getName()); taskElement.setName(taskElement.getOrderElement().getName());
taskElement.updateAdvancePercentageFromOrderElement(); taskElement.updateAdvancePercentageFromOrderElement();
Order order = taskElement.getOrderElement().getOrder(); Order order = taskElement.getOrderElement().getOrder();
if (order.isScheduleBackwards()) { if ( order.isScheduleBackwards() ) {
taskElement.setEndDate(order.getDeadline()); taskElement.setEndDate(order.getDeadline());
} else { } else {
taskElement.setStartDate(order.getInitDate()); taskElement.setStartDate(order.getInitDate());
@ -317,35 +316,31 @@ public abstract class TaskElement extends BaseEntity {
} }
public void setStartDate(Date startDate) { public void setStartDate(Date startDate) {
setIntraDayStartDate(IntraDayDate.startOfDay(LocalDate setIntraDayStartDate(IntraDayDate.startOfDay(LocalDate.fromDateFields(startDate)));
.fromDateFields(startDate)));
} }
public void setIntraDayStartDate(IntraDayDate startDate) { public void setIntraDayStartDate(IntraDayDate startDate) {
if (startDate == null) { if ( startDate == null ) {
LOG.error(doNotProvideNullsDiscouragingMessage()); LOG.error(doNotProvideNullsDiscouragingMessage());
} }
IntraDayDate previousStart = getIntraDayStartDate(); IntraDayDate previousStart = getIntraDayStartDate();
IntraDayDate previousEnd = getIntraDayEndDate(); IntraDayDate previousEnd = getIntraDayEndDate();
this.startDate = startDate; this.startDate = startDate;
datesInterceptor.setStartDate(previousStart, previousEnd, datesInterceptor.setStartDate(previousStart, previousEnd, getIntraDayStartDate());
getIntraDayStartDate());
} }
@NotNull @NotNull
public Date getEndDate() { public Date getEndDate() {
return endDate != null ? endDate.toDateTimeAtStartOfDay().toDate() return (endDate != null) ? endDate.toDateTimeAtStartOfDay().toDate() : null;
: null;
} }
public void setEndDate(Date endDate) { public void setEndDate(Date endDate) {
setIntraDayEndDate(endDate != null ? IntraDayDate.create( setIntraDayEndDate( (endDate != null) ?
LocalDate.fromDateFields(endDate), EffortDuration.zero()) IntraDayDate.create(LocalDate.fromDateFields(endDate), EffortDuration.zero()) : null);
: null);
} }
public void setIntraDayEndDate(IntraDayDate endDate) { public void setIntraDayEndDate(IntraDayDate endDate) {
if (endDate == null) { if ( endDate == null ) {
LOG.error(doNotProvideNullsDiscouragingMessage()); LOG.error(doNotProvideNullsDiscouragingMessage());
} }
IntraDayDate previousEnd = getIntraDayEndDate(); IntraDayDate previousEnd = getIntraDayEndDate();
@ -576,20 +571,19 @@ public abstract class TaskElement extends BaseEntity {
return result; return result;
} }
private void addToResult(SortedMap<LocalDate, EffortDuration> result, private void addToResult(SortedMap<LocalDate, EffortDuration> result, LocalDate date, EffortDuration duration) {
LocalDate date, EffortDuration duration) { EffortDuration current = result.get(date) != null ? result.get(date) : zero();
EffortDuration current = result.get(date) != null ? result.get(date)
: zero();
result.put(date, current.plus(duration)); result.put(date, current.plus(duration));
} }
public List<DayAssignment> getDayAssignments(DayAssignment.FilterType filter) { public List<DayAssignment> getDayAssignments(DayAssignment.FilterType filter) {
List<DayAssignment> dayAssignments = new ArrayList<DayAssignment>(); List<DayAssignment> dayAssignments = new ArrayList<DayAssignment>();
Set<ResourceAllocation<?>> resourceAllocations = getSatisfiedResourceAllocations(); Set<ResourceAllocation<?>> resourceAllocations = getSatisfiedResourceAllocations();
for (ResourceAllocation<?> resourceAllocation : resourceAllocations) { for (ResourceAllocation<?> resourceAllocation : resourceAllocations) {
dayAssignments.addAll(resourceAllocation.getAssignments()); dayAssignments.addAll(resourceAllocation.getAssignments());
Set<DerivedAllocation> derivedAllocations = resourceAllocation Set<DerivedAllocation> derivedAllocations = resourceAllocation.getDerivedAllocations();
.getDerivedAllocations();
for (DerivedAllocation each : derivedAllocations) { for (DerivedAllocation each : derivedAllocations) {
dayAssignments.addAll(each.getAssignments()); dayAssignments.addAll(each.getAssignments());
} }

View file

@ -194,17 +194,21 @@ public class TaskGroup extends TaskElement {
public void setTaskChildrenTo(List<TaskElement> children) { public void setTaskChildrenTo(List<TaskElement> children) {
Validate.noNullElements(children); Validate.noNullElements(children);
int positionOnTaskElements = 0; int positionOnTaskElements = 0;
for (int i = 0; i < children.size(); i++) { for (int i = 0; i < children.size(); i++) {
TaskElement element = children.get(i); TaskElement element = children.get(i);
element.setParent(this); element.setParent(this);
if (positionOnTaskElements >= taskElements.size()) {
if ( positionOnTaskElements >= taskElements.size() ) {
taskElements.add(element); taskElements.add(element);
} else { } else {
while (positionOnTaskElements < taskElements.size() while (positionOnTaskElements < taskElements.size() &&
&& isMilestone(taskElements.get(positionOnTaskElements))) { isMilestone(taskElements.get(positionOnTaskElements))) {
positionOnTaskElements++; positionOnTaskElements++;
} }
if (positionOnTaskElements >= taskElements.size()) {
if ( positionOnTaskElements >= taskElements.size() ) {
taskElements.add(element); taskElements.add(element);
} else { } else {
taskElements.set(positionOnTaskElements, element); taskElements.set(positionOnTaskElements, element);
@ -212,11 +216,10 @@ public class TaskGroup extends TaskElement {
} }
positionOnTaskElements++; positionOnTaskElements++;
} }
ListIterator<TaskElement> listIterator = taskElements ListIterator<TaskElement> listIterator = taskElements.listIterator(positionOnTaskElements);
.listIterator(positionOnTaskElements);
while (listIterator.hasNext()) { while (listIterator.hasNext()) {
TaskElement current = listIterator.next(); TaskElement current = listIterator.next();
if (!isMilestone(current)) { if ( !isMilestone(current) ) {
listIterator.remove(); listIterator.remove();
} }
} }
@ -344,10 +347,10 @@ public class TaskGroup extends TaskElement {
@Override @Override
public boolean isFinished() { public boolean isFinished() {
if (this.isFinished == null) { if ( this.isFinished == null ) {
this.isFinished = new Boolean(true); this.isFinished = new Boolean(true);
for (TaskElement each: taskElements) { for (TaskElement each: taskElements) {
if (!each.isFinished()) { if ( !each.isFinished() ) {
this.isFinished = new Boolean(false); this.isFinished = new Boolean(false);
break; break;
} }
@ -390,4 +393,8 @@ public class TaskGroup extends TaskElement {
return false; return false;
} }
@Override
public void setTaskSource(TaskSource taskSource) {
super.setTaskSource(taskSource);
}
} }

View file

@ -55,8 +55,8 @@ import org.libreplan.business.resources.daos.ICriterionDAO;
public class Criterion extends IntegrationEntity implements ICriterion, public class Criterion extends IntegrationEntity implements ICriterion,
Comparable<Criterion> { Comparable<Criterion> {
public static Criterion createUnvalidated(String code, String name, public static Criterion createUnvalidated(String code, String name, CriterionType type, Criterion parent,
CriterionType type, Criterion parent, Boolean active) { Boolean active) {
Criterion criterion = create(new Criterion(), code); Criterion criterion = create(new Criterion(), code);
@ -64,7 +64,7 @@ public class Criterion extends IntegrationEntity implements ICriterion,
criterion.type = type; criterion.type = type;
criterion.parent = parent; criterion.parent = parent;
if (active != null) { if ( active != null ) {
criterion.active = active; criterion.active = active;
} }

View file

@ -75,8 +75,7 @@ import org.libreplan.business.workingday.IntraDayDate.PartialDay;
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com> * @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Jacobo Aragunde Perez <jaragunde@igalia.com> * @author Jacobo Aragunde Perez <jaragunde@igalia.com>
*/ */
public abstract class Resource extends IntegrationEntity implements public abstract class Resource extends IntegrationEntity implements IHumanIdentifiable, Comparable<Resource> {
IHumanIdentifiable, Comparable<Resource> {
public static class AllResourceAssignments implements IAssignmentsOnResourceCalculator { public static class AllResourceAssignments implements IAssignmentsOnResourceCalculator {
@ -86,8 +85,7 @@ public abstract class Resource extends IntegrationEntity implements
} }
} }
public static List<Machine> machines( public static List<Machine> machines(Collection<? extends Resource> resources) {
Collection<? extends Resource> resources) {
return filter(Machine.class, resources); return filter(Machine.class, resources);
} }
@ -95,11 +93,10 @@ public abstract class Resource extends IntegrationEntity implements
return filter(Worker.class, resources); return filter(Worker.class, resources);
} }
public static <T extends Resource> List<T> filter(Class<T> klass, public static <T extends Resource> List<T> filter(Class<T> klass, Collection<? extends Resource> resources) {
Collection<? extends Resource> resources) {
List<T> result = new ArrayList<T>(); List<T> result = new ArrayList<T>();
for (Resource each : resources) { for (Resource each : resources) {
if (klass.isInstance(each)) { if ( klass.isInstance(each) ) {
result.add(klass.cast(each)); result.add(klass.cast(each));
} }
} }
@ -150,11 +147,11 @@ public abstract class Resource extends IntegrationEntity implements
} }
private List<DayAssignment> getAssignmentsForDay(LocalDate date) { private List<DayAssignment> getAssignmentsForDay(LocalDate date) {
if (assignmentsByDayCached == null) { if ( assignmentsByDayCached == null ) {
assignmentsByDayCached = DayAssignment.byDay(getAssignments()); assignmentsByDayCached = DayAssignment.byDay(getAssignments());
} }
List<DayAssignment> list = assignmentsByDayCached.get(date); List<DayAssignment> list = assignmentsByDayCached.get(date);
if (list == null){ if ( list == null ){
return Collections.emptyList(); return Collections.emptyList();
} }
return list; return list;
@ -167,7 +164,7 @@ public abstract class Resource extends IntegrationEntity implements
abstract List<DayAssignment> calculateAssignments(); abstract List<DayAssignment> calculateAssignments();
List<DayAssignment> getAssignments() { List<DayAssignment> getAssignments() {
if (cachedAssignments != null) { if ( cachedAssignments != null ) {
return cachedAssignments; return cachedAssignments;
} }
return cachedAssignments = calculateAssignments(); return cachedAssignments = calculateAssignments();
@ -185,8 +182,7 @@ public abstract class Resource extends IntegrationEntity implements
List<DayAssignment> result = new ArrayList<DayAssignment>(); List<DayAssignment> result = new ArrayList<DayAssignment>();
Scenario current = Registry.getScenarioManager().getCurrent(); Scenario current = Registry.getScenarioManager().getCurrent();
for (DayAssignment each : dayAssignments) { for (DayAssignment each : dayAssignments) {
if (each.getScenario() != null if ( each.getScenario() != null && each.getScenario().equals(current) ) {
&& each.getScenario().equals(current)) {
result.add(each); result.add(each);
} }
} }
@ -206,8 +202,7 @@ public abstract class Resource extends IntegrationEntity implements
List<DayAssignment> calculateAssignments() { List<DayAssignment> calculateAssignments() {
List<DayAssignment> result = new ArrayList<DayAssignment>(); List<DayAssignment> result = new ArrayList<DayAssignment>();
for (DayAssignment each : dayAssignments) { for (DayAssignment each : dayAssignments) {
if (isTransient(each) if ( isTransient(each) || each.getScenario().equals(currentScenario) ) {
|| each.getScenario().equals(currentScenario)) {
result.add(each); result.add(each);
} }
} }
@ -223,32 +218,28 @@ public abstract class Resource extends IntegrationEntity implements
@Valid @Valid
public Set<CriterionSatisfaction> getCriterionSatisfactions() { public Set<CriterionSatisfaction> getCriterionSatisfactions() {
Set<CriterionSatisfaction> satisfactionActives = Set<CriterionSatisfaction> satisfactionActives = new HashSet<CriterionSatisfaction>();
new HashSet<CriterionSatisfaction>();
for(CriterionSatisfaction satisfaction:criterionSatisfactions){ for(CriterionSatisfaction satisfaction:criterionSatisfactions){
if(!satisfaction.isIsDeleted()) { if( !satisfaction.isIsDeleted() ) {
satisfactionActives.add(satisfaction); satisfactionActives.add(satisfaction);
} }
} }
return satisfactionActives; return satisfactionActives;
} }
public CriterionSatisfaction getCriterionSatisfactionByCode(String code) public CriterionSatisfaction getCriterionSatisfactionByCode(String code) throws InstanceNotFoundException {
throws InstanceNotFoundException {
if (StringUtils.isBlank(code)) { if ( StringUtils.isBlank(code) ) {
throw new InstanceNotFoundException(code, throw new InstanceNotFoundException(code, CriterionSatisfaction.class.getName());
CriterionSatisfaction.class.getName());
} }
for (CriterionSatisfaction i : criterionSatisfactions) { for (CriterionSatisfaction i : criterionSatisfactions) {
if (i.getCode().equalsIgnoreCase(StringUtils.trim(code))) { if ( i.getCode().equalsIgnoreCase(StringUtils.trim(code)) ) {
return i; return i;
} }
} }
throw new InstanceNotFoundException(code, throw new InstanceNotFoundException(code, CriterionSatisfaction.class.getName());
CriterionSatisfaction.class.getName());
} }
@ -858,11 +849,11 @@ public abstract class Resource extends IntegrationEntity implements
public EffortDuration getAssignedDurationDiscounting( public EffortDuration getAssignedDurationDiscounting(
Map<Long, Set<BaseEntity>> allocationsFromWhichDiscountHours, Map<Long, Set<BaseEntity>> allocationsFromWhichDiscountHours,
LocalDate day) { LocalDate day) {
EffortDuration result = zero(); EffortDuration result = zero();
for (DayAssignment dayAssignment : getAssignmentsForDay(day)) { for (DayAssignment dayAssignment : getAssignmentsForDay(day)) {
if (!dayAssignment if ( !dayAssignment.belongsToSomeOf(allocationsFromWhichDiscountHours) ) {
.belongsToSomeOf(allocationsFromWhichDiscountHours)) {
result = result.plus(dayAssignment.getDuration()); result = result.plus(dayAssignment.getDuration());
} }
} }
@ -876,8 +867,7 @@ public abstract class Resource extends IntegrationEntity implements
this.dayAssignments.addAll(assignments); this.dayAssignments.addAll(assignments);
} }
public void removeAssignments( public void removeAssignments(Collection<? extends DayAssignment> assignments) {
Collection<? extends DayAssignment> assignments) {
Validate.noNullElements(assignments); Validate.noNullElements(assignments);
clearCachedData(); clearCachedData();
this.dayAssignments.removeAll(assignments); this.dayAssignments.removeAll(assignments);
@ -957,24 +947,25 @@ public abstract class Resource extends IntegrationEntity implements
//Create a newList with new Satisfactions and the old satisfactions //Create a newList with new Satisfactions and the old satisfactions
Set<CriterionSatisfaction> newList = new HashSet<CriterionSatisfaction>(addlist); Set<CriterionSatisfaction> newList = new HashSet<CriterionSatisfaction>(addlist);
for(CriterionSatisfaction satisfaction : criterionSatisfactions){ for(CriterionSatisfaction satisfaction : criterionSatisfactions){
if(!newList.contains(satisfaction)){ if( !newList.contains(satisfaction) ){
newList.add(satisfaction); newList.add(satisfaction);
} }
} }
//Create a activeList with not eliminated Satifaction //Create a activeList with not eliminated Satifaction
Set<CriterionSatisfaction> activeList = new HashSet<CriterionSatisfaction>(); Set<CriterionSatisfaction> activeList = new HashSet<CriterionSatisfaction>();
for(CriterionSatisfaction satisfaction : addlist){ for(CriterionSatisfaction satisfaction : addlist){
if(!satisfaction.isIsDeleted()){ if( !satisfaction.isIsDeleted() ){
activeList.add(satisfaction); activeList.add(satisfaction);
} }
} }
validateSatisfactions(activeList); validateSatisfactions(activeList);
criterionSatisfactions.clear(); criterionSatisfactions.clear();
criterionSatisfactions.addAll(newList); criterionSatisfactions.addAll(newList);
} }
private void validateSatisfactions(Set<CriterionSatisfaction> satisfactions) private void validateSatisfactions(Set<CriterionSatisfaction> satisfactions) throws ValidationException {
throws ValidationException {
for (CriterionSatisfaction satisfaction : satisfactions) { for (CriterionSatisfaction satisfaction : satisfactions) {
final Set<CriterionSatisfaction> remainingSatisfactions = new HashSet<CriterionSatisfaction>(); final Set<CriterionSatisfaction> remainingSatisfactions = new HashSet<CriterionSatisfaction>();
remainingSatisfactions.addAll(satisfactions); remainingSatisfactions.addAll(satisfactions);
@ -983,15 +974,12 @@ public abstract class Resource extends IntegrationEntity implements
} }
} }
private void validateSatisfaction(CriterionSatisfaction satisfaction, private void validateSatisfaction(CriterionSatisfaction satisfaction, Set<CriterionSatisfaction> satisfactions)
Set<CriterionSatisfaction> satisfactions)
throws ValidationException { throws ValidationException {
if (!canAddSatisfaction(satisfaction, satisfactions)) { if ( !canAddSatisfaction(satisfaction, satisfactions) ) {
String message = getReasonForNotAddingSatisfaction(satisfaction String message = getReasonForNotAddingSatisfaction(satisfaction.getCriterion().getType());
.getCriterion().getType()); throw new ValidationException(invalidValue(message, "resource", this, satisfaction));
throw new ValidationException(invalidValue(message, "resource",
this, satisfaction));
} }
} }
@ -1001,15 +989,12 @@ public abstract class Resource extends IntegrationEntity implements
} }
public boolean satisfiesCriterions(Collection<? extends ICriterion> criterions) { public boolean satisfiesCriterions(Collection<? extends ICriterion> criterions) {
ICriterion compositedCriterion = CriterionCompounder.buildAnd( ICriterion compositedCriterion = CriterionCompounder.buildAnd(criterions).getResult();
criterions).getResult();
return compositedCriterion.isSatisfiedBy(this); return compositedCriterion.isSatisfiedBy(this);
} }
public boolean satisfiesCriterionsAtSomePoint( public boolean satisfiesCriterionsAtSomePoint(Collection<? extends Criterion> criterions) {
Collection<? extends Criterion> criterions) { AvailabilityTimeLine availability = AvailabilityCalculator.getCriterionsAvailabilityFor(criterions, this);
AvailabilityTimeLine availability = AvailabilityCalculator
.getCriterionsAvailabilityFor(criterions, this);
return !availability.getValidPeriods().isEmpty(); return !availability.getValidPeriods().isEmpty();
} }
@ -1072,8 +1057,7 @@ public abstract class Resource extends IntegrationEntity implements
*/ */
for (CriterionSatisfaction i : getCriterionSatisfactions()) { for (CriterionSatisfaction i : getCriterionSatisfactions()) {
if (!(i.isStartDateSpecified() && i if ( !(i.isStartDateSpecified() && i.isPositiveTimeInterval()) ) {
.isPositiveTimeInterval())) {
return true; return true;
} }
@ -1100,8 +1084,7 @@ public abstract class Resource extends IntegrationEntity implements
* If not, it does not make sense to check assignment overlapping. * If not, it does not make sense to check assignment overlapping.
*/ */
for (ResourcesCostCategoryAssignment each : getResourcesCostCategoryAssignments()) { for (ResourcesCostCategoryAssignment each : getResourcesCostCategoryAssignments()) {
if (!(each.isInitDateSpecified() && each if ( !(each.isInitDateSpecified() && each.isPositiveTimeInterval()) ) {
.isPositiveTimeInterval())) {
return false; return false;
} }
} }
@ -1190,25 +1173,25 @@ public abstract class Resource extends IntegrationEntity implements
@AssertTrue(message = "You have exceeded the maximum limit of resources") @AssertTrue(message = "You have exceeded the maximum limit of resources")
public boolean isMaxResourcesConstraint() { public boolean isMaxResourcesConstraint() {
return Registry.getTransactionService() return Registry.getTransactionService().runOnAnotherReadOnlyTransaction(new IOnTransaction<Boolean>() {
.runOnAnotherReadOnlyTransaction(new IOnTransaction<Boolean>() {
@Override @Override
public Boolean execute() { public Boolean execute() {
Configuration configuration = Registry Configuration configuration = Registry.getConfigurationDAO().getConfiguration();
.getConfigurationDAO().getConfiguration(); if ( configuration == null ) {
if (configuration == null) {
return true; return true;
} }
Integer maxResources = configuration.getMaxResources(); Integer maxResources = configuration.getMaxResources();
if (maxResources != null && maxResources > 0) {
List<Resource> resources = Registry if ( maxResources != null && maxResources > 0 ) {
.getResourceDAO().findAll(); List<Resource> resources = Registry.getResourceDAO().findAll();
int resourcesNumber = resources.size(); int resourcesNumber = resources.size();
if (isNewObject()) {
if ( isNewObject() ) {
resourcesNumber++; resourcesNumber++;
} }
if (resourcesNumber > maxResources) {
if ( resourcesNumber > maxResources ) {
return false; return false;
} }
} }

View file

@ -29,8 +29,7 @@ import org.apache.commons.lang.Validate;
* Implementation of {@link ITreeParentNode} that mutates a list <br /> * Implementation of {@link ITreeParentNode} that mutates a list <br />
* @author Óscar González Fernández <ogonzalez@igalia.com> * @author Óscar González Fernández <ogonzalez@igalia.com>
*/ */
public abstract class TreeNodeOnList<T extends ITreeNode<T>> implements public abstract class TreeNodeOnList<T extends ITreeNode<T>> implements ITreeParentNode<T> {
ITreeParentNode<T> {
private final List<T> children; private final List<T> children;
@ -73,7 +72,7 @@ public abstract class TreeNodeOnList<T extends ITreeNode<T>> implements
@Override @Override
public void down(T existentChild) { public void down(T existentChild) {
int position = children.indexOf(existentChild); int position = children.indexOf(existentChild);
if (position < children.size() - 1) { if ( position < children.size() - 1 ) {
children.remove(position); children.remove(position);
children.add(position + 1, existentChild); children.add(position + 1, existentChild);
} }

View file

@ -73,11 +73,9 @@ public class EffortDuration implements Comparable<EffortDuration> {
} }
} }
private static final Pattern lenientEffortDurationSpecification = Pattern private static final Pattern lenientEffortDurationSpecification = Pattern.compile("(\\d+)(\\s*:\\s*\\d+\\s*)*");
.compile("(\\d+)(\\s*:\\s*\\d+\\s*)*");
private static final Pattern contiguousDigitsPattern = Pattern private static final Pattern contiguousDigitsPattern = Pattern.compile("\\d+");
.compile("\\d+");
/** /**
* If an {@link EffortDuration} can't be parsed <code>null</code> is * If an {@link EffortDuration} can't be parsed <code>null</code> is
@ -379,11 +377,9 @@ public class EffortDuration implements Comparable<EffortDuration> {
return EffortDuration.seconds(total.seconds / items); return EffortDuration.seconds(total.seconds / items);
} }
private static int roundHalfUpToHours( private static int roundHalfUpToHours(EnumMap<Granularity, Integer> components) {
EnumMap<Granularity, Integer> components) {
int seconds = components.get(Granularity.SECONDS); int seconds = components.get(Granularity.SECONDS);
int minutes = components.get(Granularity.MINUTES) int minutes = components.get(Granularity.MINUTES) + (seconds < 30 ? 0 : 1);
+ (seconds < 30 ? 0 : 1);
int hours = components.get(Granularity.HOURS) + (minutes < 30 ? 0 : 1); int hours = components.get(Granularity.HOURS) + (minutes < 30 ? 0 : 1);
return hours; return hours;
} }

View file

@ -377,8 +377,7 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
return result; return result;
} }
private static Iterator<PartialDay> createIterator( private static Iterator<PartialDay> createIterator(final IntraDayDate start, final IterationPredicate predicate) {
final IntraDayDate start, final IterationPredicate predicate) {
return new Iterator<IntraDayDate.PartialDay>() { return new Iterator<IntraDayDate.PartialDay>() {
private IntraDayDate current = start; private IntraDayDate current = start;
@ -390,7 +389,7 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
@Override @Override
public PartialDay next() { public PartialDay next() {
if (!hasNext()) { if ( !hasNext() ) {
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
IntraDayDate start = current; IntraDayDate start = current;
@ -399,8 +398,7 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
} }
private IntraDayDate calculateNext(IntraDayDate date) { private IntraDayDate calculateNext(IntraDayDate date) {
IntraDayDate nextDay = IntraDayDate.startOfDay(date.date IntraDayDate nextDay = IntraDayDate.startOfDay(date.date.plusDays(1));
.plusDays(1));
return predicate.limitNext(nextDay); return predicate.limitNext(nextDay);
} }
@ -452,18 +450,13 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
* @return a new {@link IntraDayDate} * @return a new {@link IntraDayDate}
*/ */
public IntraDayDate increaseBy(ResourcesPerDay resourcesPerDay, EffortDuration effort) { public IntraDayDate increaseBy(ResourcesPerDay resourcesPerDay, EffortDuration effort) {
EffortDuration newEnd = this.getEffortDuration().plus( EffortDuration newEnd = this.getEffortDuration().plus(calculateProportionalDuration(resourcesPerDay, effort));
calculateProportionalDuration(resourcesPerDay,
effort));
return IntraDayDate.create(getDate(), newEnd); return IntraDayDate.create(getDate(), newEnd);
} }
private EffortDuration calculateProportionalDuration( private EffortDuration calculateProportionalDuration(ResourcesPerDay resourcesPerDay, EffortDuration effort) {
ResourcesPerDay resourcesPerDay, EffortDuration effort) {
int seconds = effort.getSeconds(); int seconds = effort.getSeconds();
BigDecimal end = new BigDecimal(seconds).divide( BigDecimal end = new BigDecimal(seconds).divide(resourcesPerDay.getAmount(), RoundingMode.HALF_UP);
resourcesPerDay.getAmount(),
RoundingMode.HALF_UP);
return seconds(end.intValue()); return seconds(end.intValue());
} }
@ -478,22 +471,18 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
* @param effort * @param effort
* @return a new {@link IntraDayDate} * @return a new {@link IntraDayDate}
*/ */
public IntraDayDate decreaseBy(ResourcesPerDay resourcesPerDay, public IntraDayDate decreaseBy(ResourcesPerDay resourcesPerDay, EffortDuration effort) {
EffortDuration effort) { EffortDuration proportionalDuration = calculateProportionalDuration(resourcesPerDay, effort);
EffortDuration proportionalDuration = calculateProportionalDuration( if ( getEffortDuration().compareTo(proportionalDuration) > 0 ) {
resourcesPerDay, effort); return IntraDayDate.create(getDate(), getEffortDuration().minus(proportionalDuration));
if (getEffortDuration().compareTo(proportionalDuration) > 0) {
return IntraDayDate.create(getDate(),
getEffortDuration().minus(proportionalDuration));
} else { } else {
return IntraDayDate.startOfDay(getDate()); return IntraDayDate.startOfDay(getDate());
} }
} }
public static IntraDayDate convert(LocalDate date, public static IntraDayDate convert(LocalDate date, IntraDayDate morePreciseAlternative) {
IntraDayDate morePreciseAlternative) {
LocalDate morePreciseDate = morePreciseAlternative.getDate(); LocalDate morePreciseDate = morePreciseAlternative.getDate();
if (morePreciseDate.equals(date)) { if ( morePreciseDate.equals(date) ) {
return morePreciseAlternative; return morePreciseAlternative;
} }
return startOfDay(date); return startOfDay(date);
@ -512,13 +501,12 @@ public class IntraDayDate implements Comparable<IntraDayDate> {
EffortDuration result = EffortDuration.hours(days * 8); EffortDuration result = EffortDuration.hours(days * 8);
if (!getEffortDuration().isZero()) { if ( !getEffortDuration().isZero()) {
result = result.minus(EffortDuration.hours(8)); result = result.minus(EffortDuration.hours(8));
result = result.plus(EffortDuration.hours(8).minus( result = result.plus(EffortDuration.hours(8).minus(getEffortDuration()));
getEffortDuration()));
} }
if (!end.getEffortDuration().isZero()) { if ( !end.getEffortDuration().isZero() ) {
result = result.plus(end.getEffortDuration()); result = result.plus(end.getEffortDuration());
} }

View file

@ -38,37 +38,31 @@ public class ProportionalDistributorTest {
@Test @Test
public void mustGiveTheSameDistributionForSameTotal() { public void mustGiveTheSameDistributionForSameTotal() {
ProportionalDistributor distributor = ProportionalDistributor.create( ProportionalDistributor distributor = ProportionalDistributor.create(100, 200);
100, 200);
assertThat(distributor.distribute(300), equalToDistribution(100, 200)); assertThat(distributor.distribute(300), equalToDistribution(100, 200));
} }
@Test @Test
public void exactDivisionsWorkOk() { public void exactDivisionsWorkOk() {
ProportionalDistributor distributor = ProportionalDistributor.create( ProportionalDistributor distributor = ProportionalDistributor.create(100, 100, 100);
100, 100, 100); assertThat(distributor.distribute(600), equalToDistribution(200, 200, 200));
assertThat(distributor.distribute(600), equalToDistribution(200, 200,
200));
} }
@Test @Test
public void distributingZeroGivesZeroShares() { public void distributingZeroGivesZeroShares() {
ProportionalDistributor distributor = ProportionalDistributor.create( ProportionalDistributor distributor = ProportionalDistributor.create(100, 100, 100);
100, 100, 100);
assertThat(distributor.distribute(0), equalToDistribution(0, 0, 0)); assertThat(distributor.distribute(0), equalToDistribution(0, 0, 0));
} }
@Test @Test
public void ifOneOfTheProportionsIsZeroAlwaysGivesZeros() { public void ifOneOfTheProportionsIsZeroAlwaysGivesZeros() {
ProportionalDistributor distributor = ProportionalDistributor.create( ProportionalDistributor distributor = ProportionalDistributor.create(100, 100, 0);
100, 100, 0);
assertThat(distributor.distribute(100), equalToDistribution(50, 50, 0)); assertThat(distributor.distribute(100), equalToDistribution(50, 50, 0));
} }
@Test @Test
public void ifEmptySharesProvidedItDistributesEqually() { public void ifEmptySharesProvidedItDistributesEqually() {
ProportionalDistributor distributor = ProportionalDistributor.create(0, ProportionalDistributor distributor = ProportionalDistributor.create(0, 0, 0, 0);
0, 0, 0);
assertThat(distributor.distribute(4), equalToDistribution(1, 1, 1, 1)); assertThat(distributor.distribute(4), equalToDistribution(1, 1, 1, 1));
assertThat(distributor.distribute(5), equalToDistribution(2, 1, 1, 1)); assertThat(distributor.distribute(5), equalToDistribution(2, 1, 1, 1));
assertThat(distributor.distribute(6), equalToDistribution(2, 2, 1, 1)); assertThat(distributor.distribute(6), equalToDistribution(2, 2, 1, 1));
@ -84,15 +78,13 @@ public class ProportionalDistributorTest {
@Test @Test
public void disputedPartGoesToFirstIfEqualWeight() { public void disputedPartGoesToFirstIfEqualWeight() {
ProportionalDistributor distributor = ProportionalDistributor.create( ProportionalDistributor distributor = ProportionalDistributor.create(10, 10, 10);
10, 10, 10);
assertThat(distributor.distribute(10), equalToDistribution(4, 3, 3)); assertThat(distributor.distribute(10), equalToDistribution(4, 3, 3));
} }
@Test @Test
public void distributionIsKept() { public void distributionIsKept() {
ProportionalDistributor distributor = ProportionalDistributor.create(2, ProportionalDistributor distributor = ProportionalDistributor.create(2, 3, 5);
3, 5);
assertThat(distributor.distribute(1), equalToDistribution(0, 0, 1)); assertThat(distributor.distribute(1), equalToDistribution(0, 0, 1));
assertThat(distributor.distribute(2), equalToDistribution(0, 1, 1)); assertThat(distributor.distribute(2), equalToDistribution(0, 1, 1));
assertThat(distributor.distribute(3), equalToDistribution(1, 1, 1)); assertThat(distributor.distribute(3), equalToDistribution(1, 1, 1));
@ -105,8 +97,7 @@ public class ProportionalDistributorTest {
@Test @Test
public void addingOneEachTime() { public void addingOneEachTime() {
ProportionalDistributor distributor = ProportionalDistributor.create( ProportionalDistributor distributor = ProportionalDistributor.create(99, 101, 800);
99, 101, 800);
assertThat(distributor.distribute(1), equalToDistribution(0, 0, 1)); assertThat(distributor.distribute(1), equalToDistribution(0, 0, 1));
assertThat(distributor.distribute(3), equalToDistribution(0, 0, 3)); assertThat(distributor.distribute(3), equalToDistribution(0, 0, 3));
assertThat(distributor.distribute(6), equalToDistribution(0, 1, 5)); assertThat(distributor.distribute(6), equalToDistribution(0, 1, 5));
@ -129,7 +120,7 @@ public class ProportionalDistributorTest {
@Override @Override
public boolean matches(Object object) { public boolean matches(Object object) {
if (object instanceof int[]) { if ( object instanceof int[] ) {
int[] arg = (int[]) object; int[] arg = (int[]) object;
return Arrays.equals(arg, distribution); return Arrays.equals(arg, distribution);
} }
@ -138,8 +129,7 @@ public class ProportionalDistributorTest {
@Override @Override
public void describeTo(Description description) { public void describeTo(Description description) {
description.appendText("must equal " description.appendText("must equal " + Arrays.toString(distribution));
+ Arrays.toString(distribution));
} }
}; };
} }
@ -151,8 +141,7 @@ public class ProportionalDistributorTest {
@Test @Test
public void notThrowDivisionByZeroExceptionAtDistributeMehtod() { public void notThrowDivisionByZeroExceptionAtDistributeMehtod() {
ProportionalDistributor distributor = ProportionalDistributor ProportionalDistributor distributor = ProportionalDistributor.create(100);
.create(100);
distributor.distribute(0); distributor.distribute(0);
} }

View file

@ -50,11 +50,9 @@ import org.springframework.test.context.transaction.TransactionalTestExecutionLi
* @author Bob McCune * @author Bob McCune
* @version 1.0 * @version 1.0
*/ */
public class DBUnitTestExecutionListener extends public class DBUnitTestExecutionListener extends TransactionalTestExecutionListener {
TransactionalTestExecutionListener {
private static final Log logger = LogFactory private static final Log logger = LogFactory.getLog(DBUnitTestExecutionListener.class);
.getLog(DBUnitTestExecutionListener.class);
private static final String DEFAULT_DATASOURCE_NAME = "dataSource"; private static final String DEFAULT_DATASOURCE_NAME = "dataSource";
private static final String TABLE_TYPES[] = { "TABLE", "ALIAS" }; private static final String TABLE_TYPES[] = { "TABLE", "ALIAS" };

View file

@ -29,10 +29,9 @@ package org.libreplan.business.test;
*/ */
public class BusinessGlobalNames { public class BusinessGlobalNames {
public final static String BUSINESS_SPRING_CONFIG_TEST_FILE = public final static String BUSINESS_SPRING_CONFIG_TEST_FILE = "classpath:/libreplan-business-spring-config-test.xml";
"classpath:/libreplan-business-spring-config-test.xml";
public final static String DBUNIT_CONFIG_TEST_FILE = "/dbunit-data.xml";
public final static String DBUNIT_CONFIG_TEST_FILE =
"/dbunit-data.xml";
private BusinessGlobalNames () {} private BusinessGlobalNames () {}
} }

View file

@ -52,10 +52,8 @@ public class DefaultAdvanceTypesBootstrapListenerTest {
private IAdvanceTypeDAO advanceTypeDAO; private IAdvanceTypeDAO advanceTypeDAO;
private IDataBootstrap getAdvanceTypeBootstrap() { private IDataBootstrap getAdvanceTypeBootstrap() {
String simpleName = DefaultAdvanceTypesBootstrapListener.class String simpleName = DefaultAdvanceTypesBootstrapListener.class.getSimpleName();
.getSimpleName(); return dataBootstraps.get(simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1));
return dataBootstraps.get(simpleName.substring(0, 1).toLowerCase()
+ simpleName.substring(1));
} }
@Test @Test

View file

@ -57,8 +57,7 @@ public class AdvanceAssignmentDAOTest {
private AdvanceType givenAdvanceType() { private AdvanceType givenAdvanceType() {
BigDecimal value = new BigDecimal(100); BigDecimal value = new BigDecimal(100);
BigDecimal precision = BigDecimal.ONE; BigDecimal precision = BigDecimal.ONE;
AdvanceType advanceType = AdvanceType.create("advance-type", value, AdvanceType advanceType = AdvanceType.create("advance-type", value, true, precision, true, false);
true, precision, true, false);
advanceTypeDAO.save(advanceType); advanceTypeDAO.save(advanceType);
return advanceType; return advanceType;
} }
@ -66,8 +65,7 @@ public class AdvanceAssignmentDAOTest {
@Test @Test
@Transactional @Transactional
public void saveValidAdvanceAssignment() { public void saveValidAdvanceAssignment() {
AdvanceAssignment advance = DirectAdvanceAssignment.create(false, AdvanceAssignment advance = DirectAdvanceAssignment.create(false, BigDecimal.TEN);
BigDecimal.TEN);
advance.setAdvanceType(givenAdvanceType()); advance.setAdvanceType(givenAdvanceType());
advanceAssignmentDAO.save(advance); advanceAssignmentDAO.save(advance);
assertTrue(advance.getId() != null); assertTrue(advance.getId() != null);
@ -76,8 +74,7 @@ public class AdvanceAssignmentDAOTest {
@Test(expected = ValidationException.class) @Test(expected = ValidationException.class)
@Transactional @Transactional
public void saveAdvanceAssignmentWithZeroAsMaxValue() { public void saveAdvanceAssignmentWithZeroAsMaxValue() {
AdvanceAssignment advance = DirectAdvanceAssignment.create(false, AdvanceAssignment advance = DirectAdvanceAssignment.create(false, BigDecimal.ZERO);
BigDecimal.ZERO);
advance.setAdvanceType(givenAdvanceType()); advance.setAdvanceType(givenAdvanceType());
advanceAssignmentDAO.save(advance); advanceAssignmentDAO.save(advance);
assertTrue(advance.getId() != null); assertTrue(advance.getId() != null);
@ -86,8 +83,7 @@ public class AdvanceAssignmentDAOTest {
@Test(expected = ValidationException.class) @Test(expected = ValidationException.class)
@Transactional @Transactional
public void saveAdvanceAssignmentWithNegativeNumberAsMaxValue() { public void saveAdvanceAssignmentWithNegativeNumberAsMaxValue() {
AdvanceAssignment advance = DirectAdvanceAssignment.create(false, AdvanceAssignment advance = DirectAdvanceAssignment.create(false, BigDecimal.valueOf(-10));
BigDecimal.valueOf(-10));
advance.setAdvanceType(givenAdvanceType()); advance.setAdvanceType(givenAdvanceType());
advanceAssignmentDAO.save(advance); advanceAssignmentDAO.save(advance);
assertTrue(advance.getId() != null); assertTrue(advance.getId() != null);

View file

@ -111,18 +111,13 @@ public class GenericResourceAllocationTest {
private Task givenTaskWithStartAndEnd(Interval interval) { private Task givenTaskWithStartAndEnd(Interval interval) {
Task task = createNiceMock(Task.class); Task task = createNiceMock(Task.class);
setupCriterions(task); setupCriterions(task);
IntraDayDate start = IntraDayDate.startOfDay(interval.getStart() IntraDayDate start = IntraDayDate.startOfDay(interval.getStart().toLocalDate());
.toLocalDate()); IntraDayDate end = IntraDayDate.startOfDay(interval.getEnd().toLocalDate());
IntraDayDate end = IntraDayDate.startOfDay(interval.getEnd() expect(task.getStartDate()).andReturn(interval.getStart().toDate()).anyTimes();
.toLocalDate());
expect(task.getStartDate()).andReturn(interval.getStart().toDate())
.anyTimes();
expect(task.getIntraDayStartDate()).andReturn(start).anyTimes(); expect(task.getIntraDayStartDate()).andReturn(start).anyTimes();
expect(task.getEndDate()).andReturn(interval.getEnd().toDate()) expect(task.getEndDate()).andReturn(interval.getEnd().toDate()).anyTimes();
.anyTimes();
expect(task.getIntraDayEndDate()).andReturn(end).anyTimes(); expect(task.getIntraDayEndDate()).andReturn(end).anyTimes();
expect(task.getFirstDayNotConsolidated()).andReturn(start) expect(task.getFirstDayNotConsolidated()).andReturn(start).anyTimes();
.anyTimes();
expect(task.getCalendar()).andReturn(baseCalendar).anyTimes(); expect(task.getCalendar()).andReturn(baseCalendar).anyTimes();
replay(task); replay(task);
return this.task = task; return this.task = task;
@ -137,8 +132,7 @@ public class GenericResourceAllocationTest {
} }
private void setupCriterions(Task task) { private void setupCriterions(Task task) {
expect(task.getCriterions()).andReturn(givenPredefinedCriterions()) expect(task.getCriterions()).andReturn(givenPredefinedCriterions()).anyTimes();
.anyTimes();
} }
private void givenGenericResourceAllocationForTask(Task task) { private void givenGenericResourceAllocationForTask(Task task) {
@ -159,9 +153,7 @@ public class GenericResourceAllocationTest {
} }
private void setupIsSatisfiedByAll(Criterion criterion) { private void setupIsSatisfiedByAll(Criterion criterion) {
expect( expect(criterion.isSatisfiedBy(isA(Resource.class), isA(LocalDate.class))).andReturn(true).anyTimes();
criterion.isSatisfiedBy(isA(Resource.class),
isA(LocalDate.class))).andReturn(true).anyTimes();
} }
private void givenWorkersWithoutLoadAndWithoutCalendar() { private void givenWorkersWithoutLoadAndWithoutCalendar() {
@ -175,9 +167,8 @@ public class GenericResourceAllocationTest {
public static void mockZeroLoad(Resource... resources) { public static void mockZeroLoad(Resource... resources) {
for (Resource each : resources) { for (Resource each : resources) {
expect( expect(each.getAssignedDurationDiscounting(isA(Map.class), isA(LocalDate.class)))
each.getAssignedDurationDiscounting(isA(Map.class), .andReturn(zero()).anyTimes();
isA(LocalDate.class))).andReturn(zero()).anyTimes();
} }
} }
@ -211,7 +202,7 @@ public class GenericResourceAllocationTest {
} }
EffortDuration getLoad(LocalDate date) { EffortDuration getLoad(LocalDate date) {
if (exceptions.containsKey(date)) { if ( exceptions.containsKey(date) ) {
return exceptions.get(date); return exceptions.get(date);
} }
return defaultLoad; return defaultLoad;
@ -219,37 +210,33 @@ public class GenericResourceAllocationTest {
} }
private Worker createWorkerWithLoad(ResourceCalendar resourceCalendar, private Worker createWorkerWithLoad(ResourceCalendar resourceCalendar, int hours) {
int hours) { return createWorkerWithLoad(resourceCalendar, new LoadSpec(hours(hours)));
return createWorkerWithLoad(resourceCalendar,
new LoadSpec(hours(hours)));
} }
private Worker createWorkerWithLoad(ResourceCalendar resourceCalendar, private Worker createWorkerWithLoad(ResourceCalendar resourceCalendar, final LoadSpec loadSpec) {
final LoadSpec loadSpec) {
Worker result = createNiceMock(Worker.class); Worker result = createNiceMock(Worker.class);
expect(result.getCalendar()).andReturn(resourceCalendar).anyTimes(); expect(result.getCalendar()).andReturn(resourceCalendar).anyTimes();
expect(
result.getAssignedDurationDiscounting(isA(Map.class), expect(result.getAssignedDurationDiscounting(isA(Map.class), isA(LocalDate.class))).andAnswer(
isA(LocalDate.class))).andAnswer(
new IAnswer<EffortDuration>() { new IAnswer<EffortDuration>() {
@Override @Override
public EffortDuration answer() throws Throwable { public EffortDuration answer() throws Throwable {
Object[] currentArguments = EasyMock Object[] currentArguments = EasyMock.getCurrentArguments();
.getCurrentArguments();
LocalDate date = (LocalDate) currentArguments[1]; LocalDate date = (LocalDate) currentArguments[1];
return loadSpec.getLoad(date); return loadSpec.getLoad(date);
} }
}).anyTimes(); }).anyTimes();
expect(result.getSatisfactionsFor(isA(Criterion.class))).andReturn(
satisfactionsForPredefinedCriterions(result)).anyTimes(); expect(result.getSatisfactionsFor(isA(Criterion.class)))
.andReturn(satisfactionsForPredefinedCriterions(result)).anyTimes();
replay(result); replay(result);
return result; return result;
} }
private List<CriterionSatisfaction> satisfactionsForPredefinedCriterions( private List<CriterionSatisfaction> satisfactionsForPredefinedCriterions(Resource resource) {
Resource resource) {
List<CriterionSatisfaction> result = new ArrayList<CriterionSatisfaction>(); List<CriterionSatisfaction> result = new ArrayList<CriterionSatisfaction>();
for (Criterion each : criterions) { for (Criterion each : criterions) {
result.add(CriterionSatisfaction.create(each, resource, result.add(CriterionSatisfaction.create(each, resource,
@ -259,22 +246,18 @@ public class GenericResourceAllocationTest {
} }
private org.libreplan.business.resources.entities.Interval fromVeryEarlyTime() { private org.libreplan.business.resources.entities.Interval fromVeryEarlyTime() {
return org.libreplan.business.resources.entities.Interval return org.libreplan.business.resources.entities.Interval.from(new LocalDate(0, 1, 1));
.from(new LocalDate(0, 1, 1));
} }
private void givenCalendarsForResources(int capacity1, int capacity2, private void givenCalendarsForResources(int capacity1, int capacity2, int capacity3) {
int capacity3) { givenCalendarsForResources(fromHours(capacity1), fromHours(capacity2), fromHours(capacity3));
givenCalendarsForResources(fromHours(capacity1), fromHours(capacity2),
fromHours(capacity3));
} }
private Capacity fromHours(int hours) { private Capacity fromHours(int hours) {
return Capacity.create(hours(hours)).overAssignableWithoutLimit(); return Capacity.create(hours(hours)).overAssignableWithoutLimit();
} }
private void givenCalendarsForResources(Capacity capacity1, private void givenCalendarsForResources(Capacity capacity1, Capacity capacity2, Capacity capacity3) {
Capacity capacity2, Capacity capacity3) {
workerCalendars = new ArrayList<ResourceCalendar>(); workerCalendars = new ArrayList<ResourceCalendar>();
workerCalendars.add(createCalendar(ResourceCalendar.class, capacity1)); workerCalendars.add(createCalendar(ResourceCalendar.class, capacity1));
workerCalendars.add(createCalendar(ResourceCalendar.class, capacity2)); workerCalendars.add(createCalendar(ResourceCalendar.class, capacity2));
@ -282,18 +265,16 @@ public class GenericResourceAllocationTest {
} }
private void givenWorkersWithLoads(int hours1, int hours2, int hours3) { private void givenWorkersWithLoads(int hours1, int hours2, int hours3) {
givenWorkersWithLoads(LoadSpec.withHours(hours1), givenWorkersWithLoads(LoadSpec.withHours(hours1), LoadSpec.withHours(hours2), LoadSpec.withHours(hours3));
LoadSpec.withHours(hours2), LoadSpec.withHours(hours3));
} }
private void givenWorkersWithLoads(LoadSpec load1, LoadSpec load2, private void givenWorkersWithLoads(LoadSpec load1, LoadSpec load2, LoadSpec load3) {
LoadSpec load3) {
ResourceCalendar[] calendars; ResourceCalendar[] calendars;
if (workerCalendars == null) { if ( workerCalendars == null ) {
calendars = new ResourceCalendar[] { null, null, null }; calendars = new ResourceCalendar[] { null, null, null };
} else { } else {
calendars = new ResourceCalendar[] { workerCalendars.get(0), calendars =
workerCalendars.get(1), workerCalendars.get(2) }; new ResourceCalendar[] { workerCalendars.get(0), workerCalendars.get(1), workerCalendars.get(2) };
} }
worker1 = createWorkerWithLoad(calendars[0], load1); worker1 = createWorkerWithLoad(calendars[0], load1);
worker2 = createWorkerWithLoad(calendars[1], load2); worker2 = createWorkerWithLoad(calendars[1], load2);
@ -302,54 +283,53 @@ public class GenericResourceAllocationTest {
} }
private void givenBaseCalendarWithoutExceptions(int hoursPerDay) { private void givenBaseCalendarWithoutExceptions(int hoursPerDay) {
BaseCalendar baseCalendar = createCalendar(BaseCalendar.class, Capacity BaseCalendar baseCalendar =
.create(hours(hoursPerDay)).overAssignableWithoutLimit()); createCalendar(BaseCalendar.class, Capacity.create(hours(hoursPerDay)).overAssignableWithoutLimit());
this.baseCalendar = baseCalendar; this.baseCalendar = baseCalendar;
} }
private <T extends BaseCalendar> T createCalendar(Class<T> klass, private <T extends BaseCalendar> T createCalendar(Class<T> klass, final Capacity capacity) {
final Capacity capacity) {
return createCalendar(klass, capacity, 1); return createCalendar(klass, capacity, 1);
} }
private <T extends BaseCalendar> T createCalendar(Class<T> klass, private <T extends BaseCalendar> T createCalendar(Class<T> klass, final Capacity capacity, int units) {
final Capacity capacity, int units) {
final Capacity capacityMultipliedByUnits = capacity.multiplyBy(units); final Capacity capacityMultipliedByUnits = capacity.multiplyBy(units);
BaseCalendar baseCalendar = createNiceMock(klass); BaseCalendar baseCalendar = createNiceMock(klass);
expect(baseCalendar.getCapacityOn(isA(PartialDay.class))).andAnswer( expect(baseCalendar.getCapacityOn(isA(PartialDay.class))).andAnswer(
new IAnswer<EffortDuration>() { new IAnswer<EffortDuration>() {
@Override @Override
public EffortDuration answer() throws Throwable { public EffortDuration answer() throws Throwable {
PartialDay day = (PartialDay) getCurrentArguments()[0]; PartialDay day = (PartialDay) getCurrentArguments()[0];
return day.limitWorkingDay(capacityMultipliedByUnits return day.limitWorkingDay(capacityMultipliedByUnits.getStandardEffort());
.getStandardEffort());
} }
}).anyTimes(); }).anyTimes();
expect(baseCalendar.isActive(isA(LocalDate.class))).andReturn(true)
.anyTimes(); expect(baseCalendar.isActive(isA(LocalDate.class))).andReturn(true).anyTimes();
expect(baseCalendar.canWorkOn(isA(LocalDate.class))).andReturn(true)
.anyTimes(); expect(baseCalendar.canWorkOn(isA(LocalDate.class))).andReturn(true).anyTimes();
expect(baseCalendar.getAvailability()).andReturn(
AvailabilityTimeLine.allValid()).anyTimes(); expect(baseCalendar.getAvailability()).andReturn(AvailabilityTimeLine.allValid()).anyTimes();
IAnswer<EffortDuration> durationAnswer = new IAnswer<EffortDuration>() { IAnswer<EffortDuration> durationAnswer = new IAnswer<EffortDuration>() {
@Override @Override
public EffortDuration answer() throws Throwable { public EffortDuration answer() throws Throwable {
PartialDay day = (PartialDay) getCurrentArguments()[0]; PartialDay day = (PartialDay) getCurrentArguments()[0];
ResourcesPerDay resourcesPerDay = (ResourcesPerDay) getCurrentArguments()[1]; ResourcesPerDay resourcesPerDay = (ResourcesPerDay) getCurrentArguments()[1];
return capacityMultipliedByUnits.limitDuration(resourcesPerDay return capacityMultipliedByUnits.limitDuration(
.asDurationGivenWorkingDayOf(day.limitWorkingDay(capacity resourcesPerDay.asDurationGivenWorkingDayOf(day.limitWorkingDay(capacity.getStandardEffort())));
.getStandardEffort())));
} }
}; };
expect(
baseCalendar.asDurationOn(isA(PartialDay.class), expect(baseCalendar.asDurationOn(isA(PartialDay.class), isA(ResourcesPerDay.class)))
isA(ResourcesPerDay.class))).andAnswer(durationAnswer) .andAnswer(durationAnswer).anyTimes();
.anyTimes();
expect(baseCalendar.getCapacityWithOvertime(isA(LocalDate.class))) expect(baseCalendar.getCapacityWithOvertime(isA(LocalDate.class)))
.andReturn(capacityMultipliedByUnits).anyTimes(); .andReturn(capacityMultipliedByUnits).anyTimes();
if (baseCalendar instanceof ResourceCalendar) { if ( baseCalendar instanceof ResourceCalendar ) {
ResourceCalendar resourceCalendar = (ResourceCalendar) baseCalendar; ResourceCalendar resourceCalendar = (ResourceCalendar) baseCalendar;
expect(resourceCalendar.getCapacity()).andReturn(units).anyTimes(); expect(resourceCalendar.getCapacity()).andReturn(units).anyTimes();
} }
@ -360,24 +340,21 @@ public class GenericResourceAllocationTest {
@Test @Test
public void theCriterionsAreCopied() { public void theCriterionsAreCopied() {
givenGenericResourceAllocation(); givenGenericResourceAllocation();
GenericResourceAllocation copied = (GenericResourceAllocation) genericResourceAllocation GenericResourceAllocation copied = (GenericResourceAllocation) genericResourceAllocation.copy(mockScenario());
.copy(mockScenario());
assertThat(copied.getCriterions(), equalTo(criterions)); assertThat(copied.getCriterions(), equalTo(criterions));
} }
@Test @Test
public void hasTheCriterionsOfTheTask() { public void hasTheCriterionsOfTheTask() {
givenGenericResourceAllocation(); givenGenericResourceAllocation();
assertThat(genericResourceAllocation.getCriterions(), assertThat(genericResourceAllocation.getCriterions(), equalTo(criterions));
equalTo(criterions));
} }
@Test @Test
public void getOrderedAssignmentsReturnsEmptyListIfNotExistsWorker() { public void getOrderedAssignmentsReturnsEmptyListIfNotExistsWorker() {
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
givenGenericResourceAllocation(); givenGenericResourceAllocation();
List<GenericDayAssignment> assignments = genericResourceAllocation List<GenericDayAssignment> assignments = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertNotNull(assignments); assertNotNull(assignments);
assertTrue(assignments.isEmpty()); assertTrue(assignments.isEmpty());
} }
@ -389,13 +366,10 @@ public class GenericResourceAllocationTest {
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1)).allocate(ResourcesPerDay.amount(1));
.allocate(ResourcesPerDay.amount(1));
List<GenericDayAssignment> assignments = genericResourceAllocation List<GenericDayAssignment> assignments = genericResourceAllocation.getAssignments();
.getAssignments(); assertThat(assignments, haveResourceAllocation(genericResourceAllocation));
assertThat(assignments,
haveResourceAllocation(genericResourceAllocation));
} }
@Test @Test
@ -403,18 +377,14 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1)).allocate(ResourcesPerDay.amount(1));
.allocate(ResourcesPerDay.amount(1));
List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1); assertThat(orderedAssignmentsFor, from(start).consecutiveDays(TASK_DURATION_DAYS));
assertThat(orderedAssignmentsFor, from(start).consecutiveDays(
TASK_DURATION_DAYS));
} }
@Test @Test
@ -422,8 +392,7 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
ResourcesPerDay resourcesPerDay = ResourcesPerDay.amount(1); ResourcesPerDay resourcesPerDay = ResourcesPerDay.amount(1);
@ -432,10 +401,8 @@ public class GenericResourceAllocationTest {
.resourcesPerDayUntil(plusDays(start, 2)) .resourcesPerDayUntil(plusDays(start, 2))
.allocate(resourcesPerDay); .allocate(resourcesPerDay);
List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1); int hoursPerDay = resourcesPerDay.asDurationGivenWorkingDayOf(EffortDuration.hours(8)).getHours();
int hoursPerDay = resourcesPerDay.asDurationGivenWorkingDayOf(
EffortDuration.hours(8)).getHours();
assertThat(orderedAssignmentsFor, haveHours(hoursPerDay, hoursPerDay)); assertThat(orderedAssignmentsFor, haveHours(hoursPerDay, hoursPerDay));
} }
@ -444,22 +411,18 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
ResourcesPerDay resourcesPerDay = ResourcesPerDay.amount(1); ResourcesPerDay resourcesPerDay = ResourcesPerDay.amount(1);
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1)).allocate(resourcesPerDay);
.allocate(resourcesPerDay);
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1))
.resourcesPerDayUntil(plusDays(start, 2)) .resourcesPerDayUntil(plusDays(start, 2))
.allocate(resourcesPerDay); .allocate(resourcesPerDay);
List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1); int hoursPerDay = resourcesPerDay.asDurationGivenWorkingDayOf(EffortDuration.hours(8)).getHours();
int hoursPerDay = resourcesPerDay.asDurationGivenWorkingDayOf(
EffortDuration.hours(8)).getHours();
assertThat(orderedAssignmentsFor, haveHours(hoursPerDay, hoursPerDay)); assertThat(orderedAssignmentsFor, haveHours(hoursPerDay, hoursPerDay));
} }
@ -475,8 +438,7 @@ public class GenericResourceAllocationTest {
.resourcesPerDayUntil(minusDays(start, 1)) .resourcesPerDayUntil(minusDays(start, 1))
.allocate(resourcesPerDay); .allocate(resourcesPerDay);
assertTrue(genericResourceAllocation.getOrderedAssignmentsFor(worker1) assertTrue(genericResourceAllocation.getOrderedAssignmentsFor(worker1).isEmpty());
.isEmpty());
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -503,45 +465,38 @@ public class GenericResourceAllocationTest {
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1))
.resourcesPerDayUntil(IntraDayDate.startOfDay(start)) .resourcesPerDayUntil(IntraDayDate.startOfDay(start))
.allocate(resourcesPerDay); .allocate(resourcesPerDay);
assertThat(genericResourceAllocation.getResourcesPerDay(),
equalTo(ResourcesPerDay.amount(0))); assertThat(genericResourceAllocation.getResourcesPerDay(), equalTo(ResourcesPerDay.amount(0)));
assertTrue(genericResourceAllocation.getOrderedAssignmentsFor(worker1) assertTrue(genericResourceAllocation.getOrderedAssignmentsFor(worker1).isEmpty());
.isEmpty());
} }
@Test @Test
public void theResourcesPerDayAreChangedWhenTheAllocationIsDone() { public void theResourcesPerDayAreChangedWhenTheAllocationIsDone() {
givenTaskWithStartAndEnd(toInterval(new LocalDate(2006, 10, 5), Period givenTaskWithStartAndEnd(toInterval(new LocalDate(2006, 10, 5), Period.days(2)));
.days(2)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
ResourcesPerDay assignedResourcesPerDay = ResourcesPerDay.amount(5); ResourcesPerDay assignedResourcesPerDay = ResourcesPerDay.amount(5);
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(assignedResourcesPerDay);
assignedResourcesPerDay); assertThat(genericResourceAllocation.getResourcesPerDay(), equalTo(assignedResourcesPerDay));
assertThat(genericResourceAllocation.getResourcesPerDay(),
equalTo(assignedResourcesPerDay));
} }
@Test @Test
public void allocatingSeveralResourcesPerDayHavingJustOneResourceProducesOvertime() { public void allocatingSeveralResourcesPerDayHavingJustOneResourceProducesOvertime() {
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
final Integer standardHoursPerDay = SameWorkHoursEveryDay
.getDefaultWorkingDay() final Integer standardHoursPerDay =
.getCapacityOn(PartialDay.wholeDay(start)).getHours(); SameWorkHoursEveryDay.getDefaultWorkingDay().getCapacityOn(PartialDay.wholeDay(start)).getHours();
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(standardHoursPerDay); givenBaseCalendarWithoutExceptions(standardHoursPerDay);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1)).allocate(ResourcesPerDay.amount(2));
.allocate(ResourcesPerDay.amount(2));
List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation List<GenericDayAssignment> orderedAssignmentsFor = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1); assertThat(orderedAssignmentsFor.get(0).getHours(), equalTo(standardHoursPerDay * 2));
assertThat(orderedAssignmentsFor.get(0).getHours(),
equalTo(standardHoursPerDay * 2));
} }
@Test @Test
@ -550,16 +505,13 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 1; final int TASK_DURATION_DAYS = 1;
final int halfWorkingDay = 4; final int halfWorkingDay = 4;
givenBaseCalendarWithoutExceptions(halfWorkingDay); givenBaseCalendarWithoutExceptions(halfWorkingDay);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1)).allocate(ResourcesPerDay.amount(1));
.allocate(ResourcesPerDay.amount(1));
List<GenericDayAssignment> assigmments = genericResourceAllocation List<GenericDayAssignment> assigmments = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertThat(assigmments, haveHours(halfWorkingDay)); assertThat(assigmments, haveHours(halfWorkingDay));
} }
@ -567,20 +519,18 @@ public class GenericResourceAllocationTest {
public void ifThereisNoTaskCalendarTheWorkingHoursAreSpecifiedbyTheDefaultWorkingDay() { public void ifThereisNoTaskCalendarTheWorkingHoursAreSpecifiedbyTheDefaultWorkingDay() {
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
final int TASK_DURATION_DAYS = 1; final int TASK_DURATION_DAYS = 1;
final Integer defaultWorkableHours = SameWorkHoursEveryDay
.getDefaultWorkingDay() final Integer defaultWorkableHours =
.getCapacityOn(PartialDay.wholeDay(start)).getHours(); SameWorkHoursEveryDay.getDefaultWorkingDay().getCapacityOn(PartialDay.wholeDay(start)).getHours();
givenBaseCalendarWithoutExceptions(defaultWorkableHours); givenBaseCalendarWithoutExceptions(defaultWorkableHours);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
genericResourceAllocation.forResources(Arrays.asList(worker1)) genericResourceAllocation.forResources(Arrays.asList(worker1)).allocate(ResourcesPerDay.amount(1));
.allocate(ResourcesPerDay.amount(1));
List<GenericDayAssignment> assigmments = genericResourceAllocation List<GenericDayAssignment> assigmments = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertThat(assigmments.get(0).getHours(), equalTo(defaultWorkableHours)); assertThat(assigmments.get(0).getHours(), equalTo(defaultWorkableHours));
} }
@ -589,22 +539,19 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(3, 12, 1); givenWorkersWithLoads(3, 12, 1);
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(1));
ResourcesPerDay.amount(1));
List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertThat(assignmentsWorker1, haveHours(1, 1, 1, 1)); assertThat(assignmentsWorker1, haveHours(1, 1, 1, 1));
List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation
.getOrderedAssignmentsFor(worker2); List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation.getOrderedAssignmentsFor(worker2);
assertThat(assignmentsWorker2, haveHours()); assertThat(assignmentsWorker2, haveHours());
List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation
.getOrderedAssignmentsFor(worker3); List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation.getOrderedAssignmentsFor(worker3);
assertThat(assignmentsWorker3, haveHours(7, 7, 7, 7)); assertThat(assignmentsWorker3, haveHours(7, 7, 7, 7));
} }
@ -613,29 +560,28 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
Period.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads( givenWorkersWithLoads(
LoadSpec.withHours(3) LoadSpec.withHours(3)
.withException(start.plusDays(1), hours(1)) .withException(start.plusDays(1), hours(1))
.withException(start.plusDays(3), hours(8)), .withException(start.plusDays(3), hours(8)),
LoadSpec.withHours(12).withException(start.plusDays(3), zero()), LoadSpec.withHours(12).withException(start.plusDays(3), zero()),
LoadSpec.withHours(1) LoadSpec.withHours(1)
.withException(start.plusDays(1), hours(3)) .withException(start.plusDays(1), hours(3))
.withException(start.plusDays(3), hours(8))); .withException(start.plusDays(3), hours(8)));
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(1));
ResourcesPerDay.amount(1));
List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertThat(assignmentsWorker1, haveHours(1, 7, 1)); assertThat(assignmentsWorker1, haveHours(1, 7, 1));
List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation
.getOrderedAssignmentsFor(worker2); List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation.getOrderedAssignmentsFor(worker2);
assertThat(assignmentsWorker2, haveHours(8)); assertThat(assignmentsWorker2, haveHours(8));
List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation
.getOrderedAssignmentsFor(worker3); List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation.getOrderedAssignmentsFor(worker3);
assertThat(assignmentsWorker3, haveHours(7, 1, 7)); assertThat(assignmentsWorker3, haveHours(7, 1, 7));
} }
@ -644,27 +590,22 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
Period.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads( givenWorkersWithLoads(
LoadSpec.withHours(0) LoadSpec.withHours(0).withException(start.plusDays(3), hours(4)),
.withException(start.plusDays(3), hours(4)),
LoadSpec.withHours(12), LoadSpec.withHours(12),
LoadSpec.withHours(1) LoadSpec.withHours(1).withException(start.plusDays(3), hours(0)));
.withException(start.plusDays(3), hours(0)));
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(1));
ResourcesPerDay.amount(1));
List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation.getOrderedAssignmentsFor(worker3);
.getOrderedAssignmentsFor(worker3);
assertThat(assignmentsWorker3, haveHours(4)); assertThat(assignmentsWorker3, haveHours(4));
List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation
.getOrderedAssignmentsFor(worker1); List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
assertThat(assignmentsWorker1, haveHours(8, 8, 8, 4)); assertThat(assignmentsWorker1, haveHours(8, 8, 8, 4));
List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation
.getOrderedAssignmentsFor(worker2); List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation.getOrderedAssignmentsFor(worker2);
assertThat(assignmentsWorker2, haveHours()); assertThat(assignmentsWorker2, haveHours());
} }
@ -673,28 +614,23 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
Period.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
Capacity workingDay = Capacity.create(hours(8)); Capacity workingDay = Capacity.create(hours(8));
Capacity with2ExtraHours = workingDay Capacity with2ExtraHours = workingDay.withAllowedExtraEffort(hours(2));
.withAllowedExtraEffort(hours(2)); givenCalendarsForResources(with2ExtraHours, with2ExtraHours, workingDay.overAssignableWithoutLimit());
givenCalendarsForResources(with2ExtraHours, with2ExtraHours,
workingDay.overAssignableWithoutLimit());
givenWorkersWithLoads(0, 0, 0); givenWorkersWithLoads(0, 0, 0);
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(4));
ResourcesPerDay.amount(4));
List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertThat(assignmentsWorker1, haveHours(10, 10, 10, 10)); assertThat(assignmentsWorker1, haveHours(10, 10, 10, 10));
List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation
.getOrderedAssignmentsFor(worker2); List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation.getOrderedAssignmentsFor(worker2);
assertThat(assignmentsWorker2, haveHours(10, 10, 10, 10)); assertThat(assignmentsWorker2, haveHours(10, 10, 10, 10));
List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation
.getOrderedAssignmentsFor(worker3); List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation.getOrderedAssignmentsFor(worker3);
assertThat(assignmentsWorker3, haveHours(12, 12, 12, 12)); assertThat(assignmentsWorker3, haveHours(12, 12, 12, 12));
} }
@ -704,50 +640,52 @@ public class GenericResourceAllocationTest {
final int TASK_DURATION_DAYS = 4; final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
Period.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(0, 0, 0); givenWorkersWithLoads(0, 0, 0);
genericResourceAllocation.forResources(asList(worker1, worker2)) genericResourceAllocation.forResources(asList(worker1, worker2)).allocate(ResourcesPerDay.amount(2));
.allocate(ResourcesPerDay.amount(2));
List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertThat(assignmentsWorker1, haveHours(8, 8, 8, 8)); assertThat(assignmentsWorker1, haveHours(8, 8, 8, 8));
List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation
.getOrderedAssignmentsFor(worker2); List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation.getOrderedAssignmentsFor(worker2);
assertThat(assignmentsWorker2, haveHours(8, 8, 8, 8)); assertThat(assignmentsWorker2, haveHours(8, 8, 8, 8));
} }
@Test @Test
public void virtualWorkersAreGivenMoreLoad() { public void virtualWorkersAreGivenMoreLoad() {
final int TASK_DURATION_DAYS = 4;
givenBaseCalendarWithoutExceptions(8);
LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, Period
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(8, 8, 8);
givenVirtualWorkerWithCapacityAndLoad(Capacity.create(hours(8))
.overAssignableWithoutLimit(), 5, hours(40));
genericResourceAllocation.forResources(workers).allocate( final int TASK_DURATION_DAYS = 4;
ResourcesPerDay.amount(1));
List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation givenBaseCalendarWithoutExceptions(8);
.getOrderedAssignmentsFor(worker3);
LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(8, 8, 8);
givenVirtualWorkerWithCapacityAndLoad(Capacity.create(hours(8)).overAssignableWithoutLimit(), 5, hours(40));
genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(1));
List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation.getOrderedAssignmentsFor(worker3);
assertThat(assignmentsWorker3, haveHours(1, 1, 1, 1)); assertThat(assignmentsWorker3, haveHours(1, 1, 1, 1));
List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation
.getOrderedAssignmentsFor(worker1); List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
assertThat(assignmentsWorker1, haveHours(1, 1, 1, 1)); assertThat(assignmentsWorker1, haveHours(1, 1, 1, 1));
List<GenericDayAssignment> virtualWorkerAssignments = genericResourceAllocation
.getOrderedAssignmentsFor(workers.get(workers.size() - 1)); List<GenericDayAssignment> virtualWorkerAssignments =
genericResourceAllocation.getOrderedAssignmentsFor(workers.get(workers.size() - 1));
assertThat(virtualWorkerAssignments, haveHours(5, 5, 5, 5)); assertThat(virtualWorkerAssignments, haveHours(5, 5, 5, 5));
List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation
.getOrderedAssignmentsFor(worker2); List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation.getOrderedAssignmentsFor(worker2);
assertThat(assignmentsWorker2, haveHours(1, 1, 1, 1)); assertThat(assignmentsWorker2, haveHours(1, 1, 1, 1));
} }
@ -757,22 +695,19 @@ public class GenericResourceAllocationTest {
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
givenCalendarsForResources(4, 4, 0); givenCalendarsForResources(4, 4, 0);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, Period givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(4, 4, 4); givenWorkersWithLoads(4, 4, 4);
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(1));
ResourcesPerDay.amount(1));
List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation List<GenericDayAssignment> assignmentsWorker1 = genericResourceAllocation.getOrderedAssignmentsFor(worker1);
.getOrderedAssignmentsFor(worker1);
assertThat(assignmentsWorker1, haveHours(4, 4, 4, 4)); assertThat(assignmentsWorker1, haveHours(4, 4, 4, 4));
List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation
.getOrderedAssignmentsFor(worker2); List<GenericDayAssignment> assignmentsWorker2 = genericResourceAllocation.getOrderedAssignmentsFor(worker2);
assertThat(assignmentsWorker2, haveHours(4, 4, 4, 4)); assertThat(assignmentsWorker2, haveHours(4, 4, 4, 4));
List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation
.getOrderedAssignmentsFor(worker3); List<GenericDayAssignment> assignmentsWorker3 = genericResourceAllocation.getOrderedAssignmentsFor(worker3);
assertThat(assignmentsWorker3, haveHours()); assertThat(assignmentsWorker3, haveHours());
} }
@ -782,16 +717,16 @@ public class GenericResourceAllocationTest {
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
givenCalendarsForResources(8, 8, 8); givenCalendarsForResources(8, 8, 8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
Period.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(8, 6, 2); givenWorkersWithLoads(8, 6, 2);
IntraDayDate end = ResourceAllocation.allocating(
Arrays.asList(ResourcesPerDayModification.create( IntraDayDate end = ResourceAllocation.allocating(Arrays.asList(ResourcesPerDayModification.create(
genericResourceAllocation, genericResourceAllocation,
ResourcesPerDay.amount(new BigDecimal(1)), workers))) ResourcesPerDay.amount(new BigDecimal(1)), workers))).untilAllocating(hours(12));
.untilAllocating(hours(12));
assertThat(end.getDate(), equalTo(start.plusDays(1))); assertThat(end.getDate(), equalTo(start.plusDays(1)));
EffortDuration biggestLastAssignment = hours(4); EffortDuration biggestLastAssignment = hours(4);
assertThat(end.getEffortDuration(), equalTo(biggestLastAssignment)); assertThat(end.getEffortDuration(), equalTo(biggestLastAssignment));
} }
@ -802,36 +737,33 @@ public class GenericResourceAllocationTest {
givenBaseCalendarWithoutExceptions(8); givenBaseCalendarWithoutExceptions(8);
givenCalendarsForResources(8, 8, 8); givenCalendarsForResources(8, 8, 8);
LocalDate start = new LocalDate(2006, 10, 5); LocalDate start = new LocalDate(2006, 10, 5);
givenTaskWithStartAndEnd(toInterval(start, givenTaskWithStartAndEnd(toInterval(start, Period.days(TASK_DURATION_DAYS)));
Period.days(TASK_DURATION_DAYS)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(8, 2, 6); givenWorkersWithLoads(8, 2, 6);
IntraDayDate end = ResourceAllocation.allocating(
Arrays.asList(ResourcesPerDayModification.create( IntraDayDate end = ResourceAllocation.allocating(Arrays.asList(ResourcesPerDayModification.create(
genericResourceAllocation, ResourcesPerDay.amount(1), genericResourceAllocation,
workers))).untilAllocating(hours(16)); ResourcesPerDay.amount(1),
workers))).untilAllocating(hours(16));
assertThat(end.getDate(), equalTo(start.plusDays(2))); assertThat(end.getDate(), equalTo(start.plusDays(2)));
} }
private void givenVirtualWorkerWithCapacityAndLoad( private void givenVirtualWorkerWithCapacityAndLoad(Capacity capacityPerDayAndUnit, int capacityUnits,
Capacity capacityPerDayAndUnit, EffortDuration load) {
int capacityUnits,
EffortDuration load) {
VirtualWorker worker = createNiceMock(VirtualWorker.class); VirtualWorker worker = createNiceMock(VirtualWorker.class);
expect( expect(worker.getAssignedDurationDiscounting(isA(Map.class), isA(LocalDate.class))).andReturn(load).anyTimes();
worker.getAssignedDurationDiscounting(isA(Map.class),
isA(LocalDate.class))).andReturn(load) expect(worker.getCalendar())
.anyTimes(); .andReturn(createCalendar(ResourceCalendar.class, capacityPerDayAndUnit, capacityUnits)).anyTimes();
expect(worker.getCalendar()).andReturn(
createCalendar(ResourceCalendar.class, capacityPerDayAndUnit,
capacityUnits)).anyTimes();
replay(worker); replay(worker);
workers.add(worker); workers.add(worker);
} }
private static Interval toInterval(LocalDate start, Period period) { private static Interval toInterval(LocalDate start, Period period) {
return new Interval(start.toDateTimeAtStartOfDay(), start.plus(period) return new Interval(start.toDateTimeAtStartOfDay(), start.plus(period).toDateTimeAtStartOfDay());
.toDateTimeAtStartOfDay());
} }
@Test @Test
@ -844,36 +776,32 @@ public class GenericResourceAllocationTest {
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(3, 12, 1); givenWorkersWithLoads(3, 12, 1);
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(1));
ResourcesPerDay.amount(1));
assertThat(genericResourceAllocation.getAssignedHours(), assertThat(genericResourceAllocation.getAssignedHours(), equalTo(workableHoursDay * days));
equalTo(workableHoursDay * days));
final int hoursOnSubinterval = 3; final int hoursOnSubinterval = 3;
int daysSubinterval = 2; int daysSubinterval = 2;
genericResourceAllocation.forResources(workers) genericResourceAllocation.forResources(workers)
.onIntervalWithinTask(start, start.plusDays(daysSubinterval)) .onIntervalWithinTask(start, start.plusDays(daysSubinterval))
.allocateHours(hoursOnSubinterval); .allocateHours(hoursOnSubinterval);
assertThat(genericResourceAllocation.getAssignedHours(), assertThat(genericResourceAllocation.getAssignedHours(),
equalTo(hoursOnSubinterval + (days - daysSubinterval) equalTo(hoursOnSubinterval + (days - daysSubinterval) * workableHoursDay));
* workableHoursDay));
} }
@Test @Test
public void theRelatedResourcesCanBeRetrieved() { public void theRelatedResourcesCanBeRetrieved() {
givenTaskWithStartAndEnd(toInterval(new LocalDate(2006, 10, 5), Period givenTaskWithStartAndEnd(toInterval(new LocalDate(2006, 10, 5), Period.days(4)));
.days(4)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithoutLoadAndWithoutCalendar(); givenWorkersWithoutLoadAndWithoutCalendar();
List<Resource> resourcesGiven = Arrays.<Resource> asList(worker1, List<Resource> resourcesGiven = Arrays.<Resource> asList(worker1, worker2);
worker2); genericResourceAllocation.forResources(resourcesGiven).allocate(ResourcesPerDay.amount(1));
genericResourceAllocation.forResources(resourcesGiven)
.allocate(ResourcesPerDay.amount(1));
assertThat(asSet(genericResourceAllocation.getAssociatedResources()), assertThat(asSet(genericResourceAllocation.getAssociatedResources()),
equalTo(asSet(genericResourceAllocation equalTo(asSet(genericResourceAllocation.getAssociatedResources())));
.getAssociatedResources())));
} }
private Set<Resource> asSet(Collection<Resource> associatedResources) { private Set<Resource> asSet(Collection<Resource> associatedResources) {
@ -890,18 +818,18 @@ public class GenericResourceAllocationTest {
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(3, 12, 1); givenWorkersWithLoads(3, 12, 1);
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(1));
ResourcesPerDay.amount(1));
final int hoursOnSubinterval = 3; final int hoursOnSubinterval = 3;
int daysSubinterval = 2; int daysSubinterval = 2;
genericResourceAllocation.withPreviousAssociatedResources().onIntervalWithinTask( genericResourceAllocation.withPreviousAssociatedResources().onIntervalWithinTask(
start, start,
start.plusDays(daysSubinterval)).allocateHours( start.plusDays(daysSubinterval)).allocateHours(
hoursOnSubinterval); hoursOnSubinterval);
assertThat(genericResourceAllocation.getAssignedHours(), assertThat(genericResourceAllocation.getAssignedHours(),
equalTo(hoursOnSubinterval + (days - daysSubinterval) equalTo(hoursOnSubinterval + (days - daysSubinterval) * workableHoursDay));
* workableHoursDay));
} }
@Test @Test
@ -913,8 +841,7 @@ public class GenericResourceAllocationTest {
givenTaskWithStartAndEnd(toInterval(start, Period.days(days))); givenTaskWithStartAndEnd(toInterval(start, Period.days(days)));
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
genericResourceAllocation.withPreviousAssociatedResources().allocate( genericResourceAllocation.withPreviousAssociatedResources().allocate(ResourcesPerDay.amount(1));
ResourcesPerDay.amount(1));
assertThat(genericResourceAllocation.getAssignedHours(), equalTo(0)); assertThat(genericResourceAllocation.getAssignedHours(), equalTo(0));
} }
@ -929,16 +856,11 @@ public class GenericResourceAllocationTest {
givenGenericResourceAllocationForTask(task); givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(8, 8, 8); givenWorkersWithLoads(8, 8, 8);
genericResourceAllocation.forResources(workers).allocate( genericResourceAllocation.forResources(workers).allocate(ResourcesPerDay.amount(3));
ResourcesPerDay.amount(3)); ResourcesPerDay original = genericResourceAllocation.getResourcesPerDay();
ResourcesPerDay original = genericResourceAllocation genericResourceAllocation.forResources(workers).onIntervalWithinTask(start, start.plusDays(2)).allocateHours(60);
.getResourcesPerDay(); ResourcesPerDay current = genericResourceAllocation.getResourcesPerDay();
genericResourceAllocation.forResources(workers).onIntervalWithinTask(start, assertTrue(current.getAmount().compareTo(original.getAmount()) > 0);
start.plusDays(2)).allocateHours(60);
ResourcesPerDay current = genericResourceAllocation
.getResourcesPerDay();
assertTrue(current.getAmount()
.compareTo(original.getAmount()) > 0);
} }
} }

View file

@ -69,24 +69,19 @@ import org.libreplan.business.workingday.ResourcesPerDay;
public class SpecificResourceAllocationTest { public class SpecificResourceAllocationTest {
public static IntraDayDate date(int year, int monthOfYear, int dayOfMonth) { public static IntraDayDate date(int year, int monthOfYear, int dayOfMonth) {
return IntraDayDate.startOfDay(new LocalDate(year, monthOfYear, return IntraDayDate.startOfDay(new LocalDate(year, monthOfYear, dayOfMonth));
dayOfMonth));
} }
public static IntraDayDate plusDays(IntraDayDate date, int days) { public static IntraDayDate plusDays(IntraDayDate date, int days) {
return IntraDayDate.create(date.getDate().plusDays(days), return IntraDayDate.create(date.getDate().plusDays(days), date.getEffortDuration());
date.getEffortDuration());
} }
public static IntraDayDate minusDays(IntraDayDate date, int days) { public static IntraDayDate minusDays(IntraDayDate date, int days) {
return IntraDayDate.create(date.getDate().minusDays(days), return IntraDayDate.create(date.getDate().minusDays(days), date.getEffortDuration());
date.getEffortDuration());
} }
public static IntraDayDate plusDaysAndEffort(IntraDayDate date, int days, public static IntraDayDate plusDaysAndEffort(IntraDayDate date, int days, EffortDuration effort) {
EffortDuration effort) { return IntraDayDate.create(date.getDate().plusDays(days), date.getEffortDuration().plus(effort));
return IntraDayDate.create(date.getDate().plusDays(days), date
.getEffortDuration().plus(effort));
} }
private BaseCalendar baseCalendar; private BaseCalendar baseCalendar;
@ -109,92 +104,79 @@ public class SpecificResourceAllocationTest {
expect(workerCalendar.getCapacityOn(isA(PartialDay.class))) expect(workerCalendar.getCapacityOn(isA(PartialDay.class)))
.andReturn(EffortDuration.hours(hours)).anyTimes(); .andReturn(EffortDuration.hours(hours)).anyTimes();
IAnswer<? extends EffortDuration> asDurationAnswer = asDurationOnAnswer(hours(hours)); IAnswer<? extends EffortDuration> asDurationAnswer = asDurationOnAnswer(hours(hours));
expect(
workerCalendar.asDurationOn(isA(PartialDay.class), expect(workerCalendar.asDurationOn(isA(PartialDay.class), isA(ResourcesPerDay.class)))
isA(ResourcesPerDay.class))) .andAnswer(asDurationAnswer).anyTimes();
.andAnswer(asDurationAnswer).anyTimes();
expect(workerCalendar.getCapacityWithOvertime(isA(LocalDate.class))) expect(workerCalendar.getCapacityWithOvertime(isA(LocalDate.class)))
.andReturn( .andReturn(Capacity.create(hours(hours)).overAssignableWithoutLimit()).anyTimes();
Capacity.create(hours(hours))
.overAssignableWithoutLimit()).anyTimes(); expect(workerCalendar.getAvailability()).andReturn(AvailabilityTimeLine.allValid()).anyTimes();
expect(workerCalendar.getAvailability()).andReturn(
AvailabilityTimeLine.allValid()).anyTimes();
replay(workerCalendar); replay(workerCalendar);
return workerCalendar; return workerCalendar;
} }
private static IAnswer<? extends EffortDuration> asDurationOnAnswer( private static IAnswer<? extends EffortDuration> asDurationOnAnswer(final EffortDuration duration) {
final EffortDuration duration) {
return new IAnswer<EffortDuration>() { return new IAnswer<EffortDuration>() {
@Override @Override
public EffortDuration answer() throws Throwable { public EffortDuration answer() throws Throwable {
ResourcesPerDay perDay = (ResourcesPerDay) EasyMock ResourcesPerDay perDay = (ResourcesPerDay) EasyMock.getCurrentArguments()[1];
.getCurrentArguments()[1];
return perDay.asDurationGivenWorkingDayOf(duration); return perDay.asDurationGivenWorkingDayOf(duration);
} }
}; };
} }
private void givenResourceCalendar(final Capacity defaultAnswer, private void givenResourceCalendar(final Capacity defaultAnswer, final Map<LocalDate, Capacity> answersForDates) {
final Map<LocalDate, Capacity> answersForDates) {
this.calendar = createNiceMock(ResourceCalendar.class); this.calendar = createNiceMock(ResourceCalendar.class);
expect(this.calendar.getCapacityOn(isA(PartialDay.class))) expect(this.calendar.getCapacityOn(isA(PartialDay.class))).andAnswer(new IAnswer<EffortDuration>() {
.andAnswer(new IAnswer<EffortDuration>() {
@Override @Override
public EffortDuration answer() throws Throwable { public EffortDuration answer() throws Throwable {
PartialDay day = (PartialDay) EasyMock PartialDay day = (PartialDay) EasyMock.getCurrentArguments()[0];
.getCurrentArguments()[0];
LocalDate date = day.getDate(); LocalDate date = day.getDate();
if (answersForDates.containsKey(date)) { if ( answersForDates.containsKey(date) ) {
return day.limitWorkingDay(answersForDates return day.limitWorkingDay(answersForDates.get(date).getStandardEffort());
.get(date).getStandardEffort());
} }
return day.limitWorkingDay(defaultAnswer return day.limitWorkingDay(defaultAnswer.getStandardEffort());
.getStandardEffort());
} }
}).anyTimes(); }).anyTimes();
expect(this.calendar.getCapacityWithOvertime(isA(LocalDate.class))) expect(this.calendar.getCapacityWithOvertime(isA(LocalDate.class))).andAnswer(new IAnswer<Capacity>() {
.andAnswer(new IAnswer<Capacity>() {
@Override @Override
public Capacity answer() throws Throwable { public Capacity answer() throws Throwable {
LocalDate date = (LocalDate) EasyMock LocalDate date = (LocalDate) EasyMock.getCurrentArguments()[0];
.getCurrentArguments()[0]; if ( answersForDates.containsKey(date) ) {
if (answersForDates.containsKey(date)) {
return answersForDates.get(date); return answersForDates.get(date);
} }
return defaultAnswer; return defaultAnswer;
} }
}).anyTimes(); }).anyTimes();
final IAnswer<EffortDuration> effortAnswer = new IAnswer<EffortDuration>() { final IAnswer<EffortDuration> effortAnswer = new IAnswer<EffortDuration>() {
@Override @Override
public EffortDuration answer() throws Throwable { public EffortDuration answer() throws Throwable {
PartialDay day = (PartialDay) EasyMock PartialDay day = (PartialDay) EasyMock.getCurrentArguments()[0];
.getCurrentArguments()[0]; ResourcesPerDay resourcesPerDay = (ResourcesPerDay) EasyMock.getCurrentArguments()[1];
ResourcesPerDay resourcesPerDay = (ResourcesPerDay) EasyMock
.getCurrentArguments()[1];
LocalDate date = day.getDate(); LocalDate date = day.getDate();
Capacity capacity = answersForDates.containsKey(date) ? answersForDates Capacity capacity = answersForDates.containsKey(date) ? answersForDates.get(date) : defaultAnswer;
.get(date) : defaultAnswer;
EffortDuration oneResourcePerDayWorkingDuration = day.limitWorkingDay(capacity.getStandardEffort());
EffortDuration amountRequestedDuration =
resourcesPerDay.asDurationGivenWorkingDayOf(oneResourcePerDayWorkingDuration);
EffortDuration oneResourcePerDayWorkingDuration = day
.limitWorkingDay(capacity.getStandardEffort());
EffortDuration amountRequestedDuration = resourcesPerDay
.asDurationGivenWorkingDayOf(oneResourcePerDayWorkingDuration);
return capacity.limitDuration(amountRequestedDuration); return capacity.limitDuration(amountRequestedDuration);
} }
}; };
expect(
this.calendar.asDurationOn(isA(PartialDay.class), expect(this.calendar.asDurationOn(isA(PartialDay.class), isA(ResourcesPerDay.class)))
isA(ResourcesPerDay.class))).andAnswer(effortAnswer) .andAnswer(effortAnswer).anyTimes();
.anyTimes();
expect(this.calendar.getAvailability()).andReturn( expect(this.calendar.getAvailability()).andReturn(AvailabilityTimeLine.allValid()).anyTimes();
AvailabilityTimeLine.allValid()).anyTimes();
replay(this.calendar); replay(this.calendar);
} }
@ -207,18 +189,15 @@ public class SpecificResourceAllocationTest {
private void givenTask(IntraDayDate start, IntraDayDate end) { private void givenTask(IntraDayDate start, IntraDayDate end) {
task = createNiceMock(Task.class); task = createNiceMock(Task.class);
expect(task.getCalendar()).andReturn(baseCalendar).anyTimes(); expect(task.getCalendar()).andReturn(baseCalendar).anyTimes();
expect(task.getStartDate()).andReturn( expect(task.getStartDate()).andReturn(start.toDateTimeAtStartOfDay().toDate()).anyTimes();
start.toDateTimeAtStartOfDay().toDate()).anyTimes();
expect(task.getIntraDayStartDate()).andReturn(start).anyTimes(); expect(task.getIntraDayStartDate()).andReturn(start).anyTimes();
expect(task.getEndDate()).andReturn( expect(task.getEndDate()).andReturn(end.toDateTimeAtStartOfDay().toDate()).anyTimes();
end.toDateTimeAtStartOfDay().toDate()).anyTimes();
expect(task.getIntraDayEndDate()).andReturn(end).anyTimes(); expect(task.getIntraDayEndDate()).andReturn(end).anyTimes();
expect(task.getFirstDayNotConsolidated()).andReturn(start).anyTimes(); expect(task.getFirstDayNotConsolidated()).andReturn(start).anyTimes();
replay(task); replay(task);
} }
private void givenSpecificResourceAllocation(IntraDayDate start, private void givenSpecificResourceAllocation(IntraDayDate start, IntraDayDate end) {
IntraDayDate end) {
givenWorker(); givenWorker();
givenTask(start, end); givenTask(start, end);
specificResourceAllocation = SpecificResourceAllocation.create(task); specificResourceAllocation = SpecificResourceAllocation.create(task);

View file

@ -86,8 +86,7 @@ public class TaskElementTest {
private Dependency exampleDependency; private Dependency exampleDependency;
public TaskElementTest() { public TaskElementTest() {
this.exampleDependency = Dependency.create(new Task(), new Task(), this.exampleDependency = Dependency.create(new Task(), new Task(), Type.END_START);
Type.END_START);
} }
@Test @Test
@ -120,8 +119,7 @@ public class TaskElementTest {
} }
private static Date toStartOfDay(Date date) { private static Date toStartOfDay(Date date) {
return LocalDate.fromDateFields(date) return LocalDate.fromDateFields(date).toDateTimeAtStartOfDay().toDate();
.toDateTimeAtStartOfDay().toDate();
} }
@Test @Test
@ -132,45 +130,38 @@ public class TaskElementTest {
Type type = Type.START_END; Type type = Type.START_END;
Dependency.create(origin, destination, type); Dependency.create(origin, destination, type);
assertThat(origin.getDependenciesWithThisOrigin().size(), equalTo(1)); assertThat(origin.getDependenciesWithThisOrigin().size(), equalTo(1));
assertThat(destination.getDependenciesWithThisDestination().size(), assertThat(destination.getDependenciesWithThisDestination().size(), equalTo(1));
equalTo(1));
origin.removeDependencyWithDestination(destination, type); origin.removeDependencyWithDestination(destination, type);
assertThat(origin.getDependenciesWithThisOrigin().size(), equalTo(0)); assertThat(origin.getDependenciesWithThisOrigin().size(), equalTo(0));
assertThat(destination.getDependenciesWithThisDestination().size(), assertThat(destination.getDependenciesWithThisDestination().size(), equalTo(0));
equalTo(0));
} }
private void addDependenciesForChecking(TaskElement taskBeingTransformed, private void addDependenciesForChecking(TaskElement taskBeingTransformed, TaskElement sourceDependencyTask,
TaskElement sourceDependencyTask, TaskElement destinationDependencyTask) {
TaskElement destinationDependencyTask) {
Dependency.create(sourceDependencyTask, taskBeingTransformed, Dependency.create(sourceDependencyTask, taskBeingTransformed, Type.END_START);
Type.END_START); Dependency.create(taskBeingTransformed, destinationDependencyTask, Type.END_START);
Dependency.create(taskBeingTransformed, destinationDependencyTask,
Type.END_START);
} }
public void detachRemovesDependenciesFromRelatedTasks() { public void detachRemovesDependenciesFromRelatedTasks() {
Task taskToDetach = (Task) TaskTest.createValidTask(); Task taskToDetach = TaskTest.createValidTask();
Task sourceDependencyTask = (Task) TaskTest.createValidTask(); Task sourceDependencyTask = TaskTest.createValidTask();
Task destinationDependencyTask = (Task) TaskTest.createValidTask(); Task destinationDependencyTask = TaskTest.createValidTask();
taskToDetach.setName("prueba"); taskToDetach.setName("prueba");
taskToDetach.setNotes("blabla"); taskToDetach.setNotes("blabla");
taskToDetach.setStartDate(new Date()); taskToDetach.setStartDate(new Date());
addDependenciesForChecking(taskToDetach, sourceDependencyTask, addDependenciesForChecking(taskToDetach, sourceDependencyTask, destinationDependencyTask);
destinationDependencyTask);
taskToDetach.detach(); taskToDetach.detach();
assertThat(sourceDependencyTask.getDependenciesWithThisOrigin().size(), assertThat(sourceDependencyTask.getDependenciesWithThisOrigin().size(), equalTo(0));
equalTo(0)); assertThat(destinationDependencyTask.getDependenciesWithThisDestination().size(), equalTo(0));
assertThat(destinationDependencyTask
.getDependenciesWithThisDestination().size(), equalTo(0));
} }
@Test @Test
@Transactional @Transactional
public void detachRemovesTaskFromParent() { public void detachRemovesTaskFromParent() {
TaskGroup parent = TaskGroupTest.createValidTaskGroup(); TaskGroup parent = TaskGroupTest.createValidTaskGroup();
Task child = (Task) TaskTest.createValidTask(); Task child = TaskTest.createValidTask();
Task anotherChild = (Task) TaskTest.createValidTask(); Task anotherChild = TaskTest.createValidTask();
parent.addTaskElement(child); parent.addTaskElement(child);
parent.addTaskElement(anotherChild); parent.addTaskElement(anotherChild);
child.detach(); child.detach();
@ -198,15 +189,13 @@ public class TaskElementTest {
private TaskSource asTaskSource(OrderLine orderLine) { private TaskSource asTaskSource(OrderLine orderLine) {
List<HoursGroup> hoursGroups = orderLine.getHoursGroups(); List<HoursGroup> hoursGroups = orderLine.getHoursGroups();
if (hoursGroups.isEmpty()) { if ( hoursGroups.isEmpty() ) {
hoursGroups = Collections.singletonList(createHoursGroup(100)); hoursGroups = Collections.singletonList(createHoursGroup(100));
} }
return TaskSource.create(mockSchedulingDataForVersion(orderLine), return TaskSource.create(mockSchedulingDataForVersion(orderLine), hoursGroups);
hoursGroups);
} }
public static SchedulingDataForVersion mockSchedulingDataForVersion( public static SchedulingDataForVersion mockSchedulingDataForVersion(OrderElement orderElement) {
OrderElement orderElement) {
SchedulingDataForVersion result = createNiceMock(SchedulingDataForVersion.class); SchedulingDataForVersion result = createNiceMock(SchedulingDataForVersion.class);
TaskSource taskSource = createNiceMock(TaskSource.class); TaskSource taskSource = createNiceMock(TaskSource.class);
expect(result.getOrderElement()).andReturn(orderElement).anyTimes(); expect(result.getOrderElement()).andReturn(orderElement).anyTimes();
@ -233,8 +222,7 @@ public class TaskElementTest {
addOrderTo(orderLine); addOrderTo(orderLine);
TaskSource taskSource = asTaskSource(orderLine); TaskSource taskSource = asTaskSource(orderLine);
Task task = Task.createTask(taskSource); Task task = Task.createTask(taskSource);
assertThat(task.getPositionConstraint(), assertThat(task.getPositionConstraint(), isOfType(PositionConstraintType.AS_SOON_AS_POSSIBLE));
isOfType(PositionConstraintType.AS_SOON_AS_POSSIBLE));
} }
private void addOrderTo(OrderElement orderElement) { private void addOrderTo(OrderElement orderElement) {
@ -271,17 +259,15 @@ public class TaskElementTest {
order.setInitDate(initDate); order.setInitDate(initDate);
TaskSource taskSource = asTaskSource(orderLine); TaskSource taskSource = asTaskSource(orderLine);
Task task = Task.createTask(taskSource); Task task = Task.createTask(taskSource);
assertThat(task.getPositionConstraint(), assertThat(task.getPositionConstraint(), isOfType(PositionConstraintType.AS_SOON_AS_POSSIBLE));
isOfType(PositionConstraintType.AS_SOON_AS_POSSIBLE));
} }
private static Matcher<TaskPositionConstraint> isOfType( private static Matcher<TaskPositionConstraint> isOfType(final PositionConstraintType type) {
final PositionConstraintType type) {
return new BaseMatcher<TaskPositionConstraint>() { return new BaseMatcher<TaskPositionConstraint>() {
@Override @Override
public boolean matches(Object object) { public boolean matches(Object object) {
if (object instanceof TaskPositionConstraint) { if ( object instanceof TaskPositionConstraint ) {
TaskPositionConstraint startConstraint = (TaskPositionConstraint) object; TaskPositionConstraint startConstraint = (TaskPositionConstraint) object;
return startConstraint.getConstraintType() == type; return startConstraint.getConstraintType() == type;
} }
@ -290,35 +276,30 @@ public class TaskElementTest {
@Override @Override
public void describeTo(Description description) { public void describeTo(Description description) {
description.appendText("the start constraint must be of type " description.appendText("the start constraint must be of type " + type);
+ type);
} }
}; };
} }
private static Matcher<TaskPositionConstraint> hasValue( private static Matcher<TaskPositionConstraint> hasValue(final LocalDate value) {
final LocalDate value) {
return new BaseMatcher<TaskPositionConstraint>() { return new BaseMatcher<TaskPositionConstraint>() {
@Override @Override
public boolean matches(Object object) { public boolean matches(Object object) {
if (object instanceof TaskPositionConstraint) { if ( object instanceof TaskPositionConstraint ) {
TaskPositionConstraint startConstraint = (TaskPositionConstraint) object; TaskPositionConstraint startConstraint = (TaskPositionConstraint) object;
LocalDate constraintDate = startConstraint LocalDate constraintDate = startConstraint
.getConstraintDate().toDateTimeAtStartOfDay() .getConstraintDate().toDateTimeAtStartOfDay()
.toLocalDate(); .toLocalDate();
boolean bothNotNull = value != null boolean bothNotNull = value != null && constraintDate != null;
&& constraintDate != null; return value == constraintDate || bothNotNull && constraintDate.equals(value);
return value == constraintDate || bothNotNull
&& constraintDate.equals(value);
} }
return false; return false;
} }
@Override @Override
public void describeTo(Description description) { public void describeTo(Description description) {
description.appendText("the start constraint must have date " description.appendText("the start constraint must have date " + value);
+ value);
} }
}; };
} }

View file

@ -18,13 +18,10 @@ public class DistributorTest {
@Test @Test
public void theEffortIsDistributedEvenly() { public void theEffortIsDistributedEvenly() {
Distributor distributor = Distributor.among(Capacity.create(hours(8)), Distributor distributor = Distributor.among(Capacity.create(hours(8)), Capacity.create(hours(8)));
Capacity.create(hours(8)));
assertThat(distributor.distribute(hours(16)), assertThat(distributor.distribute(hours(16)), hasEfforts(hours(8), hours(8)));
hasEfforts(hours(8), hours(8))); assertThat(distributor.distribute(hours(8)), hasEfforts(hours(4), hours(4)));
assertThat(distributor.distribute(hours(8)),
hasEfforts(hours(4), hours(4)));
} }
@Test @Test
@ -33,8 +30,7 @@ public class DistributorTest {
.notOverAssignableWithoutLimit(), Capacity.create(hours(8)) .notOverAssignableWithoutLimit(), Capacity.create(hours(8))
.notOverAssignableWithoutLimit()); .notOverAssignableWithoutLimit());
assertThat(distributor.distribute(hours(18)), assertThat(distributor.distribute(hours(18)), hasEfforts(hours(8), hours(8)));
hasEfforts(hours(8), hours(8)));
} }
@Test @Test
@ -43,13 +39,10 @@ public class DistributorTest {
.notOverAssignableWithoutLimit(), Capacity.create(hours(8)) .notOverAssignableWithoutLimit(), Capacity.create(hours(8))
.overAssignableWithoutLimit()); .overAssignableWithoutLimit());
assertThat(distributor.distribute(hours(14)), assertThat(distributor.distribute(hours(14)), hasEfforts(hours(7), hours(7)));
hasEfforts(hours(7), hours(7))); assertThat(distributor.distribute(hours(16)), hasEfforts(hours(8), hours(8)));
assertThat(distributor.distribute(hours(16)),
hasEfforts(hours(8), hours(8)));
assertThat(distributor.distribute(hours(18)), assertThat(distributor.distribute(hours(18)), hasEfforts(hours(8), hours(10)));
hasEfforts(hours(8), hours(10)));
} }
@Test @Test
@ -58,25 +51,19 @@ public class DistributorTest {
.withAllowedExtraEffort(hours(2)), Capacity.create(hours(8)) .withAllowedExtraEffort(hours(2)), Capacity.create(hours(8))
.notOverAssignableWithoutLimit()); .notOverAssignableWithoutLimit());
assertThat(distributor.distribute(hours(16)), assertThat(distributor.distribute(hours(16)), hasEfforts(hours(8), hours(8)));
hasEfforts(hours(8), hours(8))); assertThat(distributor.distribute(hours(17)), hasEfforts(hours(9), hours(8)));
assertThat(distributor.distribute(hours(17)), assertThat(distributor.distribute(hours(18)), hasEfforts(hours(10), hours(8)));
hasEfforts(hours(9), hours(8))); assertThat(distributor.distribute(hours(19)), hasEfforts(hours(10), hours(8)));
assertThat(distributor.distribute(hours(18)),
hasEfforts(hours(10), hours(8)));
assertThat(distributor.distribute(hours(19)),
hasEfforts(hours(10), hours(8)));
} }
@Test @Test
public void ifNoCapacityItReturnsZeroHours() { public void ifNoCapacityItReturnsZeroHours() {
Distributor distributor = Distributor.among(Capacity.create(hours(0)) Distributor distributor = Distributor.among(Capacity.create(hours(0)).notOverAssignableWithoutLimit());
.notOverAssignableWithoutLimit());
assertThat(distributor.distribute(hours(4)), hasEfforts(hours(0))); assertThat(distributor.distribute(hours(4)), hasEfforts(hours(0)));
} }
private Matcher<List<EffortDuration>> hasEfforts( private Matcher<List<EffortDuration>> hasEfforts(final EffortDuration... efforts) {
final EffortDuration... efforts) {
return new BaseMatcher<List<EffortDuration>>() { return new BaseMatcher<List<EffortDuration>>() {
@Override @Override
@ -85,10 +72,10 @@ public class DistributorTest {
} }
private EffortDuration[] toArray(Object value) { private EffortDuration[] toArray(Object value) {
if (value instanceof EffortDuration[]) { if ( value instanceof EffortDuration[] ) {
return (EffortDuration[]) value; return (EffortDuration[]) value;
} }
if (value instanceof List) { if ( value instanceof List ) {
List<?> list = (List<?>) value; List<?> list = (List<?>) value;
return list.toArray(new EffortDuration[0]); return list.toArray(new EffortDuration[0]);
} }

View file

@ -29,11 +29,11 @@ package org.libreplan.web;
*/ */
public class WebappGlobalNames { public class WebappGlobalNames {
private WebappGlobalNames() { private WebappGlobalNames() {}
}
public final static String WEBAPP_SPRING_CONFIG_FILE = "classpath:/libreplan-webapp-spring-config.xml"; public final static String WEBAPP_SPRING_CONFIG_FILE = "classpath:/libreplan-webapp-spring-config.xml";
public final static String WEBAPP_SPRING_SECURITY_CONFIG_FILE = "classpath:/libreplan-webapp-spring-security-config.xml"; public final static String WEBAPP_SPRING_SECURITY_CONFIG_FILE =
"classpath:/libreplan-webapp-spring-security-config.xml";
} }

View file

@ -67,8 +67,7 @@ import org.springframework.transaction.annotation.Transactional;
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Qualifier("main") @Qualifier("main")
@OnConcurrentModification(goToPage = "/calendars/calendars.zul") @OnConcurrentModification(goToPage = "/calendars/calendars.zul")
public class BaseCalendarModel extends IntegrationEntityModel implements public class BaseCalendarModel extends IntegrationEntityModel implements IBaseCalendarModel {
IBaseCalendarModel {
/** /**
* Conversation state * Conversation state

View file

@ -159,8 +159,7 @@ public interface IBaseCalendarModel extends IIntegrationEntityModel {
CalendarExceptionType getCalendarExceptionType(LocalDate date); CalendarExceptionType getCalendarExceptionType(LocalDate date);
void updateException(CalendarExceptionType type, LocalDate startDate, void updateException(CalendarExceptionType type, LocalDate startDate, LocalDate endDate, Capacity capacity);
LocalDate endDate, Capacity capacity);
void removeCalendarData(CalendarData calendarData); void removeCalendarData(CalendarData calendarData);
@ -176,11 +175,9 @@ public interface IBaseCalendarModel extends IIntegrationEntityModel {
void createCalendarAvailability(); void createCalendarAvailability();
void setStartDate(CalendarAvailability calendarAvailability, void setStartDate(CalendarAvailability calendarAvailability, LocalDate startDate) throws IllegalArgumentException;
LocalDate startDate) throws IllegalArgumentException;
void setEndDate(CalendarAvailability calendarAvailability, LocalDate endDate) void setEndDate(CalendarAvailability calendarAvailability, LocalDate endDate) throws IllegalArgumentException;
throws IllegalArgumentException;
/* /*
* Final conversation steps * Final conversation steps
@ -212,11 +209,9 @@ public interface IBaseCalendarModel extends IIntegrationEntityModel {
Date getCurrentExpiringDate(); Date getCurrentExpiringDate();
void checkChangeExpiringDate(CalendarData version, Date date) void checkChangeExpiringDate(CalendarData version, Date date) throws ValidationException;
throws ValidationException;
void checkAndChangeStartDate(CalendarData version, Date date) void checkAndChangeStartDate(CalendarData version, Date date) throws ValidationException;
throws ValidationException;
boolean isOwnExceptionDay(); boolean isOwnExceptionDay();

View file

@ -41,8 +41,7 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Qualifier("subclass") @Qualifier("subclass")
public class ResourceCalendarModel extends BaseCalendarModel implements public class ResourceCalendarModel extends BaseCalendarModel implements IBaseCalendarModel {
IBaseCalendarModel {
@Override @Override
public void initCreate() { public void initCreate() {

View file

@ -255,14 +255,12 @@ public class ConfigurationModel implements IConfigurationModel {
public void removeEntitySequences(final List<EntitySequence> sequences) { public void removeEntitySequences(final List<EntitySequence> sequences) {
// first one is necessary to remove the deleted sequences. // first one is necessary to remove the deleted sequences.
List<EntitySequence> toRemove = entitySequenceDAO List<EntitySequence> toRemove = entitySequenceDAO.findEntitySquencesNotIn(sequences);
.findEntitySquencesNotIn(sequences);
for (final EntitySequence entitySequence : toRemove) { for (final EntitySequence entitySequence : toRemove) {
try { try {
entitySequenceDAO.remove(entitySequence); entitySequenceDAO.remove(entitySequence);
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
throw new ValidationException( throw new ValidationException(_("Some sequences to be removed do not exist"));
_("Some sequences to be removed do not exist"));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new ValidationException(e.getMessage()); throw new ValidationException(e.getMessage());
} }
@ -273,7 +271,7 @@ public class ConfigurationModel implements IConfigurationModel {
// it updates the sequences that are not active first // it updates the sequences that are not active first
List<EntitySequence> toSaveAfter = new ArrayList<EntitySequence>(); List<EntitySequence> toSaveAfter = new ArrayList<EntitySequence>();
for (EntitySequence entitySequence : sequences) { for (EntitySequence entitySequence : sequences) {
if (entitySequence.isActive()) { if ( entitySequence.isActive() ) {
toSaveAfter.add(entitySequence); toSaveAfter.add(entitySequence);
} else { } else {
entitySequenceDAO.save(entitySequence); entitySequenceDAO.save(entitySequence);

View file

@ -42,29 +42,30 @@ import org.springframework.dao.OptimisticLockingFailureException;
@Order(0) @Order(0)
public class ConcurrentModificationHandling { public class ConcurrentModificationHandling {
public static <T> T addHandling(final String goToPage, public static <T> T addHandling(final String goToPage, Class<T> interfaceKlass, T toBeWraped) {
Class<T> interfaceKlass, T toBeWraped) {
Class<?>[] classesToProxy = { interfaceKlass }; Class<?>[] classesToProxy = { interfaceKlass };
Object result = Proxy.newProxyInstance(interfaceKlass.getClassLoader(),
classesToProxy, handler(toBeWraped, goToPage)); Object result =
Proxy.newProxyInstance(interfaceKlass.getClassLoader(), classesToProxy, handler(toBeWraped, goToPage));
return interfaceKlass.cast(result); return interfaceKlass.cast(result);
} }
private static InvocationHandler handler(final Object toBeWraped, private static InvocationHandler handler(final Object toBeWraped, final String goToPage) {
final String goToPage) {
return new InvocationHandler() { return new InvocationHandler() {
@Override @Override
public Object invoke(Object proxy, Method method, public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object[] args) throws Throwable {
try { try {
return method.invoke(toBeWraped, args); return method.invoke(toBeWraped, args);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
Throwable cause = e.getCause(); Throwable cause = e.getCause();
if (cause instanceof OptimisticLockingFailureException) { if ( cause instanceof OptimisticLockingFailureException ) {
OptimisticLockingFailureException optimisticLockingFailureException = (OptimisticLockingFailureException) cause;
ConcurrentModificationController.showException( OptimisticLockingFailureException optimisticLockingFailureException =
optimisticLockingFailureException, goToPage); (OptimisticLockingFailureException) cause;
ConcurrentModificationController.showException(optimisticLockingFailureException, goToPage);
} }
throw cause; throw cause;
} }
@ -77,8 +78,7 @@ public class ConcurrentModificationHandling {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Pointcut("@within(onConcurrentModification))") @Pointcut("@within(onConcurrentModification))")
private void methodWithinConcurrentModificationMarkedType( private void methodWithinConcurrentModificationMarkedType(OnConcurrentModification onConcurrentModification) {
OnConcurrentModification onConcurrentModification) {
} }
/** /**
@ -92,15 +92,14 @@ public class ConcurrentModificationHandling {
* the annotation applied to object's type * the annotation applied to object's type
* @return the object that would be originally returned * @return the object that would be originally returned
*/ */
@Around("methodWithinConcurrentModificationMarkedType(onConcurrentModification)" @Around("methodWithinConcurrentModificationMarkedType(onConcurrentModification)" + " && execution(public * * (..))")
+ " && execution(public * * (..))")
public Object whenConcurrentModification(ProceedingJoinPoint jointPoint, public Object whenConcurrentModification(ProceedingJoinPoint jointPoint,
OnConcurrentModification onConcurrentModification) throws Throwable { OnConcurrentModification onConcurrentModification) throws Throwable {
try { try {
return jointPoint.proceed(jointPoint.getArgs()); return jointPoint.proceed(jointPoint.getArgs());
} catch (OptimisticLockingFailureException e) { } catch (OptimisticLockingFailureException e) {
ConcurrentModificationController.showException(e, ConcurrentModificationController.showException(e, onConcurrentModification.goToPage());
onConcurrentModification.goToPage());
throw e; throw e;
} }
} }

View file

@ -34,14 +34,14 @@ import org.springframework.transaction.annotation.Transactional;
/** /**
* @author Diego Pino García <ltilve@igalia.com> * @author Diego Pino García <ltilve@igalia.com>
* *
* Model for UI operations related to CostStatus in Dashboard view * Model for UI operations related to CostStatus in Dashboard view
* *
* FIXME: This Model contains several operations for calculating 'Earned * FIXME: This Model contains several operations for calculating 'Earned
* Value' measures related with cost. The code for calculating the basic * Value' measures related with cost. The code for calculating the basic
* measures: BCWP, ACWP and BCWS is copied from * measures: BCWP, ACWP and BCWS is copied from
* {@link OrderPlanningModel}. At this moment this code cannot be reused * {@link OrderPlanningModel}. At this moment this code cannot be reused
* as it's coupled with the logic for displaying the 'Earned Value' * as it's coupled with the logic for displaying the 'Earned Value'
* chart. We may consider to refactor this code in the future. * chart. We may consider to refactor this code in the future.
*/ */
@Component @Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -63,28 +63,24 @@ public class CostStatusModel implements ICostStatusModel {
} }
@Override @Override
public BigDecimal getCostPerformanceIndex(BigDecimal budgetedCost, public BigDecimal getCostPerformanceIndex(BigDecimal budgetedCost, BigDecimal actualCost) {
BigDecimal actualCost) {
return earnedValueCalculator.getCostPerformanceIndex(budgetedCost, return earnedValueCalculator.getCostPerformanceIndex(budgetedCost,
actualCost); actualCost);
} }
@Override @Override
public BigDecimal getCostVariance(BigDecimal budgetedCost, public BigDecimal getCostVariance(BigDecimal budgetedCost, BigDecimal actualCost) {
BigDecimal actualCost) {
return earnedValueCalculator.getCostVariance(budgetedCost, actualCost); return earnedValueCalculator.getCostVariance(budgetedCost, actualCost);
} }
@Override @Override
public BigDecimal getEstimateAtCompletion(BigDecimal budgetAtCompletion, public BigDecimal getEstimateAtCompletion(BigDecimal budgetAtCompletion, BigDecimal costPerformanceIndex) {
BigDecimal costPerformanceIndex) {
return earnedValueCalculator.getEstimateAtCompletion( return earnedValueCalculator.getEstimateAtCompletion(
budgetAtCompletion, costPerformanceIndex); budgetAtCompletion, costPerformanceIndex);
} }
@Override @Override
public BigDecimal getVarianceAtCompletion(BigDecimal budgetAtCompletion, public BigDecimal getVarianceAtCompletion(BigDecimal budgetAtCompletion, BigDecimal estimateAtCompletion) {
BigDecimal estimateAtCompletion) {
return budgetAtCompletion.subtract(estimateAtCompletion); return budgetAtCompletion.subtract(estimateAtCompletion);
} }
@ -100,15 +96,12 @@ public class CostStatusModel implements ICostStatusModel {
@Override @Override
public BigDecimal getBudgetedCostWorkPerformedAt(LocalDate date) { public BigDecimal getBudgetedCostWorkPerformedAt(LocalDate date) {
return earnedValueCalculator return earnedValueCalculator.getBudgetedCostWorkPerformedAt(order, date);
.getBudgetedCostWorkPerformedAt(order, date);
} }
@Override @Override
public BigDecimal getEstimateToComplete(BigDecimal estimateAtCompletion, public BigDecimal getEstimateToComplete(BigDecimal estimateAtCompletion, BigDecimal actualCost) {
BigDecimal actualCost) { return earnedValueCalculator.getEstimateToComplete(estimateAtCompletion, actualCost);
return earnedValueCalculator.getEstimateToComplete(
estimateAtCompletion, actualCost);
} }
} }

View file

@ -278,14 +278,15 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
public void initEdit(Order orderToEdit, Desktop desktop) { public void initEdit(Order orderToEdit, Desktop desktop) {
Validate.notNull(orderToEdit); Validate.notNull(orderToEdit);
loadNeededDataForConversation(); loadNeededDataForConversation();
this.planningState = planningStateCreator.retrieveOrCreate(desktop,
orderToEdit, new IActionsOnRetrieval() { this.planningState = planningStateCreator.retrieveOrCreate(desktop, orderToEdit, new IActionsOnRetrieval() {
@Override @Override
public void onRetrieval(PlanningState planningState) { public void onRetrieval(PlanningState planningState) {
planningState.reattach(); planningState.reattach();
} }
}); });
Order order = this.planningState.getOrder(); Order order = this.planningState.getOrder();
this.orderElementTreeModel = new OrderElementTreeModel(order); this.orderElementTreeModel = new OrderElementTreeModel(order);
forceLoadAdvanceAssignmentsAndMeasurements(order); forceLoadAdvanceAssignmentsAndMeasurements(order);
@ -301,7 +302,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
} }
private void forceLoadEndDateCommunicationToCustomer(Order order) { private void forceLoadEndDateCommunicationToCustomer(Order order) {
if (order != null) { if ( order != null ) {
order.getEndDateCommunicationToCustomer().size(); order.getEndDateCommunicationToCustomer().size();
} }
} }
@ -413,8 +414,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
} }
private void initializeOrder() { private void initializeOrder() {
this.orderElementTreeModel = new OrderElementTreeModel( this.orderElementTreeModel = new OrderElementTreeModel(planningState.getOrder());
planningState.getOrder());
} }
private void initializeCode() { private void initializeCode() {
@ -430,18 +430,17 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
@Transactional(readOnly = true) @Transactional(readOnly = true)
public void prepareCreationFrom(OrderTemplate template, Desktop desktop) { public void prepareCreationFrom(OrderTemplate template, Desktop desktop) {
loadNeededDataForConversation(); loadNeededDataForConversation();
Order newOrder = createOrderFrom((OrderTemplate) templateDAO Order newOrder = createOrderFrom((OrderTemplate) templateDAO.findExistingEntity(template.getId()));
.findExistingEntity(template.getId()));
newOrder.setCode(getOrder().getCode()); newOrder.setCode(getOrder().getCode());
newOrder.setCodeAutogenerated(true); newOrder.setCodeAutogenerated(true);
newOrder.setName(getOrder().getName()); newOrder.setName(getOrder().getName());
newOrder.setCustomer(((Order) getOrder()).getCustomer()); newOrder.setCustomer(getOrder().getCustomer());
newOrder.setCalendar(getCalendar()); newOrder.setCalendar(getCalendar());
newOrder.setInitDate(getOrder().getInitDate()); newOrder.setInitDate(getOrder().getInitDate());
if (getOrder().getDeadline() != null) { if ( getOrder().getDeadline() != null ) {
newOrder.setDeadline(getOrder().getDeadline()); newOrder.setDeadline(getOrder().getDeadline());
} }
@ -454,20 +453,17 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
return template.createOrder(scenarioManager.getCurrent()); return template.createOrder(scenarioManager.getCurrent());
} }
private OrderElement createOrderElementFrom(OrderLineGroup parent, private OrderElement createOrderElementFrom(OrderLineGroup parent, OrderElementTemplate template) {
OrderElementTemplate template) {
Validate.notNull(parent); Validate.notNull(parent);
return template.createElement(parent); return template.createElement(parent);
} }
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public OrderElement createFrom(OrderLineGroup parent, public OrderElement createFrom(OrderLineGroup parent, OrderElementTemplate template) {
OrderElementTemplate template) {
reattachNeededDataForConversation(); reattachNeededDataForConversation();
OrderElement result = createOrderElementFrom(parent, templateDAO OrderElement result = createOrderElementFrom(parent, templateDAO.findExistingEntity(template.getId()));
.findExistingEntity(template.getId())); if ( isCodeAutogenerated() ) {
if (isCodeAutogenerated()) {
setAllCodeToNull(result); setAllCodeToNull(result);
} }
forceLoadAdvanceAssignmentsAndMeasurements(result); forceLoadAdvanceAssignmentsAndMeasurements(result);
@ -496,7 +492,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
reattachCriterions(); reattachCriterions();
} }
}; };
if (showSaveMessage) { if ( showSaveMessage ) {
this.planningState.getSaveCommand().save(beforeSaveActions); this.planningState.getSaveCommand().save(beforeSaveActions);
} else { } else {
this.planningState.getSaveCommand().save(beforeSaveActions, null); this.planningState.getSaveCommand().save(beforeSaveActions, null);
@ -504,7 +500,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
} }
private void reattachCalendar() { private void reattachCalendar() {
if (planningState.getOrder().getCalendar() == null) { if ( planningState.getOrder().getCalendar() == null ) {
return; return;
} }
BaseCalendar calendar = planningState.getOrder().getCalendar(); BaseCalendar calendar = planningState.getOrder().getCalendar();
@ -529,7 +525,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
public void remove(Order detachedOrder) { public void remove(Order detachedOrder) {
Order order = orderDAO.findExistingEntity(detachedOrder.getId()); Order order = orderDAO.findExistingEntity(detachedOrder.getId());
removeVersions(order); removeVersions(order);
if (order.hasNoVersions()) { if ( order.hasNoVersions() ) {
removeOrderFromDB(order); removeOrderFromDB(order);
} }
} }
@ -537,22 +533,22 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
private void removeVersions(Order order) { private void removeVersions(Order order) {
Map<Long, OrderVersion> versionsRemovedById = new HashMap<Long, OrderVersion>(); Map<Long, OrderVersion> versionsRemovedById = new HashMap<Long, OrderVersion>();
List<Scenario> currentAndDerived = currentAndDerivedScenarios(); List<Scenario> currentAndDerived = currentAndDerivedScenarios();
for (Scenario each : currentAndDerived) { for (Scenario each : currentAndDerived) {
OrderVersion versionRemoved = order.disassociateFrom(each); OrderVersion versionRemoved = order.disassociateFrom(each);
if (versionRemoved != null) { if ( versionRemoved != null ) {
versionsRemovedById.put(versionRemoved.getId(), versionRemoved); versionsRemovedById.put(versionRemoved.getId(), versionRemoved);
} }
} }
for (OrderVersion each : versionsRemovedById.values()) { for (OrderVersion each : versionsRemovedById.values()) {
if (!order.isVersionUsed(each)) { if ( !order.isVersionUsed(each) ) {
removeOrderVersionAt(each, currentAndDerived); removeOrderVersionAt(each, currentAndDerived);
removeOrderVersionFromDB(each); removeOrderVersionFromDB(each);
} }
} }
} }
private void removeOrderVersionAt(OrderVersion orderVersion, private void removeOrderVersionAt(OrderVersion orderVersion, Collection<? extends Scenario> currentAndDerived) {
Collection<? extends Scenario> currentAndDerived) {
for (Scenario each : currentAndDerived) { for (Scenario each : currentAndDerived) {
each.removeVersion(orderVersion); each.removeVersion(orderVersion);
} }
@ -562,8 +558,7 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
List<Scenario> scenariosToBeDisassociatedFrom = new ArrayList<Scenario>(); List<Scenario> scenariosToBeDisassociatedFrom = new ArrayList<Scenario>();
Scenario currentScenario = scenarioManager.getCurrent(); Scenario currentScenario = scenarioManager.getCurrent();
scenariosToBeDisassociatedFrom.add(currentScenario); scenariosToBeDisassociatedFrom.add(currentScenario);
scenariosToBeDisassociatedFrom.addAll(scenarioDAO scenariosToBeDisassociatedFrom.addAll(scenarioDAO.getDerivedScenarios(currentScenario));
.getDerivedScenarios(currentScenario));
return scenariosToBeDisassociatedFrom; return scenariosToBeDisassociatedFrom;
} }

View file

@ -65,8 +65,7 @@ import org.zkoss.zul.Window;
public class ProjectDetailsController extends GenericForwardComposer { public class ProjectDetailsController extends GenericForwardComposer {
private static final Log LOG = LogFactory private static final Log LOG = LogFactory.getLog(AdvanceConsolidationController.class);
.getLog(AdvanceConsolidationController.class);
private OrderCRUDController orderController; private OrderCRUDController orderController;
@ -96,8 +95,8 @@ public class ProjectDetailsController extends GenericForwardComposer {
private OrderTemplate template; private OrderTemplate template;
public ProjectDetailsController() { public ProjectDetailsController() {
Window window = (Window) Executions.createComponents(
"/orders/_projectDetails.zul", null, Window window = (Window) Executions.createComponents("/orders/_projectDetails.zul", null,
new HashMap<String, String>()); new HashMap<String, String>());
try { try {
doAfterCompose(window); doAfterCompose(window);
@ -113,13 +112,11 @@ public class ProjectDetailsController extends GenericForwardComposer {
window.setVariable("projectController", this, true); window.setVariable("projectController", this, true);
} }
public void showWindow(OrderCRUDController orderController, public void showWindow(OrderCRUDController orderController, MultipleTabsPlannerController tabs) {
MultipleTabsPlannerController tabs) {
this.tabs = tabs; this.tabs = tabs;
this.orderController = orderController; this.orderController = orderController;
this.defaultCalendar = orderController.getOrder().getCalendar(); this.defaultCalendar = orderController.getOrder().getCalendar();
this.isCodeAutogeneratedInit = orderController.getOrder() this.isCodeAutogeneratedInit = orderController.getOrder().isCodeAutogenerated();
.isCodeAutogenerated();
try { try {
Util.reloadBindings(window); Util.reloadBindings(window);
Util.createBindingsFor(gridProjectDetails); Util.createBindingsFor(gridProjectDetails);
@ -138,18 +135,17 @@ public class ProjectDetailsController extends GenericForwardComposer {
} }
public void accept() { public void accept() {
if (validate()) { if ( validate() ) {
Desktop desktop = window.getDesktop(); Desktop desktop = window.getDesktop();
IOrderModel orderModel = orderController.getOrderModel(); IOrderModel orderModel = orderController.getOrderModel();
if (bdProjectTemplate.getSelectedElement() != null) { if ( bdProjectTemplate.getSelectedElement() != null ) {
OrderTemplate template = (OrderTemplate) bdProjectTemplate OrderTemplate template = (OrderTemplate) bdProjectTemplate.getSelectedElement();
.getSelectedElement();
orderModel.prepareCreationFrom(template, desktop); orderModel.prepareCreationFrom(template, desktop);
} else { } else {
orderModel.initEdit(orderController.getOrder(), desktop); orderModel.initEdit(orderController.getOrder(), desktop);
} }
orderModel.save(); orderModel.save();
if (tabs != null) { if ( tabs != null ) {
tabs.goToOrderDetails(orderController.getOrder()); tabs.goToOrderDetails(orderController.getOrder());
} }
orderController.editNewCreatedOrder(window); orderController.editNewCreatedOrder(window);
@ -158,11 +154,11 @@ public class ProjectDetailsController extends GenericForwardComposer {
private boolean validate() { private boolean validate() {
ConstraintChecker.isValid(window); ConstraintChecker.isValid(window);
if (initDate.getValue() == null) { if ( initDate.getValue() == null ) {
showWrongValue(); showWrongValue();
return false; return false;
} }
if (orderDAO.existsByNameAnotherTransaction(txtName.getValue())) { if ( orderDAO.existsByNameAnotherTransaction(txtName.getValue()) ) {
showWrongName(); showWrongName();
return false; return false;
} }

View file

@ -53,8 +53,9 @@ import org.libreplan.business.workingday.EffortDuration.IEffortFrom;
public class AllocationRowsHandler { public class AllocationRowsHandler {
public static AllocationRowsHandler create(Task task, public static AllocationRowsHandler create(Task task, List<AllocationRow> initialAllocations,
List<AllocationRow> initialAllocations, IWorkerFinder workerFinder) { IWorkerFinder workerFinder) {
return new AllocationRowsHandler(task, initialAllocations, workerFinder); return new AllocationRowsHandler(task, initialAllocations, workerFinder);
} }
@ -248,7 +249,7 @@ public class AllocationRowsHandler {
public Flagged<AllocationResult, Warnings> doAllocation() { public Flagged<AllocationResult, Warnings> doAllocation() {
checkInvalidValues(); checkInvalidValues();
if (!currentRows.isEmpty()) { if ( !currentRows.isEmpty() ) {
List<? extends AllocationModification> modificationsDone; List<? extends AllocationModification> modificationsDone;
modificationsDone = doSuitableAllocation(); modificationsDone = doSuitableAllocation();
@ -256,20 +257,20 @@ public class AllocationRowsHandler {
createDerived(); createDerived();
AllocationResult result = createResult(); AllocationResult result = createResult();
if (AllocationModification.allFullfiled(AllocationModification
.ofType(EffortModification.class, modificationsDone))) { if ( AllocationModification.allFullfiled(AllocationModification
.ofType(EffortModification.class, modificationsDone)) ) {
return Flagged.justValue(result); return Flagged.justValue(result);
} else { } else {
return Flagged.withFlags(result, return Flagged.withFlags(result, Warnings.SOME_GOALS_NOT_FULFILLED);
Warnings.SOME_GOALS_NOT_FULFILLED);
} }
} }
return Flagged.justValue(createResult()); return Flagged.justValue(createResult());
} }
private AllocationResult createResult() { private AllocationResult createResult() {
return AllocationResult.create(task, return AllocationResult.create(task, calculatedValue, currentRows, getWorkableDaysIfApplyable());
calculatedValue, currentRows, getWorkableDaysIfApplyable());
} }
private List<? extends AllocationModification> doSuitableAllocation() { private List<? extends AllocationModification> doSuitableAllocation() {
@ -278,30 +279,34 @@ public class AllocationRowsHandler {
case NUMBER_OF_HOURS: case NUMBER_OF_HOURS:
allocationModifications = calculateNumberOfHoursAllocation(); allocationModifications = calculateNumberOfHoursAllocation();
break; break;
case END_DATE: case END_DATE:
allocationModifications = calculateEndDateOrStartDateAllocation(); allocationModifications = calculateEndDateOrStartDateAllocation();
break; break;
case RESOURCES_PER_DAY: case RESOURCES_PER_DAY:
allocationModifications = calculateResourcesPerDayAllocation(); allocationModifications = calculateResourcesPerDayAllocation();
break; break;
default: default:
throw new RuntimeException("cant handle: " + calculatedValue); throw new RuntimeException("cant handle: " + calculatedValue);
} }
AssignmentFunction.applyAssignmentFunctionsIfAny(AllocationModification AssignmentFunction
.getBeingModified(allocationModifications)); .applyAssignmentFunctionsIfAny(AllocationModification.getBeingModified(allocationModifications));
return allocationModifications; return allocationModifications;
} }
private List<ResourcesPerDayModification> calculateNumberOfHoursAllocation() { private List<ResourcesPerDayModification> calculateNumberOfHoursAllocation() {
List<ResourcesPerDayModification> allocations = AllocationRow
.createAndAssociate(task, currentRows, requestedToRemove); List<ResourcesPerDayModification> allocations =
if (isForwardsAllocation()) { AllocationRow.createAndAssociate(task, currentRows, requestedToRemove);
ResourceAllocation.allocating(allocations).allocateUntil(
formBinder.getAllocationEnd()); if ( isForwardsAllocation() ) {
ResourceAllocation.allocating(allocations).allocateUntil(formBinder.getAllocationEnd());
} else { } else {
ResourceAllocation.allocating(allocations).allocateFromEndUntil( ResourceAllocation.allocating(allocations).allocateFromEndUntil(formBinder.getAllocationStart());
formBinder.getAllocationStart());
} }
return allocations; return allocations;
} }
@ -337,48 +342,45 @@ public class AllocationRowsHandler {
} }
private List<EffortModification> calculateResourcesPerDayAllocation() { private List<EffortModification> calculateResourcesPerDayAllocation() {
List<EffortModification> hours = AllocationRow List<EffortModification> hours =
.createHoursModificationsAndAssociate(task, currentRows, AllocationRow.createHoursModificationsAndAssociate(task, currentRows, requestedToRemove);
requestedToRemove);
if (isForwardsAllocation()) { if ( isForwardsAllocation() ) {
ResourceAllocation.allocatingHours(hours).allocateUntil( ResourceAllocation.allocatingHours(hours).allocateUntil(formBinder.getAllocationEnd());
formBinder.getAllocationEnd());
} else { } else {
ResourceAllocation.allocatingHours(hours).allocateFromEndUntil( ResourceAllocation.allocatingHours(hours).allocateFromEndUntil(formBinder.getAllocationStart());
formBinder.getAllocationStart());
} }
return hours; return hours;
} }
private Integer getWorkableDaysIfApplyable() { private Integer getWorkableDaysIfApplyable() {
switch (calculatedValue) { switch (calculatedValue) {
case NUMBER_OF_HOURS: case NUMBER_OF_HOURS:
case RESOURCES_PER_DAY: case RESOURCES_PER_DAY:
return formBinder.getWorkableDays(); return formBinder.getWorkableDays();
case END_DATE: case END_DATE:
return null; return null;
default: default:
throw new RuntimeException("unexpected calculatedValue: " throw new RuntimeException("unexpected calculatedValue: " + calculatedValue);
+ calculatedValue);
} }
} }
private void createDerived() { private void createDerived() {
List<ResourceAllocation<?>> lastFrom = AllocationRow List<ResourceAllocation<?>> lastFrom = AllocationRow.getBeingModified(currentRows);
.getBeingModified(currentRows);
for (ResourceAllocation<?> each : lastFrom) { for (ResourceAllocation<?> each : lastFrom) {
each.createDerived(workersFinder); each.createDerived(workersFinder);
} }
} }
public FormBinder createFormBinder(Scenario currentScenario, public FormBinder createFormBinder(Scenario currentScenario, IResourceAllocationModel resourceAllocationModel) {
IResourceAllocationModel resourceAllocationModel) { if ( formBinder != null ) {
if (formBinder != null) { throw new IllegalStateException("there is already a binder associated with this object");
throw new IllegalStateException(
"there is already a binder associated with this object");
} }
formBinder = new FormBinder(currentScenario, this, formBinder = new FormBinder(currentScenario, this, resourceAllocationModel);
resourceAllocationModel);
return formBinder; return formBinder;
} }

View file

@ -104,9 +104,9 @@ public class FormBinder {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
Component target = event.getTarget(); Component target = event.getTarget();
if (target instanceof InputElement) { if ( target instanceof InputElement ) {
InputElement inputElement = (InputElement) target; InputElement inputElement = (InputElement) target;
if (inputElement.isDisabled()) { if ( inputElement.isDisabled() ) {
return; return;
} }
} }
@ -141,7 +141,7 @@ public class FormBinder {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
if (effortInput.isDisabled()) { if ( effortInput.isDisabled() ) {
effortInput.setValue(sumAllEffortFromInputs(rows)); effortInput.setValue(sumAllEffortFromInputs(rows));
} }
} }
@ -151,7 +151,7 @@ public class FormBinder {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
if (allResourcesPerDay.isDisabled()) { if ( allResourcesPerDay.isDisabled() ) {
sumResourcesPerDayFromRowsAndAssignToAllResourcesPerDay(); sumResourcesPerDayFromRowsAndAssignToAllResourcesPerDay();
} }
} }
@ -161,7 +161,7 @@ public class FormBinder {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
if (!effortInput.isDisabled()) { if ( !effortInput.isDisabled() ) {
distributeHoursFromTotalToRows(); distributeHoursFromTotalToRows();
} }
} }
@ -171,7 +171,7 @@ public class FormBinder {
@Override @Override
public void onEvent(Event event) { public void onEvent(Event event) {
if (!allResourcesPerDay.isDisabled()) { if ( !allResourcesPerDay.isDisabled() ) {
distributeResourcesPerDayToRows(); distributeResourcesPerDayToRows();
} }
} }
@ -187,18 +187,16 @@ public class FormBinder {
private Button advancedSearchButton; private Button advancedSearchButton;
public FormBinder(Scenario currentScenario, public FormBinder(Scenario currentScenario, AllocationRowsHandler allocationRowsHandler,
AllocationRowsHandler allocationRowsHandler, IResourceAllocationModel resourceAllocationModel) {
IResourceAllocationModel resourceAllocationModel) {
this.allocationRowsHandler = allocationRowsHandler; this.allocationRowsHandler = allocationRowsHandler;
this.resourceAllocationModel = resourceAllocationModel; this.resourceAllocationModel = resourceAllocationModel;
this.lastAllocation = this.allocationRowsHandler this.lastAllocation = this.allocationRowsHandler.getInitialAllocation(currentScenario);
.getInitialAllocation(currentScenario);
this.aggregate = this.lastAllocation.getAggregate(); this.aggregate = this.lastAllocation.getAggregate();
} }
public void setAssignedEffortComponent( public void setAssignedEffortComponent(EffortDurationBox assignedEffortComponent) {
EffortDurationBox assignedEffortComponent) {
this.effortInput = assignedEffortComponent; this.effortInput = assignedEffortComponent;
this.effortInput.setConstraint(positiveValueRequired()); this.effortInput.setConstraint(positiveValueRequired());
allHoursInputComponentDisabilityRule(); allHoursInputComponentDisabilityRule();
@ -268,16 +266,14 @@ public class FormBinder {
} }
private void onChangeEnableApply(InputElement inputElement) { private void onChangeEnableApply(InputElement inputElement) {
Util.ensureUniqueListener(inputElement, Events.ON_CHANGE, Util.ensureUniqueListener(inputElement, Events.ON_CHANGE, onChangeEnableApply);
onChangeEnableApply);
} }
public void setWorkableDays(Intbox duration, public void setWorkableDays(Intbox duration, final TaskPropertiesController taskPropertiesController,
final TaskPropertiesController taskPropertiesController, final Label labelTaskStart, final Label labelTaskEnd) {
final Label labelTaskStart, final Label labelTaskEnd) {
this.workableDaysAndDatesBinder = new WorkableDaysAndDatesBinder( this.workableDaysAndDatesBinder =
duration, labelTaskStart, labelTaskEnd, new WorkableDaysAndDatesBinder(duration, labelTaskStart, labelTaskEnd, taskPropertiesController);
taskPropertiesController);
} }
class WorkableDaysAndDatesBinder { class WorkableDaysAndDatesBinder {
@ -290,17 +286,15 @@ public class FormBinder {
private final TaskPropertiesController taskPropertiesController; private final TaskPropertiesController taskPropertiesController;
WorkableDaysAndDatesBinder(final Intbox taskWorkableDays, WorkableDaysAndDatesBinder(final Intbox taskWorkableDays, final Label labelTaskStart, final Label labelTaskEnd,
final Label labelTaskStart, final Label labelTaskEnd,
final TaskPropertiesController taskPropertiesController) { final TaskPropertiesController taskPropertiesController) {
this.taskWorkableDays = taskWorkableDays; this.taskWorkableDays = taskWorkableDays;
this.labelTaskStart = labelTaskStart; this.labelTaskStart = labelTaskStart;
this.labelTaskEnd = labelTaskEnd; this.labelTaskEnd = labelTaskEnd;
this.taskPropertiesController = taskPropertiesController; this.taskPropertiesController = taskPropertiesController;
initializeDateAndDurationFieldsFromTaskOriginalValues(); initializeDateAndDurationFieldsFromTaskOriginalValues();
final LocalDate firstPossibleDay = getTask() final LocalDate firstPossibleDay = getTask().getFirstDayNotConsolidated().nextDayAtStart().asExclusiveEnd();
.getFirstDayNotConsolidated().nextDayAtStart()
.asExclusiveEnd();
Util.ensureUniqueListeners(taskWorkableDays, Events.ON_CHANGE, Util.ensureUniqueListeners(taskWorkableDays, Events.ON_CHANGE,
new EventListener() { new EventListener() {
@ -308,51 +302,47 @@ public class FormBinder {
public void onEvent(Event event) { public void onEvent(Event event) {
Task task = getTask(); Task task = getTask();
Integer workableDays = taskWorkableDays.getValue(); Integer workableDays = taskWorkableDays.getValue();
if (allocationRowsHandler.isForwardsAllocation()) { if ( allocationRowsHandler.isForwardsAllocation() ) {
IntraDayDate newEnd = ensureItIsAfterConsolidation(task
.calculateEndGivenWorkableDays(workableDays)); IntraDayDate newEnd =
updateWorkableDaysIfNecessary(workableDays, ensureItIsAfterConsolidation(task.calculateEndGivenWorkableDays(workableDays));
getTask().getIntraDayStartDate(),
newEnd); updateWorkableDaysIfNecessary(workableDays, getTask().getIntraDayStartDate(), newEnd);
taskPropertiesController taskPropertiesController.updateTaskEndDate(newEnd.getDate());
.updateTaskEndDate(newEnd.getDate()); showValueOfDateOn(labelTaskEnd, newEnd.getDate());
showValueOfDateOn(labelTaskEnd,
newEnd.getDate());
} else { } else {
IntraDayDate newStart = ensureItIsAfterConsolidation(task
.calculateStartGivenWorkableDays(workableDays)); IntraDayDate newStart =
updateWorkableDaysIfNecessary(workableDays, ensureItIsAfterConsolidation(task.calculateStartGivenWorkableDays(workableDays));
newStart, task.getIntraDayEndDate());
taskPropertiesController updateWorkableDaysIfNecessary(workableDays, newStart, task.getIntraDayEndDate());
.updateTaskStartDate(newStart.getDate()); taskPropertiesController.updateTaskStartDate(newStart.getDate());
showValueOfDateOn(labelTaskStart, showValueOfDateOn(labelTaskStart, newStart.getDate());
newStart.getDate());
} }
} }
private void updateWorkableDaysIfNecessary( private void updateWorkableDaysIfNecessary(int specifiedWorkableDays,
int specifiedWorkableDays, IntraDayDate allocationStart,
IntraDayDate allocationStart, IntraDayDate allocationEnd) {
IntraDayDate allocationEnd) {
Integer effectiveWorkableDays = getTask() Integer effectiveWorkableDays = getTask().getWorkableDaysFrom(
.getWorkableDaysFrom(
allocationStart.getDate(), allocationStart.getDate(),
allocationEnd.asExclusiveEnd()); allocationEnd.asExclusiveEnd());
if (effectiveWorkableDays < specifiedWorkableDays) {
if ( effectiveWorkableDays < specifiedWorkableDays ) {
Clients.response(new AuWrongValue( Clients.response(new AuWrongValue(
taskWorkableDays, taskWorkableDays,
_("The original workable days value {0} cannot be modified as it has consolidations", _("The original workable days value {0} cannot be modified as it has consolidations",
specifiedWorkableDays))); specifiedWorkableDays)) );
taskWorkableDays taskWorkableDays.setValue(effectiveWorkableDays);
.setValue(effectiveWorkableDays);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private IntraDayDate ensureItIsAfterConsolidation( private IntraDayDate ensureItIsAfterConsolidation(IntraDayDate newDate) {
IntraDayDate newDate) { if ( getTask().hasConsolidations() ) {
if (getTask().hasConsolidations()) { return Collections.max(
return Collections.max(Arrays.asList(newDate, Arrays.asList(newDate,
IntraDayDate.startOfDay(firstPossibleDay))); IntraDayDate.startOfDay(firstPossibleDay)));
} }
return newDate; return newDate;
@ -363,9 +353,9 @@ public class FormBinder {
} }
void applyDisabledRules() { void applyDisabledRules() {
this.taskWorkableDays.setDisabled(allocationRowsHandler this.taskWorkableDays.setDisabled(allocationRowsHandler.getCalculatedValue() == CalculatedValue.END_DATE ||
.getCalculatedValue() == CalculatedValue.END_DATE isAnyManual() ||
|| isAnyManual() || isTaskUpdatedFromTimesheets()); isTaskUpdatedFromTimesheets());
} }
private void initializeDateAndDurationFieldsFromTaskOriginalValues() { private void initializeDateAndDurationFieldsFromTaskOriginalValues() {
@ -514,14 +504,15 @@ public class FormBinder {
} }
public void doApply() { public void doApply() {
AllocationResult allocationResult = resourceAllocationModel AllocationResult allocationResult =
.onAllocationContext(new IResourceAllocationContext<AllocationResult>() { resourceAllocationModel.onAllocationContext(new IResourceAllocationContext<AllocationResult>() {
@Override @Override
public AllocationResult doInsideTransaction() { public AllocationResult doInsideTransaction() {
return allocationRowsHandler.doAllocation().getValue(); return allocationRowsHandler.doAllocation().getValue();
} }
}); });
allocationProduced(allocationResult); allocationProduced(allocationResult);
TaskPropertiesController.allocationResult = allocationResult; TaskPropertiesController.allocationResult = allocationResult;
@ -533,15 +524,14 @@ public class FormBinder {
* exit the edition form * exit the edition form
*/ */
public boolean accept() { public boolean accept() {
if (isTaskUpdatedFromTimesheets()) { if ( isTaskUpdatedFromTimesheets() ) {
return true; return true;
} }
Flagged<AllocationResult, Warnings> result = resourceAllocationModel Flagged<AllocationResult, Warnings> result = resourceAllocationModel.accept();
.accept();
// result can be null when editing milestones // result can be null when editing milestones
if (result != null && result.isFlagged()) { if ( result != null && result.isFlagged() ) {
allocationProduced(result.getValue()); allocationProduced(result.getValue());
} }
return result == null || !result.isFlagged(); return result == null || !result.isFlagged();
@ -565,11 +555,10 @@ public class FormBinder {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void loadSclassRowSatisfied() { private void loadSclassRowSatisfied() {
try { try {
List<org.zkoss.zul.Row> rows = (List<org.zkoss.zul.Row>) allocationsGrid List<org.zkoss.zul.Row> rows = (List<org.zkoss.zul.Row>) allocationsGrid.getRows().getChildren();
.getRows().getChildren();
for (org.zkoss.zul.Row row : rows) { for (org.zkoss.zul.Row row : rows) {
if (row.getValue() instanceof AllocationRow) { if ( row.getValue() instanceof AllocationRow ) {
if (!((AllocationRow) row.getValue()).isSatisfied()) { if ( !((AllocationRow) row.getValue()).isSatisfied() ) {
row.setSclass("allocation-not-satisfied"); row.setSclass("allocation-not-satisfied");
} else { } else {
row.setSclass("allocation-satisfied"); row.setSclass("allocation-satisfied");
@ -616,13 +605,12 @@ public class FormBinder {
FormBinder.this.applyButton.setDisabled(true); FormBinder.this.applyButton.setDisabled(true);
} }
}; };
Util.ensureUniqueListener(this.applyButton, Events.ON_CLICK, Util.ensureUniqueListener(this.applyButton, Events.ON_CLICK, applyButtonListener);
applyButtonListener);
} }
public EffortDuration getAssignedEffort() { public EffortDuration getAssignedEffort() {
EffortDuration result = effortInput.getEffortDurationValue(); EffortDuration result = effortInput.getEffortDurationValue();
if (result == null) { if ( result == null ) {
throw new RuntimeException("assignedHoursComponent returns null"); throw new RuntimeException("assignedHoursComponent returns null");
} }
return result; return result;
@ -668,30 +656,24 @@ public class FormBinder {
} }
public void markNoResourcesMatchedByCriterions(ResourceEnum resourceType, public void markNoResourcesMatchedByCriterions(ResourceEnum resourceType,
Collection<? extends Criterion> criterions) { Collection<? extends Criterion> criterions) {
messagesForUser messagesForUser.showMessage(Level.ERROR,
.showMessage(
Level.ERROR,
_("there are no resources for required criteria: {0}. So the generic allocation can't be added", _("there are no resources for required criteria: {0}. So the generic allocation can't be added",
Criterion.getCaptionFor(resourceType, Criterion.getCaptionFor(resourceType, criterions)));
criterions)));
} }
public void markThereisAlreadyAssignmentWith(ResourceEnum resourceType, public void markThereisAlreadyAssignmentWith(ResourceEnum resourceType,
Collection<? extends Criterion> criterions) { Collection<? extends Criterion> criterions) {
messagesForUser.showMessage( messagesForUser.showMessage(Level.ERROR,
Level.ERROR, _("already exists an allocation for criteria {0}", Criterion.getCaptionFor(resourceType, criterions)));
_("already exists an allocation for criteria {0}",
Criterion.getCaptionFor(resourceType, criterions)));
} }
public void markNoEmptyResourcesPerDay(List<AllocationRow> rows) { public void markNoEmptyResourcesPerDay(List<AllocationRow> rows) {
Validate.isTrue(!rows.isEmpty()); Validate.isTrue(!rows.isEmpty());
final String message = _("resources per day cannot be empty or less than zero"); final String message = _("resources per day cannot be empty or less than zero");
if (!recommendedAllocation) { if ( !recommendedAllocation ) {
AllocationRow first = rows.get(0); AllocationRow first = rows.get(0);
throw new WrongValueException( throw new WrongValueException(first.getIntendedResourcesPerDayInput(), message);
first.getIntendedResourcesPerDayInput(), message);
} else { } else {
throw new WrongValueException(allResourcesPerDay, message); throw new WrongValueException(allResourcesPerDay, message);
} }
@ -706,20 +688,17 @@ public class FormBinder {
} }
public void detach() { public void detach() {
if (this.applyButton != null) { if ( this.applyButton != null ) {
this.applyButton.removeEventListener(Events.ON_CLICK, this.applyButton.removeEventListener(Events.ON_CLICK, applyButtonListener);
applyButtonListener);
} }
for (InputElement inputElement : inputsAssociatedWithOnChangeEnableApply) { for (InputElement inputElement : inputsAssociatedWithOnChangeEnableApply) {
inputElement.removeEventListener(Events.ON_CHANGE, inputElement.removeEventListener(Events.ON_CHANGE, onChangeEnableApply);
onChangeEnableApply);
} }
} }
public void setRecommendedAllocation(Button recommendedAllocation) { public void setRecommendedAllocation(Button recommendedAllocation) {
this.btnRecommendedAllocation = recommendedAllocation; this.btnRecommendedAllocation = recommendedAllocation;
this.btnRecommendedAllocation.setDisabled(isAnyManual() this.btnRecommendedAllocation.setDisabled(isAnyManual() || isTaskUpdatedFromTimesheets());
|| isTaskUpdatedFromTimesheets());
Util.ensureUniqueListener(recommendedAllocation, Events.ON_CLICK, Util.ensureUniqueListener(recommendedAllocation, Events.ON_CLICK,
new EventListener() { new EventListener() {
@Override @Override
@ -740,26 +719,27 @@ public class FormBinder {
private void activatingRecommendedAllocation() { private void activatingRecommendedAllocation() {
allocationRowsHandler.removeAll(); allocationRowsHandler.removeAll();
ProportionalDistributor distributor = resourceAllocationModel ProportionalDistributor distributor = resourceAllocationModel.addDefaultAllocations();
.addDefaultAllocations();
boolean recommendAllocationSuccessful = distributor != null; boolean recommendAllocationSuccessful = distributor != null;
if (recommendAllocationSuccessful) {
if ( recommendAllocationSuccessful ) {
hoursDistributorForRecommendedAllocation = distributor; hoursDistributorForRecommendedAllocation = distributor;
resourcesPerDayDistributorForRecommendedAllocation = ResourcesPerDay
.distributor(hoursDistributorForRecommendedAllocation); resourcesPerDayDistributorForRecommendedAllocation =
ResourcesPerDay.distributor(hoursDistributorForRecommendedAllocation);
this.recommendedAllocation = true; this.recommendedAllocation = true;
disableIfNeededWorkerSearch(); disableIfNeededWorkerSearch();
applyDisabledRules(); applyDisabledRules();
effortInput.addEventListener(Events.ON_CHANGE, allHoursInputChange); effortInput.addEventListener(Events.ON_CHANGE, allHoursInputChange);
allResourcesPerDay.addEventListener(Events.ON_CHANGE, allResourcesPerDay.addEventListener(Events.ON_CHANGE, allResourcesPerDayChange);
allResourcesPerDayChange);
resetStateForResourcesPerDayInputsWhenDoingRecommendedAllocation(); resetStateForResourcesPerDayInputsWhenDoingRecommendedAllocation();
} }
Util.reloadBindings(allocationsGrid); Util.reloadBindings(allocationsGrid);
} }
private void resetStateForResourcesPerDayInputsWhenDoingRecommendedAllocation() { private void resetStateForResourcesPerDayInputsWhenDoingRecommendedAllocation() {
if (allResourcesPerDay.isDisabled()) { if ( allResourcesPerDay.isDisabled() ) {
allResourcesPerDay.setValue((BigDecimal) null); allResourcesPerDay.setValue((BigDecimal) null);
AllocationRow.unknownResourcesPerDay(rows); AllocationRow.unknownResourcesPerDay(rows);
} else { } else {
@ -800,8 +780,7 @@ public class FormBinder {
private void deactivatingRecommendedAllocation() { private void deactivatingRecommendedAllocation() {
this.recommendedAllocation = false; this.recommendedAllocation = false;
effortInput.removeEventListener(Events.ON_CHANGE, allHoursInputChange); effortInput.removeEventListener(Events.ON_CHANGE, allHoursInputChange);
allResourcesPerDay.removeEventListener(Events.ON_CHANGE, allResourcesPerDay.removeEventListener(Events.ON_CHANGE, allResourcesPerDayChange);
allResourcesPerDayChange);
applyDisabledRules(); applyDisabledRules();
disableIfNeededWorkerSearch(); disableIfNeededWorkerSearch();
} }
@ -822,14 +801,13 @@ public class FormBinder {
this.advancedSearchButton.setDisabled(recommendedAllocation); this.advancedSearchButton.setDisabled(recommendedAllocation);
} }
public void setNewAllocationSelectorCombo( public void setNewAllocationSelectorCombo(NewAllocationSelectorCombo newAllocationSelectorCombo) {
NewAllocationSelectorCombo newAllocationSelectorCombo) {
this.newAllocationSelectorCombo = newAllocationSelectorCombo; this.newAllocationSelectorCombo = newAllocationSelectorCombo;
this.newAllocationSelectorCombo.setDisabled(recommendedAllocation); this.newAllocationSelectorCombo.setDisabled(recommendedAllocation);
} }
private void sumResourcesPerDayFromRowsAndAssignToAllResourcesPerDay() { private void sumResourcesPerDayFromRowsAndAssignToAllResourcesPerDay() {
if (allResourcesPerDay.isDisabled()) { if ( allResourcesPerDay.isDisabled() ) {
allResourcesPerDay.setValue(sumResourcesPerDayFromInputs()); allResourcesPerDay.setValue(sumResourcesPerDayFromInputs());
} }
} }
@ -837,7 +815,7 @@ public class FormBinder {
private BigDecimal sumResourcesPerDayFromInputs() { private BigDecimal sumResourcesPerDayFromInputs() {
BigDecimal sum = BigDecimal.ZERO; BigDecimal sum = BigDecimal.ZERO;
for (AllocationRow each : rows) { for (AllocationRow each : rows) {
if (each.getIntendedResourcesPerDayInput().isValid()) { if ( each.getIntendedResourcesPerDayInput().isValid() ) {
sum = sum.add(each.getResourcesPerDayFromInput().getAmount()); sum = sum.add(each.getResourcesPerDayFromInput().getAmount());
} }
} }
@ -892,8 +870,7 @@ public class FormBinder {
return allTotalResourcesPerDay; return allTotalResourcesPerDay;
} }
public void setAllConsolidatedResourcesPerDay( public void setAllConsolidatedResourcesPerDay(Label allConsolidatedResourcesPerDay) {
Label allConsolidatedResourcesPerDay) {
this.allConsolidatedResourcesPerDay = allConsolidatedResourcesPerDay; this.allConsolidatedResourcesPerDay = allConsolidatedResourcesPerDay;
} }
@ -903,17 +880,12 @@ public class FormBinder {
public void loadAggregatedCalculations() { public void loadAggregatedCalculations() {
// Calculate aggregated values // Calculate aggregated values
if (behaviour.allowMultipleSelection()) { if ( behaviour.allowMultipleSelection() ) {
allOriginalEffort.setValue(sumAllOriginalEffort(this.rows) allOriginalEffort.setValue(sumAllOriginalEffort(this.rows).toFormattedString());
.toFormattedString()); allTotalEffort.setValue(sumAllTotalEffort(this.rows).toFormattedString());
allTotalEffort.setValue(sumAllTotalEffort(this.rows) allConsolidatedEffort.setValue(AllocationRow.sumAllConsolidatedEffort(this.rows).toFormattedString());
.toFormattedString()); allTotalResourcesPerDay.setValue(sumAllTotalResourcesPerDay().toString());
allConsolidatedEffort.setValue(AllocationRow allConsolidatedResourcesPerDay.setValue(sumAllConsolidatedResourcesPerDay().toString());
.sumAllConsolidatedEffort(this.rows).toFormattedString());
allTotalResourcesPerDay.setValue(sumAllTotalResourcesPerDay()
.toString());
allConsolidatedResourcesPerDay
.setValue(sumAllConsolidatedResourcesPerDay().toString());
} }
} }
@ -922,10 +894,8 @@ public class FormBinder {
} }
public void cannotAllocateMoreThanOneResource(List<Resource> resources) { public void cannotAllocateMoreThanOneResource(List<Resource> resources) {
messagesForUser.showMessage( messagesForUser.showMessage(Level.ERROR,
Level.ERROR, _("{0} could not be allocated. " + "Cannot allocate more than one resource",
_("{0} could not be allocated. "
+ "Cannot allocate more than one resource",
Resource.getCaptionFor(resources))); Resource.getCaptionFor(resources)));
} }
@ -934,9 +904,8 @@ public class FormBinder {
} }
public boolean isAnyNotFlat() { public boolean isAnyNotFlat() {
for (AllocationRow allocationRow : allocationRowsHandler for (AllocationRow allocationRow : allocationRowsHandler.getCurrentRows()) {
.getCurrentRows()) { if ( allocationRow.isAssignmentFunctionNotFlat() ) {
if (allocationRow.isAssignmentFunctionNotFlat()) {
return true; return true;
} }
} }
@ -944,9 +913,8 @@ public class FormBinder {
} }
public boolean isAnyManual() { public boolean isAnyManual() {
for (AllocationRow allocationRow : allocationRowsHandler for (AllocationRow allocationRow : allocationRowsHandler.getCurrentRows()) {
.getCurrentRows()) { if ( allocationRow.isAssignmentFunctionManual() ) {
if (allocationRow.isAssignmentFunctionManual()) {
return true; return true;
} }
} }

View file

@ -53,18 +53,15 @@ public class ResourceAllocationCommand implements IResourceAllocationCommand {
} }
@Override @Override
public void doAction(IContextWithPlannerTask<TaskElement> context, public void doAction(IContextWithPlannerTask<TaskElement> context, TaskElement taskElement) {
TaskElement taskElement) {
editTaskUtilities.reattach(taskElement); editTaskUtilities.reattach(taskElement);
if (isApplicableTo(taskElement)) { if ( isApplicableTo(taskElement) ) {
Task task = (Task) taskElement; Task task = (Task) taskElement;
if (task.isSubcontracted()) { if ( task.isSubcontracted() ) {
editTaskController.showEditFormSubcontract(context, task, editTaskController.showEditFormSubcontract(context, task, planningState);
planningState);
} else { } else {
editTaskController.showEditFormResourceAllocation(context, editTaskController.showEditFormResourceAllocation(context, task, planningState);
task, planningState);
} }
} }
} }
@ -75,8 +72,7 @@ public class ResourceAllocationCommand implements IResourceAllocationCommand {
} }
@Override @Override
public void initialize(EditTaskController editTaskController, public void initialize(EditTaskController editTaskController, PlanningState planningState) {
PlanningState planningState) {
this.editTaskController = editTaskController; this.editTaskController = editTaskController;
this.planningState = planningState; this.planningState = planningState;
} }

View file

@ -38,6 +38,7 @@ import org.libreplan.business.planner.entities.DerivedAllocation;
import org.libreplan.business.planner.entities.ResourceAllocation; import org.libreplan.business.planner.entities.ResourceAllocation;
import org.libreplan.business.planner.entities.TaskElement; import org.libreplan.business.planner.entities.TaskElement;
import org.libreplan.business.resources.entities.ResourceEnum; import org.libreplan.business.resources.entities.ResourceEnum;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.web.I18nHelper; import org.libreplan.web.I18nHelper;
import org.libreplan.web.common.EffortDurationBox; import org.libreplan.web.common.EffortDurationBox;
import org.libreplan.web.common.IMessagesForUser; import org.libreplan.web.common.IMessagesForUser;
@ -93,8 +94,7 @@ import org.zkoss.zul.Window;
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ResourceAllocationController extends GenericForwardComposer { public class ResourceAllocationController extends GenericForwardComposer {
private static final Log LOG = LogFactory private static final Log LOG = LogFactory.getLog(ResourceAllocationController.class);
.getLog(ResourceAllocationController.class);
private IResourceAllocationModel resourceAllocationModel; private IResourceAllocationModel resourceAllocationModel;
@ -177,18 +177,15 @@ public class ResourceAllocationController extends GenericForwardComposer {
* @param ganttTask * @param ganttTask
* @param planningState * @param planningState
*/ */
public void init(IContextWithPlannerTask<TaskElement> context, public void init(IContextWithPlannerTask<TaskElement> context, Task task, PlanningState planningState,
org.libreplan.business.planner.entities.Task task, IMessagesForUser messagesForUser) {
PlanningState planningState, IMessagesForUser messagesForUser) {
try { try {
if (formBinder != null) { if ( formBinder != null ) {
formBinder.detach(); formBinder.detach();
} }
allocationRows = resourceAllocationModel.initAllocationsFor(task, allocationRows = resourceAllocationModel.initAllocationsFor(task, context, planningState);
context, planningState);
formBinder = allocationRows.createFormBinder(planningState formBinder = allocationRows.createFormBinder(planningState.getCurrentScenario(), resourceAllocationModel);
.getCurrentScenario(), resourceAllocationModel);
formBinder.setBehaviour(ResourceAllocationBehaviour.NON_LIMITING); formBinder.setBehaviour(ResourceAllocationBehaviour.NON_LIMITING);
formBinder.setAllOriginalEffort(allOriginalEffort); formBinder.setAllOriginalEffort(allOriginalEffort);
formBinder.setAllTotalEffort(allTotalEffort); formBinder.setAllTotalEffort(allTotalEffort);
@ -196,21 +193,17 @@ public class ResourceAllocationController extends GenericForwardComposer {
formBinder.setAssignedEffortComponent(assignedEffortComponent); formBinder.setAssignedEffortComponent(assignedEffortComponent);
formBinder.setAllTotalResourcesPerDay(allTotalResourcesPerDay); formBinder.setAllTotalResourcesPerDay(allTotalResourcesPerDay);
formBinder formBinder.setAllConsolidatedResourcesPerDay(allConsolidatedResourcesPerDay);
.setAllConsolidatedResourcesPerDay(allConsolidatedResourcesPerDay);
formBinder.setAllResourcesPerDay(allResourcesPerDay); formBinder.setAllResourcesPerDay(allResourcesPerDay);
TaskPropertiesController taskPropertiesController = editTaskController TaskPropertiesController taskPropertiesController = editTaskController.getTaskPropertiesController();
.getTaskPropertiesController(); formBinder.setWorkableDays(getTaskWorkableDays(), taskPropertiesController, getTaskStart(), getTaskEnd());
formBinder.setWorkableDays(getTaskWorkableDays(),
taskPropertiesController, getTaskStart(), getTaskEnd());
formBinder.setApplyButton(applyButton); formBinder.setApplyButton(applyButton);
formBinder.setAllocationsGrid(allocationsGrid); formBinder.setAllocationsGrid(allocationsGrid);
formBinder.setMessagesForUser(messagesForUser); formBinder.setMessagesForUser(messagesForUser);
formBinder.setWorkerSearchTab(workerSearchTab); formBinder.setWorkerSearchTab(workerSearchTab);
formBinder formBinder.setNewAllocationSelectorCombo(newAllocationSelectorCombo);
.setNewAllocationSelectorCombo(newAllocationSelectorCombo);
initializeTaskInformationComponent(); initializeTaskInformationComponent();
initializeAllocationConfigurationComponent(); initializeAllocationConfigurationComponent();
@ -219,8 +212,7 @@ public class ResourceAllocationController extends GenericForwardComposer {
tbResourceAllocation.setSelected(true); tbResourceAllocation.setSelected(true);
newAllocationSelector.setAllocationsAdder(resourceAllocationModel); newAllocationSelector.setAllocationsAdder(resourceAllocationModel);
newAllocationSelectorCombo newAllocationSelectorCombo.setAllocationsAdder(resourceAllocationModel);
.setAllocationsAdder(resourceAllocationModel);
Util.reloadBindings(allocationsGrid); Util.reloadBindings(allocationsGrid);
} catch (WrongValueException e) { } catch (WrongValueException e) {
@ -234,13 +226,11 @@ public class ResourceAllocationController extends GenericForwardComposer {
} }
public Label getTaskStart() { public Label getTaskStart() {
return (allocationConfiguration != null) ? allocationConfiguration return (allocationConfiguration != null) ? allocationConfiguration.getTaskStart() : null;
.getTaskStart() : null;
} }
public Label getTaskEnd() { public Label getTaskEnd() {
return (allocationConfiguration != null) ? allocationConfiguration return (allocationConfiguration != null) ? allocationConfiguration.getTaskEnd() : null;
.getTaskEnd() : null;
} }
private Radiogroup getCalculationTypeSelector() { private Radiogroup getCalculationTypeSelector() {
@ -248,10 +238,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
} }
private void initializeTaskInformationComponent() { private void initializeTaskInformationComponent() {
taskInformation.initializeGridTaskRows(resourceAllocationModel taskInformation.initializeGridTaskRows(resourceAllocationModel.getHoursAggregatedByCriterions());
.getHoursAggregatedByCriterions()); formBinder.setRecommendedAllocation(taskInformation.getBtnRecommendedAllocation());
formBinder.setRecommendedAllocation(taskInformation
.getBtnRecommendedAllocation());
taskInformation.onCalculateTotalHours(new ITotalHoursCalculationListener() { taskInformation.onCalculateTotalHours(new ITotalHoursCalculationListener() {
@Override @Override
@ -269,23 +257,20 @@ public class ResourceAllocationController extends GenericForwardComposer {
CRITERIONS { CRITERIONS {
@Override @Override
public Component cell(HoursRendererColumn column, public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) {
AggregatedHoursGroup data) {
return new Label(data.getCriterionsJoinedByComma()); return new Label(data.getCriterionsJoinedByComma());
} }
}, },
RESOURCE_TYPE{ RESOURCE_TYPE{
@Override @Override
public Component cell(HoursRendererColumn column, public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) {
AggregatedHoursGroup data) {
return new Label(asString(data.getResourceType())); return new Label(asString(data.getResourceType()));
} }
}, },
HOURS { HOURS {
@Override @Override
public Component cell(HoursRendererColumn column, public Component cell(HoursRendererColumn column, AggregatedHoursGroup data) {
AggregatedHoursGroup data) {
Label result = new Label(Integer.toString(data.getHours())); Label result = new Label(Integer.toString(data.getHours()));
return result; return result;
} }
@ -293,17 +278,19 @@ public class ResourceAllocationController extends GenericForwardComposer {
private static String asString(ResourceEnum resourceType) { private static String asString(ResourceEnum resourceType) {
switch (resourceType) { switch (resourceType) {
case MACHINE: case MACHINE:
case WORKER: case WORKER:
return _(resourceType.getDisplayName()); return _(resourceType.getDisplayName());
default: default:
LOG.warn("no i18n for " + resourceType.name()); LOG.warn("no i18n for " + resourceType.name());
return resourceType.name(); return resourceType.name();
} }
} }
public abstract Component cell(HoursRendererColumn column, public abstract Component cell(HoursRendererColumn column, AggregatedHoursGroup data);
AggregatedHoursGroup data);
} }
/** /**

View file

@ -70,14 +70,13 @@ import org.zkoss.zk.ui.Executions;
public abstract class ChartFiller implements IChartFiller { public abstract class ChartFiller implements IChartFiller {
protected abstract class EffortByDayCalculator<T> { protected abstract class EffortByDayCalculator<T> {
public SortedMap<LocalDate, EffortDuration> calculate( public SortedMap<LocalDate, EffortDuration> calculate(Collection<? extends T> elements) {
Collection<? extends T> elements) {
SortedMap<LocalDate, EffortDuration> result = new TreeMap<LocalDate, EffortDuration>(); SortedMap<LocalDate, EffortDuration> result = new TreeMap<LocalDate, EffortDuration>();
if (elements.isEmpty()) { if ( elements.isEmpty() ) {
return result; return result;
} }
for (T element : elements) { for (T element : elements) {
if (included(element)) { if ( included(element) ) {
EffortDuration duration = getDurationFor(element); EffortDuration duration = getDurationFor(element);
LocalDate day = getDayFor(element); LocalDate day = getDayFor(element);
EffortDuration previous = result.get(day); EffortDuration previous = result.get(day);

View file

@ -182,9 +182,8 @@ public abstract class EarnedValueChartFiller extends ChartFiller {
indicators.put(type, calculatedValueForEveryDay(values, interval)); indicators.put(type, calculatedValueForEveryDay(values, interval));
} }
protected void addZeroBeforeTheFirstValue( protected void addZeroBeforeTheFirstValue(SortedMap<LocalDate, BigDecimal> map) {
SortedMap<LocalDate, BigDecimal> map) { if ( !map.isEmpty() ) {
if (!map.isEmpty()) {
map.put(map.firstKey().minusDays(1), BigDecimal.ZERO); map.put(map.firstKey().minusDays(1), BigDecimal.ZERO);
} }
} }
@ -204,7 +203,7 @@ public abstract class EarnedValueChartFiller extends ChartFiller {
plotinfos.add(plotinfo); plotinfos.add(plotinfo);
} }
if (plotinfos.isEmpty()) { if ( plotinfos.isEmpty() ) {
// If user doesn't select any indicator, it is needed to create // If user doesn't select any indicator, it is needed to create
// a default Plotinfo in order to avoid errors on Timemplot // a default Plotinfo in order to avoid errors on Timemplot
plotinfos.add(new Plotinfo()); plotinfos.add(new Plotinfo());
@ -233,8 +232,7 @@ public abstract class EarnedValueChartFiller extends ChartFiller {
public LocalDate initialDateForIndicatorValues() { public LocalDate initialDateForIndicatorValues() {
Interval chartInterval = getIndicatorsDefinitionInterval(); Interval chartInterval = getIndicatorsDefinitionInterval();
LocalDate today = new LocalDate(); LocalDate today = new LocalDate();
return includes(chartInterval, today) ? today : chartInterval return includes(chartInterval, today) ? today : chartInterval.getFinish().minusDays(1);
.getFinish().minusDays(1);
} }
/** /**

View file

@ -63,8 +63,7 @@ import org.zkoss.zul.Tab;
@Scope(BeanDefinition.SCOPE_PROTOTYPE) @Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class LimitingResourceAllocationController extends GenericForwardComposer { public class LimitingResourceAllocationController extends GenericForwardComposer {
private static final Log LOG = LogFactory private static final Log LOG = LogFactory.getLog(LimitingResourceAllocationController.class);
.getLog(LimitingResourceAllocationController.class);
@Autowired @Autowired
private ILimitingResourceAllocationModel resourceAllocationModel; private ILimitingResourceAllocationModel resourceAllocationModel;

View file

@ -267,8 +267,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private String tabSelected = "load_tab"; private String tabSelected = "load_tab";
private static class NullSeparatorCommandOnTask<T> implements private static class NullSeparatorCommandOnTask<T> implements ICommandOnTask<T> {
ICommandOnTask<T> {
@Override @Override
public String getName() { public String getName() {
@ -294,37 +293,36 @@ public class OrderPlanningModel implements IOrderPlanningModel {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public void setConfigurationToPlanner(final Planner planner, Order order, public void setConfigurationToPlanner(final Planner planner,
ViewSwitcher switcher, Order order,
EditTaskController editTaskController, ViewSwitcher switcher,
AdvancedAllocationTaskController advancedAllocationTaskController, EditTaskController editTaskController,
AdvanceAssignmentPlanningController advanceAssignmentPlanningController, AdvancedAllocationTaskController advancedAllocationTaskController,
AdvanceConsolidationController advanceConsolidationController, AdvanceAssignmentPlanningController advanceAssignmentPlanningController,
CalendarAllocationController calendarAllocationController, AdvanceConsolidationController advanceConsolidationController,
List<ICommand<TaskElement>> additional) { CalendarAllocationController calendarAllocationController,
List<ICommand<TaskElement>> additional) {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
this.planner = planner; this.planner = planner;
planningState = createPlanningStateFor(order); planningState = createPlanningStateFor(order);
PlannerConfiguration<TaskElement> configuration = planningState PlannerConfiguration<TaskElement> configuration = planningState.getConfiguration();
.getConfiguration(); PROFILING_LOG.debug("load data and create configuration took: " + (System.currentTimeMillis() - time) + " ms");
PROFILING_LOG.debug("load data and create configuration took: "
+ (System.currentTimeMillis() - time) + " ms");
User user; User user;
try { try {
user = this.userDAO.findByLoginName(SecurityUtils user = this.userDAO.findByLoginName(SecurityUtils.getSessionUserLoginName());
.getSessionUserLoginName());
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
configuration.setExpandPlanningViewCharts(user
.isExpandOrderPlanningViewCharts()); configuration.setExpandPlanningViewCharts(user.isExpandOrderPlanningViewCharts());
addAdditional(additional, configuration); addAdditional(additional, configuration);
planner.setInitialZoomLevel(getZoomLevel(configuration, order)); planner.setInitialZoomLevel(getZoomLevel(configuration, order));
final boolean writingAllowed = isWritingAllowedOnOrder(); final boolean writingAllowed = isWritingAllowedOnOrder();
ISaveCommand saveCommand = setupSaveCommand(configuration, ISaveCommand saveCommand = setupSaveCommand(configuration, writingAllowed);
writingAllowed);
setupEditingCapabilities(configuration, writingAllowed); setupEditingCapabilities(configuration, writingAllowed);
configuration.addGlobalCommand(buildReassigningCommand()); configuration.addGlobalCommand(buildReassigningCommand());
@ -335,25 +333,21 @@ public class OrderPlanningModel implements IOrderPlanningModel {
final IResourceAllocationCommand resourceAllocationCommand = buildResourceAllocationCommand(editTaskController); final IResourceAllocationCommand resourceAllocationCommand = buildResourceAllocationCommand(editTaskController);
final IAdvanceAssignmentPlanningCommand advanceAssignmentPlanningCommand = buildAdvanceAssignmentPlanningCommand(advanceAssignmentPlanningController); final IAdvanceAssignmentPlanningCommand advanceAssignmentPlanningCommand =
buildAdvanceAssignmentPlanningCommand(advanceAssignmentPlanningController);
// Build context menu // Build context menu
configuration.addCommandOnTask(buildMilestoneCommand()); configuration.addCommandOnTask(buildMilestoneCommand());
configuration.addCommandOnTask(buildDeleteMilestoneCommand()); configuration.addCommandOnTask(buildDeleteMilestoneCommand());
configuration.addCommandOnTask(separator); configuration.addCommandOnTask(separator);
configuration configuration.addCommandOnTask(buildTaskPropertiesCommand(editTaskController));
.addCommandOnTask(buildTaskPropertiesCommand(editTaskController));
configuration.addCommandOnTask(resourceAllocationCommand); configuration.addCommandOnTask(resourceAllocationCommand);
configuration configuration.addCommandOnTask(buildAdvancedAllocationCommand(advancedAllocationTaskController));
.addCommandOnTask(buildAdvancedAllocationCommand(advancedAllocationTaskController)); configuration.addCommandOnTask(buildSubcontractCommand(editTaskController));
configuration configuration.addCommandOnTask(buildCalendarAllocationCommand(calendarAllocationController));
.addCommandOnTask(buildSubcontractCommand(editTaskController));
configuration
.addCommandOnTask(buildCalendarAllocationCommand(calendarAllocationController));
configuration.addCommandOnTask(separator); configuration.addCommandOnTask(separator);
configuration.addCommandOnTask(advanceAssignmentPlanningCommand); configuration.addCommandOnTask(advanceAssignmentPlanningCommand);
configuration configuration.addCommandOnTask(buildAdvanceConsolidationCommand(advanceConsolidationController));
.addCommandOnTask(buildAdvanceConsolidationCommand(advanceConsolidationController));
configuration.setDoubleClickCommand(resourceAllocationCommand); configuration.setDoubleClickCommand(resourceAllocationCommand);
addPrintSupport(configuration, order); addPrintSupport(configuration, order);
@ -366,8 +360,10 @@ public class OrderPlanningModel implements IOrderPlanningModel {
configureModificators(planningState.getOrder(), configuration); configureModificators(planningState.getOrder(), configuration);
long setConfigurationTime = System.currentTimeMillis(); long setConfigurationTime = System.currentTimeMillis();
planner.setConfiguration(configuration); planner.setConfiguration(configuration);
PROFILING_LOG.debug("setConfiguration on planner took: "
+ (System.currentTimeMillis() - setConfigurationTime) + " ms"); PROFILING_LOG.debug("setConfiguration on planner took: " +
(System.currentTimeMillis() - setConfigurationTime) + " ms");
long preparingChartsAndMisc = System.currentTimeMillis(); long preparingChartsAndMisc = System.currentTimeMillis();
setupZoomLevelListener(planner, order); setupZoomLevelListener(planner, order);
@ -389,37 +385,31 @@ public class OrderPlanningModel implements IOrderPlanningModel {
ChangeHooker changeHooker = new ChangeHooker(configuration, saveCommand); ChangeHooker changeHooker = new ChangeHooker(configuration, saveCommand);
setupLoadChart(chartLoadTimeplot, planner, changeHooker); setupLoadChart(chartLoadTimeplot, planner, changeHooker);
setupEarnedValueChart(chartEarnedValueTimeplot, earnedValueChartFiller, setupEarnedValueChart(chartEarnedValueTimeplot, earnedValueChartFiller, planner, changeHooker);
planner, changeHooker);
setupAdvanceAssignmentPlanningController(planner, advanceAssignmentPlanningController); setupAdvanceAssignmentPlanningController(planner, advanceAssignmentPlanningController);
PROFILING_LOG
.debug("preparing charts and miscellaneous took: " PROFILING_LOG.debug("preparing charts and miscellaneous took: " +
+ (System.currentTimeMillis() - preparingChartsAndMisc) (System.currentTimeMillis() - preparingChartsAndMisc) + " ms");
+ " ms");
// Calculate critical path progress, needed for 'Project global progress' chart in Dashboard view // Calculate critical path progress, needed for 'Project global progress' chart in Dashboard view
planner.addGraphChangeListenersFromConfiguration(configuration); planner.addGraphChangeListenersFromConfiguration(configuration);
long overalProgressContentTime = System.currentTimeMillis(); long overalProgressContentTime = System.currentTimeMillis();
PROFILING_LOG.debug("overalProgressContent took: " PROFILING_LOG.debug("overalProgressContent took: " + (System.currentTimeMillis() - overalProgressContentTime));
+ (System.currentTimeMillis() - overalProgressContentTime));
} }
private ZoomLevel getZoomLevel( private ZoomLevel getZoomLevel(PlannerConfiguration<TaskElement> configuration, Order order) {
PlannerConfiguration<TaskElement> configuration, Order order) {
ZoomLevel sessionZoom = FilterUtils.readZoomLevel(order); ZoomLevel sessionZoom = FilterUtils.readZoomLevel(order);
if (sessionZoom != null) { if ( sessionZoom != null ) {
return sessionZoom; return sessionZoom;
} }
return OrderPlanningModel.calculateDefaultLevel(configuration); return OrderPlanningModel.calculateDefaultLevel(configuration);
} }
private void setupZoomLevelListener(Planner planner, Order order) { private void setupZoomLevelListener(Planner planner, Order order) {
planner.getTimeTracker().addZoomListener( planner.getTimeTracker().addZoomListener(getSessionZoomLevelListener(order));
getSessionZoomLevelListener(order));
} }
private IZoomLevelChangedListener getSessionZoomLevelListener( private IZoomLevelChangedListener getSessionZoomLevelListener(final Order order) {
final Order order) {
IZoomLevelChangedListener zoomListener = new IZoomLevelChangedListener() { IZoomLevelChangedListener zoomListener = new IZoomLevelChangedListener() {
@Override @Override
@ -434,7 +424,8 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private OrderEarnedValueChartFiller earnedValueChartFiller; private OrderEarnedValueChartFiller earnedValueChartFiller;
private void setupAdvanceAssignmentPlanningController(final Planner planner, private void setupAdvanceAssignmentPlanningController(
final Planner planner,
AdvanceAssignmentPlanningController advanceAssignmentPlanningController) { AdvanceAssignmentPlanningController advanceAssignmentPlanningController) {
advanceAssignmentPlanningController.setReloadEarnedValueListener(new IReloadChartListener() { advanceAssignmentPlanningController.setReloadEarnedValueListener(new IReloadChartListener() {
@ -445,12 +436,13 @@ public class OrderPlanningModel implements IOrderPlanningModel {
@Override @Override
public Void execute() { public Void execute() {
if (isExecutingOutsideZKExecution()) { if ( isExecutingOutsideZKExecution() ) {
return null; return null;
} }
if (planner.isVisibleChart()) { if ( planner.isVisibleChart() ) {
//update earned value chart //update earned value chart
earnedValueChart.fillChart(); earnedValueChart.fillChart();
//update earned value legend //update earned value legend
updateEarnedValueChartLegend(); updateEarnedValueChartLegend();
} }
@ -591,31 +583,26 @@ public class OrderPlanningModel implements IOrderPlanningModel {
return result; return result;
} }
void hookInto(EnumSet<ChangeTypes> reloadOn, void hookInto(EnumSet<ChangeTypes> reloadOn, IReloadChartListener reloadChart) {
IReloadChartListener reloadChart) {
Validate.notNull(reloadChart); Validate.notNull(reloadChart);
hookIntoImpl(wrapIfNeeded(reloadChart), reloadOn); hookIntoImpl(wrapIfNeeded(reloadChart), reloadOn);
} }
private IReloadChartListener wrapIfNeeded( private IReloadChartListener wrapIfNeeded(IReloadChartListener reloadChart) {
IReloadChartListener reloadChart) { if ( !wrapOnReadOnlyTransaction ) {
if (!wrapOnReadOnlyTransaction) {
return reloadChart; return reloadChart;
} }
return AdHocTransactionService.readOnlyProxy(transactionService, return AdHocTransactionService.readOnlyProxy(transactionService, IReloadChartListener.class, reloadChart);
IReloadChartListener.class, reloadChart);
} }
private void hookIntoImpl(IReloadChartListener reloadChart, private void hookIntoImpl(IReloadChartListener reloadChart, EnumSet<ChangeTypes> reloadOn) {
EnumSet<ChangeTypes> reloadOn) { if ( saveCommand != null && reloadOn.contains(ChangeTypes.ON_GRAPH_CHANGED) ) {
if (saveCommand != null
&& reloadOn.contains(ChangeTypes.ON_GRAPH_CHANGED)) {
hookIntoSaveCommand(reloadChart); hookIntoSaveCommand(reloadChart);
} }
if (reloadOn.contains(ChangeTypes.ON_RELOAD_CHART_REQUESTED)) { if ( reloadOn.contains(ChangeTypes.ON_RELOAD_CHART_REQUESTED) ) {
hookIntoReloadChartRequested(reloadChart); hookIntoReloadChartRequested(reloadChart);
} }
if (reloadOn.contains(ChangeTypes.ON_GRAPH_CHANGED)) { if ( reloadOn.contains(ChangeTypes.ON_GRAPH_CHANGED) ) {
hookIntoGraphChanged(reloadChart); hookIntoGraphChanged(reloadChart);
} }
} }
@ -630,14 +617,12 @@ public class OrderPlanningModel implements IOrderPlanningModel {
saveCommand.addListener(afterSaveListener); saveCommand.addListener(afterSaveListener);
} }
private void hookIntoReloadChartRequested( private void hookIntoReloadChartRequested(IReloadChartListener reloadChart) {
IReloadChartListener reloadChart) {
configuration.addReloadChartListener(reloadChart); configuration.addReloadChartListener(reloadChart);
} }
private void hookIntoGraphChanged(final IReloadChartListener reloadChart) { private void hookIntoGraphChanged(final IReloadChartListener reloadChart) {
configuration configuration.addPostGraphChangeListener(new IGraphChangeListener() {
.addPostGraphChangeListener(new IGraphChangeListener() {
@Override @Override
public void execute() { public void execute() {
@ -648,8 +633,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
} }
private void addPrintSupport( private void addPrintSupport(PlannerConfiguration<TaskElement> configuration, final Order order) {
PlannerConfiguration<TaskElement> configuration, final Order order) {
configuration.setPrintAction(new IPrintAction() { configuration.setPrintAction(new IPrintAction() {
@Override @Override
public void doPrint() { public void doPrint() {
@ -662,8 +646,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
} }
@Override @Override
public void doPrint(HashMap<String, String> parameters, public void doPrint(HashMap<String, String> parameters, Planner planner) {
Planner planner) {
CutyPrint.print(order, parameters, planner); CutyPrint.print(order, parameters, planner);
} }
@ -676,8 +659,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
return deleteMilestoneCommand; return deleteMilestoneCommand;
} }
private void configureModificators(Order orderReloaded, private void configureModificators(Order orderReloaded, PlannerConfiguration<TaskElement> configuration) {
PlannerConfiguration<TaskElement> configuration) {
// Either InitDate or DeadLine must be set, depending on forwards or // Either InitDate or DeadLine must be set, depending on forwards or
// backwards planning // backwards planning
configuration.setSecondLevelModificators(SeveralModificators.create( configuration.setSecondLevelModificators(SeveralModificators.create(
@ -743,7 +725,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private Tab createTab(String name, final String id) { private Tab createTab(String name, final String id) {
Tab tab = new Tab(name); Tab tab = new Tab(name);
tab.setId(id); tab.setId(id);
if (id.equals(tabSelected)) { if ( id.equals(tabSelected) ) {
tab.setSelected(true); tab.setSelected(true);
} }
tab.addEventListener("onClick", new EventListener() { tab.addEventListener("onClick", new EventListener() {
@ -761,13 +743,11 @@ public class OrderPlanningModel implements IOrderPlanningModel {
hbox.setClass("legend-container"); hbox.setClass("legend-container");
hbox.setAlign("center"); hbox.setAlign("center");
hbox.setPack("center"); hbox.setPack("center");
Executions.createComponents("/planner/_legendLoadChartOrder.zul", hbox, Executions.createComponents("/planner/_legendLoadChartOrder.zul", hbox, null);
null);
return hbox; return hbox;
} }
private Constraint dateMustBeInsideVisualizationArea( private Constraint dateMustBeInsideVisualizationArea(final OrderEarnedValueChartFiller earnedValueChartFiller) {
final OrderEarnedValueChartFiller earnedValueChartFiller) {
return new Constraint() { return new Constraint() {
@Override @Override
@ -775,13 +755,12 @@ public class OrderPlanningModel implements IOrderPlanningModel {
Object valueObject) Object valueObject)
throws WrongValueException { throws WrongValueException {
Date value = (Date) valueObject; Date value = (Date) valueObject;
if (value != null
&& !EarnedValueChartFiller.includes( if ( value != null && !EarnedValueChartFiller.includes(
earnedValueChartFiller earnedValueChartFiller.getIndicatorsDefinitionInterval(),
.getIndicatorsDefinitionInterval(), LocalDate LocalDate.fromDateFields(value)) ) {
.fromDateFields(value))) {
throw new WrongValueException(comp, throw new WrongValueException(comp, _("Date must be inside visualization area"));
_("Date must be inside visualization area"));
} }
} }
@ -790,16 +769,15 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private void dateInfutureMessage(Datebox datebox) { private void dateInfutureMessage(Datebox datebox) {
Date value = datebox.getValue(); Date value = datebox.getValue();
Date today = LocalDate.fromDateFields(new Date()) Date today = LocalDate.fromDateFields(new Date()).toDateTimeAtStartOfDay().toDate();
.toDateTimeAtStartOfDay().toDate(); if ( value != null && (value.compareTo(today) > 0) ) {
if (value != null && (value.compareTo(today) > 0)) {
throw new WrongValueException(datebox, _("date in the future")); throw new WrongValueException(datebox, _("date in the future"));
} }
} }
private void appendEventListenerToDateboxIndicators( private void appendEventListenerToDateboxIndicators(final OrderEarnedValueChartFiller earnedValueChartFiller,
final OrderEarnedValueChartFiller earnedValueChartFiller, final Vbox vbox) {
final Vbox vbox) {
earnedValueChartLegendDatebox.addEventListener(Events.ON_CHANGE, earnedValueChartLegendDatebox.addEventListener(Events.ON_CHANGE,
new EventListener() { new EventListener() {
@ -816,33 +794,29 @@ public class OrderPlanningModel implements IOrderPlanningModel {
try { try {
//force the validation again (getValue alone doesn't work because //force the validation again (getValue alone doesn't work because
//the result of the validation is cached) //the result of the validation is cached)
earnedValueChartLegendDatebox.setValue( earnedValueChartLegendDatebox.setValue(earnedValueChartLegendDatebox.getValue());
earnedValueChartLegendDatebox.getValue());
} }
catch (WrongValueException e) { catch (WrongValueException e) {
//the user moved the gantt and the legend became out of the //the user moved the gantt and the legend became out of the
//visualization area, reset to a correct date //visualization area, reset to a correct date
earnedValueChartLegendDatebox.setValue(earnedValueChartFiller. earnedValueChartLegendDatebox.setValue(earnedValueChartFiller.initialDateForIndicatorValues().
initialDateForIndicatorValues().toDateTimeAtStartOfDay() toDateTimeAtStartOfDay().toDate());
.toDate());
} }
LocalDate date = new LocalDate(earnedValueChartLegendDatebox.getRawValue()); LocalDate date = new LocalDate(earnedValueChartLegendDatebox.getRawValue());
org.zkoss.zk.ui.Component child = earnedValueChartLegendContainer org.zkoss.zk.ui.Component child = earnedValueChartLegendContainer.getFellow("indicatorsTable");
.getFellow("indicatorsTable");
updateEarnedValueChartLegend(date); updateEarnedValueChartLegend(date);
} }
private void updateEarnedValueChartLegend(LocalDate date) { private void updateEarnedValueChartLegend(LocalDate date) {
for (EarnedValueType type : EarnedValueType.values()) { for (EarnedValueType type : EarnedValueType.values()) {
Label valueLabel = (Label) earnedValueChartLegendContainer Label valueLabel = (Label) earnedValueChartLegendContainer.getFellow(type.toString());
.getFellow(type.toString()); valueLabel.setValue(getLabelTextEarnedValueType(earnedValueChartFiller, type, date));
valueLabel.setValue(getLabelTextEarnedValueType(
earnedValueChartFiller, type, date));
} }
} }
private org.zkoss.zk.ui.Component getEarnedValueChartConfigurableLegend( private org.zkoss.zk.ui.Component getEarnedValueChartConfigurableLegend(
OrderEarnedValueChartFiller earnedValueChartFiller, LocalDate date) { OrderEarnedValueChartFiller earnedValueChartFiller, LocalDate date) {
Hbox mainhbox = new Hbox(); Hbox mainhbox = new Hbox();
mainhbox.setId("indicatorsTable"); mainhbox.setId("indicatorsTable");
@ -864,8 +838,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
checkbox.setAttribute("indicator", type); checkbox.setAttribute("indicator", type);
checkbox.setStyle("color: " + type.getColor()); checkbox.setStyle("color: " + type.getColor());
Label valueLabel = new Label(getLabelTextEarnedValueType( Label valueLabel = new Label(getLabelTextEarnedValueType(earnedValueChartFiller, type, date));
earnedValueChartFiller, type, date));
valueLabel.setId(type.toString()); valueLabel.setId(type.toString());
Hbox hbox = new Hbox(); Hbox hbox = new Hbox();
@ -874,9 +847,11 @@ public class OrderPlanningModel implements IOrderPlanningModel {
columnNumber = columnNumber + 1; columnNumber = columnNumber + 1;
switch (columnNumber) { switch (columnNumber) {
case 1: case 1:
column1.appendChild(hbox); column1.appendChild(hbox);
break; break;
case 2: case 2:
column2.appendChild(hbox); column2.appendChild(hbox);
columnNumber = 0; columnNumber = 0;
@ -897,13 +872,12 @@ public class OrderPlanningModel implements IOrderPlanningModel {
return mainhbox; return mainhbox;
} }
private String getLabelTextEarnedValueType( private String getLabelTextEarnedValueType(OrderEarnedValueChartFiller earnedValueChartFiller,
OrderEarnedValueChartFiller earnedValueChartFiller, EarnedValueType type, LocalDate date) {
EarnedValueType type, LocalDate date) {
BigDecimal value = earnedValueChartFiller.getIndicator(type, date); BigDecimal value = earnedValueChartFiller.getIndicator(type, date);
String units = _("h"); String units = _("h");
if (type.equals(EarnedValueType.CPI) if ( type.equals(EarnedValueType.CPI) || type.equals(EarnedValueType.SPI) ) {
|| type.equals(EarnedValueType.SPI)) {
value = value.multiply(new BigDecimal(100)); value = value.multiply(new BigDecimal(100));
units = "%"; units = "%";
} }
@ -912,11 +886,12 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private void markAsSelectedDefaultIndicators() { private void markAsSelectedDefaultIndicators() {
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) { for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
EarnedValueType type = (EarnedValueType) checkbox EarnedValueType type = (EarnedValueType) checkbox.getAttribute("indicator");
.getAttribute("indicator");
switch (type) { switch (type) {
case BCWS: case BCWS:
case ACWP: case ACWP:
case BCWP: case BCWP:
checkbox.setChecked(true); checkbox.setChecked(true);
break; break;
@ -931,17 +906,15 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private Set<EarnedValueType> getEarnedValueSelectedIndicators() { private Set<EarnedValueType> getEarnedValueSelectedIndicators() {
Set<EarnedValueType> result = new HashSet<EarnedValueType>(); Set<EarnedValueType> result = new HashSet<EarnedValueType>();
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) { for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
if (checkbox.isChecked()) { if ( checkbox.isChecked() ) {
EarnedValueType type = (EarnedValueType) checkbox EarnedValueType type = (EarnedValueType) checkbox.getAttribute("indicator");
.getAttribute("indicator");
result.add(type); result.add(type);
} }
} }
return result; return result;
} }
private void setEventListenerConfigurationCheckboxes( private void setEventListenerConfigurationCheckboxes(final Chart earnedValueChart) {
final Chart earnedValueChart) {
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) { for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
checkbox.addEventListener(Events.ON_CHECK, new EventListener() { checkbox.addEventListener(Events.ON_CHECK, new EventListener() {
@ -962,25 +935,22 @@ public class OrderPlanningModel implements IOrderPlanningModel {
} }
} }
private void refillLoadChartWhenNeeded(ChangeHooker changeHooker, private void refillLoadChartWhenNeeded(ChangeHooker changeHooker, final Planner planner, final Chart loadChart,
final Planner planner, final Chart loadChart, final boolean updateEarnedValueChartLegend) {
final boolean updateEarnedValueChartLegend) {
planner.getTimeTracker().addZoomListener(
fillOnZoomChange(loadChart, planner, updateEarnedValueChartLegend));
planner
.addChartVisibilityListener(fillOnChartVisibilityChange(loadChart));
changeHooker.withReadOnlyTransactionWraping().hookInto( planner.getTimeTracker().addZoomListener(fillOnZoomChange(loadChart, planner, updateEarnedValueChartLegend));
EnumSet.allOf(ChangeTypes.class), new IReloadChartListener() { planner.addChartVisibilityListener(fillOnChartVisibilityChange(loadChart));
changeHooker.withReadOnlyTransactionWraping().hookInto(EnumSet.allOf(ChangeTypes.class), new IReloadChartListener() {
@Override @Override
public void reloadChart() { public void reloadChart() {
if (isExecutingOutsideZKExecution()) { if ( isExecutingOutsideZKExecution() ) {
return; return;
} }
if (planner.isVisibleChart()) { if ( planner.isVisibleChart() ) {
loadChart.fillChart(); loadChart.fillChart();
if(updateEarnedValueChartLegend) { if( updateEarnedValueChartLegend ) {
updateEarnedValueChartLegend(); updateEarnedValueChartLegend();
} }
} }
@ -993,20 +963,21 @@ public class OrderPlanningModel implements IOrderPlanningModel {
} }
private void addAdditional(List<ICommand<TaskElement>> additional, private void addAdditional(List<ICommand<TaskElement>> additional,
PlannerConfiguration<TaskElement> configuration) { PlannerConfiguration<TaskElement> configuration) {
for (ICommand<TaskElement> c : additional) { for (ICommand<TaskElement> c : additional) {
configuration.addGlobalCommand(c); configuration.addGlobalCommand(c);
} }
} }
private boolean isWritingAllowedOnOrder() { private boolean isWritingAllowedOnOrder() {
if (planningState.getSavedOrderState() == OrderStatusEnum.STORED if ( planningState.getSavedOrderState() == OrderStatusEnum.STORED &&
&& planningState.getOrder().getState() == OrderStatusEnum.STORED) { planningState.getOrder().getState() == OrderStatusEnum.STORED ) {
// STORED orders can't be saved, independently of user permissions // STORED orders can't be saved, independently of user permissions
return false; return false;
} }
if (SecurityUtils if ( SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_EDIT_ALL_PROJECTS) ) {
.isSuperuserOrUserInRoles(UserRole.ROLE_EDIT_ALL_PROJECTS)) {
return true; return true;
} }
return thereIsWriteAuthorizationFor(planningState.getOrder()); return thereIsWriteAuthorizationFor(planningState.getOrder());
@ -1016,9 +987,8 @@ public class OrderPlanningModel implements IOrderPlanningModel {
String loginName = SecurityUtils.getSessionUserLoginName(); String loginName = SecurityUtils.getSessionUserLoginName();
try { try {
User user = userDAO.findByLoginName(loginName); User user = userDAO.findByLoginName(loginName);
for (OrderAuthorization authorization : orderAuthorizationDAO for (OrderAuthorization authorization : orderAuthorizationDAO.listByOrderUserAndItsProfiles(order, user)) {
.listByOrderUserAndItsProfiles(order, user)) { if ( authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION ) {
if (authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) {
return true; return true;
} }
} }
@ -1364,8 +1334,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
} }
private ISubcontractCommand buildSubcontractCommand( private ISubcontractCommand buildSubcontractCommand(EditTaskController editTaskController) {
EditTaskController editTaskController) {
subcontractCommand.initialize(editTaskController, planningState); subcontractCommand.initialize(editTaskController, planningState);
return subcontractCommand; return subcontractCommand;
} }
@ -1390,7 +1359,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private void forceLoadLabels(OrderElement orderElement) { private void forceLoadLabels(OrderElement orderElement) {
orderElement.getLabels().size(); orderElement.getLabels().size();
if (!orderElement.isLeaf()) { if ( !orderElement.isLeaf() ) {
for (OrderElement element : orderElement.getChildren()) { for (OrderElement element : orderElement.getChildren()) {
forceLoadLabels(element); forceLoadLabels(element);
} }
@ -1403,7 +1372,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
hoursGroup.getCriterionRequirements().size(); hoursGroup.getCriterionRequirements().size();
} }
if (!orderElement.isLeaf()) { if ( !orderElement.isLeaf() ) {
for (OrderElement element : orderElement.getChildren()) { for (OrderElement element : orderElement.getChildren()) {
forceLoadCriterionRequirements(element); forceLoadCriterionRequirements(element);
} }

View file

@ -130,32 +130,33 @@ public class SaveCommandBuilder {
private static final Log LOG = LogFactory.getLog(SaveCommandBuilder.class); private static final Log LOG = LogFactory.getLog(SaveCommandBuilder.class);
public ISaveCommand build(PlanningState planningState, public ISaveCommand build(PlanningState planningState, PlannerConfiguration<TaskElement> plannerConfiguration) {
PlannerConfiguration<TaskElement> plannerConfiguration) { SaveCommand result = new SaveCommand(planningState, plannerConfiguration);
SaveCommand result = new SaveCommand(planningState,
plannerConfiguration);
return ConcurrentModificationHandling.addHandling( return ConcurrentModificationHandling.addHandling(
"/planner/index.zul;company_scheduling", ISaveCommand.class, "/planner/index.zul;company_scheduling", ISaveCommand.class, result);
result);
} }
public static void dontPoseAsTransientAndChildrenObjects( public static void dontPoseAsTransientAndChildrenObjects(
Collection<? extends ResourceAllocation<?>> resourceAllocations) { Collection<? extends ResourceAllocation<?>> resourceAllocations) {
for (ResourceAllocation<?> each : resourceAllocations) { for (ResourceAllocation<?> each : resourceAllocations) {
each.dontPoseAsTransientObjectAnymore(); each.dontPoseAsTransientObjectAnymore();
each.makeAssignmentsContainersDontPoseAsTransientAnyMore(); each.makeAssignmentsContainersDontPoseAsTransientAnyMore();
for (DayAssignment eachAssignment : each.getAssignments()) { for (DayAssignment eachAssignment : each.getAssignments()) {
eachAssignment.dontPoseAsTransientObjectAnymore(); eachAssignment.dontPoseAsTransientObjectAnymore();
} }
for (DerivedAllocation eachDerived : each.getDerivedAllocations()) { for (DerivedAllocation eachDerived : each.getDerivedAllocations()) {
eachDerived.dontPoseAsTransientObjectAnymore(); eachDerived.dontPoseAsTransientObjectAnymore();
Collection<DerivedDayAssignmentsContainer> containers = eachDerived Collection<DerivedDayAssignmentsContainer> containers = eachDerived.getContainers();
.getContainers();
for (DerivedDayAssignmentsContainer eachContainer : containers) { for (DerivedDayAssignmentsContainer eachContainer : containers) {
eachContainer.dontPoseAsTransientObjectAnymore(); eachContainer.dontPoseAsTransientObjectAnymore();
} }
for (DerivedDayAssignment eachAssignment : eachDerived
.getAssignments()) { for (DerivedDayAssignment eachAssignment : eachDerived.getAssignments()) {
eachAssignment.dontPoseAsTransientObjectAnymore(); eachAssignment.dontPoseAsTransientObjectAnymore();
} }
} }
@ -164,13 +165,11 @@ public class SaveCommandBuilder {
} }
private static void dontPoseAsTransient(LimitingResourceQueueElement element) { private static void dontPoseAsTransient(LimitingResourceQueueElement element) {
if (element != null) { if ( element != null ) {
for (LimitingResourceQueueDependency d : element for (LimitingResourceQueueDependency d : element.getDependenciesAsOrigin()) {
.getDependenciesAsOrigin()) {
d.dontPoseAsTransientObjectAnymore(); d.dontPoseAsTransientObjectAnymore();
} }
for (LimitingResourceQueueDependency d : element for (LimitingResourceQueueDependency d : element.getDependenciesAsDestiny()) {
.getDependenciesAsDestiny()) {
d.dontPoseAsTransientObjectAnymore(); d.dontPoseAsTransientObjectAnymore();
} }
element.dontPoseAsTransientObjectAnymore(); element.dontPoseAsTransientObjectAnymore();
@ -236,31 +235,27 @@ public class SaveCommandBuilder {
private boolean disabled = false; private boolean disabled = false;
public SaveCommand(PlanningState planningState, public SaveCommand(PlanningState planningState, PlannerConfiguration<TaskElement> configuration) {
PlannerConfiguration<TaskElement> configuration) {
this.state = planningState; this.state = planningState;
this.configuration = configuration; this.configuration = configuration;
this.adapter = configuration.getAdapter(); this.adapter = configuration.getAdapter();
this.constraintCalculator = new ConstraintCalculator<TaskElement>( this.constraintCalculator = new ConstraintCalculator<TaskElement>(configuration.isScheduleBackwards()) {
configuration.isScheduleBackwards()) {
@Override @Override
protected GanttDate getStartDate(TaskElement vertex) { protected GanttDate getStartDate(TaskElement vertex) {
return TaskElementAdapter.toGantt(vertex return TaskElementAdapter.toGantt(vertex.getIntraDayStartDate());
.getIntraDayStartDate());
} }
@Override @Override
protected GanttDate getEndDate(TaskElement vertex) { protected GanttDate getEndDate(TaskElement vertex) {
return TaskElementAdapter.toGantt(vertex return TaskElementAdapter.toGantt(vertex.getIntraDayEndDate());
.getIntraDayEndDate());
} }
}; };
} }
@Override @Override
public void doAction(IContext<TaskElement> context) { public void doAction(IContext<TaskElement> context) {
if (disabled) { if ( disabled ) {
return; return;
} }
@ -269,7 +264,7 @@ public class SaveCommandBuilder {
@Override @Override
public void doActions() { public void doActions() {
// A little bit hack // A little bit hack
if (taskPropertiesController != null) if ( taskPropertiesController != null )
taskPropertiesController.emailNotificationAddNew(); taskPropertiesController.emailNotificationAddNew();
notifyUserThatSavingIsDone(); notifyUserThatSavingIsDone();
@ -289,44 +284,39 @@ public class SaveCommandBuilder {
} }
@Override @Override
public void save(final IBeforeSaveActions beforeSaveActions, public void save(final IBeforeSaveActions beforeSaveActions, IAfterSaveActions afterSaveActions) {
IAfterSaveActions afterSaveActions) {
try { try {
if (state.getScenarioInfo().isUsingTheOwnerScenario() if ( state.getScenarioInfo().isUsingTheOwnerScenario() || userAcceptsCreateANewOrderVersion() ) {
|| userAcceptsCreateANewOrderVersion()) { transactionService.runOnTransaction(new IOnTransaction<Void>() {
transactionService @Override
.runOnTransaction(new IOnTransaction<Void>() { public Void execute() {
@Override if (beforeSaveActions != null) {
public Void execute() { beforeSaveActions.doActions();
if (beforeSaveActions != null) { }
beforeSaveActions.doActions(); doTheSaving();
} return null;
doTheSaving(); }
return null; });
}
});
dontPoseAsTransientObjectAnymore(state.getOrder()); dontPoseAsTransientObjectAnymore(state.getOrder());
dontPoseAsTransientObjectAnymore(state.getOrder() dontPoseAsTransientObjectAnymore(state.getOrder().getEndDateCommunicationToCustomer());
.getEndDateCommunicationToCustomer());
state.getScenarioInfo().afterCommit(); state.getScenarioInfo().afterCommit();
if (state.getOrder() if ( state.getOrder().isNeededToRecalculateSumChargedEfforts() ) {
.isNeededToRecalculateSumChargedEfforts()) { sumChargedEffortRecalculator.recalculate(state.getOrder().getId());
sumChargedEffortRecalculator.recalculate(state
.getOrder().getId());
} }
if (state.getOrder().isNeededToRecalculateSumExpenses()) { if ( state.getOrder().isNeededToRecalculateSumExpenses() ) {
sumExpensesRecalculator.recalculate(state.getOrder().getId()); sumExpensesRecalculator.recalculate(state.getOrder().getId());
} }
fireAfterSave(); fireAfterSave();
if (afterSaveActions != null) { if ( afterSaveActions != null ) {
afterSaveActions.doActions(); afterSaveActions.doActions();
} }
} }
} catch (ValidationException validationException) { } catch (ValidationException validationException) {
if (Executions.getCurrent() == null) { if ( Executions.getCurrent() == null ) {
throw validationException; throw validationException;
} }
@ -334,22 +324,21 @@ public class SaveCommandBuilder {
String message = ""; String message = "";
LabelCreatorForInvalidValues labelCreator = new LabelCreatorForInvalidValues(); LabelCreatorForInvalidValues labelCreator = new LabelCreatorForInvalidValues();
for (InvalidValue invalidValue : validationException
.getInvalidValues()) { for (InvalidValue invalidValue : validationException.getInvalidValues()) {
message += "* " message += "* " + ((Label) labelCreator.createLabelFor(invalidValue)).getValue() + "\n";
+ ((Label) labelCreator
.createLabelFor(invalidValue))
.getValue() + "\n";
} }
if (validationException.getInvalidValues().isEmpty()) { if ( validationException.getInvalidValues().isEmpty() ) {
message += validationException.getMessage(); message += validationException.getMessage();
} }
LOG.warn("Error saving the project", validationException); LOG.warn("Error saving the project", validationException);
Messagebox.show( Messagebox.show(
_("Error saving the project\n{0}", message), _("Error saving the project\n{0}", message),
_("Error"), Messagebox.OK, Messagebox.ERROR); _("Error"), Messagebox.OK, Messagebox.ERROR);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -364,23 +353,20 @@ public class SaveCommandBuilder {
} }
private void notifyUserThatSavingIsDone() { private void notifyUserThatSavingIsDone() {
if (Executions.getCurrent() == null) { if ( Executions.getCurrent() == null ) {
// test environment // test environment
return; return;
} }
try { try {
Messagebox.show(_("Project saved"), _("Information"), Messagebox.show(_("Project saved"), _("Information"), Messagebox.OK, Messagebox.INFORMATION);
Messagebox.OK, Messagebox.INFORMATION);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
if (Executions.getCurrent() != null) { if ( Executions.getCurrent() != null ) {
// Reset timer of warning on leaving page // Reset timer of warning on leaving page
ConfirmCloseUtil.resetConfirmClose(); ConfirmCloseUtil.resetConfirmClose();
if (SecurityUtils.loggedUserCanWrite(state.getOrder())) { if ( SecurityUtils.loggedUserCanWrite(state.getOrder()) ) {
ConfirmCloseUtil ConfirmCloseUtil.setConfirmClose(Executions.getCurrent().getDesktop(),
.setConfirmClose(
Executions.getCurrent().getDesktop(),
_("You are about to leave the planning editing. Unsaved changes will be lost!")); _("You are about to leave the planning editing. Unsaved changes will be lost!"));
} }
} }
@ -398,7 +384,7 @@ public class SaveCommandBuilder {
TaskGroup rootTask = state.getRootTask(); TaskGroup rootTask = state.getRootTask();
if (rootTask != null) { if ( rootTask != null ) {
// This reattachment is needed to ensure that the root task in // This reattachment is needed to ensure that the root task in
// the state is the one associated to the transaction's session. // the state is the one associated to the transaction's session.
// Otherwise if some order element has been removed, when doing // Otherwise if some order element has been removed, when doing
@ -416,7 +402,7 @@ public class SaveCommandBuilder {
removeTasksToRemove(); removeTasksToRemove();
loadDataAccessedWithNotPosedAsTransientInOrder(state.getOrder()); loadDataAccessedWithNotPosedAsTransientInOrder(state.getOrder());
loadDataAccessedWithNotPosedAsTransient(state.getOrder()); loadDataAccessedWithNotPosedAsTransient(state.getOrder());
if (state.getRootTask() != null) { if ( state.getRootTask() != null ) {
loadDependenciesCollectionsForTaskRoot(state.getRootTask()); loadDependenciesCollectionsForTaskRoot(state.getRootTask());
} }
subcontractedTaskDataDAO.removeOrphanedSubcontractedTaskData(); subcontractedTaskDataDAO.removeOrphanedSubcontractedTaskData();
@ -1064,16 +1050,15 @@ public class SaveCommandBuilder {
@Override @Override
public org.zkoss.zk.ui.Component createLabelFor( public org.zkoss.zk.ui.Component createLabelFor(
InvalidValue invalidValue) { InvalidValue invalidValue) {
if (invalidValue.getRootBean() instanceof OrderElement) { if ( invalidValue.getRootBean() instanceof OrderElement ) {
Label result = new Label(); Label result = new Label();
String orderElementName; String orderElementName;
if (invalidValue.getRootBean() instanceof Order) { if ( invalidValue.getRootBean() instanceof Order ) {
orderElementName = _("Project"); orderElementName = _("Project");
} else { } else {
orderElementName = _("Task {0}", orderElementName = _("Task {0}",
((OrderElement) invalidValue.getRootBean()) ((OrderElement) invalidValue.getRootBean()).getName());
.getName());
} }
result.setValue(orderElementName + ": " result.setValue(orderElementName + ": "

View file

@ -133,14 +133,15 @@ public class EditTaskController extends GenericForwardComposer {
return subcontractController; return subcontractController;
} }
private void showEditForm(IContextWithPlannerTask<TaskElement> context, private void showEditForm(IContextWithPlannerTask<TaskElement> context, TaskElement taskElement,
TaskElement taskElement, PlanningState planningState) { PlanningState planningState) {
showEditForm(context, taskElement, planningState, false); showEditForm(context, taskElement, planningState, false);
} }
private void showEditForm(IContextWithPlannerTask<TaskElement> context, private void showEditForm(IContextWithPlannerTask<TaskElement> context, TaskElement taskElement,
TaskElement taskElement, PlanningState planningState, PlanningState planningState, boolean fromLimitingResourcesView) {
boolean fromLimitingResourcesView) {
this.taskElement = taskElement; this.taskElement = taskElement;
this.context = context; this.context = context;
this.planningState = planningState; this.planningState = planningState;
@ -152,7 +153,7 @@ public class EditTaskController extends GenericForwardComposer {
showSelectedTabPanel(); showSelectedTabPanel();
Util.createBindingsFor(window); Util.createBindingsFor(window);
Util.reloadBindings(window); Util.reloadBindings(window);
if (fromLimitingResourcesView) { if ( fromLimitingResourcesView ) {
window.doModal(); window.doModal();
} else { } else {
window.setMode("modal"); window.setMode("modal");
@ -163,30 +164,22 @@ public class EditTaskController extends GenericForwardComposer {
} }
private void showSelectedTabPanel() { private void showSelectedTabPanel() {
showTabPanel(taskPropertiesController showTabPanel(taskPropertiesController.getResourceAllocationType(taskElement));
.getResourceAllocationType(taskElement));
} }
public void showTabPanel( public void showTabPanel(ResourceAllocationTypeEnum resourceAllocationType) {
ResourceAllocationTypeEnum resourceAllocationType) {
subcontractTab.setVisible(false); subcontractTab.setVisible(false);
resourceAllocationTab.setVisible(false); resourceAllocationTab.setVisible(false);
limitingResourceAllocationTab.setVisible(false); limitingResourceAllocationTab.setVisible(false);
if (ResourceAllocationTypeEnum.SUBCONTRACT if ( ResourceAllocationTypeEnum.SUBCONTRACT.equals(resourceAllocationType) ) {
.equals(resourceAllocationType)) { subcontractController.init(asTask(taskElement), context, taskPropertiesController.getTaskEditFormComposer());
subcontractController.init(asTask(taskElement), context,
taskPropertiesController.getTaskEditFormComposer());
showSubcontractTab(); showSubcontractTab();
} else if (ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES } else if ( ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES.equals(resourceAllocationType) ) {
.equals(resourceAllocationType)) {
resourceAllocationController.init(context, asTask(taskElement), planningState, messagesForUser); resourceAllocationController.init(context, asTask(taskElement), planningState, messagesForUser);
showNonLimitingResourcesTab(); showNonLimitingResourcesTab();
} else if (ResourceAllocationTypeEnum.LIMITING_RESOURCES } else if ( ResourceAllocationTypeEnum.LIMITING_RESOURCES.equals(resourceAllocationType) ) {
.equals(resourceAllocationType)) { limitingResourceAllocationController.init(context, asTask(taskElement), planningState, messagesForUser);
limitingResourceAllocationController.init(context, asTask(taskElement),
planningState, messagesForUser);
showLimitingResourcesTab(); showLimitingResourcesTab();
} }
} }
@ -205,9 +198,9 @@ public class EditTaskController extends GenericForwardComposer {
limitingResourceAllocationTab.setVisible(true); limitingResourceAllocationTab.setVisible(true);
} }
public void showEditFormTaskProperties( public void showEditFormTaskProperties(IContextWithPlannerTask<TaskElement> context, TaskElement taskElement,
IContextWithPlannerTask<TaskElement> context, PlanningState planningState) {
TaskElement taskElement, PlanningState planningState) {
editTaskTabbox.setSelectedPanelApi(taskPropertiesTabpanel); editTaskTabbox.setSelectedPanelApi(taskPropertiesTabpanel);
showEditForm(context, taskElement, planningState); showEditForm(context, taskElement, planningState);
} }
@ -218,21 +211,17 @@ public class EditTaskController extends GenericForwardComposer {
showEditFormResourceAllocation(null, taskElement, null, true); showEditFormResourceAllocation(null, taskElement, null, true);
} }
public void showEditFormResourceAllocation( public void showEditFormResourceAllocation(IContextWithPlannerTask<TaskElement> context, TaskElement taskElement,
IContextWithPlannerTask<TaskElement> context, PlanningState planningState) {
TaskElement taskElement, PlanningState planningState) { showEditFormResourceAllocation(context, taskElement, planningState, false);
showEditFormResourceAllocation(context, taskElement, planningState,
false);
} }
public void showEditFormResourceAllocation( public void showEditFormResourceAllocation(IContextWithPlannerTask<TaskElement> context, TaskElement taskElement,
IContextWithPlannerTask<TaskElement> context, PlanningState planningState, boolean fromLimitingResourcesView) {
TaskElement taskElement, PlanningState planningState,
boolean fromLimitingResourcesView) {
if (isTask(taskElement)) { if ( isTask(taskElement) ) {
Task task = asTask(taskElement); Task task = asTask(taskElement);
if (task.isLimiting()) { if ( task.isLimiting() ) {
editTaskTabbox.setSelectedPanelApi(limitingResourceAllocationTabpanel); editTaskTabbox.setSelectedPanelApi(limitingResourceAllocationTabpanel);
} else { } else {
editTaskTabbox.setSelectedPanelApi(resourceAllocationTabpanel); editTaskTabbox.setSelectedPanelApi(resourceAllocationTabpanel);
@ -240,18 +229,17 @@ public class EditTaskController extends GenericForwardComposer {
} else { } else {
editTaskTabbox.setSelectedPanelApi(taskPropertiesTabpanel); editTaskTabbox.setSelectedPanelApi(taskPropertiesTabpanel);
} }
showEditForm(context, taskElement, planningState, showEditForm(context, taskElement, planningState, fromLimitingResourcesView);
fromLimitingResourcesView);
} }
public void selectAssignmentTab(int index) { public void selectAssignmentTab(int index) {
editTaskTabbox.setSelectedIndex(index); editTaskTabbox.setSelectedIndex(index);
} }
public void showEditFormSubcontract( public void showEditFormSubcontract(IContextWithPlannerTask<TaskElement> context, TaskElement taskElement,
IContextWithPlannerTask<TaskElement> context, PlanningState planningState) {
TaskElement taskElement, PlanningState planningState) {
if (isSubcontractedAndIsTask(taskElement)) { if ( isSubcontractedAndIsTask(taskElement) ) {
editTaskTabbox.setSelectedPanelApi(subcontractTabpanel); editTaskTabbox.setSelectedPanelApi(subcontractTabpanel);
} else { } else {
editTaskTabbox.setSelectedPanelApi(taskPropertiesTabpanel); editTaskTabbox.setSelectedPanelApi(taskPropertiesTabpanel);
@ -261,7 +249,7 @@ public class EditTaskController extends GenericForwardComposer {
public void accept() { public void accept() {
try { try {
if (taskPropertiesController.stateHasChanged()) { if ( taskPropertiesController.stateHasChanged() ) {
ResourceAllocationTypeEnum oldState = taskPropertiesController.getOriginalState(); ResourceAllocationTypeEnum oldState = taskPropertiesController.getOriginalState();
removeAssociatedData(oldState); removeAssociatedData(oldState);
} }
@ -270,16 +258,16 @@ public class EditTaskController extends GenericForwardComposer {
taskPropertiesController.accept(); taskPropertiesController.accept();
ResourceAllocationTypeEnum currentState = taskPropertiesController.getCurrentState(); ResourceAllocationTypeEnum currentState = taskPropertiesController.getCurrentState();
if (ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES.equals(currentState)) { if ( ResourceAllocationTypeEnum.NON_LIMITING_RESOURCES.equals(currentState) ) {
editTaskTabbox.setSelectedPanelApi(resourceAllocationTabpanel); editTaskTabbox.setSelectedPanelApi(resourceAllocationTabpanel);
boolean mustNotExit = !resourceAllocationController.accept(); boolean mustNotExit = !resourceAllocationController.accept();
if (mustNotExit) { if ( mustNotExit ) {
return; return;
} }
} else if (ResourceAllocationTypeEnum.SUBCONTRACT.equals(currentState)) { } else if ( ResourceAllocationTypeEnum.SUBCONTRACT.equals(currentState) ) {
editTaskTabbox.setSelectedPanelApi(subcontractTabpanel); editTaskTabbox.setSelectedPanelApi(subcontractTabpanel);
subcontractController.accept(); subcontractController.accept();
} else if (ResourceAllocationTypeEnum.LIMITING_RESOURCES.equals(currentState)) { } else if ( ResourceAllocationTypeEnum.LIMITING_RESOURCES.equals(currentState) ) {
editTaskTabbox.setSelectedPanelApi(limitingResourceAllocationTabpanel); editTaskTabbox.setSelectedPanelApi(limitingResourceAllocationTabpanel);
limitingResourceAllocationController.accept(); limitingResourceAllocationController.accept();
} }

View file

@ -537,7 +537,7 @@ public class TaskPropertiesController extends GenericForwardComposer {
} }
public ResourceAllocationTypeEnum getResourceAllocationType(TaskElement taskElement) { public ResourceAllocationTypeEnum getResourceAllocationType(TaskElement taskElement) {
if (taskElement == null || !isTask(taskElement)) { if ( taskElement == null || !isTask(taskElement) ) {
return null; return null;
} }
return getResourceAllocationType(asTask(currentTaskElement)); return getResourceAllocationType(asTask(currentTaskElement));

View file

@ -87,7 +87,7 @@ public class AssignedCriterionsModel extends IntegrationEntityModel implements
@Transactional(readOnly = true) @Transactional(readOnly = true)
public void prepareForEdit(Worker worker) { public void prepareForEdit(Worker worker) {
this.worker = worker; this.worker = worker;
if (worker != null) { if ( worker != null ) {
reattachmentWorker(); reattachmentWorker();
initDTOs(); initDTOs();
} }
@ -100,11 +100,9 @@ public class AssignedCriterionsModel extends IntegrationEntityModel implements
private void initDTOs() { private void initDTOs() {
criterionSatisfactionDTOs = new HashSet<CriterionSatisfactionDTO>(); criterionSatisfactionDTOs = new HashSet<CriterionSatisfactionDTO>();
for (CriterionSatisfaction criterionSatisfaction : worker for (CriterionSatisfaction criterionSatisfaction : worker.getCriterionSatisfactions()) {
.getCriterionSatisfactions()) { if ( !criterionSatisfaction.isIsDeleted() ) {
if (!criterionSatisfaction.isIsDeleted()) { CriterionSatisfactionDTO dto = new CriterionSatisfactionDTO(criterionSatisfaction);
CriterionSatisfactionDTO dto = new CriterionSatisfactionDTO(
criterionSatisfaction);
criterionSatisfactionDTOs.add(dto); criterionSatisfactionDTOs.add(dto);
} }
} }
@ -344,32 +342,32 @@ public class AssignedCriterionsModel extends IntegrationEntityModel implements
} }
private List<CriterionSatisfactionDTO> getWithCriterionAssignedDTOs() { private List<CriterionSatisfactionDTO> getWithCriterionAssignedDTOs() {
return CriterionSatisfactionDTO return CriterionSatisfactionDTO.keepHavingCriterion(criterionSatisfactionDTOs);
.keepHavingCriterion(criterionSatisfactionDTOs);
} }
private void updateDTOs() throws ValidationException, IllegalStateException { private void updateDTOs() throws ValidationException, IllegalStateException {
// Create a new list of Criterion satisfaction // Create a new list of Criterion satisfaction
Set<CriterionSatisfaction> newList = new HashSet<CriterionSatisfaction>(); Set<CriterionSatisfaction> newList = new HashSet<CriterionSatisfaction>();
for (CriterionSatisfactionDTO satisfactionDTO : getWithCriterionAssignedDTOs()) { for (CriterionSatisfactionDTO satisfactionDTO : getWithCriterionAssignedDTOs()) {
CriterionSatisfaction satisfaction; CriterionSatisfaction satisfaction;
if (satisfactionDTO.isNewObject()) {
Criterion criterion = satisfactionDTO.getCriterionWithItsType() if ( satisfactionDTO.isNewObject() ) {
.getCriterion(); Criterion criterion = satisfactionDTO.getCriterionWithItsType().getCriterion();
Interval interval = satisfactionDTO.getInterval(); Interval interval = satisfactionDTO.getInterval();
satisfaction = CriterionSatisfaction.create(criterion, worker, satisfaction = CriterionSatisfaction.create(criterion, worker, interval);
interval);
// set the autogenerated code // set the autogenerated code
currentCriterionSatisfaction = satisfaction; currentCriterionSatisfaction = satisfaction;
setDefaultCode(); setDefaultCode();
} else { } else {
satisfaction = satisfactionDTO.getCriterionSatisfaction(); satisfaction = satisfactionDTO.getCriterionSatisfaction();
if (satisfactionDTO.isIsDeleted()) { if ( satisfactionDTO.isIsDeleted() ) {
satisfaction.setIsDeleted(true); satisfaction.setIsDeleted(true);
} else { } else {
satisfaction.setStartDate(satisfactionDTO.getStart()); satisfaction.setStartDate(satisfactionDTO.getStart());
if (satisfactionDTO.getEndDate() != null) {
if ( satisfactionDTO.getEndDate() != null ) {
satisfaction.finish(satisfactionDTO.getEnd()); satisfaction.finish(satisfactionDTO.getEnd());
} else { } else {
satisfaction.noFinish(); satisfaction.noFinish();

View file

@ -72,21 +72,21 @@ public class WorkRelationshipsController extends GenericForwardComposer {
private final IMessagesForUser messagesForUser; private final IMessagesForUser messagesForUser;
public WorkRelationshipsController(IWorkerModel workerModel, public WorkRelationshipsController(IWorkerModel workerModel,
WorkerCRUDController workerCRUDController, WorkerCRUDController workerCRUDController,
IMessagesForUser messagesForUser) { IMessagesForUser messagesForUser) {
this.workerModel = workerModel; this.workerModel = workerModel;
this.workerCRUDController = workerCRUDController; this.workerCRUDController = workerCRUDController;
this.messagesForUser = messagesForUser; this.messagesForUser = messagesForUser;
this.workCriterions = new ArrayList<Criterion>(); this.workCriterions = new ArrayList<Criterion>();
Map<ICriterionType<?>, Collection<Criterion>> map = workerModel Map<ICriterionType<?>, Collection<Criterion>> map = workerModel.getLaboralRelatedCriterions();
.getLaboralRelatedCriterions();
this.fromCriterionToType = new HashMap<Criterion, CriterionWithItsType>(); this.fromCriterionToType = new HashMap<Criterion, CriterionWithItsType>();
for (Entry<ICriterionType<?>, Collection<Criterion>> entry : map
.entrySet()) { for (Entry<ICriterionType<?>, Collection<Criterion>> entry : map.entrySet()) {
this.workCriterions.addAll(entry.getValue()); this.workCriterions.addAll(entry.getValue());
for (Criterion criterion : entry.getValue()) { for (Criterion criterion : entry.getValue()) {
this.fromCriterionToType.put(criterion, this.fromCriterionToType.put(criterion, new CriterionWithItsType(entry.getKey(), criterion));
new CriterionWithItsType(entry.getKey(), criterion));
} }
} }
} }

View file

@ -103,8 +103,7 @@ import org.zkoss.zul.api.Window;
* @author Manuel Rego Casasnovas <rego@igalia.com> * @author Manuel Rego Casasnovas <rego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com> * @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
public class WorkerCRUDController extends GenericForwardComposer implements public class WorkerCRUDController extends GenericForwardComposer implements IWorkerCRUDControllerEntryPoints {
IWorkerCRUDControllerEntryPoints {
@Autowired @Autowired
private IDBPasswordEncoderService dbPasswordEncoderService; private IDBPasswordEncoderService dbPasswordEncoderService;
@ -247,7 +246,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
} }
public void saveAndExit() { public void saveAndExit() {
if (save()) { if ( save() ) {
goToList(); goToList();
} }
} }
@ -268,22 +267,22 @@ public class WorkerCRUDController extends GenericForwardComposer implements
setUserBindingInfo(); setUserBindingInfo();
// Validate 'Cost category assignment' tab is correct // Validate 'Cost category assignment' tab is correct
if (resourcesCostCategoryAssignmentController != null) { if ( resourcesCostCategoryAssignmentController != null ) {
if (!resourcesCostCategoryAssignmentController.validate()) { if ( !resourcesCostCategoryAssignmentController.validate() ) {
return false; return false;
} }
} }
try { try {
if (baseCalendarEditionController != null) { if ( baseCalendarEditionController != null ) {
baseCalendarEditionController.save(); baseCalendarEditionController.save();
} }
if (criterionsController != null){ if ( criterionsController != null ){
if(!criterionsController.validate()){ if( !criterionsController.validate() ){
return false; return false;
} }
} }
if (workerModel.getCalendar() == null) { if ( workerModel.getCalendar() == null ) {
createCalendar(); createCalendar();
} }
workerModel.save(); workerModel.save();
@ -298,28 +297,26 @@ public class WorkerCRUDController extends GenericForwardComposer implements
private void setUserBindingInfo() { private void setUserBindingInfo() {
int option = userBindingRadiogroup.getSelectedIndex(); int option = userBindingRadiogroup.getSelectedIndex();
if (UserBindingOption.NOT_BOUND.ordinal() == option) { if ( UserBindingOption.NOT_BOUND.ordinal() == option ) {
getWorker().setUser(null); getWorker().setUser(null);
} }
if (UserBindingOption.EXISTING_USER.ordinal() == option) { if ( UserBindingOption.EXISTING_USER.ordinal() == option ) {
if (getWorker().getUser() == null) { if ( getWorker().getUser() == null ) {
throw new WrongValueException(userBandbox, throw new WrongValueException(userBandbox, _("please select a user to bound"));
_("please select a user to bound"));
} }
getWorker().updateUserData(); getWorker().updateUserData();
} }
if (UserBindingOption.CREATE_NEW_USER.ordinal() == option) { if ( UserBindingOption.CREATE_NEW_USER.ordinal() == option ) {
getWorker().setUser(createNewUserForBinding()); getWorker().setUser(createNewUserForBinding());
} }
} }
private User createNewUserForBinding() { private User createNewUserForBinding() {
String loginName = loginNameTextbox.getValue(); String loginName = loginNameTextbox.getValue();
if (StringUtils.isBlank(loginName)) { if ( StringUtils.isBlank(loginName) ) {
throw new WrongValueException(loginNameTextbox, throw new WrongValueException(loginNameTextbox, _("cannot be empty"));
_("cannot be empty"));
} }
String password = passwordTextbox.getValue(); String password = passwordTextbox.getValue();
@ -394,17 +391,15 @@ public class WorkerCRUDController extends GenericForwardComposer implements
state = CRUDControllerState.EDIT; state = CRUDControllerState.EDIT;
getBookmarker().goToEditForm(worker); getBookmarker().goToEditForm(worker);
workerModel.prepareEditFor(worker); workerModel.prepareEditFor(worker);
resourcesCostCategoryAssignmentController.setResource(workerModel resourcesCostCategoryAssignmentController.setResource(workerModel.getWorker());
.getWorker()); if ( isCalendarNotNull() ) {
if (isCalendarNotNull()) {
editCalendar(); editCalendar();
} }
editAsignedCriterions(); editAsignedCriterions();
updateUserBindingComponents(); updateUserBindingComponents();
showEditWindow(_("Edit Worker: {0}", worker.getHumanId())); showEditWindow(_("Edit Worker: {0}", worker.getHumanId()));
Textbox workerFirstname = (Textbox) editWindow Textbox workerFirstname = (Textbox) editWindow.getFellow("workerFirstname");
.getFellow("workerFirstname");
workerFirstname.focus(); workerFirstname.focus();
} }
@ -453,13 +448,11 @@ public class WorkerCRUDController extends GenericForwardComposer implements
getBookmarker().goToCreateForm(); getBookmarker().goToCreateForm();
workerModel.prepareForCreate(); workerModel.prepareForCreate();
createAsignedCriterions(); createAsignedCriterions();
resourcesCostCategoryAssignmentController.setResource(workerModel resourcesCostCategoryAssignmentController.setResource(workerModel.getWorker());
.getWorker());
updateUserBindingComponents(); updateUserBindingComponents();
showEditWindow(_("Create Worker")); showEditWindow(_("Create Worker"));
resourceCalendarModel.cancel(); resourceCalendarModel.cancel();
Textbox workerFirstname = (Textbox) editWindow Textbox workerFirstname = (Textbox) editWindow.getFellow("workerFirstname");
.getFellow("workerFirstname");
workerFirstname.focus(); workerFirstname.focus();
} }
@ -473,12 +466,10 @@ public class WorkerCRUDController extends GenericForwardComposer implements
@Override @Override
public void doAfterCompose(Component comp) throws Exception { public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp); super.doAfterCompose(comp);
localizationsForEditionController = createLocalizationsController(comp, localizationsForEditionController = createLocalizationsController(comp, "editWindow");
"editWindow"); localizationsForCreationController = createLocalizationsController(comp, "editWindow");
localizationsForCreationController = createLocalizationsController(
comp, "editWindow");
comp.setVariable("controller", this, true); comp.setVariable("controller", this, true);
if (messagesContainer == null) { if ( messagesContainer == null ) {
throw new RuntimeException(_("MessagesContainer is needed")); throw new RuntimeException(_("MessagesContainer is needed"));
} }
messages = new MessagesForUser(messagesContainer); messages = new MessagesForUser(messagesContainer);
@ -490,22 +481,20 @@ public class WorkerCRUDController extends GenericForwardComposer implements
initializeTabs(); initializeTabs();
initUserBindingComponents(); initUserBindingComponents();
final EntryPointsHandler<IWorkerCRUDControllerEntryPoints> handler = URLHandlerRegistry final EntryPointsHandler<IWorkerCRUDControllerEntryPoints> handler =
.getRedirectorFor(IWorkerCRUDControllerEntryPoints.class); URLHandlerRegistry.getRedirectorFor(IWorkerCRUDControllerEntryPoints.class);
handler.register(this, page); handler.register(this, page);
} }
private void initUserBindingComponents() { private void initUserBindingComponents() {
userBindingGroupbox = (Groupbox) editWindow userBindingGroupbox = (Groupbox) editWindow.getFellowIfAny("userBindingGroupbox");
.getFellowIfAny("userBindingGroupbox"); userBindingRadiogroup = (Radiogroup) editWindow.getFellowIfAny("userBindingRadiogroup");
userBindingRadiogroup = (Radiogroup) editWindow
.getFellowIfAny("userBindingRadiogroup");
initUserBindingOptions(); initUserBindingOptions();
userBandbox = (BandboxSearch) editWindow.getFellowIfAny("userBandbox"); userBandbox = (BandboxSearch) editWindow.getFellowIfAny("userBandbox");
loginNameTextbox = (Textbox) editWindow.getFellowIfAny("loginName"); loginNameTextbox = (Textbox) editWindow.getFellowIfAny("loginName");
passwordTextbox = (Textbox) editWindow.getFellowIfAny("password"); passwordTextbox = (Textbox) editWindow.getFellowIfAny("password");
passwordConfirmationTextbox = (Textbox) editWindow passwordConfirmationTextbox = (Textbox) editWindow.getFellowIfAny("passwordConfirmation");
.getFellowIfAny("passwordConfirmation");
emailTextbox = (Textbox) editWindow.getFellowIfAny("email"); emailTextbox = (Textbox) editWindow.getFellowIfAny("email");
} }
@ -513,9 +502,10 @@ public class WorkerCRUDController extends GenericForwardComposer implements
UserBindingOption[] values = UserBindingOption.values(); UserBindingOption[] values = UserBindingOption.values();
for (UserBindingOption option : values) { for (UserBindingOption option : values) {
Radio radio = new Radio(_(option.label)); Radio radio = new Radio(_(option.label));
if (option.equals(UserBindingOption.CREATE_NEW_USER)
&& !SecurityUtils if ( option.equals(UserBindingOption.CREATE_NEW_USER) &&
.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS)) { !SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_USER_ACCOUNTS)) {
radio.setDisabled(true); radio.setDisabled(true);
radio.setTooltiptext(_("You do not have permissions to create new users")); radio.setTooltiptext(_("You do not have permissions to create new users"));
} }
@ -530,14 +520,10 @@ public class WorkerCRUDController extends GenericForwardComposer implements
} }
private void initFilterComponent() { private void initFilterComponent() {
this.filterFinishDate = (Datebox) listWindow this.filterFinishDate = (Datebox) listWindow.getFellowIfAny("filterFinishDate");
.getFellowIfAny("filterFinishDate"); this.filterStartDate = (Datebox) listWindow.getFellowIfAny("filterStartDate");
this.filterStartDate = (Datebox) listWindow this.filterLimitingResource = (Listbox) listWindow.getFellowIfAny("filterLimitingResource");
.getFellowIfAny("filterStartDate"); this.bdFilters = (BandboxMultipleSearch) listWindow.getFellowIfAny("bdFilters");
this.filterLimitingResource = (Listbox) listWindow
.getFellowIfAny("filterLimitingResource");
this.bdFilters = (BandboxMultipleSearch) listWindow
.getFellowIfAny("bdFilters");
this.txtfilter = (Textbox) listWindow.getFellowIfAny("txtfilter"); this.txtfilter = (Textbox) listWindow.getFellowIfAny("txtfilter");
this.listing = (Grid) listWindow.getFellowIfAny("listing"); this.listing = (Grid) listWindow.getFellowIfAny("listing");
clearFilterDates(); clearFilterDates();

View file

@ -49,7 +49,6 @@ import org.libreplan.business.planner.daos.IDayAssignmentDAO;
import org.libreplan.business.planner.daos.IResourceAllocationDAO; import org.libreplan.business.planner.daos.IResourceAllocationDAO;
import org.libreplan.business.resources.daos.ICriterionDAO; import org.libreplan.business.resources.daos.ICriterionDAO;
import org.libreplan.business.resources.daos.IResourceDAO; import org.libreplan.business.resources.daos.IResourceDAO;
import org.libreplan.business.resources.daos.IWorkerDAO;
import org.libreplan.business.resources.entities.Criterion; import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.CriterionSatisfaction; import org.libreplan.business.resources.entities.CriterionSatisfaction;
import org.libreplan.business.resources.entities.CriterionWithItsType; import org.libreplan.business.resources.entities.CriterionWithItsType;
@ -152,21 +151,20 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
removeCalendarIfNeeded(); removeCalendarIfNeeded();
resetRoleInOriginalBoundUser(); resetRoleInOriginalBoundUser();
resourceDAO.save(worker); resourceDAO.save(worker);
if (worker.getCalendar() != null) { if ( worker.getCalendar() != null ) {
baseCalendarModel.checkInvalidValuesCalendar(worker.getCalendar()); baseCalendarModel.checkInvalidValuesCalendar(worker.getCalendar());
} }
getLocalizationsAssigner().applyChanges(); getLocalizationsAssigner().applyChanges();
if(assignedCriterionsModel != null){ if( assignedCriterionsModel != null ){
assignedCriterionsModel.confirm(); assignedCriterionsModel.confirm();
} }
localizationsAssigner = null; localizationsAssigner = null;
} }
private void resetRoleInOriginalBoundUser() { private void resetRoleInOriginalBoundUser() {
if (boundUser != null) { if ( boundUser != null ) {
User user = worker.getUser(); User user = worker.getUser();
if (user == null || user.getId() == null if ( user == null || user.getId() == null || !user.getId().equals(boundUser.getId()) ) {
|| !user.getId().equals(boundUser.getId())) {
boundUser.removeRole(UserRole.ROLE_BOUND_USER); boundUser.removeRole(UserRole.ROLE_BOUND_USER);
userDAO.save(boundUser); userDAO.save(boundUser);
} }
@ -174,7 +172,7 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
} }
private void removeCalendarIfNeeded() { private void removeCalendarIfNeeded() {
if (calendarToRemove != null) { if ( calendarToRemove != null ) {
try { try {
resourceDAO.reattach(worker); resourceDAO.reattach(worker);
baseCalendarDAO.remove(calendarToRemove.getId()); baseCalendarDAO.remove(calendarToRemove.getId());
@ -224,19 +222,19 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
@Transactional(readOnly = true) @Transactional(readOnly = true)
public void prepareForCreate(boolean virtual) { public void prepareForCreate(boolean virtual) {
if (virtual) { if ( virtual ) {
worker = VirtualWorker.create(""); worker = VirtualWorker.create("");
} else { } else {
worker = Worker.create(""); worker = Worker.create("");
} }
worker.setCodeAutogenerated(configurationDAO.getConfiguration() worker.setCodeAutogenerated(configurationDAO.getConfiguration().getGenerateCodeForResources());
.getGenerateCodeForResources()); if ( worker.isCodeAutogenerated() ) {
if (worker.isCodeAutogenerated()) {
setDefaultCode(); setDefaultCode();
} }
localizationsAssigner = new MultipleCriterionActiveAssigner( localizationsAssigner =
criterionDAO, worker, PredefinedCriterionTypes.LOCATION); new MultipleCriterionActiveAssigner(criterionDAO, worker, PredefinedCriterionTypes.LOCATION);
boundUser = null; boundUser = null;
} }
@ -250,9 +248,10 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
forceLoadCalendar(this.worker); forceLoadCalendar(this.worker);
forceLoadUser(this.worker); forceLoadUser(this.worker);
this.boundUser = this.worker.getUser(); this.boundUser = this.worker.getUser();
localizationsAssigner = new MultipleCriterionActiveAssigner(
criterionDAO, this.worker, localizationsAssigner =
PredefinedCriterionTypes.LOCATION); new MultipleCriterionActiveAssigner(criterionDAO, this.worker, PredefinedCriterionTypes.LOCATION);
initOldCodes(); initOldCodes();
} catch (InstanceNotFoundException e) { } catch (InstanceNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -624,15 +623,14 @@ public class WorkerModel extends IntegrationEntityModel implements IWorkerModel
@Override @Override
@Transactional @Transactional
public void confirmRemove(Worker worker, boolean removeBoundUser) public void confirmRemove(Worker worker, boolean removeBoundUser) throws InstanceNotFoundException {
throws InstanceNotFoundException {
resourceDAO.remove(worker.getId()); resourceDAO.remove(worker.getId());
User user = getBoundUserFromDB(worker); User user = getBoundUserFromDB(worker);
if (removeBoundUser) { if ( removeBoundUser ) {
userDAO.remove(user); userDAO.remove(user);
} else { } else {
if (user != null) { if ( user != null ) {
user.removeRole(UserRole.ROLE_BOUND_USER); user.removeRole(UserRole.ROLE_BOUND_USER);
userDAO.save(user); userDAO.save(user);
} }

View file

@ -88,8 +88,7 @@ import org.zkoss.zul.impl.api.InputElement;
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Diego Pino García <dpino@igalia.com> * @author Diego Pino García <dpino@igalia.com>
*/ */
public abstract class TreeController<T extends ITreeNode<T>> extends public abstract class TreeController<T extends ITreeNode<T>> extends GenericForwardComposer {
GenericForwardComposer {
private static final ValidatorFactory validatorFactory = Validation private static final ValidatorFactory validatorFactory = Validation
.buildDefaultValidatorFactory(); .buildDefaultValidatorFactory();
@ -238,11 +237,11 @@ public abstract class TreeController<T extends ITreeNode<T>> extends
Textbox name = (Textbox) cmp.getFellow("newOrderElementName"); Textbox name = (Textbox) cmp.getFellow("newOrderElementName");
Intbox hours = (Intbox) cmp.getFellow("newOrderElementHours"); Intbox hours = (Intbox) cmp.getFellow("newOrderElementHours");
if (StringUtils.isEmpty(name.getValue())) { if ( StringUtils.isEmpty(name.getValue()) ) {
throw new WrongValueException(name, _("cannot be empty")); throw new WrongValueException(name, _("cannot be empty"));
} }
if (hours.getValue() == null) { if ( hours.getValue() == null ) {
hours.setValue(0); hours.setValue(0);
} }
@ -250,11 +249,10 @@ public abstract class TreeController<T extends ITreeNode<T>> extends
// Parse hours // Parse hours
try { try {
if (tree.getSelectedCount() == 1) { if ( tree.getSelectedCount() == 1 ) {
T node = getSelectedNode(); T node = getSelectedNode();
T newNode = getModel().addElementAt(node, name.getValue(), T newNode = getModel().addElementAt(node, name.getValue(), hours.getValue());
hours.getValue());
getRenderer().refreshHoursValueForThisNodeAndParents(newNode); getRenderer().refreshHoursValueForThisNodeAndParents(newNode);
getRenderer().refreshBudgetValueForThisNodeAndParents(newNode); getRenderer().refreshBudgetValueForThisNodeAndParents(newNode);
@ -262,13 +260,12 @@ public abstract class TreeController<T extends ITreeNode<T>> extends
// to select the proper element to focus // to select the proper element to focus
reloadTreeUIAfterChanges(); reloadTreeUIAfterChanges();
if (node.isLeaf() && !node.isEmptyLeaf()) { if ( node.isLeaf() && !node.isEmptyLeaf() ) {
// Then a new container will be created // Then a new container will be created
nameTextbox = getRenderer().getNameTextbox(node); nameTextbox = getRenderer().getNameTextbox(node);
} else { } else {
// select the parent row to add new children ASAP // select the parent row to add new children ASAP
tree.setSelectedItem(getRenderer().getTreeitemForNode( tree.setSelectedItem(getRenderer().getTreeitemForNode(newNode.getParent().getThis()));
newNode.getParent().getThis()));
} }
} else { } else {
getModel().addElement(name.getValue(), hours.getValue()); getModel().addElement(name.getValue(), hours.getValue());
@ -285,7 +282,7 @@ public abstract class TreeController<T extends ITreeNode<T>> extends
name.setValue(""); name.setValue("");
hours.setValue(0); hours.setValue(0);
if (nameTextbox != null) { if ( nameTextbox != null ) {
nameTextbox.focus(); nameTextbox.focus();
} else { } else {
name.focus(); name.focus();

View file

@ -75,8 +75,7 @@ public class ExportTimesheetsToTimTest {
@Before @Before
public void loadProperties() throws FileNotFoundException, IOException { public void loadProperties() throws FileNotFoundException, IOException {
String filename = System.getProperty("user.dir") String filename = System.getProperty("user.dir") + "/../scripts/tim-connector/tim-conn.properties";
+ "/../scripts/tim-connector/tim-conn.properties";
properties = new Properties(); properties = new Properties();
properties.load(new FileInputStream(filename)); properties.load(new FileInputStream(filename));
} }
@ -159,30 +158,24 @@ public class ExportTimesheetsToTimTest {
@Test @Test
@Transactional @Transactional
@Ignore("Only working if you have a Tim server configured") @Ignore("Only working if you have a Tim server configured")
public void testExportTimesheetsToTimWithValidCodeAndOrder() public void testExportTimesheetsToTimWithValidCodeAndOrder() throws ConnectorException {
throws ConnectorException {
Order order = givenOrder(); Order order = givenOrder();
exportTimesheetsToTim.exportTimesheets("5160", order); exportTimesheetsToTim.exportTimesheets("5160", order);
boolean result = exportTimesheetsToTim.getSynchronizationInfo() boolean result = exportTimesheetsToTim.getSynchronizationInfo().isSuccessful();
.isSuccessful(); if ( !result ) {
if (!result) {
fail("Export timesheets to tim failed"); fail("Export timesheets to tim failed");
} }
assertTrue(result); assertTrue(result);
} }
@Test(expected = ConnectorException.class) @Test(expected = ConnectorException.class)
@Transactional public void testExportTimesheetsToTimWithInvalidCode() throws ConnectorException {
public void testExportTimesheetsToTimWithInvalidCode()
throws ConnectorException {
Order order = givenOrder(); Order order = givenOrder();
exportTimesheetsToTim.exportTimesheets("", order); exportTimesheetsToTim.exportTimesheets("", order);
} }
@Test(expected = ConnectorException.class) @Test(expected = ConnectorException.class)
@Transactional public void testExportTimesheetsToTimWithOrderNull() throws ConnectorException {
public void testExportTimesheetsToTimWithOrderNull()
throws ConnectorException {
exportTimesheetsToTim.exportTimesheets("5160", null); exportTimesheetsToTim.exportTimesheets("5160", null);
} }
} }

View file

@ -97,8 +97,7 @@ import org.zkoss.zk.ui.Desktop;
WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE }) WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE })
public class OrderModelTest { public class OrderModelTest {
public static OrderVersion setupVersionUsing( public static OrderVersion setupVersionUsing(IScenarioManager scenarioManager, Order order) {
IScenarioManager scenarioManager, Order order) {
Scenario current = scenarioManager.getCurrent(); Scenario current = scenarioManager.getCurrent();
OrderVersion result = OrderVersion.createInitialVersion(current); OrderVersion result = OrderVersion.createInitialVersion(current);
order.setVersionForScenario(current, result); order.setVersionForScenario(current, result);
@ -168,13 +167,11 @@ public class OrderModelTest {
} }
private PlanningState createPlanningStateFor(final Order newOrder) { private PlanningState createPlanningStateFor(final Order newOrder) {
return adHocTransaction return adHocTransaction.runOnAnotherReadOnlyTransaction(new IOnTransaction<PlanningState>() {
.runOnAnotherReadOnlyTransaction(new IOnTransaction<PlanningState>() {
@Override @Override
public PlanningState execute() { public PlanningState execute() {
return planningStateCreator.createOn(mockDesktop(), return planningStateCreator.createOn(mockDesktop(), newOrder);
newOrder);
} }
}); });
} }
@ -186,25 +183,29 @@ public class OrderModelTest {
order.setName("name"); order.setName("name");
order.setResponsible("responsible"); order.setResponsible("responsible");
order.setCode("code-" + UUID.randomUUID()); order.setCode("code-" + UUID.randomUUID());
BaseCalendar calendar = adHocTransaction
.runOnReadOnlyTransaction(new IOnTransaction<BaseCalendar>() { BaseCalendar calendar = adHocTransaction.runOnReadOnlyTransaction(new IOnTransaction<BaseCalendar>() {
@Override @Override
public BaseCalendar execute() { public BaseCalendar execute() {
BaseCalendar result = configurationDAO
.getConfigurationWithReadOnlyTransaction() BaseCalendar result =
.getDefaultCalendar(); configurationDAO.getConfigurationWithReadOnlyTransaction().getDefaultCalendar();
BaseCalendarModel.forceLoadBaseCalendar(result); BaseCalendarModel.forceLoadBaseCalendar(result);
return result; return result;
} }
}); });
order.setCalendar(calendar); order.setCalendar(calendar);
return order; return order;
} }
private ExternalCompany createValidExternalCompany() { private ExternalCompany createValidExternalCompany() {
ExternalCompany externalCompany = ExternalCompany.create(UUID ExternalCompany externalCompany = ExternalCompany.create(
.randomUUID().toString(), UUID.randomUUID().toString()); UUID.randomUUID().toString(),
UUID.randomUUID().toString());
externalCompanyDAO.save(externalCompany); externalCompanyDAO.save(externalCompany);
return externalCompany; return externalCompany;
} }
@ -312,8 +313,7 @@ public class OrderModelTest {
@Test(expected = ValidationException.class) @Test(expected = ValidationException.class)
@Transactional @Transactional
@Ignore("FIXME pending review after rename to libreplan") @Ignore("FIXME pending review after rename to libreplan")
public void shouldSendValidationExceptionIfEndDateIsBeforeThanStartingDate() public void shouldSendValidationExceptionIfEndDateIsBeforeThanStartingDate() throws ValidationException {
throws ValidationException {
Order order = createValidOrder(); Order order = createValidOrder();
order.setDeadline(year(0)); order.setDeadline(year(0));
orderModel.setPlanningState(createPlanningStateFor(order)); orderModel.setPlanningState(createPlanningStateFor(order));
@ -332,19 +332,17 @@ public class OrderModelTest {
@Test @Test
@Ignore("FIXME pending review after rename to libreplan") @Ignore("FIXME pending review after rename to libreplan")
public void testOrderPreserved() throws ValidationException, public void testOrderPreserved() throws ValidationException, InstanceNotFoundException {
InstanceNotFoundException {
final Order order = createValidOrder(); final Order order = createValidOrder();
orderModel.setPlanningState(createPlanningStateFor(order)); orderModel.setPlanningState(createPlanningStateFor(order));
final OrderElement[] containers = new OrderLineGroup[10]; final OrderElement[] containers = new OrderLineGroup[10];
for (int i = 0; i < containers.length; i++) { for (int i = 0; i < containers.length; i++) {
containers[i] = adHocTransaction containers[i] = adHocTransaction.runOnTransaction(new IOnTransaction<OrderLineGroup>() {
.runOnTransaction(new IOnTransaction<OrderLineGroup>() { @Override
@Override public OrderLineGroup execute() {
public OrderLineGroup execute() { return OrderLineGroup.create();
return OrderLineGroup.create(); }
} });
});
containers[i].setName("bla"); containers[i].setName("bla");
containers[i].setCode("code-" + UUID.randomUUID()); containers[i].setCode("code-" + UUID.randomUUID());
order.add(containers[i]); order.add(containers[i]);
@ -372,26 +370,24 @@ public class OrderModelTest {
try { try {
Order reloaded = orderDAO.find(order.getId()); Order reloaded = orderDAO.find(order.getId());
List<OrderElement> elements = reloaded.getOrderElements(); List<OrderElement> elements = reloaded.getOrderElements();
for (OrderElement orderElement : elements) { for (OrderElement orderElement : elements) {
assertThat(((OrderLineGroup) orderElement) assertThat(orderElement.getIndirectAdvanceAssignments().size(), equalTo(2));
.getIndirectAdvanceAssignments().size(),
equalTo(2));
} }
for (int i = 0; i < containers.length; i++) { for (int i = 0; i < containers.length; i++) {
assertThat(elements.get(i).getId(), assertThat(elements.get(i).getId(), equalTo(containers[i].getId()));
equalTo(containers[i].getId()));
} }
OrderLineGroup container = (OrderLineGroup) reloaded OrderLineGroup container = (OrderLineGroup) reloaded.getOrderElements().iterator().next();
.getOrderElements().iterator().next();
List<OrderElement> children = container.getChildren(); List<OrderElement> children = container.getChildren();
for (int i = 0; i < orderElements.length; i++) { for (int i = 0; i < orderElements.length; i++) {
assertThat(children.get(i).getId(), assertThat(children.get(i).getId(), equalTo(orderElements[i].getId()));
equalTo(orderElements[i].getId()));
} }
for (int i = 1; i < containers.length; i++) { for (int i = 1; i < containers.length; i++) {
OrderLineGroup orderLineGroup = (OrderLineGroup) containers[i]; OrderLineGroup orderLineGroup = (OrderLineGroup) containers[i];
assertThat(orderLineGroup.getChildren().size(), assertThat(orderLineGroup.getChildren().size(), equalTo(1));
equalTo(1));
} }
return null; return null;
} catch (Exception e) { } catch (Exception e) {

View file

@ -22,22 +22,77 @@
package org.libreplan.web.planner.chart; package org.libreplan.web.planner.chart;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.libreplan.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Calendar;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.UUID;
import org.easymock.EasyMock;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import org.libreplan.business.IDataBootstrap;
import org.libreplan.business.calendars.daos.IBaseCalendarDAO;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.common.IAdHocTransactionService;
import org.libreplan.business.common.IOnTransaction;
import org.libreplan.business.common.daos.IConfigurationDAO;
import org.libreplan.business.orders.entities.HoursGroup;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderLine;
import org.libreplan.business.planner.entities.IOrderEarnedValueCalculator;
import org.libreplan.business.planner.entities.SpecificDayAssignmentsContainer;
import org.libreplan.business.planner.entities.SpecificResourceAllocation;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.scenarios.entities.Scenario;
import org.libreplan.business.workingday.ResourcesPerDay;
import org.libreplan.web.calendars.BaseCalendarModel;
import org.libreplan.web.calendars.IBaseCalendarModel;
import org.libreplan.web.common.IConfigurationModel;
import org.libreplan.web.orders.IOrderModel;
import org.libreplan.web.planner.order.PlanningStateCreator;
import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState;
import org.libreplan.web.resources.worker.IAssignedCriterionsModel;
import org.libreplan.web.resources.worker.IWorkerModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import org.zkforge.timeplot.Timeplot; import org.zkforge.timeplot.Timeplot;
import org.zkoss.ganttz.util.Interval; import org.zkoss.ganttz.util.Interval;
import org.zkoss.zk.ui.Desktop;
import javax.annotation.Resource;
/** /**
* Tests for {@link ChartFiller} * Tests for {@link ChartFiller}
* *
* @author Manuel Rego Casasnovas <mrego@igalia.com> * @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Vova Perebykivskiy <vova@libreplan-enterprise.com>
*/ */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
BUSINESS_SPRING_CONFIG_FILE,
WEBAPP_SPRING_CONFIG_FILE,
WEBAPP_SPRING_CONFIG_TEST_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE
})
@Transactional
public class ChartFillerTest { public class ChartFillerTest {
private ChartFiller chartFiller = new ChartFiller() { private ChartFiller chartFiller = new ChartFiller() {
@ -64,26 +119,207 @@ public class ChartFillerTest {
@Test @Test
public void testCalculatedValueForEveryDay() { public void testCalculatedValueForEveryDay() {
SortedMap<LocalDate, BigDecimal> result = chartFiller SortedMap<LocalDate, BigDecimal> result =
.calculatedValueForEveryDay(givenExampleMap(), START_DAY, chartFiller.calculatedValueForEveryDay(givenExampleMap(), START_DAY, FINISH_DAY);
FINISH_DAY);
assertThat(result.get(START_DAY), equalTo(BigDecimal.ZERO.setScale(2))); assertThat(result.get(START_DAY), equalTo(BigDecimal.ZERO.setScale(2)));
assertThat(result.get(START_DAY.plusDays(1)), assertThat(result.get(START_DAY.plusDays(1)), equalTo(new BigDecimal(25).setScale(2)));
equalTo(new BigDecimal(25).setScale(2)));
assertThat(result.get(FIRST_DAY), equalTo(new BigDecimal(100) assertThat(result.get(FIRST_DAY), equalTo(new BigDecimal(100).setScale(2)));
.setScale(2))); assertThat(result.get(FIRST_DAY.plusDays(1)), equalTo(new BigDecimal(105).setScale(2)));
assertThat(result.get(FIRST_DAY.plusDays(1)), equalTo(new BigDecimal(
105).setScale(2)));
assertThat(result.get(LAST_DAY), equalTo(new BigDecimal(150) assertThat(result.get(LAST_DAY), equalTo(new BigDecimal(150).setScale(2)));
.setScale(2))); assertThat(result.get(LAST_DAY.plusDays(1)), equalTo(new BigDecimal(150).setScale(2)));
assertThat(result.get(LAST_DAY.plusDays(1)),
equalTo(new BigDecimal(150).setScale(2)));
assertThat(result.get(FINISH_DAY), equalTo(new BigDecimal(150) assertThat(result.get(FINISH_DAY), equalTo(new BigDecimal(150).setScale(2)));
.setScale(2))); }
@Resource
private IDataBootstrap defaultAdvanceTypesBootstrapListener;
@Resource
private IDataBootstrap scenariosBootstrap;
@Resource
private IDataBootstrap configurationBootstrap;
@Autowired
private IAdHocTransactionService transactionService;
@Before
public void loadRequiredaData() {
IOnTransaction<Void> load = new IOnTransaction<Void>() {
@Override
public Void execute() {
defaultAdvanceTypesBootstrapListener.loadRequiredData();
configurationBootstrap.loadRequiredData();
scenariosBootstrap.loadRequiredData();
return null;
}
};
transactionService.runOnAnotherTransaction(load);
}
// Testing BAC values
// 1. Create Worker
// 2. Create Project
// 3. Create 2 Tasks
// 4. Assign Resources to Tasks
// 5. Check BAC values
@Resource
IBaseCalendarModel baseCalendarModel;
@Autowired
IBaseCalendarDAO baseCalendarDAO;
@Autowired
IConfigurationModel configurationModel;
@Test
public void testBAC(){
createAndSaveWorker();
createAndSaveProject();
createAndSaveTwoTasksForProject();
assignAndSaveResourcesForTasks();
BigDecimal BAC = earnedValueCalculator.getBudgetAtCompletion(orderModel.getOrder());
assertEquals(BAC, new BigDecimal(50));
}
// For creating worker
@Autowired
IWorkerModel workerModel;
@Autowired
IAssignedCriterionsModel assignedCriterionsModel;
private void createAndSaveWorker() {
workerModel.prepareForCreate();
workerModel.getWorker().setFirstName("Neil");
workerModel.getWorker().setSurname("Armstrong");
workerModel.getWorker().setNif("666");
workerModel.getAssignedCriterionsModel().prepareForCreate(workerModel.getWorker());
workerModel.save();
}
// For creating project
@Autowired
IOrderModel orderModel;
@Autowired
private PlanningStateCreator planningStateCreator;
@Autowired
private IAdHocTransactionService adHocTransaction;
@Autowired
private IConfigurationDAO configurationDAO;
private void createAndSaveProject(){
final Order project = Order.create();
project.setDescription("Goal of project: do not be thirsty");
// Create initDate
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, 2016);
project.setInitDate(calendar.getTime());
project.setName("To be not thirsty");
project.setResponsible("human");
project.setCode("code-" + UUID.randomUUID());
BaseCalendar baseCalendar = adHocTransaction.runOnReadOnlyTransaction(new IOnTransaction<BaseCalendar>() {
@Override
public BaseCalendar execute() {
BaseCalendar result =
configurationDAO.getConfigurationWithReadOnlyTransaction().getDefaultCalendar();
BaseCalendarModel.forceLoadBaseCalendar(result);
return result;
}
});
project.setCalendar(baseCalendar);
// Create planningState
PlanningState planningState =
adHocTransaction.runOnAnotherReadOnlyTransaction(new IOnTransaction<PlanningState>() {
@Override
public PlanningStateCreator.PlanningState execute() {
return planningStateCreator.createOn(EasyMock.createNiceMock(Desktop.class), project);
}
});
orderModel.setPlanningState(planningState);
orderModel.save();
}
private void createAndSaveTwoTasksForProject(){
OrderElement task1 = OrderLine.createOrderLineWithUnfixedPercentage(10);
task1.setName("Take bottle");
task1.setCode(UUID.randomUUID().toString());
for (HoursGroup current : task1.getHoursGroups()) current.setCode(UUID.randomUUID().toString());
OrderElement task2 = OrderLine.createOrderLineWithUnfixedPercentage(40);
task2.setName("Drink water");
task2.setCode(UUID.randomUUID().toString());
for (HoursGroup current : task2.getHoursGroups()) current.setCode(UUID.randomUUID().toString());
orderModel.getOrder().add(task1);
orderModel.getOrder().add(task2);
orderModel.save();
}
// For assigning resources to tasks
@Autowired
private IOrderEarnedValueCalculator earnedValueCalculator;
private void assignAndSaveResourcesForTasks(){
// Task 1
Task task1 = (Task) orderModel.getOrder().getAllChildrenAssociatedTaskElements().get(0);
SpecificResourceAllocation specificResourceAllocation1 = SpecificResourceAllocation.create(task1);
specificResourceAllocation1.setResource(workerModel.getWorker());
Scenario orderScenario1 = null;
for (Scenario scenario : orderModel.getOrder().getScenarios().keySet()) {
orderScenario1 = scenario;
}
specificResourceAllocation1.copyAssignments(orderScenario1, orderScenario1);
specificResourceAllocation1.allocate(ResourcesPerDay.amount(1));
for (SpecificDayAssignmentsContainer item : specificResourceAllocation1.getSpecificDayAssignmentsContainers()) {
item.addAll(specificResourceAllocation1.getAssignments());
}
task1.addResourceAllocation(specificResourceAllocation1);
// Task 2
Task task2 = (Task) orderModel.getOrder().getAllChildrenAssociatedTaskElements().get(1);
SpecificResourceAllocation specificResourceAllocation2 = SpecificResourceAllocation.create(task2);
specificResourceAllocation2.setResource(workerModel.getWorker());
Scenario orderScenario2 = null;
for (Scenario scenario : orderModel.getOrder().getScenarios().keySet()) {
orderScenario2 = scenario;
}
specificResourceAllocation2.copyAssignments(orderScenario2, orderScenario2);
specificResourceAllocation2.allocate(ResourcesPerDay.amount(1));
for (SpecificDayAssignmentsContainer item : specificResourceAllocation2.getSpecificDayAssignmentsContainers()) {
item.addAll(specificResourceAllocation2.getAssignments());
}
task2.addResourceAllocation(specificResourceAllocation2);
} }
} }

View file

@ -68,9 +68,7 @@ public class WorkerModelTest {
private IResourceDAO resourceDAO; private IResourceDAO resourceDAO;
@Test @Test
@Transactional public void testWorkerValid() throws ValidationException, InstanceNotFoundException {
public void testWorkerValid() throws ValidationException,
InstanceNotFoundException {
IResourceDAO resourceDAOMock = createMock(IResourceDAO.class); IResourceDAO resourceDAOMock = createMock(IResourceDAO.class);
ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class); ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class);
@ -78,20 +76,17 @@ public class WorkerModelTest {
workerToReturn.setFirstName("firstName"); workerToReturn.setFirstName("firstName");
workerToReturn.setSurname("surname"); workerToReturn.setSurname("surname");
workerToReturn.setNif("232344243"); workerToReturn.setNif("232344243");
// expectations // expectations
List<Criterion> criterions = new ArrayList<Criterion>(); List<Criterion> criterions = new ArrayList<Criterion>();
expect( expect(criterionServiceMock.findByType(PredefinedCriterionTypes.LOCATION)).andReturn(criterions).anyTimes();
criterionServiceMock expect(resourceDAOMock.find(workerToReturn.getId())).andReturn(workerToReturn);
.findByType(PredefinedCriterionTypes.LOCATION))
.andReturn(criterions).anyTimes();
expect(resourceDAOMock.find(workerToReturn.getId()))
.andReturn(workerToReturn);
resourceDAOMock.save(workerToReturn); resourceDAOMock.save(workerToReturn);
workerToReturn.checkNotOverlaps(); workerToReturn.checkNotOverlaps();
replay(resourceDAOMock, criterionServiceMock); replay(resourceDAOMock, criterionServiceMock);
// perform actions // perform actions
WorkerModel workerModel = new WorkerModel(resourceDAOMock, WorkerModel workerModel = new WorkerModel(resourceDAOMock, criterionServiceMock);
criterionServiceMock);
workerModel.prepareEditFor(workerToReturn); workerModel.prepareEditFor(workerToReturn);
workerModel.save(); workerModel.save();
@ -100,20 +95,16 @@ public class WorkerModelTest {
@Ignore @Ignore
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
@Transactional @Transactional
public void testWorkerInvalid() throws ValidationException, public void testWorkerInvalid() throws ValidationException, InstanceNotFoundException, IllegalStateException {
InstanceNotFoundException, IllegalStateException {
IResourceDAO resourceDAOMock = createMock(IResourceDAO.class); IResourceDAO resourceDAOMock = createMock(IResourceDAO.class);
ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class); ICriterionDAO criterionServiceMock = createMock(ICriterionDAO.class);
final Worker workerToReturn = Worker.create(); final Worker workerToReturn = Worker.create();
// expectations // expectations
List<Criterion> criterions = new ArrayList<Criterion>(); List<Criterion> criterions = new ArrayList<Criterion>();
expect( expect(criterionServiceMock.findByType(PredefinedCriterionTypes.LOCATION)).andReturn(criterions).anyTimes();
criterionServiceMock expect(resourceDAOMock.find(workerToReturn.getId())).andReturn(workerToReturn);
.findByType(PredefinedCriterionTypes.LOCATION))
.andReturn(criterions).anyTimes();
expect(resourceDAOMock.find(workerToReturn.getId())).andReturn(
workerToReturn);
resourceDAOMock.save(workerToReturn); resourceDAOMock.save(workerToReturn);
expectLastCall().andAnswer(new IAnswer<Object>() { expectLastCall().andAnswer(new IAnswer<Object>() {
@Override @Override
@ -124,9 +115,9 @@ public class WorkerModelTest {
} }
}); });
replay(resourceDAOMock, criterionServiceMock); replay(resourceDAOMock, criterionServiceMock);
// perform actions // perform actions
WorkerModel workerModel = new WorkerModel(resourceDAOMock, WorkerModel workerModel = new WorkerModel(resourceDAOMock, criterionServiceMock);
criterionServiceMock);
workerModel.prepareEditFor(workerToReturn); workerModel.prepareEditFor(workerToReturn);
workerModel.save(); workerModel.save();
} }

View file

@ -29,10 +29,9 @@ package org.libreplan.web.test;
*/ */
public class WebappGlobalNames { public class WebappGlobalNames {
public final static String WEBAPP_SPRING_CONFIG_TEST_FILE = public final static String WEBAPP_SPRING_CONFIG_TEST_FILE = "classpath:/libreplan-webapp-spring-config-test.xml";
"classpath:/libreplan-webapp-spring-config-test.xml";
public final static String WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE = public final static String WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE =
"classpath:/libreplan-webapp-spring-security-config-test.xml"; "classpath:/libreplan-webapp-spring-security-config-test.xml";
} }