ItEr24S08CUAsignacionGrupoRecursosAPlanificacionItEr23S10: Revamped ResourceAllocation
Error on loading Task after deleting one ResourceAllocation and Cancel
This commit is contained in:
parent
47c4e73845
commit
e62f1f51bd
9 changed files with 585 additions and 264 deletions
|
|
@ -79,6 +79,10 @@ public class Task extends TaskElement {
|
|||
resourceAllocations.remove(resourceAllocation);
|
||||
}
|
||||
|
||||
public Boolean getFixedDuration() {
|
||||
return fixedDuration;
|
||||
}
|
||||
|
||||
public void setFixedDuration(Boolean fixed_duration) {
|
||||
this.fixedDuration = fixed_duration;
|
||||
}
|
||||
|
|
@ -207,4 +211,41 @@ public class Task extends TaskElement {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Set<GenericResourceAllocation> getGenericResourceAllocations() {
|
||||
Set<GenericResourceAllocation> result = new HashSet<GenericResourceAllocation>();
|
||||
|
||||
Set<ResourceAllocation> resourceAllocations = getResourceAllocations();
|
||||
for (ResourceAllocation resourceAllocation : resourceAllocations) {
|
||||
if (resourceAllocation instanceof GenericResourceAllocation) {
|
||||
result.add((GenericResourceAllocation) resourceAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Set<SpecificResourceAllocation> getSpecificResourceAllocations() {
|
||||
Set<SpecificResourceAllocation> result = new HashSet<SpecificResourceAllocation>();
|
||||
|
||||
Set<ResourceAllocation> resourceAllocations = getResourceAllocations();
|
||||
for (ResourceAllocation resourceAllocation : resourceAllocations) {
|
||||
if (resourceAllocation instanceof SpecificResourceAllocation) {
|
||||
result.add((SpecificResourceAllocation) resourceAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public BigDecimal getSumPercentage(
|
||||
List<ResourceAllocation> resourceAllocations) {
|
||||
BigDecimal result = new BigDecimal(0);
|
||||
|
||||
for (ResourceAllocation resourceAllocation : resourceAllocations) {
|
||||
result = result.add(resourceAllocation.getPercentage());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,25 @@
|
|||
package org.navalplanner.business.resources.daos;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDAO;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
|
||||
/**
|
||||
* DAO interface for the <code>Resource</code> entity.
|
||||
*
|
||||
* @author Fernando Bellas Permuy <fbellas@udc.es>
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*/
|
||||
public interface IResourceDAO extends IGenericDAO<Resource, Long> {
|
||||
public List<Worker> getWorkers();
|
||||
|
||||
/**
|
||||
* Returns all {@link Resource} which satisfy a set of {@link Criterion}
|
||||
*/
|
||||
List<Resource> getAllByCriterions(Set<Criterion> criterions);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package org.navalplanner.business.resources.daos;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
|
@ -11,7 +14,9 @@ import org.springframework.stereotype.Repository;
|
|||
|
||||
/**
|
||||
* Hibernate DAO for the <code>Resource</code> entity.
|
||||
*
|
||||
* @author Fernando Bellas Permuy <fbellas@udc.es>
|
||||
* @author Diego Pino Garcia <dpino@udc.es>
|
||||
*/
|
||||
@Repository
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
|
|
@ -21,4 +26,17 @@ public class ResourceDAO extends GenericDAOHibernate<Resource, Long> implements
|
|||
public List<Worker> getWorkers() {
|
||||
return list(Worker.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource> getAllByCriterions(Set<Criterion> criterions) {
|
||||
String strQuery = "SELECT resource "
|
||||
+ "FROM Resource resource "
|
||||
+ "LEFT OUTER JOIN resource.criterionSatisfactions criterionSatisfactions "
|
||||
+ "LEFT OUTER JOIN criterionSatisfactions.criterion criterion "
|
||||
+ "WHERE criterion IN (:criterions)";
|
||||
Query query = getSession().createQuery(strQuery);
|
||||
query.setParameterList("criterions", criterions);
|
||||
return (List<Resource>) query.list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ public abstract class Resource extends BaseEntity{
|
|||
|
||||
private Set<CriterionSatisfaction> criterionSatisfactions = new HashSet<CriterionSatisfaction>();
|
||||
|
||||
public Set<CriterionSatisfaction> getCriterionSatisfactions() {
|
||||
return criterionSatisfactions;
|
||||
}
|
||||
|
||||
public abstract String getDescription();
|
||||
|
||||
private interface IPredicate {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package org.navalplanner.business.resources.entities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.validator.Min;
|
||||
import org.hibernate.validator.NotEmpty;
|
||||
|
||||
|
|
@ -94,4 +97,10 @@ public class Worker extends Resource {
|
|||
return dailyHours;
|
||||
}
|
||||
|
||||
public boolean satisfiesCriterions(Set<Criterion> criterions) {
|
||||
ICriterion compositedCriterion = CriterionCompounder.buildAnd(
|
||||
new ArrayList<ICriterion>(criterions)).getResult();
|
||||
return compositedCriterion.isSatisfiedBy(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package org.navalplanner.web.planner;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
|
|
@ -12,9 +14,72 @@ import org.navalplanner.business.resources.entities.Worker;
|
|||
* Contract for {@link Task}.
|
||||
*
|
||||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
public interface IResourceAllocationModel {
|
||||
|
||||
/**
|
||||
* Adds a new {@link GenericResourceAllocation} to the current {@link Task}.
|
||||
*/
|
||||
void addGenericResourceAllocation();
|
||||
|
||||
/**
|
||||
* Adds {@link SpecificResourceAllocation} to {@link Task}
|
||||
* {@link ResourceAllocation} list
|
||||
*
|
||||
* If a {@link SpecificResourceAllocation} satisfies {@link Task} criterions
|
||||
* one of the {@link GenericResourceAllocation} assigned to
|
||||
* {@link ResourceAllocation} is removed (in case any exists)
|
||||
*
|
||||
*/
|
||||
void addSpecificResourceAllocation(Worker worker) throws Exception;
|
||||
|
||||
/**
|
||||
* Returns {@link Set} of {@link Criterion} of the current {@link Task}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Set<Criterion> getCriterions();
|
||||
|
||||
/**
|
||||
* Returns {@link Set} of {@link GenericResourceAllocation} of current
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Set<GenericResourceAllocation> getGenericResourceAllocations();
|
||||
|
||||
/**
|
||||
* Returns number of {@link ResourceAllocation} which are candidate to add
|
||||
* as {@link GenericResourceAllocation}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int getNumberUnassignedResources();
|
||||
|
||||
/**
|
||||
* Returns the {@link Set} of {@link ResourceAllocation} of the current
|
||||
* {@link Task}.
|
||||
*
|
||||
* @return A {@link Set} of {@link ResourceAllocation}
|
||||
*/
|
||||
Set<ResourceAllocation> getResourceAllocations();
|
||||
|
||||
/**
|
||||
* Return sum of percentages for current {@link Task}
|
||||
* {@link ResourceAllocation}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
BigDecimal getSumPercentageResourceAllocations();
|
||||
|
||||
/**
|
||||
* Return sum of percentages for current {@link Task}
|
||||
* {@link SpecificResourceAllocation}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
BigDecimal getSumPercentageSpecificResourceAllocations();
|
||||
|
||||
/**
|
||||
* Gets the current {@link Task} object.
|
||||
*
|
||||
|
|
@ -22,11 +87,6 @@ public interface IResourceAllocationModel {
|
|||
*/
|
||||
Task getTask();
|
||||
|
||||
/**
|
||||
* Adds a new {@link ResourceAllocation} to the current {@link Task}.
|
||||
*/
|
||||
void addResourceAllocation();
|
||||
|
||||
/**
|
||||
* Removes the {@link ResourceAllocation} from the current {@link Task}.
|
||||
*
|
||||
|
|
@ -36,72 +96,13 @@ public interface IResourceAllocationModel {
|
|||
void removeResourceAllocation(ResourceAllocation resourceAllocation);
|
||||
|
||||
/**
|
||||
* Tries to find a {@link Worker} with the specified NIF.
|
||||
*
|
||||
* @param nif
|
||||
* The NIF to search the {@link Worker}
|
||||
* @return The {@link Worker} with this NIF or <code>null</code> if it's not
|
||||
* found
|
||||
*/
|
||||
Worker findWorkerByNif(String nif);
|
||||
|
||||
/**
|
||||
* Relates a {@link Worker} and a {@link Task} through a
|
||||
* {@link SpecificResourceAllocation}.
|
||||
* Removes {@link SpecificResourceAllocation} from current {@link Task}
|
||||
* {@link ResourceAllocation} list
|
||||
*
|
||||
* @param resourceAllocation
|
||||
* A {@link SpecificResourceAllocation} to set the {@link Worker}
|
||||
* @param worker
|
||||
* A {@link Worker} for the {@link SpecificResourceAllocation}
|
||||
*/
|
||||
void setWorker(SpecificResourceAllocation resourceAllocation, Worker worker);
|
||||
|
||||
/**
|
||||
* Sets the current {@link Task}, where the user is allocating resources.
|
||||
*
|
||||
* @param task
|
||||
* A {@link Task}
|
||||
*/
|
||||
void setTask(Task task);
|
||||
|
||||
/**
|
||||
* Gets the {@link Set} of {@link Criterion} of the current task.
|
||||
*
|
||||
* @return A {@link Set} of {@link Criterion}
|
||||
*/
|
||||
Set<Criterion> getCriterions();
|
||||
|
||||
/**
|
||||
* Gets the {@link Set} of {@link ResourceAllocation} of the current task.
|
||||
*
|
||||
* @return A {@link Set} of {@link ResourceAllocation}
|
||||
*/
|
||||
Set<ResourceAllocation> getResourceAllocations();
|
||||
|
||||
/**
|
||||
* Sets the current {@link ResourceAllocation} to be rendered.
|
||||
*
|
||||
* @param resourceAllocation
|
||||
* The current {@link ResourceAllocation}
|
||||
*/
|
||||
void setResourceAllocation(ResourceAllocation resourceAllocation);
|
||||
|
||||
/**
|
||||
* Gets the {@link Worker} of the current {@link ResourceAllocation}.
|
||||
*
|
||||
* @return A {@link Worker}
|
||||
*/
|
||||
Worker getWorker();
|
||||
|
||||
/**
|
||||
* Checks if the {@link Worker} of the current {@link ResourceAllocation}
|
||||
* satisfies the {@link Criterion} of the current {@link Task}.
|
||||
*
|
||||
* @return True if the {@link Worker} satisfies the {@link Criterion}
|
||||
* required. Or if the current {@link Worker} is <code>null</code>.
|
||||
* Or if the {@link Criterion} list is empty.
|
||||
*/
|
||||
boolean workerSatisfiesCriterions();
|
||||
void removeSpecificResourceAllocation(
|
||||
SpecificResourceAllocation resourceAllocation);
|
||||
|
||||
/**
|
||||
* Sets the current Gantt {@link org.zkoss.ganttz.data.Task ganttTask},
|
||||
|
|
@ -111,6 +112,14 @@ public interface IResourceAllocationModel {
|
|||
*/
|
||||
void setGanttTask(org.zkoss.ganttz.data.Task ganttTask);
|
||||
|
||||
/**
|
||||
* Sets the current {@link Task}, where the user is allocating resources.
|
||||
*
|
||||
* @param task
|
||||
* A {@link Task}
|
||||
*/
|
||||
void setTask(Task task);
|
||||
|
||||
/**
|
||||
* Update the duration of the current Gantt
|
||||
* {@link org.zkoss.ganttz.data.Task ganttTask}, depending on the resources
|
||||
|
|
@ -121,10 +130,11 @@ public interface IResourceAllocationModel {
|
|||
void updateGanttTaskDuration();
|
||||
|
||||
/**
|
||||
* Adds {@link SpecificResourceAllocation} to {@link Task}
|
||||
* Updates {@link GenericResourceAllocation} percentages of current
|
||||
* {@link Task}
|
||||
*
|
||||
* @param worker
|
||||
* @param totalPercentage
|
||||
*/
|
||||
void addSpecificResourceAllocation(Worker worker);
|
||||
void updateGenericPercentages(BigDecimal totalPercentage);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,29 @@ package org.navalplanner.web.planner;
|
|||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
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.common.components.WorkerSearch;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
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.util.Clients;
|
||||
import org.zkoss.zk.ui.event.InputEvent;
|
||||
import org.zkoss.zk.ui.util.GenericForwardComposer;
|
||||
import org.zkoss.zul.Button;
|
||||
import org.zkoss.zul.Decimalbox;
|
||||
|
|
@ -35,6 +40,7 @@ import org.zkoss.zul.api.Window;
|
|||
* Controller for {@link ResourceAllocation} view.
|
||||
*
|
||||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*/
|
||||
@org.springframework.stereotype.Component("resourceAllocationController")
|
||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
|
|
@ -44,56 +50,36 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
|||
|
||||
private ResourceAllocationRenderer resourceAllocationRenderer = new ResourceAllocationRenderer();
|
||||
|
||||
private Component messagesContainer;
|
||||
|
||||
private IMessagesForUser messagesForUser;
|
||||
|
||||
private Listbox resourcesList;
|
||||
|
||||
private Decimalbox genericResourceAllocationPercentage;
|
||||
|
||||
private Window window;
|
||||
|
||||
public Set<Criterion> getCriterions() {
|
||||
Set<Criterion> criterions = resourceAllocationModel.getCriterions();
|
||||
if (criterions.isEmpty()) {
|
||||
window.getFellow("requiredCriterions").setVisible(false);
|
||||
window.getFellow("requiredCriterionsEmpty").setVisible(true);
|
||||
} else {
|
||||
window.getFellow("requiredCriterionsEmpty").setVisible(false);
|
||||
window.getFellow("requiredCriterions").setVisible(true);
|
||||
}
|
||||
|
||||
return criterions;
|
||||
}
|
||||
|
||||
public Set<ResourceAllocation> getResourceAllocations() {
|
||||
return resourceAllocationModel.getResourceAllocations();
|
||||
}
|
||||
|
||||
public ResourceAllocationRenderer getResourceAllocationRenderer() {
|
||||
return resourceAllocationRenderer;
|
||||
}
|
||||
|
||||
public void addResourceAllocation() {
|
||||
resourceAllocationModel.addResourceAllocation();
|
||||
Util.reloadBindings(resourcesList);
|
||||
}
|
||||
|
||||
public void removeResourceAllocation() {
|
||||
Set<Listitem> selectedItems = resourcesList.getSelectedItems();
|
||||
for (Listitem listitem : selectedItems) {
|
||||
ResourceAllocation resourceAllocation = (ResourceAllocation) listitem
|
||||
.getValue();
|
||||
resourceAllocationModel.removeResourceAllocation(resourceAllocation);
|
||||
}
|
||||
Util.reloadBindings(resourcesList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterCompose(Component comp) throws Exception {
|
||||
super.doAfterCompose(comp);
|
||||
messagesForUser = new MessagesForUser(messagesContainer);
|
||||
this.window = (Window) comp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows Resource Allocation window
|
||||
*
|
||||
* @param task
|
||||
* @param ganttTask
|
||||
*/
|
||||
public void showWindow(Task task, org.zkoss.ganttz.data.Task ganttTask) {
|
||||
resourceAllocationModel.setTask(task);
|
||||
resourceAllocationModel.setGanttTask(ganttTask);
|
||||
|
||||
// Add generic resources to resources list
|
||||
addGenericResources();
|
||||
|
||||
Util.reloadBindings(window);
|
||||
try {
|
||||
window.doModal();
|
||||
|
|
@ -104,30 +90,24 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
|||
}
|
||||
}
|
||||
|
||||
public void back() {
|
||||
Set<ResourceAllocation> resourceAllocations = resourceAllocationModel.getResourceAllocations();
|
||||
for (ResourceAllocation resourceAllocation : resourceAllocations) {
|
||||
if (((SpecificResourceAllocation) resourceAllocation).getWorker() == null) {
|
||||
throw new WrongValueException(
|
||||
window.getFellow("resourcesList"),
|
||||
_("Worker not valid in some resource allocation"));
|
||||
}
|
||||
/**
|
||||
* Check how many {@link ResourceAllocation} object can be assigned to this
|
||||
* {@link Task} and add them to {@link ResourceAllocation} list
|
||||
*/
|
||||
private void addGenericResources() {
|
||||
int n = resourceAllocationModel.getNumberUnassignedResources();
|
||||
for (int i = 0; i < n; i++) {
|
||||
resourceAllocationModel.addGenericResourceAllocation();
|
||||
}
|
||||
|
||||
if (!resourceAllocationModel.getTask()
|
||||
.isValidResourceAllocationWorkers()) {
|
||||
throw new WrongValueException(window.getFellow("resourcesList"),
|
||||
_("There is some Worker assigned twice (or more)"));
|
||||
}
|
||||
|
||||
Clients.closeErrorBox(window.getFellow("resourcesList"));
|
||||
|
||||
resourceAllocationModel.updateGanttTaskDuration();
|
||||
|
||||
window.setVisible(false);
|
||||
}
|
||||
|
||||
public void showSearchResources(Event e) {
|
||||
/**
|
||||
* Shows WorkerSearch window, add picked workers as
|
||||
* {@link SpecificResourceAllocation} to {@link ResourceAllocation} list
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public void showSearchResources() {
|
||||
WorkerSearch workerSearch = new WorkerSearch();
|
||||
workerSearch.setParent(self.getParent());
|
||||
workerSearch.afterCompose();
|
||||
|
|
@ -143,15 +123,99 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get selected workers and add specificResourceAllocations
|
||||
List<Worker> workers = workerSearch.getWorkers();
|
||||
for (Worker worker : workers) {
|
||||
resourceAllocationModel.addSpecificResourceAllocation(worker);
|
||||
}
|
||||
addSpecificResourceAllocations(workerSearch.getWorkers());
|
||||
|
||||
Util.reloadBindings(resourcesList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a list of {@link Worker} to {@link ResourceAllocation} list
|
||||
*
|
||||
* @param workers
|
||||
*/
|
||||
private void addSpecificResourceAllocations(List<Worker> workers) {
|
||||
for (Worker worker : workers) {
|
||||
addSpecificResourceAllocation(worker);
|
||||
}
|
||||
updateGenericPercentages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update percentages of {@link GenericResourceAllocation} items when
|
||||
* genericResourceAllocationPercentage box is changed
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
public void updateGenericPercentages(InputEvent e) {
|
||||
updateGenericPercentages(new BigDecimal((String) e.getValue()));
|
||||
}
|
||||
|
||||
public void updateGenericPercentages() {
|
||||
updateGenericPercentages(genericResourceAllocationPercentage.getValue());
|
||||
}
|
||||
|
||||
private void updateGenericPercentages(BigDecimal genericPercentage) {
|
||||
if (genericPercentage != null) {
|
||||
resourceAllocationModel.updateGenericPercentages(genericPercentage
|
||||
.divide(new BigDecimal(100)));
|
||||
}
|
||||
Util.reloadBindings(resourcesList);
|
||||
}
|
||||
|
||||
private void addSpecificResourceAllocation(Worker worker) {
|
||||
try {
|
||||
resourceAllocationModel.addSpecificResourceAllocation(worker);
|
||||
} catch (Exception e1) {
|
||||
messagesForUser.showMessage(Level.ERROR, e1.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of {@link Criterion} separated by comma
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getTaskCriterions() {
|
||||
Set<String> criterionNames = new HashSet<String>();
|
||||
|
||||
Set<Criterion> criterions = resourceAllocationModel.getCriterions();
|
||||
for (Criterion criterion : criterions) {
|
||||
criterionNames.add(criterion.getName());
|
||||
}
|
||||
|
||||
return StringUtils.join(criterionNames, ",");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns hours of {@link Task}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getTaskHours() {
|
||||
Task task = resourceAllocationModel.getTask();
|
||||
return (task != null && task.getHours() != null) ? task.getHours()
|
||||
.toString() : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns type of {@link Task} based on value of fixedDuration attribute
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getTaskType() {
|
||||
Task task = resourceAllocationModel.getTask();
|
||||
return (task != null && task.getFixedDuration()) ? _("Fixed duration")
|
||||
: _("Variable duration");
|
||||
}
|
||||
|
||||
public Set<ResourceAllocation> getResourceAllocations() {
|
||||
return resourceAllocationModel.getResourceAllocations();
|
||||
}
|
||||
|
||||
public ResourceAllocationRenderer getResourceAllocationRenderer() {
|
||||
return resourceAllocationRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Renders a {@link SpecificResourceAllocation} item
|
||||
|
|
@ -163,14 +227,25 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
|||
|
||||
@Override
|
||||
public void render(Listitem item, Object data) throws Exception {
|
||||
final SpecificResourceAllocation resourceAllocation = (SpecificResourceAllocation) data;
|
||||
if (data instanceof SpecificResourceAllocation) {
|
||||
renderSpecificResourceAllocation(item,
|
||||
(SpecificResourceAllocation) data);
|
||||
}
|
||||
if (data instanceof GenericResourceAllocation) {
|
||||
renderGenericResourceAllocation(item,
|
||||
(GenericResourceAllocation) data);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderSpecificResourceAllocation(Listitem item,
|
||||
final SpecificResourceAllocation resourceAllocation)
|
||||
throws Exception {
|
||||
item.setValue(resourceAllocation);
|
||||
|
||||
// Label fields are fixed, can only be viewed
|
||||
appendLabel(item, resourceAllocation.getWorker().getName());
|
||||
appendLabel(item, resourceAllocation.getWorker().getNif());
|
||||
// Pecentage field is editable
|
||||
// appendLabel(item, resourceAllocation.getWorker().getNif());
|
||||
// Percentage field is editable
|
||||
bindPercentage(appendDecimalbox(item), resourceAllocation);
|
||||
// On click delete button
|
||||
appendButton(item, _("Delete")).addEventListener("onClick",
|
||||
|
|
@ -178,18 +253,43 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
|||
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
resourceAllocationModel
|
||||
.removeResourceAllocation(resourceAllocation);
|
||||
Util.reloadBindings(resourcesList);
|
||||
removeSpecificResourceAllocation(resourceAllocation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void removeSpecificResourceAllocation(
|
||||
SpecificResourceAllocation resourceAllocation) {
|
||||
resourceAllocationModel
|
||||
.removeSpecificResourceAllocation(resourceAllocation);
|
||||
updateGenericPercentages();
|
||||
Util.reloadBindings(resourcesList);
|
||||
}
|
||||
|
||||
private void renderGenericResourceAllocation(Listitem item,
|
||||
final GenericResourceAllocation resourceAllocation)
|
||||
throws Exception {
|
||||
item.setValue(resourceAllocation);
|
||||
|
||||
// Set name
|
||||
appendLabel(item, _("Generic"));
|
||||
// Set percentage
|
||||
BigDecimal percentage = resourceAllocation.getPercentage();
|
||||
if (!new BigDecimal(0).equals(resourceAllocation.getPercentage())) {
|
||||
percentage = percentage.scaleByPowerOfTen(2).setScale(2,
|
||||
BigDecimal.ROUND_CEILING);
|
||||
}
|
||||
appendLabel(item, percentage.toString());
|
||||
// No buttons
|
||||
appendLabel(item, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends {@link Label} to {@link Listitem}
|
||||
*
|
||||
* @param listitem
|
||||
* @param name value for {@link Label}
|
||||
* @param name
|
||||
* value for {@link Label}
|
||||
*/
|
||||
private void appendLabel(Listitem listitem, String name) {
|
||||
Label label = new Label(name);
|
||||
|
|
@ -203,7 +303,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
|||
* Appends {@link Button} to {@link Listitem}
|
||||
*
|
||||
* @param listitem
|
||||
* @param label value for {@link Button}
|
||||
* @param label
|
||||
* value for {@link Button}
|
||||
* @return
|
||||
*/
|
||||
private Button appendButton(Listitem listitem, String label) {
|
||||
|
|
@ -245,16 +346,21 @@ public class ResourceAllocationController extends GenericForwardComposer {
|
|||
|
||||
@Override
|
||||
public BigDecimal get() {
|
||||
return resourceAllocation.getPercentage().scaleByPowerOfTen(2);
|
||||
return (resourceAllocation.getPercentage() != null) ? resourceAllocation
|
||||
.getPercentage().scaleByPowerOfTen(2)
|
||||
: new BigDecimal(0);
|
||||
}
|
||||
|
||||
}, new Util.Setter<BigDecimal>() {
|
||||
|
||||
@Override
|
||||
public void set(BigDecimal value) {
|
||||
resourceAllocation
|
||||
.setPercentage(value.setScale(2).divide(
|
||||
new BigDecimal(100), BigDecimal.ROUND_DOWN));
|
||||
if (value != null) {
|
||||
value = value.setScale(2).divide(new BigDecimal(100),
|
||||
BigDecimal.ROUND_DOWN);
|
||||
updateGenericPercentages();
|
||||
decimalbox.setValue(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,28 @@
|
|||
package org.navalplanner.web.planner;
|
||||
|
||||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.orders.daos.IHoursGroupDAO;
|
||||
import org.navalplanner.business.orders.entities.HoursGroup;
|
||||
import org.navalplanner.business.planner.daos.IResourceAllocationDAO;
|
||||
import org.navalplanner.business.planner.daos.ITaskElementDAO;
|
||||
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.daos.IWorkerDAO;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.CriterionCompounder;
|
||||
import org.navalplanner.business.resources.entities.CriterionSatisfaction;
|
||||
import org.navalplanner.business.resources.entities.ICriterion;
|
||||
import org.navalplanner.business.resources.entities.CriterionType;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
|
@ -31,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* Model for UI operations related to {@link Task}
|
||||
*
|
||||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
@Service
|
||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
|
|
@ -43,10 +47,10 @@ public class ResourceAllocationModel implements IResourceAllocationModel {
|
|||
private IWorkerDAO workerDAO;
|
||||
|
||||
@Autowired
|
||||
private SessionFactory sessionFactory;
|
||||
private IHoursGroupDAO hoursGroupDAO;
|
||||
|
||||
@Autowired
|
||||
private IHoursGroupDAO hoursGroupDAO;
|
||||
private IResourceDAO resourceDAO;
|
||||
|
||||
@Autowired
|
||||
private IResourceAllocationDAO resourceAllocationDAO;
|
||||
|
|
@ -55,30 +59,110 @@ public class ResourceAllocationModel implements IResourceAllocationModel {
|
|||
|
||||
private org.zkoss.ganttz.data.Task ganttTask;
|
||||
|
||||
private ResourceAllocation resourceAllocation;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void setTask(Task task) {
|
||||
taskElementDAO.save(task);
|
||||
task.getResourceAllocations().size();
|
||||
|
||||
HoursGroup hoursGroup = task.getHoursGroup();
|
||||
hoursGroupDAO.save(hoursGroup);
|
||||
hoursGroup.getCriterions().size();
|
||||
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceAllocation() {
|
||||
ResourceAllocation resourceAllocation = SpecificResourceAllocation.create(task);
|
||||
@Transactional(readOnly = true)
|
||||
public void setTask(Task task) {
|
||||
try {
|
||||
task = (Task) taskElementDAO.find(task.getId());
|
||||
reattachResourceAllocations(task.getResourceAllocations());
|
||||
hoursGroupDAO.save(task.getHoursGroup());
|
||||
reattachHoursGroup(task.getHoursGroup());
|
||||
reattachCriterions(task.getHoursGroup().getCriterions());
|
||||
|
||||
this.task = task;
|
||||
} catch (InstanceNotFoundException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void reattachResourceAllocations(
|
||||
Set<ResourceAllocation> resourceAllocations) {
|
||||
resourceAllocations.size();
|
||||
for (ResourceAllocation resourceAllocation : resourceAllocations) {
|
||||
resourceAllocation.getPercentage();
|
||||
if (resourceAllocation instanceof SpecificResourceAllocation) {
|
||||
reattachSpecificResourceAllocation((SpecificResourceAllocation) resourceAllocation);
|
||||
}
|
||||
resourceAllocationDAO.save(resourceAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
private void reattachSpecificResourceAllocation(
|
||||
SpecificResourceAllocation resourceAllocation) {
|
||||
resourceAllocation.getWorker().getName();
|
||||
reattachCriterionSatisfactions(resourceAllocation.getWorker()
|
||||
.getCriterionSatisfactions());
|
||||
}
|
||||
|
||||
private void reattachHoursGroup(HoursGroup hoursGroup) {
|
||||
hoursGroup.getPercentage();
|
||||
}
|
||||
|
||||
private void reattachCriterions(Set<Criterion> criterions) {
|
||||
for (Criterion criterion : criterions) {
|
||||
reattachCriterion(criterion);
|
||||
}
|
||||
}
|
||||
|
||||
private void reattachCriterion(Criterion criterion) {
|
||||
criterion.getName();
|
||||
reattachCriterionType(criterion.getType());
|
||||
}
|
||||
|
||||
private void reattachCriterionType(CriterionType criterionType) {
|
||||
criterionType.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void addGenericResourceAllocation() {
|
||||
GenericResourceAllocation resourceAllocation = GenericResourceAllocation
|
||||
.create(task);
|
||||
resourceAllocation.setPercentage(new BigDecimal(0));
|
||||
task.addResourceAllocation(resourceAllocation);
|
||||
taskElementDAO.save(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void addSpecificResourceAllocation(Worker worker) throws Exception {
|
||||
|
||||
// ResourceAllocation already exists
|
||||
if (findSpecificResourceAllocationByWorker(worker) != null) {
|
||||
throw new IllegalArgumentException(_(
|
||||
"{0} already assigned to resource allocation list", worker
|
||||
.getName()));
|
||||
}
|
||||
|
||||
// Prepare resourceAllocation
|
||||
SpecificResourceAllocation resourceAllocation = SpecificResourceAllocation
|
||||
.create(task);
|
||||
resourceAllocation.setWorker(worker);
|
||||
resourceAllocation.setPercentage((new BigDecimal(1)));
|
||||
|
||||
reattachWorker(worker);
|
||||
// Check if worker was itself a generic resource
|
||||
if (worker.satisfiesCriterions(getCriterions())) {
|
||||
Set<GenericResourceAllocation> genericResourceAllocations = getGenericResourceAllocations();
|
||||
// Generic resources always match criterions, so we need to remove
|
||||
// one generic resource to leave room for a specific resource
|
||||
if (genericResourceAllocations.size() > 0) {
|
||||
removeResourceAllocation(genericResourceAllocations.iterator()
|
||||
.next());
|
||||
}
|
||||
}
|
||||
task.addResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Set<GenericResourceAllocation> getGenericResourceAllocations() {
|
||||
return task.getGenericResourceAllocations();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -86,92 +170,122 @@ public class ResourceAllocationModel implements IResourceAllocationModel {
|
|||
task.removeResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Worker findWorkerByNif(String nif) {
|
||||
try {
|
||||
return workerDAO.findUniqueByNif(nif);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorker(SpecificResourceAllocation resourceAllocation,
|
||||
Worker worker) {
|
||||
resourceAllocation.setWorker(worker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Criterion> getCriterions() {
|
||||
if (task == null) {
|
||||
return new HashSet<Criterion>();
|
||||
}
|
||||
return task.getHoursGroup().getCriterions();
|
||||
return (task != null) ? task.getHoursGroup().getCriterions()
|
||||
: new HashSet<Criterion>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ResourceAllocation> getResourceAllocations() {
|
||||
if (task == null) {
|
||||
return new HashSet<ResourceAllocation>();
|
||||
}
|
||||
return task.getResourceAllocations();
|
||||
return (task != null) ? task.getResourceAllocations()
|
||||
: new HashSet<ResourceAllocation>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void setResourceAllocation(ResourceAllocation resourceAllocation) {
|
||||
resourceAllocationDAO.save(resourceAllocation);
|
||||
public void removeSpecificResourceAllocation(
|
||||
SpecificResourceAllocation resourceAllocation) {
|
||||
boolean addGenericResourceAllocation = false;
|
||||
|
||||
Worker worker = ((SpecificResourceAllocation) resourceAllocation)
|
||||
.getWorker();
|
||||
if (worker != null) {
|
||||
workerDAO.save(worker);
|
||||
Set<CriterionSatisfaction> criterionSatisfactions = worker
|
||||
.getAllSatisfactions();
|
||||
for (CriterionSatisfaction criterionSatisfaction : criterionSatisfactions) {
|
||||
criterionSatisfaction.getCriterion().getName();
|
||||
criterionSatisfaction.getCriterion().getType().getName();
|
||||
// On removing this resourceAllocation, it may be room for a new generic
|
||||
// resource allocation
|
||||
Worker worker = resourceAllocation.getWorker();
|
||||
if (worker.satisfiesCriterions(getCriterions())) {
|
||||
addGenericResourceAllocation = true;
|
||||
}
|
||||
resourceAllocationDAO.save(resourceAllocation);
|
||||
task.removeResourceAllocation(resourceAllocation);
|
||||
// Add new generic resource
|
||||
if (addGenericResourceAllocation) {
|
||||
addGenericResourceAllocation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void updateGenericPercentages(BigDecimal totalPercentage) {
|
||||
Set<GenericResourceAllocation> genericResourceAllocations = getGenericResourceAllocations();
|
||||
BigDecimal percentagePerResource = totalPercentage;
|
||||
|
||||
percentagePerResource = percentagePerResource
|
||||
.subtract(getSumPercentageSpecificResourceAllocations());
|
||||
if (genericResourceAllocations.size() > 0) {
|
||||
percentagePerResource = percentagePerResource.setScale(8).divide(
|
||||
new BigDecimal(genericResourceAllocations.size()),
|
||||
BigDecimal.ROUND_DOWN);
|
||||
|
||||
// Percentage cannot be negative
|
||||
if (percentagePerResource.compareTo(new BigDecimal(0)) < 0) {
|
||||
percentagePerResource = new BigDecimal(0);
|
||||
}
|
||||
|
||||
for (ResourceAllocation resourceAllocation : genericResourceAllocations) {
|
||||
resourceAllocation.setPercentage(percentagePerResource);
|
||||
}
|
||||
}
|
||||
|
||||
this.resourceAllocation = resourceAllocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Worker getWorker() {
|
||||
if (resourceAllocation == null) {
|
||||
return null;
|
||||
public BigDecimal getSumPercentageSpecificResourceAllocations() {
|
||||
return getSumPercentage(task.getSpecificResourceAllocations());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private BigDecimal getSumPercentage(Set resourceAllocations) {
|
||||
BigDecimal result = new BigDecimal(0);
|
||||
|
||||
for (Iterator i = resourceAllocations.iterator(); i.hasNext();) {
|
||||
ResourceAllocation resourceAllocation = (ResourceAllocation) i
|
||||
.next();
|
||||
result = result.add(resourceAllocation.getPercentage());
|
||||
}
|
||||
Worker worker = ((SpecificResourceAllocation) resourceAllocation)
|
||||
.getWorker();
|
||||
if (worker == null) {
|
||||
return null;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SpecificResourceAllocation findSpecificResourceAllocationByWorker(Worker worker) {
|
||||
for (SpecificResourceAllocation resourceAllocation : task
|
||||
.getSpecificResourceAllocations()) {
|
||||
if (resourceAllocation.getWorker().getId().equals(worker.getId())) {
|
||||
return resourceAllocation;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return workerDAO.find(worker.getId());
|
||||
} catch (InstanceNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
private void reattachWorker(Worker worker) {
|
||||
workerDAO.save(worker);
|
||||
reattachCriterionSatisfactions(worker.getCriterionSatisfactions());
|
||||
}
|
||||
|
||||
private void reattachCriterionSatisfactions(
|
||||
Set<CriterionSatisfaction> criterionSatisfactions) {
|
||||
for (CriterionSatisfaction criterionSatisfaction : criterionSatisfactions) {
|
||||
criterionSatisfaction.getStartDate();
|
||||
reattachCriterion(criterionSatisfaction.getCriterion());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean workerSatisfiesCriterions() {
|
||||
public BigDecimal getSumPercentageResourceAllocations() {
|
||||
return getSumPercentage(task.getResourceAllocations());
|
||||
}
|
||||
|
||||
for (Criterion criterion : getCriterions()) {
|
||||
sessionFactory.getCurrentSession().lock(criterion, LockMode.NONE);
|
||||
}
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public int getNumberUnassignedResources() {
|
||||
List<Resource> resources = resourceDAO
|
||||
.getAllByCriterions(getCriterions());
|
||||
Set<ResourceAllocation> resourceAllocations = task
|
||||
.getResourceAllocations();
|
||||
|
||||
Worker worker = getWorker();
|
||||
|
||||
if (worker == null) {
|
||||
return true;
|
||||
}
|
||||
ICriterion compositedCriterion = CriterionCompounder.buildAnd(
|
||||
new ArrayList<ICriterion>(getCriterions())).getResult();
|
||||
return compositedCriterion.isSatisfiedBy(worker);
|
||||
return (resources.size() - resourceAllocations.size() > 0) ? resources
|
||||
.size()
|
||||
- resourceAllocations.size() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -187,13 +301,4 @@ public class ResourceAllocationModel implements IResourceAllocationModel {
|
|||
ganttTask.setEndDate(task.getEndDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSpecificResourceAllocation(Worker worker) {
|
||||
SpecificResourceAllocation resourceAllocation = SpecificResourceAllocation
|
||||
.create(task);
|
||||
resourceAllocation.setWorker(worker);
|
||||
resourceAllocation.setPercentage(new BigDecimal(1));
|
||||
task.addResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,34 +64,52 @@
|
|||
apply="${allocationController}"
|
||||
title="${i18n:_('Resource allocation')}" width="600px"
|
||||
closable="true" visible="false">
|
||||
<tabbox>
|
||||
<tabs>
|
||||
<tab
|
||||
label="${i18n:_('Specific resource allocation')}">
|
||||
</tab>
|
||||
</tabs>
|
||||
|
||||
<tabpanels>
|
||||
<tabpanel>
|
||||
<listbox id="resourcesList"
|
||||
model="@{allocationController.resourceAllocations}"
|
||||
itemRenderer="@{allocationController.resourceAllocationRenderer}">
|
||||
<listhead>
|
||||
<listheader label="${i18n:_('Name')}" />
|
||||
<listheader label="${i18n:_('NIF')}" />
|
||||
<listheader label="${i18n:_('Percentage')}" />
|
||||
<listheader label="" />
|
||||
</listhead>
|
||||
</listbox>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
<panel title="Generic resource allocation" border="normal" style="margin-bottom: 5px">
|
||||
<panelchildren>
|
||||
<hbox>
|
||||
<label value="${i18n:_('Task type')}:"
|
||||
style="font-weight:bold" />
|
||||
<label value="@{allocationController.taskType}" />
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label value="${i18n:_('Criterions')}:"
|
||||
style="font-weight:bold" />
|
||||
<label
|
||||
value="@{allocationController.taskCriterions}" />
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label value="${i18n:_('Hours')}:"
|
||||
style="font-weight:bold" />
|
||||
<label value="@{allocationController.taskHours}" />
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label value="${i18n:_('Generic allocation')}:"
|
||||
style="font-weight:bold" />
|
||||
<decimalbox id="genericResourceAllocationPercentage" width="48px"
|
||||
onChange="allocationController.updateGenericPercentages(event)" />
|
||||
</hbox>
|
||||
</panelchildren>
|
||||
</panel>
|
||||
|
||||
<vbox id="messagesContainer"></vbox>
|
||||
|
||||
<listbox id="resourcesList"
|
||||
model="@{allocationController.resourceAllocations}"
|
||||
itemRenderer="@{allocationController.resourceAllocationRenderer}"
|
||||
style="margin-bottom: 5px">
|
||||
<listhead>
|
||||
<listheader label="${i18n:_('Name')}" />
|
||||
<listheader label="${i18n:_('Percentage')}" />
|
||||
<listheader label="" />
|
||||
</listhead>
|
||||
</listbox>
|
||||
|
||||
<hbox>
|
||||
<button label="${i18n:_('Save')}" />
|
||||
<button label="${i18n:_('Cancel')}" />
|
||||
<button label="${i18n:_('Search resources...')}"
|
||||
onClick="allocationController.showSearchResources(event)" />
|
||||
onClick="allocationController.showSearchResources()" />
|
||||
<button label="${i18n:_('Advance allocation')}" />
|
||||
</hbox>
|
||||
</window>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue