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;
@ -61,6 +59,7 @@ public class SchedulingDataForVersion extends BaseEntity {
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);
} }
} }
@ -90,12 +87,12 @@ 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,35 +105,99 @@ 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

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;
} }
@ -81,12 +79,12 @@ 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, return create(new SpecificDayAssignmentsContainer(specificResourceAllocation, scenario));
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,
ResourcesPerDay.amount(1),
workers))).untilAllocating(hours(16)); 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,
int capacityUnits,
EffortDuration load) { 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,
Type.END_START); Dependency.create(sourceDependencyTask, taskBeingTransformed, Type.END_START);
Dependency.create(taskBeingTransformed, destinationDependencyTask, Dependency.create(taskBeingTransformed, destinationDependencyTask, Type.END_START);
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

@ -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(
duration, labelTaskStart, labelTaskEnd, this.workableDaysAndDatesBinder =
taskPropertiesController); new WorkableDaysAndDatesBinder(duration, labelTaskStart, labelTaskEnd, 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()
.getWorkableDaysFrom( Integer effectiveWorkableDays = getTask().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;
@ -669,29 +657,23 @@ 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,7 +293,8 @@ 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,
Order order,
ViewSwitcher switcher, ViewSwitcher switcher,
EditTaskController editTaskController, EditTaskController editTaskController,
AdvancedAllocationTaskController advancedAllocationTaskController, AdvancedAllocationTaskController advancedAllocationTaskController,
@ -302,29 +302,27 @@ public class OrderPlanningModel implements IOrderPlanningModel {
AdvanceConsolidationController advanceConsolidationController, AdvanceConsolidationController advanceConsolidationController,
CalendarAllocationController calendarAllocationController, CalendarAllocationController calendarAllocationController,
List<ICommand<TaskElement>> additional) { 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();
} }
} }
@ -994,19 +964,20 @@ 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,13 +284,10 @@ 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
.runOnTransaction(new IOnTransaction<Void>() {
@Override @Override
public Void execute() { public Void execute() {
if (beforeSaveActions != null) { if (beforeSaveActions != null) {
@ -305,28 +297,26 @@ public class SaveCommandBuilder {
return null; 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

@ -74,19 +74,19 @@ public class WorkRelationshipsController extends GenericForwardComposer {
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,14 +332,12 @@ 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();
@ -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,8 +29,7 @@ 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";