Tell the user when the intended and the real resources per day differ

FEA: ItEr74S04BugFixing
This commit is contained in:
Óscar González Fernández 2011-04-22 19:41:25 +02:00
parent 175f785f91
commit ff327d8109
6 changed files with 119 additions and 76 deletions

View file

@ -39,6 +39,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -567,6 +568,13 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
return intendedResourcesPerDay;
}
public boolean areIntendedResourcesPerDaySatisfied() {
CalculatedValue calculatedValue = getTask().getCalculatedValue();
return calculatedValue == CalculatedValue.RESOURCES_PER_DAY
|| ObjectUtils.equals(getNonConsolidatedResourcePerDay(),
getIntendedResourcesPerDay());
}
public ResourceAllocation(Task task) {
this(task, null);
}

View file

@ -79,6 +79,9 @@ import org.zkoss.zul.SimpleListModel;
*/
public abstract class AllocationRow {
private static final ResourcesPerDay RESOURCES_PER_DAY_DEFAULT_VALUE = ResourcesPerDay
.amount(1);
public static final SimpleConstraint CONSTRAINT_FOR_RESOURCES_PER_DAY = new SimpleConstraint(
SimpleConstraint.NO_EMPTY | SimpleConstraint.NO_NEGATIVE);
@ -98,7 +101,8 @@ public abstract class AllocationRow {
ResourcesPerDay[] resourcesPerDay) {
int i = 0;
for (AllocationRow each : rows) {
each.setNonConsolidatedResourcesPerDay(resourcesPerDay[i++]);
each.setResourcesPerDayEditedValue(resourcesPerDay[i++]);
each.clearRealResourcesPerDay();
}
}
@ -109,6 +113,7 @@ public abstract class AllocationRow {
.iterator();
for (AllocationRow each : rows) {
each.loadDataFromLast();
each.clearRealResourcesPerDay();
AllocationModification modification = iterator.next();
if (!modification.satisfiesModificationRequested()) {
@ -218,22 +223,53 @@ public abstract class AllocationRow {
private String name;
private ResourcesPerDay nonConsolidatedResourcesPerDay;
private Intbox hoursInput = new Intbox();
private final Decimalbox resourcesPerDayInput = new Decimalbox();
private final Decimalbox intendedResourcesPerDayInput = new Decimalbox();
private ResourcesPerDay editedValue;
private final Label realResourcesPerDay = new Label();
private Grid derivedAllocationsGrid;
public AllocationRow(CalculatedValue calculatedValue) {
this.currentCalculatedValue = calculatedValue;
this.origin = null;
setResourcesPerDayEditedValue(RESOURCES_PER_DAY_DEFAULT_VALUE);
initialize();
}
public AllocationRow(ResourceAllocation<?> origin) {
this.origin = origin;
this.currentCalculatedValue = origin.getTask().getCalculatedValue();
setResourcesPerDayEditedValue(resourcesPerDayForInputFrom(origin));
if (origin != null && !origin.areIntendedResourcesPerDaySatisfied()) {
onDifferentRealResourcesPerDay(origin
.getNonConsolidatedResourcePerDay());
}
loadHours();
initialize();
}
private static ResourcesPerDay resourcesPerDayForInputFrom(
ResourceAllocation<?> resourceAllocation) {
CalculatedValue calculatedValue = resourceAllocation.getTask()
.getCalculatedValue();
return calculatedValue == CalculatedValue.RESOURCES_PER_DAY ? resourceAllocation
.getNonConsolidatedResourcePerDay() : resourceAllocation
.getIntendedResourcesPerDay();
}
private void initializeResourcesPerDayInput() {
resourcesPerDayInput.setConstraint(CONSTRAINT_FOR_RESOURCES_PER_DAY);
resourcesPerDayInput.setWidth("80px");
Util.bind(resourcesPerDayInput, new Util.Getter<BigDecimal>() {
intendedResourcesPerDayInput
.setConstraint(CONSTRAINT_FOR_RESOURCES_PER_DAY);
intendedResourcesPerDayInput.setWidth("80px");
Util.bind(intendedResourcesPerDayInput, new Util.Getter<BigDecimal>() {
@Override
public BigDecimal get() {
return getNonConsolidatedResourcesPerDay().getAmount();
return getResourcesPerDayEditedValue().getAmount();
}
}, new Util.Setter<BigDecimal>() {
@ -241,26 +277,13 @@ public abstract class AllocationRow {
@Override
public void set(BigDecimal value) {
BigDecimal amount = value == null ? new BigDecimal(0) : value;
setNonConsolidatedResourcesPerDay(ResourcesPerDay
setResourcesPerDayEditedValue(ResourcesPerDay
.amount(amount));
}
});
}
public AllocationRow(CalculatedValue calculatedValue) {
this.currentCalculatedValue = calculatedValue;
this.origin = null;
initialize();
}
public AllocationRow(ResourceAllocation<?> origin) {
this.origin = origin;
this.currentCalculatedValue = origin.getTask().getCalculatedValue();
initialize();
}
private void initialize() {
setNonConsolidatedResourcesPerDay(ResourcesPerDay.amount(0));
initializeResourcesPerDayInput();
hoursInput.setWidth("80px");
hoursInput.setConstraint(constraintForHoursInput());
@ -286,6 +309,18 @@ public abstract class AllocationRow {
return origin;
}
private void onDifferentRealResourcesPerDay(
ResourcesPerDay realResourcesPerDay) {
this.realResourcesPerDay
.setTooltiptext(_("It can't allocate the intended resources per day"));
this.realResourcesPerDay.setValue(_("(achieved: {0})",
realResourcesPerDay.getAmount().toPlainString()));
}
private void clearRealResourcesPerDay() {
this.realResourcesPerDay.setValue("");
}
public boolean hasDerivedAllocations() {
return ! getDerivedAllocations().isEmpty();
}
@ -310,20 +345,19 @@ public abstract class AllocationRow {
this.name = name;
}
public ResourcesPerDay getNonConsolidatedResourcesPerDay() {
return this.nonConsolidatedResourcesPerDay;
public ResourcesPerDay getResourcesPerDayEditedValue() {
return this.editedValue;
}
public ResourcesPerDay getResourcesPerDayFromInput() {
BigDecimal value = resourcesPerDayInput.getValue();
BigDecimal value = intendedResourcesPerDayInput.getValue();
value = value != null ? value : BigDecimal.ZERO;
return ResourcesPerDay.amount(value);
}
public void setNonConsolidatedResourcesPerDay(
ResourcesPerDay resourcesPerDay) {
this.nonConsolidatedResourcesPerDay = resourcesPerDay;
resourcesPerDayInput.setValue(getAmount(resourcesPerDay));
private void setResourcesPerDayEditedValue(ResourcesPerDay resourcesPerDay) {
this.editedValue = resourcesPerDay;
intendedResourcesPerDayInput.setValue(getAmount(resourcesPerDay));
}
private BigDecimal getAmount(ResourcesPerDay resourcesPerDay) {
@ -339,7 +373,7 @@ public abstract class AllocationRow {
public abstract boolean isGeneric();
public boolean isEmptyResourcesPerDay() {
return getNonConsolidatedResourcesPerDay().isZero();
return getResourcesPerDayEditedValue().isZero();
}
public abstract List<Resource> getAssociatedResources();
@ -348,13 +382,17 @@ public abstract class AllocationRow {
return hoursInput;
}
public Decimalbox getResourcesPerDayInput() {
return resourcesPerDayInput;
public Decimalbox getIntendedResourcesPerDayInput() {
return intendedResourcesPerDayInput;
}
public Label getRealResourcesPerDay() {
return realResourcesPerDay;
}
public void addListenerForInputChange(EventListener onChangeListener) {
getHoursInput().addEventListener(Events.ON_CHANGE, onChangeListener);
getResourcesPerDayInput().addEventListener(Events.ON_CHANGE,
getIntendedResourcesPerDayInput().addEventListener(Events.ON_CHANGE,
onChangeListener);
}
@ -383,10 +421,14 @@ public abstract class AllocationRow {
.setDisabled(calculatedValue != CalculatedValue.RESOURCES_PER_DAY
|| recommendedAllocation);
hoursInput.setConstraint(constraintForHoursInput());
resourcesPerDayInput
intendedResourcesPerDayInput
.setDisabled(calculatedValue == CalculatedValue.RESOURCES_PER_DAY
|| recommendedAllocation);
resourcesPerDayInput.setConstraint(constraintForResourcesPerDayInput());
if (intendedResourcesPerDayInput.isDisabled()) {
clearRealResourcesPerDay();
}
intendedResourcesPerDayInput
.setConstraint(constraintForResourcesPerDayInput());
}
private Constraint constraintForHoursInput() {
@ -394,17 +436,16 @@ public abstract class AllocationRow {
}
private Constraint constraintForResourcesPerDayInput() {
return (resourcesPerDayInput.isDisabled()) ? null
return (intendedResourcesPerDayInput.isDisabled()) ? null
: CONSTRAINT_FOR_RESOURCES_PER_DAY;
}
private void loadDataFromLast() {
Clients.closeErrorBox(hoursInput);
Clients.closeErrorBox(resourcesPerDayInput);
Clients.closeErrorBox(intendedResourcesPerDayInput);
hoursInput.setValue(temporal.getAssignedHours());
resourcesPerDayInput
.setValue(temporal.getResourcesPerDay().getAmount());
loadResourcesPerDayFrom(temporal);
}
private void warnObjectiveNotSatisfied(AllocationModification modification) {
@ -413,10 +454,10 @@ public abstract class AllocationRow {
@Override
public Void onResourcesPerDay(
ResourcesPerDayModification modification) {
ResourcesPerDay goal = modification.getGoal();
Clients.response(new AuWrongValue(resourcesPerDayInput, _(
"{0} resources per day cannot be fulfilled", goal
.getAmount().toPlainString())));
ResourcesPerDay realResourcesPerDay = modification
.getBeingModified().getNonConsolidatedResourcePerDay();
onDifferentRealResourcesPerDay(realResourcesPerDay);
return null;
}
@ -442,7 +483,7 @@ public abstract class AllocationRow {
public void addListenerForResourcesPerDayInputChange(
EventListener resourcesPerDayRowInputChange) {
resourcesPerDayInput.addEventListener(Events.ON_CHANGE,
intendedResourcesPerDayInput.addEventListener(Events.ON_CHANGE,
resourcesPerDayRowInputChange);
}
@ -560,19 +601,17 @@ public abstract class AllocationRow {
}
public void loadResourcesPerDay() {
if (temporal != null) {
nonConsolidatedResourcesPerDay = temporal.getNonConsolidatedResourcePerDay();
} else {
if (origin != null) {
nonConsolidatedResourcesPerDay = origin
.getNonConsolidatedResourcePerDay();
} else {
nonConsolidatedResourcesPerDay = ResourcesPerDay.amount(0);
}
}
loadResourcesPerDayFrom(temporal != null ? temporal : origin);
}
resourcesPerDayInput.setValue(nonConsolidatedResourcesPerDay
.getAmount());
private void loadResourcesPerDayFrom(ResourceAllocation<?> allocation) {
if (allocation == null) {
setResourcesPerDayEditedValue(ResourcesPerDay.amount(0));
}
boolean useIntention = currentCalculatedValue != CalculatedValue.RESOURCES_PER_DAY;
setResourcesPerDayEditedValue(useIntention ? allocation
.getIntendedResourcesPerDay() : allocation
.getNonConsolidatedResourcePerDay());
}
public abstract ResourceEnum getType();
@ -631,7 +670,7 @@ public abstract class AllocationRow {
@Override
public Void on(ResourcesPerDayIsZero result) {
throw new WrongValueException(resourcesPerDayInput,
throw new WrongValueException(intendedResourcesPerDayInput,
_("Resources per day are zero"));
}
});

View file

@ -654,7 +654,7 @@ public class FormBinder {
final String message = _("resources per day must be not empty and bigger than zero");
if (!recommendedAllocation) {
AllocationRow first = rows.get(0);
throw new WrongValueException(first.getResourcesPerDayInput(),
throw new WrongValueException(first.getIntendedResourcesPerDayInput(),
message);
} else {
throw new WrongValueException(allResourcesPerDay, message);
@ -790,7 +790,7 @@ public class FormBinder {
private BigDecimal sumResourcesPerDayFromInputs() {
BigDecimal sum = BigDecimal.ZERO;
for (AllocationRow each : rows) {
if (each.getResourcesPerDayInput().isValid()) {
if (each.getIntendedResourcesPerDayInput().isValid()) {
sum = sum.add(each.getResourcesPerDayFromInput().getAmount());
}
}

View file

@ -42,7 +42,6 @@ import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.ResourceEnum;
import org.navalplanner.business.resources.entities.ResourceType;
import org.navalplanner.business.workingday.ResourcesPerDay;
/**
* The information required for creating a {@link GenericResourceAllocation}
@ -54,7 +53,6 @@ public class GenericAllocationRow extends AllocationRow {
GenericAllocationRow result, ResourceEnum resourceType) {
Validate.notNull(resourceType);
result.setName(_("Generic"));
result.setNonConsolidatedResourcesPerDay(ResourcesPerDay.amount(0));
result.resourceType = resourceType;
return result;
}
@ -81,9 +79,6 @@ public class GenericAllocationRow extends AllocationRow {
new GenericAllocationRow(resourceAllocation),
resourceAllocation.getResourceType());
result.setNonConsolidatedResourcesPerDay(resourceAllocation
.getNonConsolidatedResourcePerDay());
ResourceType type = resourceAllocation.isLimiting() ?
ResourceType.LIMITING_RESOURCE :
ResourceType.NON_LIMITING_RESOURCE;
@ -134,7 +129,7 @@ public class GenericAllocationRow extends AllocationRow {
GenericResourceAllocation newGeneric = createGenericAllocation(task,
requestedToRemove);
return ResourcesPerDayModification
.create(newGeneric, getNonConsolidatedResourcesPerDay(), this.resources);
.create(newGeneric, getResourcesPerDayEditedValue(), this.resources);
}
private GenericResourceAllocation createGenericAllocation(Task task,

View file

@ -66,6 +66,7 @@ import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Column;
import org.zkoss.zul.Columns;
import org.zkoss.zul.Decimalbox;
import org.zkoss.zul.Div;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Intbox;
@ -636,7 +637,14 @@ public class ResourceAllocationController extends GenericForwardComposer {
.toString()));
append(row, new Label(data.getConsolidatedResourcesPerDay()
.getAmount().toString()));
append(row, data.getResourcesPerDayInput());
Div resourcesPerDayContainer = append(row, new Div());
append(resourcesPerDayContainer,
data.getIntendedResourcesPerDayInput());
Label realResourcesPerDay = append(resourcesPerDayContainer,
data.getRealResourcesPerDay());
realResourcesPerDay.setStyle("float: right; padding-right: 1em;");
// On click delete button
Button deleteButton = appendDeleteButton(row);
formBinder.setDeleteButtonFor(data, deleteButton);
@ -685,8 +693,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
return append(row, button);
}
private <T extends Component> T append(Row row, T component) {
row.appendChild(component);
private <T extends Component> T append(Component parent, T component) {
parent.appendChild(component);
return component;
}
}

View file

@ -34,7 +34,6 @@ import org.navalplanner.business.planner.entities.allocationalgorithms.HoursModi
import org.navalplanner.business.planner.entities.allocationalgorithms.ResourcesPerDayModification;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.ResourceEnum;
import org.navalplanner.business.workingday.ResourcesPerDay;
/**
* The information required for creating a {@link SpecificResourceAllocation}
@ -89,10 +88,6 @@ public class SpecificAllocationRow extends AllocationRow {
public static SpecificAllocationRow from(SpecificResourceAllocation specific) {
SpecificAllocationRow result = new SpecificAllocationRow(specific);
setupResource(result, specific.getResource());
result.setNonConsolidatedResourcesPerDay(specific
.getNonConsolidatedResourcePerDay());
return result;
}
@ -108,8 +103,6 @@ public class SpecificAllocationRow extends AllocationRow {
Resource resource) {
specificRow.setName(resource.getShortDescription());
specificRow.setResource(resource);
specificRow
.setNonConsolidatedResourcesPerDay(ResourcesPerDay.amount(1));
}
private Resource resource;
@ -126,7 +119,7 @@ public class SpecificAllocationRow extends AllocationRow {
public ResourcesPerDayModification toResourcesPerDayModification(Task task,
Collection<? extends ResourceAllocation<?>> requestedToRemove) {
return ResourcesPerDayModification.create(createSpecific(task),
getNonConsolidatedResourcesPerDay());
getResourcesPerDayEditedValue());
}
private SpecificResourceAllocation createSpecific(Task task) {