ItEr34S13CUAsignacionRecursosEspecificosAPlanificacionItEr33S15: Created controller and model for configuration window of stretches function.

This commit is contained in:
Manuel Rego Casasnovas 2009-11-16 11:44:22 +01:00 committed by Javier Moran Rua
parent 3009f5b23f
commit f9565a2b9f
6 changed files with 549 additions and 8 deletions

View file

@ -480,6 +480,10 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
return assignmentFunction;
}
public void setAssignmentFunction(AssignmentFunction assignmentFunction) {
this.assignmentFunction = assignmentFunction;
}
public int getAssignedHours() {
int total = 0;
for (DayAssignment dayAssignment : getAssignments()) {

View file

@ -48,6 +48,7 @@ import org.navalplanner.business.planner.entities.TaskElement;
import org.navalplanner.web.common.IMessagesForUser;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.MessagesForUser;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.resourceload.ResourceLoadModel;
import org.zkoss.ganttz.timetracker.ICellForDetailItemRenderer;
import org.zkoss.ganttz.timetracker.IConvertibleToColumn;
@ -61,6 +62,7 @@ import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.Interval;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@ -77,6 +79,7 @@ import org.zkoss.zul.Intbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.api.Column;
import org.zkoss.zul.api.Window;
public class AdvancedAllocationController extends GenericForwardComposer {
@ -334,7 +337,6 @@ public class AdvancedAllocationController extends GenericForwardComposer {
public AdvancedAllocationController(IBack back,
List<AllocationInput> allocationInputs) {
setInputData(back, allocationInputs);
}
private void setInputData(IBack back, List<AllocationInput> allocationInputs) {
@ -776,19 +778,34 @@ class Row {
Messagebox.EXCLAMATION);
} else {
if (assignmentFunction.equals(StretchesFunction.class)) {
// TODO
Messagebox.show(
"TODO: Stretches Function Configuration",
"WIP",
Messagebox.OK, Messagebox.INFORMATION);
goToStretchesFunctionConfiguration();
} else {
Messagebox.show(_("Unknown assignment function: ",
assignmentFunction.getName()), "WIP",
Messagebox.OK, Messagebox.EXCLAMATION);
assignmentFunction.getName()), _("Error"),
Messagebox.OK, Messagebox.ERROR);
}
}
}
private void goToStretchesFunctionConfiguration()
throws Exception {
StretchesFunctionController stretchesFunctionController = new StretchesFunctionController();
HashMap<String, Object> args = new HashMap<String, Object>();
args.put("stretchesFunctionController",
stretchesFunctionController);
Window window = (Window) Executions.createComponents(
"/planner/stretches_function.zul", allHoursInput
.getParent(), args);
Util.createBindingsFor(window);
stretchesFunctionController
.setResourceAllocation(getAllocation());
stretchesFunctionController.showWindow();
getAllocation().setAssignmentFunction(
stretchesFunctionController.getAssignmentFunction());
}
});
return button;

View file

@ -0,0 +1,68 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.planner.allocation;
import java.util.Date;
import java.util.List;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.planner.entities.AssignmentFunction;
import org.navalplanner.business.planner.entities.Stretch;
import org.navalplanner.business.planner.entities.StretchesFunction;
/**
* Contract for {@link StretchesFunctionModel}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public interface IStretchesFunctionModel {
/*
* Initial conversation steps
*/
void initCreate(Date taskEndDate);
void initEdit(StretchesFunction stretchesFunction);
/*
* Intermediate conversation steps
*/
List<Stretch> getStretches();
void addStretch();
void removeStretch(Stretch stretch);
AssignmentFunction getStretchesFunction();
/*
* Final conversation steps
*/
void confirm() throws ValidationException;
void cancel();
}

View file

@ -0,0 +1,242 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.planner.allocation;
import static org.navalplanner.web.I18nHelper._;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import org.joda.time.LocalDate;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.planner.entities.AssignmentFunction;
import org.navalplanner.business.planner.entities.ResourceAllocation;
import org.navalplanner.business.planner.entities.Stretch;
import org.navalplanner.business.planner.entities.StretchesFunction;
import org.navalplanner.web.common.Util;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Decimalbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.api.Window;
public class StretchesFunctionController extends GenericForwardComposer {
private Window window;
private IStretchesFunctionModel stretchesFunctionModel;
private StretchesRenderer stretchesRenderer = new StretchesRenderer();
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
window = (Window) comp;
}
public AssignmentFunction getAssignmentFunction() {
return stretchesFunctionModel.getStretchesFunction();
}
public void setResourceAllocation(ResourceAllocation<?> resourceAllocation) {
AssignmentFunction assignmentFunction = resourceAllocation
.getAssignmentFunction();
if (assignmentFunction == null) {
stretchesFunctionModel.initCreate(resourceAllocation.getTask()
.getEndDate());
} else {
if (assignmentFunction instanceof StretchesFunction) {
stretchesFunctionModel
.initEdit((StretchesFunction) assignmentFunction);
} else {
stretchesFunctionModel.initCreate(resourceAllocation.getTask()
.getEndDate());
}
}
reloadStretchesList();
}
public void showWindow() throws SuspendNotAllowedException,
InterruptedException {
window.doModal();
}
public void confirm() throws InterruptedException {
try {
stretchesFunctionModel.confirm();
window.setVisible(false);
} catch (ValidationException e) {
Messagebox.show(e.getMessage(), _("Error"), Messagebox.OK,
Messagebox.ERROR);
}
}
public void cancel() throws InterruptedException {
int status = Messagebox.show(
_("You will lose the changes. Are you sure?"),
_("Confirm cancel"), Messagebox.YES | Messagebox.NO,
Messagebox.QUESTION);
if (Messagebox.YES == status) {
stretchesFunctionModel.cancel();
window.setVisible(false);
}
}
public List<Stretch> getStretches() {
return stretchesFunctionModel.getStretches();
}
public StretchesRenderer getStretchesRenderer() {
return stretchesRenderer;
}
/**
* Renders a {@link Stretch}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
private class StretchesRenderer implements ListitemRenderer {
@Override
public void render(Listitem item, Object data) throws Exception {
Stretch stretch = (Stretch) data;
item.setValue(stretch);
appendDate(item, stretch);
appendLengthPercentage(item, stretch);
appendAmountWorkPercentage(item, stretch);
appendOperations(item, stretch);
}
private void appendChild(Listitem item, Component component) {
Listcell listcell = new Listcell();
listcell.appendChild(component);
item.appendChild(listcell);
}
private void appendDate(Listitem item, final Stretch stretch) {
Datebox datebox = Util.bind(new Datebox(), new Util.Getter<Date>() {
@Override
public Date get() {
return stretch.getDate().toDateTimeAtStartOfDay().toDate();
}
}, new Util.Setter<Date>() {
@Override
public void set(Date value) {
stretch.setDate(new LocalDate(value));
}
});
appendChild(item, datebox);
}
private void appendLengthPercentage(Listitem item, final Stretch stretch) {
final Decimalbox tempDecimalbox = new Decimalbox();
Decimalbox decimalbox = Util.bind(tempDecimalbox,
new Util.Getter<BigDecimal>() {
@Override
public BigDecimal get() {
return stretch.getLengthPercentage().multiply(
new BigDecimal(100));
}
}, new Util.Setter<BigDecimal>() {
@Override
public void set(BigDecimal value) {
value = value.setScale(2).divide(
new BigDecimal(100), RoundingMode.DOWN);
try {
stretch.setLengthPercentage(value);
} catch (IllegalArgumentException e) {
throw new WrongValueException(
tempDecimalbox,
_("Length percentage should be between 0 and 100"));
}
}
});
appendChild(item, decimalbox);
}
private void appendAmountWorkPercentage(Listitem item,
final Stretch stretch) {
final Decimalbox tempDecimalbox = new Decimalbox();
Decimalbox decimalbox = Util.bind(tempDecimalbox,
new Util.Getter<BigDecimal>() {
@Override
public BigDecimal get() {
return stretch.getAmountWorkPercentage().multiply(
new BigDecimal(100));
}
}, new Util.Setter<BigDecimal>() {
@Override
public void set(BigDecimal value) {
value = value.setScale(2).divide(
new BigDecimal(100), RoundingMode.DOWN);
try {
stretch.setAmountWorkPercentage(value);
} catch (IllegalArgumentException e) {
throw new WrongValueException(tempDecimalbox,
_("Amount work percentage should be between 0 and 100"));
}
}
});
appendChild(item, decimalbox);
}
private void appendOperations(Listitem item, final Stretch stretch) {
Button button = new Button("", "/common/img/ico_borrar1.png");
button.setHoverImage("/common/img/ico_borrar.png");
button.setSclass("icono");
button.setTooltiptext(_("Delete"));
button.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
stretchesFunctionModel.removeStretch(stretch);
reloadStretchesList();
}
});
appendChild(item, button);
}
}
public void addStretch() {
stretchesFunctionModel.addStretch();
reloadStretchesList();
}
private void reloadStretchesList() {
Util.reloadBindings(window.getFellow("stretchesList"));
}
}

View file

@ -0,0 +1,148 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.planner.allocation;
import static org.navalplanner.web.I18nHelper._;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.joda.time.LocalDate;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.planner.entities.AssignmentFunction;
import org.navalplanner.business.planner.entities.Stretch;
import org.navalplanner.business.planner.entities.StretchesFunction;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
/**
* Model for UI operations related to {@link StretchesFunction} configuration.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class StretchesFunctionModel implements IStretchesFunctionModel {
/**
* Conversation state
*/
private StretchesFunction stretchesFunction;
private StretchesFunction originalStretchesFunction;
@Override
public void initCreate(Date taskEndDate) {
stretchesFunction = StretchesFunction.create();
Stretch stretch = new Stretch();
stretch.setDate(new LocalDate(taskEndDate));
stretch.setLengthPercentage(BigDecimal.ONE);
stretch.setAmountWorkPercentage(BigDecimal.ONE);
stretchesFunction.addStretch(stretch);
}
@Override
public void initEdit(StretchesFunction stretchesFunction) {
this.originalStretchesFunction = stretchesFunction;
this.stretchesFunction = copy(stretchesFunction);
}
private static StretchesFunction copy(StretchesFunction stretchesFunction) {
StretchesFunction copy = StretchesFunction.create();
copyStretches(stretchesFunction, copy);
return copy;
}
private static void copyStretches(StretchesFunction original,
StretchesFunction copy) {
copy.removeAllStretches();
for (Stretch stretch : original.getStretches()) {
Stretch newStretch = new Stretch();
newStretch.setDate(stretch.getDate());
newStretch.setLengthPercentage(stretch.getLengthPercentage());
newStretch.setAmountWorkPercentage(stretch
.getAmountWorkPercentage());
copy.addStretch(newStretch);
}
}
@Override
public List<Stretch> getStretches() {
if (stretchesFunction == null) {
return new ArrayList<Stretch>();
}
return stretchesFunction.getStretches();
}
@Override
public void confirm() throws ValidationException {
if (stretchesFunction != null) {
if (!stretchesFunction.checkNoEmpty()) {
throw new ValidationException(
_("At least one stretch is needed"));
}
if (!stretchesFunction.checkStretchesOrder()) {
throw new ValidationException(
_("Some stretch has higher or equal values than the "
+ "previous stretch"));
}
if (!stretchesFunction.checkOneHundredPercent()) {
throw new ValidationException(
_("Last stretch should have one hundred percent for "
+ "length and amount of work percentage"));
}
if (originalStretchesFunction != null) {
copyStretches(stretchesFunction, originalStretchesFunction);
stretchesFunction = originalStretchesFunction;
}
}
}
@Override
public void cancel() {
stretchesFunction = originalStretchesFunction;
}
@Override
public void addStretch() {
if (stretchesFunction != null) {
stretchesFunction.addStretch(new Stretch());
}
}
@Override
public void removeStretch(Stretch stretch) {
if (stretchesFunction != null) {
stretchesFunction.removeStretch(stretch);
}
}
@Override
public AssignmentFunction getStretchesFunction() {
return stretchesFunction;
}
}

View file

@ -0,0 +1,62 @@
<!--
This file is part of ###PROJECT_NAME###
Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
Desenvolvemento Tecnolóxico de Galicia
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<?page title="${i18n:_('Navalpro: Scheduling')}"?>
<?taglib uri="/WEB-INF/tld/i18n.tld" prefix="i18n"?>
<zk>
<zscript><![CDATA[
stretchesFunctionController = arg.get("stretchesFunctionController");
]]>
</zscript>
<window border="normal" title="${i18n:_('Stretches function configuration')}"
apply="${stretchesFunctionController}">
<vbox>
<label>${i18n:_('Stretches')}</label>
<listbox id="stretchesList"
model="@{stretchesFunctionController.stretches}"
itemRenderer="@{stretchesFunctionController.stretchesRenderer}"
style="margin-bottom: 5px" fixedLayout="true" rows="4">
<listhead>
<listheader label="${i18n:_('Date')}" />
<listheader label="${i18n:_('Length percentage')}" />
<listheader label="${i18n:_('Amount work percentage')}" />
<listheader label="${i18n:_('Operations')}" />
</listhead>
</listbox>
<hbox>
<button label="${i18n:_('Add stretch')}" onClick="stretchesFunctionController.addStretch()" />
</hbox>
<hbox>
<button label="${i18n:_('Accept')}"
onClick="stretchesFunctionController.confirm()" />
<button label="${i18n:_('Cancel')}"
onClick="stretchesFunctionController.cancel()" />
</hbox>
</vbox>
</window>
</zk>