Tell the user when the intended and the real resources per day differ
FEA: ItEr74S04BugFixing
This commit is contained in:
parent
175f785f91
commit
ff327d8109
6 changed files with 119 additions and 76 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue