Merge master into scenarios
This commit is contained in:
commit
8a94cdeffa
200 changed files with 18553 additions and 10223 deletions
|
|
@ -97,4 +97,7 @@ public class CommandOnTaskContextualized<T> {
|
|||
return commandOnTask.isApplicableTo(domainObject);
|
||||
}
|
||||
|
||||
public IDomainAndBeansMapper<T> getMapper() {
|
||||
return this.mapper;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,4 +73,9 @@ public class DatesMapperOnInterval implements IDatesMapper {
|
|||
return millisecondsPerPixel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHorizontalSize() {
|
||||
return this.horizontalSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -161,6 +161,12 @@ public class FunctionalityExposedForExtensions<T> implements IContext<T> {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends TaskContainer> getParents(Task task) {
|
||||
Position position = findPositionFor(task);
|
||||
return position.getAncestors();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final Planner planner;
|
||||
|
|
|
|||
|
|
@ -38,4 +38,6 @@ public interface IDatesMapper {
|
|||
|
||||
long getMilisecondsPerPixel();
|
||||
|
||||
int getHorizontalSize();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.util.Set;
|
|||
import java.util.Map.Entry;
|
||||
|
||||
import org.zkoss.ganttz.adapters.IDisabilityConfiguration;
|
||||
import org.zkoss.ganttz.adapters.IDomainAndBeansMapper;
|
||||
import org.zkoss.ganttz.adapters.PlannerConfiguration;
|
||||
import org.zkoss.ganttz.data.Dependency;
|
||||
import org.zkoss.ganttz.data.GanttDiagramGraph;
|
||||
|
|
@ -161,6 +162,31 @@ public class Planner extends HtmlMacroComponent {
|
|||
return getTaskList().getTasksNumber();
|
||||
}
|
||||
|
||||
private static int PIXELS_PER_TASK_LEVEL = 21;
|
||||
private static int PIXELS_PER_CHARACTER = 5;
|
||||
|
||||
public int calculateMinimumWidthForTaskNameColumn(boolean expand) {
|
||||
return calculateMinimumWidthForTaskNameColumn(expand, getTaskList().getAllTasks());
|
||||
}
|
||||
|
||||
private int calculateMinimumWidthForTaskNameColumn(boolean expand, List<Task> tasks) {
|
||||
IDomainAndBeansMapper<?> mapper = getContext().getMapper();
|
||||
int widest = 0;
|
||||
for(Task task : tasks) {
|
||||
int numberOfAncestors =
|
||||
mapper.findPositionFor(task).getAncestors().size();
|
||||
int numberOfCharacters = task.getName().length();
|
||||
widest = Math.max(widest,
|
||||
numberOfCharacters * PIXELS_PER_CHARACTER +
|
||||
numberOfAncestors * PIXELS_PER_TASK_LEVEL);
|
||||
if(expand && !task.isLeaf()) {
|
||||
widest = Math.max(widest,
|
||||
calculateMinimumWidthForTaskNameColumn(expand, task.getTasks()));
|
||||
}
|
||||
}
|
||||
return widest;
|
||||
}
|
||||
|
||||
public int getAllTasksNumber() {
|
||||
return diagramGraph.getTasks().size();
|
||||
}
|
||||
|
|
@ -206,7 +232,10 @@ public class Planner extends HtmlMacroComponent {
|
|||
}
|
||||
|
||||
public ListModel getZoomLevels() {
|
||||
return new SimpleListModel(ZoomLevel.values());
|
||||
ZoomLevel[] selectableZoomlevels = { ZoomLevel.DETAIL_ONE,
|
||||
ZoomLevel.DETAIL_TWO, ZoomLevel.DETAIL_THREE,
|
||||
ZoomLevel.DETAIL_FOUR, ZoomLevel.DETAIL_FIVE };
|
||||
return new SimpleListModel(selectableZoomlevels);
|
||||
}
|
||||
|
||||
public void setZoomLevel(final ZoomLevel zoomLevel) {
|
||||
|
|
@ -262,10 +291,7 @@ public class Planner extends HtmlMacroComponent {
|
|||
.getStartConstraints(), configuration.getEndConstraints(), configuration.isDependenciesConstraintsHavePriority());
|
||||
FunctionalityExposedForExtensions<T> newContext = new FunctionalityExposedForExtensions<T>(
|
||||
this, configuration, diagramGraph);
|
||||
diagramGraph.addPreChangeListeners(configuration
|
||||
.getPreChangeListeners());
|
||||
diagramGraph.addPostChangeListeners(configuration
|
||||
.getPostChangeListeners());
|
||||
addGraphChangeListenersFromConfiguration(configuration);
|
||||
this.contextualizedGlobalCommands = contextualize(newContext,
|
||||
configuration.getGlobalCommands());
|
||||
this.commandsOnTasksContextualized = contextualize(newContext,
|
||||
|
|
@ -627,4 +653,12 @@ public class Planner extends HtmlMacroComponent {
|
|||
chartVisibilityListeners.addListener(chartVisibilityChangedListener);
|
||||
}
|
||||
|
||||
public void addGraphChangeListenersFromConfiguration(
|
||||
PlannerConfiguration<?> configuration) {
|
||||
diagramGraph.addPreChangeListeners(configuration
|
||||
.getPreChangeListeners());
|
||||
diagramGraph.addPostChangeListeners(configuration
|
||||
.getPostChangeListeners());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public class TaskComponent extends Div implements AfterCompose {
|
|||
private static final Log LOG = LogFactory.getLog(TaskComponent.class);
|
||||
|
||||
private static final int HEIGHT_PER_TASK = 10;
|
||||
private static final int CONSOLIDATED_MARK_HALF_WIDTH = 3;
|
||||
|
||||
|
||||
private static Pattern pixelsSpecificationPattern = Pattern
|
||||
.compile("\\s*(\\d+)px\\s*;?\\s*");
|
||||
|
|
@ -207,6 +209,9 @@ public class TaskComponent extends Div implements AfterCompose {
|
|||
|
||||
response("setClass", new AuInvoke(TaskComponent.this,
|
||||
"setClass", cssClass));
|
||||
|
||||
// FIXME: Refactorize to another listener
|
||||
updateDeadline();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -437,9 +442,17 @@ public class TaskComponent extends Div implements AfterCompose {
|
|||
String position = getMapper().toPixels(task.getDeadline()) + "px";
|
||||
response(null, new AuInvoke(this, "moveDeadline", position));
|
||||
}
|
||||
if (task.getConsolidatedline() != null) {
|
||||
String position = (getMapper().toPixels(task.getConsolidatedline()) - CONSOLIDATED_MARK_HALF_WIDTH)
|
||||
+ "px";
|
||||
response(null, new AuInvoke(this, "moveConsolidatedline", position));
|
||||
} else {
|
||||
// Move consolidated line out of visible area
|
||||
response(null, new AuInvoke(this, "moveConsolidatedline", "-100px"));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCompletionIfPossible() {
|
||||
public void updateCompletionIfPossible() {
|
||||
try {
|
||||
updateCompletion();
|
||||
} catch (Exception e) {
|
||||
|
|
@ -475,6 +488,10 @@ public class TaskComponent extends Div implements AfterCompose {
|
|||
widthAdvancePercentage));
|
||||
}
|
||||
|
||||
public void updateTooltipText() {
|
||||
smartUpdate("taskTooltipText", task.updateTooltipText());
|
||||
}
|
||||
|
||||
private DependencyList getDependencyList() {
|
||||
return getGanntPanel().getDependencyList();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,6 +93,10 @@ public class TaskList extends XulElement implements AfterCompose {
|
|||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
public List<Task> getAllTasks() {
|
||||
return new ArrayList<Task>(currentTotalTasks);
|
||||
}
|
||||
|
||||
public static TaskList createFor(
|
||||
FunctionalityExposedForExtensions<?> context,
|
||||
CommandOnTaskContextualized<?> doubleClickCommand,
|
||||
|
|
@ -307,8 +311,31 @@ public class TaskList extends XulElement implements AfterCompose {
|
|||
}
|
||||
for (CommandOnTaskContextualized<?> command : commandsOnTasksContextualized) {
|
||||
if (command.accepts(taskComponent)) {
|
||||
menuBuilder.item(command.getName(), command.getIcon(),
|
||||
if (command.getName().equals("Advance assignment")) {
|
||||
final CommandOnTaskContextualized<?> commandAdvances = command;
|
||||
menuBuilder.item(command.getName(), command.getIcon(),
|
||||
new ItemAction<TaskComponent>() {
|
||||
@Override
|
||||
public void onEvent(TaskComponent choosen,
|
||||
Event event) {
|
||||
commandAdvances.doAction(choosen);
|
||||
if (commandAdvances.getMapper() != null) {
|
||||
List<Task> listTaskComponents = new ArrayList<Task>(
|
||||
commandAdvances
|
||||
.getMapper()
|
||||
.getParents(
|
||||
choosen
|
||||
.getTask()));
|
||||
listTaskComponents.add(choosen
|
||||
.getTask());
|
||||
updateTaskAndItsParents(listTaskComponents);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
menuBuilder.item(command.getName(), command.getIcon(),
|
||||
command.toItemAction());
|
||||
}
|
||||
}
|
||||
}
|
||||
Menupopup result = menuBuilder.createWithoutSettingContext();
|
||||
|
|
@ -318,6 +345,14 @@ public class TaskList extends XulElement implements AfterCompose {
|
|||
return contextMenus.get(taskComponent);
|
||||
}
|
||||
|
||||
private void updateTaskAndItsParents(List<Task> taskList) {
|
||||
for (Task task : taskList) {
|
||||
TaskComponent choosen = this.find(task);
|
||||
choosen.updateCompletionIfPossible();
|
||||
choosen.updateTooltipText();
|
||||
}
|
||||
}
|
||||
|
||||
GanttPanel getGanttPanel() {
|
||||
return (GanttPanel) getParent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@
|
|||
|
||||
package org.zkoss.ganttz.adapters;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.zkoss.ganttz.data.Position;
|
||||
import org.zkoss.ganttz.data.Task;
|
||||
import org.zkoss.ganttz.data.TaskContainer;
|
||||
|
||||
/**
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
|
|
@ -62,5 +64,13 @@ public interface IDomainAndBeansMapper<T> {
|
|||
*/
|
||||
Task findAssociatedBean(T domainObject) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Used to know the parents for a given task.
|
||||
* @return If the task is top level returns an empty list.<br />
|
||||
* Otherwise it returns the list of parents from more immediate to
|
||||
* most distant parent
|
||||
*/
|
||||
List<? extends TaskContainer> getParents(Task task);
|
||||
|
||||
public Map<T, Task> getMapDomainToTask();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,13 +393,17 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
|
|||
public void addPreGraphChangeListener(
|
||||
IGraphChangeListener preGraphChangeListener) {
|
||||
Validate.notNull(preGraphChangeListener);
|
||||
preGraphChangeListeners.add(preGraphChangeListener);
|
||||
if (!preGraphChangeListeners.contains(preGraphChangeListener)) {
|
||||
preGraphChangeListeners.add(preGraphChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPostGraphChangeListener(
|
||||
IGraphChangeListener postGraphChangeListener) {
|
||||
Validate.notNull(postGraphChangeListener);
|
||||
postGraphChangeListeners.add(postGraphChangeListener);
|
||||
if (!postGraphChangeListeners.contains(postGraphChangeListener)) {
|
||||
postGraphChangeListeners.add(postGraphChangeListener);
|
||||
}
|
||||
}
|
||||
|
||||
public List<IGraphChangeListener> getPreChangeListeners() {
|
||||
|
|
|
|||
|
|
@ -189,4 +189,18 @@ public class DefaultFundamentalProperties implements ITaskFundamentalProperties
|
|||
return "unassigned";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFixed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getConsolidatedline() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String updateTooltipText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ public class GanttDiagramGraph<V, D> {
|
|||
|
||||
boolean isVisible(D dependency);
|
||||
|
||||
boolean isFixed(V task);
|
||||
|
||||
}
|
||||
|
||||
static class GanttZKAdapter implements IAdapter<Task, Dependency> {
|
||||
|
|
@ -230,6 +232,11 @@ public class GanttDiagramGraph<V, D> {
|
|||
return ((TaskContainer) container).getSmallestBeginDateFromChildren();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFixed(Task task) {
|
||||
return task.isFixed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class GanttZKDiagramGraph extends
|
||||
|
|
@ -772,11 +779,7 @@ public class GanttDiagramGraph<V, D> {
|
|||
|
||||
private void doRecalculations(List<Recalculation> recalculationsNeeded) {
|
||||
Set<V> allModified = new HashSet<V>();
|
||||
List<Recalculation> calculated = new ArrayList<Recalculation>();
|
||||
for (Recalculation each : recalculationsNeeded) {
|
||||
if (each.haveToDoCalculation()) {
|
||||
calculated.add(each);
|
||||
}
|
||||
boolean modified = each.doRecalculation();
|
||||
if (modified) {
|
||||
allModified.add(each.taskPoint.task);
|
||||
|
|
@ -1032,6 +1035,9 @@ public class GanttDiagramGraph<V, D> {
|
|||
@SuppressWarnings("unchecked")
|
||||
private boolean enforceEndDate(V task, Date previousEndDate,
|
||||
Set<D> incoming) {
|
||||
if (adapter.isFixed(task)) {
|
||||
return false;
|
||||
}
|
||||
Constraint<Date> currentLength = adapter
|
||||
.getCurrentLenghtConstraintFor(task);
|
||||
Constraint<Date> respectStartDate = adapter
|
||||
|
|
@ -1048,6 +1054,9 @@ public class GanttDiagramGraph<V, D> {
|
|||
}
|
||||
|
||||
private boolean enforceStartDate(V task, Set<D> incoming) {
|
||||
if (adapter.isFixed(task)) {
|
||||
return false;
|
||||
}
|
||||
Date newStart = calculateStartDateFor(task, incoming);
|
||||
if (!adapter.getStartDate(task).equals(newStart)) {
|
||||
adapter.setStartDateFor(task, newStart);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ public interface ITaskFundamentalProperties {
|
|||
*/
|
||||
public Date getDeadline();
|
||||
|
||||
public Date getConsolidatedline();
|
||||
|
||||
public void setLengthMilliseconds(long lengthMilliseconds);
|
||||
|
||||
public long getLengthMilliseconds();
|
||||
|
|
@ -88,4 +90,8 @@ public interface ITaskFundamentalProperties {
|
|||
|
||||
public String getAssignedStatus();
|
||||
|
||||
public boolean isFixed();
|
||||
|
||||
public String updateTooltipText();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -296,6 +296,10 @@ public abstract class Task implements ITaskFundamentalProperties {
|
|||
return fundamentalProperties.getTooltipText();
|
||||
}
|
||||
|
||||
public String updateTooltipText() {
|
||||
return fundamentalProperties.updateTooltipText();
|
||||
}
|
||||
|
||||
public String getLabelsText() {
|
||||
return fundamentalProperties.getLabelsText();
|
||||
}
|
||||
|
|
@ -316,6 +320,11 @@ public abstract class Task implements ITaskFundamentalProperties {
|
|||
return fundamentalProperties.getDeadline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getConsolidatedline() {
|
||||
return fundamentalProperties.getConsolidatedline();
|
||||
}
|
||||
|
||||
public void addConstraintViolationListener(
|
||||
IConstraintViolationListener<Date> listener) {
|
||||
violationNotificator.addConstraintViolationListener(listener);
|
||||
|
|
@ -373,4 +382,8 @@ public abstract class Task implements ITaskFundamentalProperties {
|
|||
return fundamentalProperties.getAssignedStatus();
|
||||
}
|
||||
|
||||
public boolean isFixed() {
|
||||
return fundamentalProperties.isFixed();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
package org.zkoss.ganttz.data.resourceload;
|
||||
|
||||
import static org.zkoss.ganttz.i18n.I18nHelper._;
|
||||
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
|
|
@ -55,13 +53,13 @@ public class TimeLineRole<T> {
|
|||
*/
|
||||
public enum TimeLineRoleEnum {
|
||||
|
||||
NONE(_("None")), WORKER(_("Worker")), ORDER(_("Order")), TASK(_("Task")) {
|
||||
NONE("None"), WORKER("Worker"), ORDER("Order"), TASK("Task") {
|
||||
@Override
|
||||
public boolean isVisibleScheduled() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
CRITERION(_("Criterion"));
|
||||
CRITERION("Criterion");
|
||||
|
||||
private String name;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,27 +18,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.zkoss.ganttz;
|
||||
package org.zkoss.ganttz.resourceload;
|
||||
|
||||
import org.zkoss.zk.au.AuRequest;
|
||||
import org.zkoss.zk.au.Command;
|
||||
public interface IPaginationFilterChangedListener {
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francisco Javier Moran Rúa
|
||||
*
|
||||
*/
|
||||
public class TaskAssignmentMoveCommand extends Command {
|
||||
|
||||
public TaskAssignmentMoveCommand(String event,int flags) {
|
||||
super(event,flags);
|
||||
}
|
||||
|
||||
protected void process(AuRequest request) {
|
||||
|
||||
System.out.println("Processing command");
|
||||
|
||||
|
||||
}
|
||||
public void filterChanged(int initialPosition);
|
||||
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ import org.zkoss.zk.au.out.AuInvoke;
|
|||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.HtmlMacroComponent;
|
||||
import org.zkoss.zk.ui.ext.AfterCompose;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
|
||||
/**
|
||||
* Component to include a list of ResourceLoads inside the ResourcesLoadPanel.
|
||||
|
|
@ -98,6 +99,8 @@ public class ResourceLoadList extends HtmlMacroComponent implements
|
|||
for (LoadTimeLine l : line.getAllChildren()) {
|
||||
getComponentFor(l).detach();
|
||||
}
|
||||
Clients
|
||||
.evalJavaScript("zkResourcesLoadList.recalculateTimetrackerHeight();");
|
||||
}
|
||||
|
||||
private ResourceLoadComponent getComponentFor(LoadTimeLine l) {
|
||||
|
|
@ -118,7 +121,8 @@ public class ResourceLoadList extends HtmlMacroComponent implements
|
|||
insertBefore(child, nextSibling);
|
||||
nextSibling = child;
|
||||
}
|
||||
|
||||
Clients
|
||||
.evalJavaScript("zkResourcesLoadList.recalculateTimetrackerHeight();");
|
||||
}
|
||||
|
||||
private List<LoadTimeLine> getChildrenReverseOrderFor(LoadTimeLine line) {
|
||||
|
|
|
|||
|
|
@ -82,15 +82,16 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
private Listbox listZoomLevels;
|
||||
|
||||
private static final String filterResources = _("by resources");
|
||||
private static final String filterCriterions = _("by criterions");
|
||||
private static final String filterCriteria = _("by criteria");
|
||||
private String feedBackMessage;
|
||||
private Boolean filterbyResources;
|
||||
|
||||
private boolean refreshNameFilter = true;
|
||||
private int filterByNamePosition = 0;
|
||||
private int numberOfGroupsByName = 10;
|
||||
private PaginationType paginationType;
|
||||
|
||||
private WeakReferencedListeners<IFilterChangedListener> nameFilterListener =
|
||||
private WeakReferencedListeners<IPaginationFilterChangedListener> nameFilterListener =
|
||||
WeakReferencedListeners.create();
|
||||
|
||||
private Component loadChart;
|
||||
|
|
@ -104,9 +105,10 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
|
||||
public ResourcesLoadPanel(List<LoadTimeLine> groups,
|
||||
TimeTracker timeTracker, Component componentOnWhichGiveFeedback,
|
||||
boolean expandResourceLoadViewCharts) {
|
||||
boolean expandResourceLoadViewCharts, PaginationType paginationType) {
|
||||
this.componentOnWhichGiveFeedback = componentOnWhichGiveFeedback;
|
||||
this.expandResourceLoadViewCharts = expandResourceLoadViewCharts;
|
||||
this.paginationType = paginationType;
|
||||
init(groups, timeTracker);
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +124,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
}
|
||||
|
||||
public ListModel getFilters() {
|
||||
String[] filters = new String[] { filterResources, filterCriterions };
|
||||
String[] filters = new String[] { filterResources, filterCriteria };
|
||||
return new SimpleListModel(filters);
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +134,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
this.feedBackMessage = _("showing resources");
|
||||
} else {
|
||||
this.filterbyResources = false;
|
||||
this.feedBackMessage = _("showing criterions");
|
||||
this.feedBackMessage = _("showing criteria");
|
||||
}
|
||||
refreshNameFilter = true;
|
||||
filterByNamePosition = 0;
|
||||
|
|
@ -178,7 +180,10 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
}
|
||||
|
||||
public ListModel getZoomLevels() {
|
||||
return new SimpleListModel(ZoomLevel.values());
|
||||
ZoomLevel[] selectableZoomlevels = { ZoomLevel.DETAIL_ONE,
|
||||
ZoomLevel.DETAIL_TWO, ZoomLevel.DETAIL_THREE,
|
||||
ZoomLevel.DETAIL_FOUR, ZoomLevel.DETAIL_FIVE };
|
||||
return new SimpleListModel(selectableZoomlevels);
|
||||
}
|
||||
|
||||
public void setZoomLevel(final ZoomLevel zoomLevel) {
|
||||
|
|
@ -311,9 +316,13 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
listZoomLevels = (Listbox) getFellow("listZoomLevels");
|
||||
listZoomLevels.setSelectedIndex(timeTracker.getDetailLevel().ordinal());
|
||||
|
||||
if(refreshNameFilter) {
|
||||
if(paginationType == PaginationType.INTERNAL_PAGINATION && refreshNameFilter) {
|
||||
setupNameFilter();
|
||||
}
|
||||
else if(paginationType == PaginationType.NONE) {
|
||||
getFellow("filterByNameCombo").setVisible(false);
|
||||
getFellow("filterByNameLabel").setVisible(false);
|
||||
}
|
||||
|
||||
getFellow("insertionPointChart").appendChild(loadChart);
|
||||
|
||||
|
|
@ -389,7 +398,8 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
* @return
|
||||
*/
|
||||
private List<LoadTimeLine> getGroupsToShow() {
|
||||
if(filterByNamePosition == -1) {
|
||||
if(paginationType != PaginationType.INTERNAL_PAGINATION ||
|
||||
filterByNamePosition == -1) {
|
||||
return groups;
|
||||
}
|
||||
int endPosition =
|
||||
|
|
@ -400,9 +410,11 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
}
|
||||
|
||||
public void onSelectFilterByName(Integer filterByNamePosition) {
|
||||
if(paginationType != PaginationType.NONE) {
|
||||
this.filterByNamePosition = filterByNamePosition.intValue();
|
||||
this.feedBackMessage = _("filtering by name");
|
||||
changeNameFilterWithFeedback();
|
||||
}
|
||||
}
|
||||
|
||||
private void changeNameFilterWithFeedback() {
|
||||
|
|
@ -411,15 +423,18 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
|
||||
@Override
|
||||
public void doAction() throws Exception {
|
||||
treeModel = createModelForTree();
|
||||
timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker);
|
||||
resourceLoadList = new ResourceLoadList(timeTracker, treeModel);
|
||||
leftPane = new ResourceLoadLeftPane(treeModel, resourceLoadList);
|
||||
registerNeededScripts();
|
||||
nameFilterListener.fireEvent(new IListenerNotification<IFilterChangedListener>() {
|
||||
if(paginationType == PaginationType.INTERNAL_PAGINATION) {
|
||||
//if the pagination is internal, we are in charge of repainting the graph
|
||||
treeModel = createModelForTree();
|
||||
timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker);
|
||||
resourceLoadList = new ResourceLoadList(timeTracker, treeModel);
|
||||
leftPane = new ResourceLoadLeftPane(treeModel, resourceLoadList);
|
||||
registerNeededScripts();
|
||||
}
|
||||
nameFilterListener.fireEvent(new IListenerNotification<IPaginationFilterChangedListener>() {
|
||||
@Override
|
||||
public void doNotify(IFilterChangedListener listener) {
|
||||
listener.filterChanged(getFilter());
|
||||
public void doNotify(IPaginationFilterChangedListener listener) {
|
||||
listener.filterChanged(filterByNamePosition);
|
||||
}
|
||||
});
|
||||
afterCompose();
|
||||
|
|
@ -432,7 +447,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
});
|
||||
}
|
||||
|
||||
public void setNameFilterDisabled(boolean disabled) {
|
||||
public void setInternalPaginationDisabled(boolean disabled) {
|
||||
Combobox combo = ((Combobox) getFellow("filterByNameCombo"));
|
||||
if(combo.isDisabled() != disabled) {
|
||||
filterByNamePosition = disabled? -1 :
|
||||
|
|
@ -442,7 +457,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
}
|
||||
|
||||
public void addNameFilterListener(
|
||||
IFilterChangedListener iFilterChangedListener) {
|
||||
IPaginationFilterChangedListener iFilterChangedListener) {
|
||||
nameFilterListener.addListener(iFilterChangedListener);
|
||||
}
|
||||
|
||||
|
|
@ -471,4 +486,32 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
this.loadChart = loadChart;
|
||||
}
|
||||
|
||||
public int getPaginationFilterPageSize() {
|
||||
return numberOfGroupsByName;
|
||||
}
|
||||
|
||||
public Combobox getPaginationFilterCombobox() {
|
||||
if(paginationType == PaginationType.EXTERNAL_PAGINATION) {
|
||||
return (Combobox) getFellow("filterByNameCombo");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum PaginationType {
|
||||
/**
|
||||
* Sets the widget to take care of the pagination of all the LoadTimeLine objects received.
|
||||
*/
|
||||
INTERNAL_PAGINATION,
|
||||
/**
|
||||
* The widget will only show the combo box but its content has to be configured externally.
|
||||
* The pagination has to be managed externally too: the widget will show all the LoadTimeLine
|
||||
* objects received.
|
||||
*/
|
||||
EXTERNAL_PAGINATION,
|
||||
/**
|
||||
* Disables pagination. Shows all the LoadTimeLine objects received.
|
||||
*/
|
||||
NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -55,6 +55,10 @@ public class TimeTracker {
|
|||
public Collection<DetailItem> selectsSecondLevel(
|
||||
Collection<DetailItem> secondLevelDetails);
|
||||
|
||||
public Interval getCurrentPaginationInterval();
|
||||
|
||||
public void resetInterval();
|
||||
|
||||
}
|
||||
|
||||
private ZoomLevel detailLevel = ZoomLevel.DETAIL_ONE;
|
||||
|
|
@ -80,6 +84,10 @@ public class TimeTracker {
|
|||
|
||||
private IDetailItemFilter filter = null;
|
||||
|
||||
public IDetailItemFilter getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public TimeTracker(Interval interval, ZoomLevel zoomLevel, Component parent) {
|
||||
this(interval, zoomLevel, SeveralModificators.empty(),
|
||||
SeveralModificators.empty(), parent);
|
||||
|
|
@ -115,6 +123,7 @@ public class TimeTracker {
|
|||
|
||||
public void setFilter(IDetailItemFilter filter) {
|
||||
this.filter = filter;
|
||||
datesMapper = null;
|
||||
}
|
||||
|
||||
public ZoomLevel getDetailLevel() {
|
||||
|
|
@ -194,10 +203,20 @@ public class TimeTracker {
|
|||
realIntervalCached = null;
|
||||
}
|
||||
|
||||
public void resetMapper() {
|
||||
datesMapper = null;
|
||||
realIntervalCached = null;
|
||||
}
|
||||
|
||||
public IDatesMapper getMapper() {
|
||||
if (datesMapper == null) {
|
||||
datesMapper = new DatesMapperOnInterval(getHorizontalSize(),
|
||||
getRealInterval());
|
||||
if (filter == null) {
|
||||
datesMapper = new DatesMapperOnInterval(getHorizontalSize(),
|
||||
getRealInterval());
|
||||
} else {
|
||||
datesMapper = new DatesMapperOnInterval(getHorizontalSize(),
|
||||
filter.getCurrentPaginationInterval());
|
||||
}
|
||||
}
|
||||
return datesMapper;
|
||||
}
|
||||
|
|
@ -306,7 +325,12 @@ public class TimeTracker {
|
|||
|
||||
private Date startMinusTwoWeeks(Task task) {
|
||||
// the deadline could be before the start
|
||||
return new LocalDate(min(task.getBeginDate(), task.getDeadline()))
|
||||
.minusWeeks(2).toDateMidnight().toDate();
|
||||
Date start = min(task.getBeginDate(), task.getDeadline());
|
||||
// the last consolidated value could be before the start
|
||||
if (task.getConsolidatedline() != null) {
|
||||
start = min(start, task.getConsolidatedline());
|
||||
}
|
||||
return new LocalDate(start).minusWeeks(2).toDateMidnight().toDate();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,13 +57,19 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent {
|
|||
|
||||
@Override
|
||||
public void zoomLevelChanged(ZoomLevel detailLevel) {
|
||||
recreate();
|
||||
if (isInPage()) {
|
||||
recreate();
|
||||
}
|
||||
}
|
||||
};
|
||||
this.timeTracker.addZoomListener(zoomListener);
|
||||
timeTrackerElementId = timetrackerId;
|
||||
}
|
||||
|
||||
private boolean isInPage() {
|
||||
return getPage() != null;
|
||||
}
|
||||
|
||||
public int getHorizontalSizePixels() {
|
||||
return timeTracker.getHorizontalSize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.zkoss.ganttz.timetracker.zoom;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.ReadablePeriod;
|
||||
|
||||
/**
|
||||
* Zoom level for weeks in the first level and days in the second level
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class DetailSixTimeTrackerState extends TimeTrackerStateUsingJodaTime {
|
||||
|
||||
private static final int NUMBER_OF_DAYS_MINIMUM = 50;
|
||||
public static final int FIRST_LEVEL_SIZE = 672;
|
||||
public static final int SECOND_LEVEL_SIZE = 96;
|
||||
|
||||
DetailSixTimeTrackerState(IDetailItemModificator firstLevelModificator,
|
||||
IDetailItemModificator secondLevelModificator) {
|
||||
super(firstLevelModificator, secondLevelModificator);
|
||||
}
|
||||
|
||||
public final double daysPerPixel() {
|
||||
return ((double) 1 / SECOND_LEVEL_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDetailItemCreator getDetailItemCreatorFirstLevel() {
|
||||
return new IDetailItemCreator() {
|
||||
|
||||
@Override
|
||||
public DetailItem create(DateTime dateTime) {
|
||||
return new DetailItem(FIRST_LEVEL_SIZE, dateTime
|
||||
.getWeekOfWeekyear()
|
||||
+ dateTime.toString(", MMM YYYY"), dateTime, dateTime
|
||||
.plusDays(7));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDetailItemCreator getDetailItemCreatorSecondLevel() {
|
||||
return new IDetailItemCreator() {
|
||||
|
||||
@Override
|
||||
public DetailItem create(DateTime dateTime) {
|
||||
return new DetailItem(SECOND_LEVEL_SIZE, dateTime
|
||||
.getDayOfMonth()
|
||||
+ "", dateTime, dateTime.plusDays(1));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadablePeriod getPeriodFirstLevel() {
|
||||
return Days.days(7);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadablePeriod getPeriodSecondLevel() {
|
||||
return Days.days(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LocalDate round(LocalDate date, boolean down) {
|
||||
int dayOfWeek = date.getDayOfWeek();
|
||||
if (dayOfWeek == 1) {
|
||||
return date;
|
||||
}
|
||||
return down ? date.withDayOfWeek(1) : date.withDayOfWeek(1)
|
||||
.plusWeeks(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Days getMinimumPeriod() {
|
||||
return Days.days(NUMBER_OF_DAYS_MINIMUM);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ZoomLevel getZoomLevel() {
|
||||
return ZoomLevel.DETAIL_FIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSecondLevelSize() {
|
||||
return SECOND_LEVEL_SIZE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -89,6 +89,19 @@ public enum ZoomLevel {
|
|||
return new DetailFiveTimeTrackerState(firstLevel, secondLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuitableFor(int days) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
DETAIL_SIX(_("Hour")) {
|
||||
@Override
|
||||
public TimeTrackerState getTimeTrackerState(
|
||||
IDetailItemModificator firstLevel,
|
||||
IDetailItemModificator secondLevel) {
|
||||
return new DetailSixTimeTrackerState(firstLevel, secondLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuitableFor(int days) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ public class Interval {
|
|||
|
||||
public double getProportion(Date date) {
|
||||
if (!isIncluded(date)) {
|
||||
throw new IllegalArgumentException("date " + date
|
||||
+ " must be between [" + start + "," + finish + "]");
|
||||
// Negative proportions are allowed for tasks starting before
|
||||
// interval so no exception raised
|
||||
}
|
||||
return ((double) date.getTime() - start.getTime()) / lengthBetween;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-03-08 19:27+0100\n"
|
||||
"PO-Revision-Date: 2010-03-02 14:13+0100\n"
|
||||
"POT-Creation-Date: 2010-05-17 02:07+0200\n"
|
||||
"PO-Revision-Date: 2010-05-17 02:15+0200\n"
|
||||
"Last-Translator: Jacobo Aragunde Pérez <jaragunde@igalia.com>\n"
|
||||
"Language-Team: Spanish <>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -21,18 +21,103 @@ msgstr ""
|
|||
msgid "Erase"
|
||||
msgstr "Borrar"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:106
|
||||
msgid "0% - 100%"
|
||||
msgstr "0% - 100%"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:303
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:297
|
||||
msgid "Add Dependency"
|
||||
msgstr "Añadir dependencia"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Worker"
|
||||
msgstr "Trabajador"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:28
|
||||
msgid "Start"
|
||||
msgstr "Inicio"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:85
|
||||
msgid "by criteria"
|
||||
msgstr "por criterios"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:35
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:21
|
||||
msgid "Zoom"
|
||||
msgstr "Zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Order"
|
||||
msgstr "Pedido"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:214
|
||||
msgid "Set End-End"
|
||||
msgstr "Asignar Fin-Fin"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Task"
|
||||
msgstr "Tarea"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:84
|
||||
msgid "by resources"
|
||||
msgstr "por recursos"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:64
|
||||
msgid "Criterion"
|
||||
msgstr "Criterio"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:17
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
|
||||
msgid "Week"
|
||||
msgstr "Semana"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:404
|
||||
msgid "filtering by name"
|
||||
msgstr "filtrando por nombre"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java:108
|
||||
msgid "See scheduling"
|
||||
msgstr "Ver planificación"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
|
||||
msgid "End"
|
||||
msgstr "Fin"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:221
|
||||
msgid "changing zoom"
|
||||
msgstr "cambiando zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
|
||||
msgid "Quarter"
|
||||
msgstr "Cuarto"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:41
|
||||
msgid "Flatten/Unflatten tree"
|
||||
msgstr "Aplanar/expandir árbol"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:43
|
||||
msgid "Filter"
|
||||
msgstr "Filtro"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:49
|
||||
msgid "Name filter"
|
||||
msgstr "Filtro por nombres"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:27
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:37
|
||||
msgid "Expand/Collapse all"
|
||||
msgstr "Expandir/plegar todo"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:135
|
||||
msgid "showing criteria"
|
||||
msgstr "mostrando criterios"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
|
||||
msgid "Year"
|
||||
msgstr "Año"
|
||||
|
|
@ -45,31 +130,18 @@ msgstr "Mes"
|
|||
msgid "Show/Hide resources"
|
||||
msgstr "Mostrar/ocultar recursos"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:35
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:21
|
||||
msgid "Zoom"
|
||||
msgstr "Zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:206
|
||||
msgid "Set End-Start"
|
||||
msgstr "Asignar Fin-Inicio"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:214
|
||||
msgid "Set End-End"
|
||||
msgstr "Asignar Fin-Fin"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:232
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:245
|
||||
msgid "decreasing zoom"
|
||||
msgstr "reduciendo zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:443
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:479
|
||||
msgid "Hide critical path"
|
||||
msgstr "Ocultar camino crítico"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:116
|
||||
msgid "+ 100%"
|
||||
msgstr "+ 100%"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:84
|
||||
msgid "Day"
|
||||
msgstr "Día"
|
||||
|
|
@ -78,52 +150,57 @@ msgstr "Día"
|
|||
msgid "Show/Hide Critical path"
|
||||
msgstr "Mostrar/ocultar camino crítico"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:111
|
||||
msgid "100%"
|
||||
msgstr "100%"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:132
|
||||
msgid "showing resources"
|
||||
msgstr "mostrando recursos"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:31
|
||||
msgid "Show/Hide labels"
|
||||
msgstr "Mostrar/ocultar etiquetas"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:17
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:101
|
||||
msgid "Assignation percentage"
|
||||
msgstr "Porcentaje asignado"
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
|
||||
msgid "Graphics"
|
||||
msgstr "Gráficas"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:210
|
||||
msgid "Set Start-Start"
|
||||
msgstr "Definir Inicio-Inicio"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
|
||||
msgid "Week"
|
||||
msgstr "Semana"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:142
|
||||
msgid "See resource allocation"
|
||||
msgstr "Ver asignación de recursos"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:215
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:228
|
||||
msgid "increasing zoom"
|
||||
msgstr "aumentando zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:221
|
||||
msgid "changing zoom"
|
||||
msgstr "cambiando zoom"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:378
|
||||
msgid "Show all elements"
|
||||
msgstr "Mostrar todos los elementos"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
|
||||
msgid "Quarter"
|
||||
msgstr "Cuarto"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:377
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:14
|
||||
msgid "Refresh"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:438
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:474
|
||||
msgid "Show critical path"
|
||||
msgstr "Mostrar camino crítico"
|
||||
|
||||
#~ msgid "Filter"
|
||||
#~ msgstr "Filtro"
|
||||
#~ msgid "0% - 100%"
|
||||
#~ msgstr "0% - 100%"
|
||||
|
||||
#~ msgid "+ 100%"
|
||||
#~ msgstr "+ 100%"
|
||||
|
||||
#~ msgid "100%"
|
||||
#~ msgstr "100%"
|
||||
|
||||
#~ msgid "Assignation percentage"
|
||||
#~ msgstr "Porcentaje asignado"
|
||||
|
||||
#~ msgid "Critical path"
|
||||
#~ msgstr "Camino crítico"
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-03-08 19:27+0100\n"
|
||||
"PO-Revision-Date: 2010-03-02 14:13+0100\n"
|
||||
"POT-Creation-Date: 2010-05-17 02:07+0200\n"
|
||||
"PO-Revision-Date: 2010-05-17 02:15+0200\n"
|
||||
"Last-Translator: Jacobo Aragunde Pérez <jaragunde@igalia.com>\n"
|
||||
"Language-Team: Spanish <>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -21,18 +21,103 @@ msgstr ""
|
|||
msgid "Erase"
|
||||
msgstr "Borrar"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:106
|
||||
msgid "0% - 100%"
|
||||
msgstr "0% - 100%"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:303
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:297
|
||||
msgid "Add Dependency"
|
||||
msgstr "Engadir dependencia"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Worker"
|
||||
msgstr "Traballador"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:28
|
||||
msgid "Start"
|
||||
msgstr "Inicio"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:85
|
||||
msgid "by criteria"
|
||||
msgstr "por criterios"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:35
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:21
|
||||
msgid "Zoom"
|
||||
msgstr "Zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Order"
|
||||
msgstr "Pedido"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:214
|
||||
msgid "Set End-End"
|
||||
msgstr "Definir Fin-Fin"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Task"
|
||||
msgstr "Tarefa"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:84
|
||||
msgid "by resources"
|
||||
msgstr "por recursos"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:64
|
||||
msgid "Criterion"
|
||||
msgstr "Criterio"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:17
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
|
||||
msgid "Week"
|
||||
msgstr "Semana"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:404
|
||||
msgid "filtering by name"
|
||||
msgstr "filtrando por nome"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java:108
|
||||
msgid "See scheduling"
|
||||
msgstr "Ver planificación"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
|
||||
msgid "End"
|
||||
msgstr "Fin"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:221
|
||||
msgid "changing zoom"
|
||||
msgstr "cambiando zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
|
||||
msgid "Quarter"
|
||||
msgstr "Cuarto"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "None"
|
||||
msgstr "Ningún"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:41
|
||||
msgid "Flatten/Unflatten tree"
|
||||
msgstr "Aplanar/expandir árbore"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:43
|
||||
msgid "Filter"
|
||||
msgstr "Filtro"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:49
|
||||
msgid "Name filter"
|
||||
msgstr "Filtro por nomes"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:27
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:37
|
||||
msgid "Expand/Collapse all"
|
||||
msgstr "Expandir/pregar todo"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:135
|
||||
msgid "showing criteria"
|
||||
msgstr "mostrando criterios"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
|
||||
msgid "Year"
|
||||
msgstr "Ano"
|
||||
|
|
@ -45,31 +130,18 @@ msgstr "Mes"
|
|||
msgid "Show/Hide resources"
|
||||
msgstr "Mostrar/ocultar recursos"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:35
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:21
|
||||
msgid "Zoom"
|
||||
msgstr "Zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:206
|
||||
msgid "Set End-Start"
|
||||
msgstr "Definir Fin-Inicio"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:214
|
||||
msgid "Set End-End"
|
||||
msgstr "Definir Fin-Fin"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:232
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:245
|
||||
msgid "decreasing zoom"
|
||||
msgstr "reducindo zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:443
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:479
|
||||
msgid "Hide critical path"
|
||||
msgstr "Ocultar camiño crítico"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:116
|
||||
msgid "+ 100%"
|
||||
msgstr "+ 100%"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:84
|
||||
msgid "Day"
|
||||
msgstr "Día"
|
||||
|
|
@ -78,52 +150,57 @@ msgstr "Día"
|
|||
msgid "Show/Hide Critical path"
|
||||
msgstr "Ocultar/ocultar camiño crítico"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:111
|
||||
msgid "100%"
|
||||
msgstr "100%"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:132
|
||||
msgid "showing resources"
|
||||
msgstr "mostrando recursos"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:31
|
||||
msgid "Show/Hide labels"
|
||||
msgstr "Mostrar/ocultar etiquetas"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:17
|
||||
msgid "Print"
|
||||
msgstr "Imprimir"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:101
|
||||
msgid "Assignation percentage"
|
||||
msgstr "Porcentaxe asignado"
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
|
||||
msgid "Graphics"
|
||||
msgstr "Gráficas"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:210
|
||||
msgid "Set Start-Start"
|
||||
msgstr "Definir Inicio-Inicio"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
|
||||
msgid "Week"
|
||||
msgstr "Semana"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:142
|
||||
msgid "See resource allocation"
|
||||
msgstr "Ver asignación de recursoss"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:215
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:228
|
||||
msgid "increasing zoom"
|
||||
msgstr "aumentando zoom"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:221
|
||||
msgid "changing zoom"
|
||||
msgstr "cambiando zoom"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:378
|
||||
msgid "Show all elements"
|
||||
msgstr "Mostrar tódolos elementos"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
|
||||
msgid "Quarter"
|
||||
msgstr "Cuarto"
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:377
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:14
|
||||
msgid "Refresh"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:438
|
||||
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:474
|
||||
msgid "Show critical path"
|
||||
msgstr "Mostrar camiño crítico"
|
||||
|
||||
#~ msgid "Filter"
|
||||
#~ msgstr "Filtro"
|
||||
#~ msgid "0% - 100%"
|
||||
#~ msgstr "0% - 100%"
|
||||
|
||||
#~ msgid "+ 100%"
|
||||
#~ msgstr "+ 100%"
|
||||
|
||||
#~ msgid "100%"
|
||||
#~ msgstr "100%"
|
||||
|
||||
#~ msgid "Assignation percentage"
|
||||
#~ msgstr "Porcentaxe asignado"
|
||||
|
||||
#~ msgid "Critical path"
|
||||
#~ msgstr "Camiño crítico"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-03-08 19:27+0100\n"
|
||||
"POT-Creation-Date: 2010-05-17 02:07+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
@ -20,18 +20,103 @@ msgstr ""
|
|||
msgid "Erase"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:106
|
||||
msgid "0% - 100%"
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:297
|
||||
msgid "Add Dependency"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:303
|
||||
msgid "Add Dependency"
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Worker"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:28
|
||||
msgid "Start"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:85
|
||||
msgid "by criteria"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:35
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:21
|
||||
msgid "Zoom"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Order"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:214
|
||||
msgid "Set End-End"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "Task"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:84
|
||||
msgid "by resources"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:64
|
||||
msgid "Criterion"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:17
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
|
||||
msgid "Week"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:404
|
||||
msgid "filtering by name"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java:108
|
||||
msgid "See scheduling"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
|
||||
msgid "End"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:221
|
||||
msgid "changing zoom"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
|
||||
msgid "Quarter"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:41
|
||||
msgid "Flatten/Unflatten tree"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:43
|
||||
msgid "Filter"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:49
|
||||
msgid "Name filter"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:27
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:37
|
||||
msgid "Expand/Collapse all"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:135
|
||||
msgid "showing criteria"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
|
||||
msgid "Year"
|
||||
msgstr ""
|
||||
|
|
@ -44,31 +129,18 @@ msgstr ""
|
|||
msgid "Show/Hide resources"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:35
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:21
|
||||
msgid "Zoom"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:206
|
||||
msgid "Set End-Start"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:214
|
||||
msgid "Set End-End"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:232
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:245
|
||||
msgid "decreasing zoom"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:443
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:479
|
||||
msgid "Hide critical path"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:116
|
||||
msgid "+ 100%"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:84
|
||||
msgid "Day"
|
||||
msgstr ""
|
||||
|
|
@ -77,46 +149,42 @@ msgstr ""
|
|||
msgid "Show/Hide Critical path"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:111
|
||||
msgid "100%"
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:132
|
||||
msgid "showing resources"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:31
|
||||
msgid "Show/Hide labels"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:17
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:101
|
||||
msgid "Assignation percentage"
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
|
||||
msgid "Graphics"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:210
|
||||
msgid "Set Start-Start"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
|
||||
msgid "Week"
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:142
|
||||
msgid "See resource allocation"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:215
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:228
|
||||
msgid "increasing zoom"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:221
|
||||
msgid "changing zoom"
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:378
|
||||
msgid "Show all elements"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
|
||||
msgid "Quarter"
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:377
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:14
|
||||
msgid "Refresh"
|
||||
msgstr ""
|
||||
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:438
|
||||
#: ./ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:474
|
||||
msgid "Show critical path"
|
||||
msgstr ""
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 287 B After Width: | Height: | Size: 223 B |
BIN
ganttzk/src/main/resources/web/ganttz/img/deadline_green.png
Normal file
BIN
ganttzk/src/main/resources/web/ganttz/img/deadline_green.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 263 B |
BIN
ganttzk/src/main/resources/web/ganttz/img/deadline_red.png
Normal file
BIN
ganttzk/src/main/resources/web/ganttz/img/deadline_red.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 287 B |
|
|
@ -8,4 +8,5 @@
|
|||
${z:redraw(child, null)}
|
||||
</c:forEach>
|
||||
<div id="deadline${self.uuid}" class="deadline"></div>
|
||||
<div id="consolidatedline${self.uuid}" class="consolidatedline"></div>
|
||||
</div>
|
||||
|
|
@ -17,12 +17,16 @@
|
|||
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/>.
|
||||
-->
|
||||
|
||||
<?xel-method prefix="i18n" name="_" class="org.zkoss.ganttz.i18n.I18nHelper"
|
||||
signature="java.lang.String _(java.lang.String name)" ?>
|
||||
|
||||
<div>
|
||||
<tree id="tasksTree" fixedLayout="true" sclass="taskTreeCols">
|
||||
<treecols sizable="false" >
|
||||
<treecol label="Name" sclass="tree-text" height="32px" />
|
||||
<treecol label="Start" width="76px" />
|
||||
<treecol label="End" width="76px" />
|
||||
<treecol label="${i18n:_('Name')}" sclass="tree-text" height="32px" />
|
||||
<treecol label="${i18n:_('Start')}" width="76px" />
|
||||
<treecol label="${i18n:_('End')}" width="76px" />
|
||||
</treecols>
|
||||
</tree>
|
||||
</div>
|
||||
|
|
@ -40,13 +40,13 @@ resourcesLoadPanel = self;
|
|||
<separator/>
|
||||
<hbox id="additionalFilterInsertionPoint1" />
|
||||
<separator/>
|
||||
Filter:
|
||||
${i18n:_('Filter')}:
|
||||
<listbox id="listFilters" mold="select" rows="1" width="100px"
|
||||
model="${resourcesLoadPanel.filters}"
|
||||
onSelect="resourcesLoadPanel.setFilter(self.selectedItem.value);">
|
||||
</listbox>
|
||||
<separator/>
|
||||
${i18n:_('Name filter')}:
|
||||
<label id="filterByNameLabel">${i18n:_('Name filter')}:</label>
|
||||
<combobox id="filterByNameCombo" width="50px"
|
||||
onChange="resourcesLoadPanel.onSelectFilterByName(self.selectedItemApi.value)" />
|
||||
<separator/>
|
||||
|
|
@ -60,11 +60,11 @@ resourcesLoadPanel = self;
|
|||
splittable="true" autoscroll="true">
|
||||
|
||||
<borderlayout >
|
||||
<north border="0" height="38px" flex="true" collapsible="true">
|
||||
<north border="0" height="35px" flex="true" collapsible="true">
|
||||
<vbox pack="top" align="center">
|
||||
<tree fixedLayout="true">
|
||||
<treecols>
|
||||
<treecol label="Name" height="29px"/>
|
||||
<treecol label="${i18n:_('Name')}" height="29px"/>
|
||||
</treecols>
|
||||
</tree>
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ resourcesLoadPanel = self;
|
|||
|
||||
<center sclass="taskspanel">
|
||||
<borderlayout>
|
||||
<north border="0"><div sclass="timetrackergap" height="33px" id="insertionPointTimetracker"></div></north>
|
||||
<north border="0"><div sclass="timetrackergap" height="30px" id="insertionPointTimetracker"></div></north>
|
||||
<center autoscroll="true" border="0" sclass="rightpanellayout">
|
||||
<div id="insertionPointRightPanel" sclass="taskspanelgap"></div>
|
||||
</center>
|
||||
|
|
@ -87,7 +87,7 @@ resourcesLoadPanel = self;
|
|||
</center>
|
||||
</borderlayout>
|
||||
</center>
|
||||
<south height="200px" collapsible="true" title="Graphics"
|
||||
<south height="200px" collapsible="true" title="${i18n:_('Graphics')}"
|
||||
sclass="scheduling-graphics" id="graphics"
|
||||
onOpen="resourcesLoadPanel.changeChartVisibility(event.open);">
|
||||
<div id="insertionPointChart" />
|
||||
|
|
|
|||
|
|
@ -20,6 +20,28 @@
|
|||
|
||||
zkResourcesLoadList = addResourcesLoadListMethods( {});
|
||||
|
||||
zkResourcesLoadList.WATERMARK_MIN_HEIGHT = 450;
|
||||
zkResourcesLoadList.WATERMARK_MARGIN_BOTTOM = 40;
|
||||
|
||||
|
||||
zkResourcesLoadList.recalculateTimetrackerHeight = function (cmp) {
|
||||
|
||||
zkResourcesLoadList.resourceloadlist = function(elem) {
|
||||
return YAHOO.util.Selector.query('.resourceloadlist')[0];
|
||||
}
|
||||
|
||||
zkResourcesLoadList.firstWatermarkColumn = function(elem) {
|
||||
return YAHOO.util.Selector.query('.rightpanellayout tr#watermark td')[0];
|
||||
}
|
||||
|
||||
if (zkResourcesLoadList.resourceloadlist() != undefined && zkResourcesLoadList.firstWatermarkColumn() != undefined) {
|
||||
var height = Math.max(
|
||||
zkResourcesLoadList.resourceloadlist().clientHeight + zkResourcesLoadList.WATERMARK_MARGIN_BOTTOM,
|
||||
zkResourcesLoadList.WATERMARK_MIN_HEIGHT);
|
||||
zkResourcesLoadList.firstWatermarkColumn().style.height = height + "px";
|
||||
}
|
||||
}
|
||||
|
||||
function addResourcesLoadListMethods(object) {
|
||||
var scrollSync;
|
||||
|
||||
|
|
@ -65,12 +87,10 @@ function addResourcesLoadListMethods(object) {
|
|||
zkResourcesLoadList.adjustTimeTrackerSize, cmp);
|
||||
scrollSync = new ScrollSync(cmp);
|
||||
scrollSync.synchXChangeTo(timetracker);
|
||||
|
||||
listenToScroll();
|
||||
};
|
||||
|
||||
function listenToScroll() {
|
||||
|
||||
var timetrackergap_ = timetrackergap();
|
||||
var scrolledpannel_ = scrolledpannel();
|
||||
var resourcesloadgraph_ = resourcesloadgraph();
|
||||
|
|
@ -80,6 +100,7 @@ function addResourcesLoadListMethods(object) {
|
|||
var onScroll = function() {
|
||||
var timeplotcontainer_ = YAHOO.util.Selector.query('canvas.timeplot-canvas')[0];
|
||||
timeplotcontainer_.style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
|
||||
timetrackergap_.style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
|
||||
leftpanel_.style["top"] = "-" + scrolledpannel_.scrollTop + "px";
|
||||
resourcesloadgraph_.scrollLeft = scrolledpannel_.scrollLeft;
|
||||
};
|
||||
|
|
@ -87,17 +108,14 @@ function addResourcesLoadListMethods(object) {
|
|||
rightpanel_.onscroll = onScroll;
|
||||
}
|
||||
|
||||
|
||||
object.adjustTimeTrackerSize = function(cmp) {
|
||||
zkResourcesLoadList.recalculateTimetrackerHeight();
|
||||
watermark().style["height"] = cmp.clientHeight + "px";
|
||||
timetracker().style["width"] = cmp.clientWidth + "px";
|
||||
/* Set watermark width */
|
||||
YAHOO.util.Selector.query('.resourceloadlist')[0].style["width"] = YAHOO.util.Selector
|
||||
.query('.second_level_')[0].clientWidth
|
||||
+ "px";
|
||||
YAHOO.util.Selector.query('.rightpanellayout tr#watermark td')[0].style["height"] =
|
||||
/* Calculate min : taskspanelgap().clientHeight + 120 + 'px'; ) */
|
||||
YAHOO.util.Selector.query('.resourceloadlist')[0].clientHeight + 120
|
||||
+ "px";
|
||||
.query('.second_level_')[0].clientWidth + "px";
|
||||
};
|
||||
|
||||
object.adjustResourceLoadRows = function(cmp) {
|
||||
|
|
|
|||
|
|
@ -407,6 +407,20 @@ zkTask.setAttr = function(cmp, name, val) {
|
|||
}
|
||||
};
|
||||
|
||||
zkTask.setAttr = function(cmp, name, val) {
|
||||
switch (name) {
|
||||
case "taskTooltipText":{
|
||||
var taskTooltipTextElement = YAHOO.util.Selector.query(
|
||||
'.task_tooltip', cmp, true);
|
||||
taskTooltipTextElement.innerHTML = val;
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
zkTask.addDependency = function(cmp) {
|
||||
zkTask.createArrow(cmp);
|
||||
};
|
||||
|
|
@ -567,11 +581,19 @@ zkTask.getElementsByAttribute = function(oElm, strTagName, strAttributeName,
|
|||
return arrReturnElements;
|
||||
}
|
||||
|
||||
|
||||
zkTask.moveDeadline = function(cmp, width) {
|
||||
var deadlineDiv = zkTask.next(cmp);
|
||||
deadlineDiv["style"].left = width;
|
||||
}
|
||||
|
||||
zkTask.moveConsolidatedline = function(cmp, width) {
|
||||
var deadlineDiv = zkTask.next(cmp);
|
||||
var consolidatedlineDiv = zkTask.next(deadlineDiv);
|
||||
consolidatedlineDiv["style"].left = width;
|
||||
}
|
||||
|
||||
|
||||
zkTask.resizeCompletionAdvance = function(cmp, width) {
|
||||
var completionDiv = YAHOO.util.Selector.query('.completion', cmp, true);
|
||||
completionDiv["style"].width = width;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ public abstract class AdvanceAssignment extends BaseEntity {
|
|||
|
||||
public void setReportGlobalAdvance(boolean reportGlobalAdvance) {
|
||||
this.reportGlobalAdvance = reportGlobalAdvance;
|
||||
if (this.orderElement != null) {
|
||||
this.orderElement.markAsDirtyLastAdvanceMeasurementForSpreading();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getReportGlobalAdvance() {
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ public class AdvanceMeasurement extends BaseEntity {
|
|||
this.value.setScale(2, BigDecimal.ROUND_DOWN);
|
||||
}
|
||||
resetCommunicationDate();
|
||||
if (advanceAssignment != null) {
|
||||
advanceAssignment.getOrderElement()
|
||||
.markAsDirtyLastAdvanceMeasurementForSpreading();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull(message = "value not specified")
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
|
|||
}
|
||||
|
||||
public AdvanceMeasurement getLastAdvanceMeasurement() {
|
||||
|
||||
if (advanceMeasurements.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -136,13 +137,14 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
|
|||
if (advanceMeasurement == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return advanceMeasurement.getValue().setScale(2).divide(maxValue,
|
||||
return advanceMeasurement.getValue().divide(maxValue, 2,
|
||||
RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
public void addAdvanceMeasurements(AdvanceMeasurement advanceMeasurement) {
|
||||
this.advanceMeasurements.add(advanceMeasurement);
|
||||
advanceMeasurement.setAdvanceAssignment(this);
|
||||
getOrderElement().markAsDirtyLastAdvanceMeasurementForSpreading();
|
||||
}
|
||||
|
||||
public AdvanceMeasurement getAdvanceMeasurementAtExactDate(LocalDate date) {
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ public class ProportionalDistributor {
|
|||
}
|
||||
|
||||
public int[] distribute(final int total) {
|
||||
if (proportions.length == 0) {
|
||||
return new int[0];
|
||||
}
|
||||
int[] result = new int[proportions.length];
|
||||
int remaining = total - assignIntegerParts(total, result);
|
||||
if (remaining == 0) {
|
||||
|
|
@ -117,7 +120,8 @@ public class ProportionalDistributor {
|
|||
.transform(difference(currentProportions));
|
||||
Collections.sort(transform, Collections.reverseOrder());
|
||||
for (int i = 0; i < remaining; i++) {
|
||||
ProportionWithPosition proportionWithPosition = transform.get(i);
|
||||
ProportionWithPosition proportionWithPosition = transform.get(i
|
||||
% currentProportions.length);
|
||||
result[proportionWithPosition.position] = result[proportionWithPosition.position] + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,16 +55,12 @@ public class Order extends OrderLineGroup {
|
|||
public static Order create() {
|
||||
Order order = new Order();
|
||||
order.setNewObject(true);
|
||||
|
||||
OrderLineGroup.setupOrderLineGroup(order);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
public static Order createUnvalidated(String code) {
|
||||
Order order = create(new Order(), code);
|
||||
OrderLineGroup.setupOrderLineGroup(order);
|
||||
return order;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,10 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
|
||||
private OrderElementTemplate template;
|
||||
|
||||
private BigDecimal lastAdvanceMeausurementForSpreading = BigDecimal.ZERO;
|
||||
|
||||
private Boolean dirtyLastAdvanceMeasurementForSpreading = true;
|
||||
|
||||
public OrderElementTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
|
@ -502,9 +506,12 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
|
||||
public DirectAdvanceAssignment getDirectAdvanceAssignmentByType(
|
||||
AdvanceType advanceType) {
|
||||
for (DirectAdvanceAssignment directAdvanceAssignment : getDirectAdvanceAssignments()) {
|
||||
if (directAdvanceAssignment.getAdvanceType().equals(advanceType)) {
|
||||
if (advanceType != null) {
|
||||
for (DirectAdvanceAssignment directAdvanceAssignment : getDirectAdvanceAssignments()) {
|
||||
if (directAdvanceAssignment.getAdvanceType().getId().equals(
|
||||
advanceType.getId())) {
|
||||
return directAdvanceAssignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
@ -532,6 +539,7 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
if (this.getParent() != null) {
|
||||
this.getParent().removeIndirectAdvanceAssignment(
|
||||
advanceAssignment.getAdvanceType());
|
||||
removeChildrenAdvanceInParents(this.getParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -584,11 +592,41 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
this.directAdvanceAssignments.add(newAdvanceAssignment);
|
||||
|
||||
if (this.getParent() != null) {
|
||||
addChildrenAdvanceInParents(this.getParent());
|
||||
this.getParent().addIndirectAdvanceAssignment(
|
||||
newAdvanceAssignment.createIndirectAdvanceFor(this.getParent()));
|
||||
}
|
||||
}
|
||||
|
||||
public void addChildrenAdvanceInParents(OrderLineGroup parent) {
|
||||
if ((parent != null) && (!parent.existChildrenAdvance())) {
|
||||
parent.addChildrenAdvanceOrderLineGroup();
|
||||
addChildrenAdvanceInParents(parent.getParent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeChildrenAdvanceInParents(OrderLineGroup parent) {
|
||||
if ((parent != null) && (parent.existChildrenAdvance())
|
||||
&& (!itsChildsHasAdvances(parent))) {
|
||||
parent.removeChildrenAdvanceOrderLineGroup();
|
||||
removeChildrenAdvanceInParents(parent.getParent());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean itsChildsHasAdvances(OrderElement orderElement) {
|
||||
for (OrderElement child : orderElement.getChildren()) {
|
||||
if ((!child.getIndirectAdvanceAssignments().isEmpty())
|
||||
|| (!child.getDirectAdvanceAssignments().isEmpty())) {
|
||||
return true;
|
||||
}
|
||||
if (itsChildsHasAdvances(child)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void checkNoOtherGlobalAdvanceAssignment(
|
||||
DirectAdvanceAssignment newAdvanceAssignment)
|
||||
throws DuplicateValueTrueReportGlobalAdvanceException {
|
||||
|
|
@ -616,7 +654,9 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
OrderElement orderElement,
|
||||
DirectAdvanceAssignment newAdvanceAssignment)
|
||||
throws DuplicateAdvanceAssignmentForOrderElementException {
|
||||
for (DirectAdvanceAssignment directAdvanceAssignment : orderElement.directAdvanceAssignments) {
|
||||
for (DirectAdvanceAssignment directAdvanceAssignment : orderElement
|
||||
.getDirectAdvanceAssignments()) {
|
||||
|
||||
if (AdvanceType.equivalentInDB(directAdvanceAssignment
|
||||
.getAdvanceType(), newAdvanceAssignment.getAdvanceType())) {
|
||||
throw new DuplicateAdvanceAssignmentForOrderElementException(
|
||||
|
|
@ -642,7 +682,8 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
OrderElement orderElement,
|
||||
DirectAdvanceAssignment newAdvanceAssignment)
|
||||
throws DuplicateAdvanceAssignmentForOrderElementException {
|
||||
for (DirectAdvanceAssignment directAdvanceAssignment : orderElement.directAdvanceAssignments) {
|
||||
for (DirectAdvanceAssignment directAdvanceAssignment : orderElement
|
||||
.getDirectAdvanceAssignments()) {
|
||||
if (AdvanceType.equivalentInDB(directAdvanceAssignment
|
||||
.getAdvanceType(), newAdvanceAssignment.getAdvanceType())) {
|
||||
throw new DuplicateAdvanceAssignmentForOrderElementException(
|
||||
|
|
@ -660,13 +701,23 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
}
|
||||
|
||||
public BigDecimal getAdvancePercentage() {
|
||||
return getAdvancePercentage(null);
|
||||
if ((dirtyLastAdvanceMeasurementForSpreading == null)
|
||||
|| dirtyLastAdvanceMeasurementForSpreading) {
|
||||
lastAdvanceMeausurementForSpreading = getAdvancePercentage(null);
|
||||
dirtyLastAdvanceMeasurementForSpreading = false;
|
||||
}
|
||||
return lastAdvanceMeausurementForSpreading;
|
||||
}
|
||||
|
||||
public abstract BigDecimal getAdvancePercentage(LocalDate date);
|
||||
|
||||
public abstract Set<IndirectAdvanceAssignment> getIndirectAdvanceAssignments();
|
||||
|
||||
public abstract DirectAdvanceAssignment calculateFakeDirectAdvanceAssignment(
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment);
|
||||
|
||||
public abstract BigDecimal getAdvancePercentageChildren();
|
||||
|
||||
public List<OrderElement> getAllChildren() {
|
||||
List<OrderElement> children = getChildren();
|
||||
List<OrderElement> result = new ArrayList<OrderElement>();
|
||||
|
|
@ -1196,4 +1247,12 @@ public abstract class OrderElement extends IntegrationEntity implements
|
|||
protected IIntegrationEntityDAO<OrderElement> getIntegrationEntityDAO() {
|
||||
return Registry.getOrderElementDAO();
|
||||
}
|
||||
|
||||
public void markAsDirtyLastAdvanceMeasurementForSpreading() {
|
||||
if (parent != null) {
|
||||
parent.markAsDirtyLastAdvanceMeasurementForSpreading();
|
||||
}
|
||||
dirtyLastAdvanceMeasurementForSpreading = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -321,6 +321,17 @@ public class OrderLine extends OrderElement {
|
|||
return OrderLineTemplate.create(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirectAdvanceAssignment calculateFakeDirectAdvanceAssignment(
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getAdvancePercentageChildren() {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<IndirectAdvanceAssignment> getIndirectAdvanceAssignments() {
|
||||
return Collections.emptySet();
|
||||
|
|
|
|||
|
|
@ -108,25 +108,69 @@ public class OrderLineGroup extends OrderElement implements
|
|||
public static OrderLineGroup create() {
|
||||
OrderLineGroup result = new OrderLineGroup();
|
||||
result.setNewObject(true);
|
||||
|
||||
setupOrderLineGroup(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static OrderLineGroup createUnvalidated(String code) {
|
||||
OrderLineGroup orderLineGroup = create(new OrderLineGroup(), code);
|
||||
setupOrderLineGroup(orderLineGroup);
|
||||
return orderLineGroup;
|
||||
}
|
||||
|
||||
protected static void setupOrderLineGroup(OrderLineGroup result) {
|
||||
public void addChildrenAdvanceOrderLineGroup() {
|
||||
boolean spread = (getReportGlobalAdvanceAssignment() == null);
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment = IndirectAdvanceAssignment
|
||||
.create(true);
|
||||
.create(spread);
|
||||
AdvanceType advanceType = PredefinedAdvancedTypes.CHILDREN.getType();
|
||||
indirectAdvanceAssignment.setAdvanceType(advanceType);
|
||||
indirectAdvanceAssignment.setOrderElement(result);
|
||||
result.addIndirectAdvanceAssignment(indirectAdvanceAssignment);
|
||||
indirectAdvanceAssignment.setOrderElement(this);
|
||||
addIndirectAdvanceAssignment(indirectAdvanceAssignment);
|
||||
}
|
||||
|
||||
public void removeChildrenAdvanceOrderLineGroup() {
|
||||
for (IndirectAdvanceAssignment advance : getIndirectAdvanceAssignments()) {
|
||||
if (advance.getAdvanceType().getUnitName().equals(
|
||||
PredefinedAdvancedTypes.CHILDREN.getTypeName())) {
|
||||
indirectAdvanceAssignments.remove(advance);
|
||||
updateSpreadAdvance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSpreadAdvance(){
|
||||
if(getReportGlobalAdvanceAssignment() == null){
|
||||
AdvanceType type = PredefinedAdvancedTypes.PERCENTAGE.getType();
|
||||
DirectAdvanceAssignment advancePercentage = getAdvanceAssignmentByType(type);
|
||||
if(advancePercentage != null) {
|
||||
if(advancePercentage.isFake()){
|
||||
for (IndirectAdvanceAssignment each : getIndirectAdvanceAssignments()) {
|
||||
if (type != null && each.getAdvanceType().getId().equals(type.getId())) {
|
||||
each.setReportGlobalAdvance(true);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
advancePercentage.setReportGlobalAdvance(true);
|
||||
}
|
||||
} else {
|
||||
for (DirectAdvanceAssignment advance : getDirectAdvanceAssignments()) {
|
||||
advance.setReportGlobalAdvance(true);
|
||||
return;
|
||||
}
|
||||
for (IndirectAdvanceAssignment advance : getIndirectAdvanceAssignments()) {
|
||||
advance.setReportGlobalAdvance(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean existChildrenAdvance() {
|
||||
for (IndirectAdvanceAssignment advance : getIndirectAdvanceAssignments()) {
|
||||
if (advance.getAdvanceType().getUnitName().equals(
|
||||
PredefinedAdvancedTypes.CHILDREN.getTypeName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<OrderElement> children = new ArrayList<OrderElement>();
|
||||
|
|
@ -301,6 +345,7 @@ public class OrderLineGroup extends OrderElement implements
|
|||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getAdvancePercentageChildren() {
|
||||
return getAdvancePercentageChildren(null);
|
||||
}
|
||||
|
|
@ -329,6 +374,7 @@ public class OrderLineGroup extends OrderElement implements
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirectAdvanceAssignment calculateFakeDirectAdvanceAssignment(
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment) {
|
||||
if (indirectAdvanceAssignment.getAdvanceType().getUnitName().equals(
|
||||
|
|
|
|||
|
|
@ -151,15 +151,19 @@ public class DayAssignmentDAO extends GenericDAOHibernate<DayAssignment, Long>
|
|||
|
||||
@Override
|
||||
public List<DayAssignment> findByResources(Scenario scenario, List<Resource> resources) {
|
||||
// TODO incorporate scenario filtering to the query instead of doing it
|
||||
// in memory
|
||||
return DayAssignment.withScenario(scenario, findByResources(resources));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DayAssignment> findByResources(List<Resource> resources) {
|
||||
if (resources.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Criteria criteria = getSession().createCriteria(DayAssignment.class)
|
||||
.add(Restrictions.in("resource", resources));
|
||||
List<DayAssignment> list = criteria.list();
|
||||
// TODO incorporate scenario filtering to the query instead of doing it
|
||||
// in memory
|
||||
return DayAssignment.withScenario(scenario, list);
|
||||
return (List<DayAssignment>) criteria.list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import java.util.List;
|
|||
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.planner.entities.Dependency;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueDependency;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
|
|
|||
|
|
@ -50,4 +50,6 @@ public interface IDayAssignmentDAO extends IGenericDAO<DayAssignment, Long> {
|
|||
|
||||
public List<DayAssignment> findByResources(Scenario scenario, List<Resource> resources);
|
||||
|
||||
public List<DayAssignment> findByResources(List<Resource> resources);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public class AvailabilityCalculator {
|
|||
return result.and(getCriterionsAvailabilityFor(criterions, each));
|
||||
}
|
||||
|
||||
private static AvailabilityTimeLine getCriterionsAvailabilityFor(
|
||||
public static AvailabilityTimeLine getCriterionsAvailabilityFor(
|
||||
Collection<? extends Criterion> criterions, Resource resource) {
|
||||
AvailabilityTimeLine result = AvailabilityTimeLine.allValid();
|
||||
for (Criterion each : criterions) {
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.entities;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class DateAndHour implements Comparable<DateAndHour> {
|
||||
|
||||
private LocalDate date;
|
||||
|
||||
private Integer hour;
|
||||
|
||||
public DateAndHour(LocalDate date, Integer hour) {
|
||||
this.date = date;
|
||||
this.hour = hour;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public Integer getHour() {
|
||||
return hour;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(DateAndHour dateAndTime) {
|
||||
int compareDate = date.compareTo(getDate(dateAndTime));
|
||||
return (compareDate != 0) ? compareDate : compareHour(dateAndTime
|
||||
.getHour());
|
||||
}
|
||||
|
||||
private LocalDate getDate(DateAndHour dateAndHour) {
|
||||
return (dateAndHour != null) ? dateAndHour.getDate() : null;
|
||||
}
|
||||
|
||||
private int compareHour(int hour) {
|
||||
int deltaHour = this.hour - hour;
|
||||
return (deltaHour != 0) ? deltaHour / Math.abs(deltaHour) : 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return date + "; " + hour;
|
||||
}
|
||||
|
||||
public static DateAndHour Max(DateAndHour arg0, DateAndHour arg1) {
|
||||
if (arg0 == null) {
|
||||
return arg1;
|
||||
}
|
||||
if (arg1 == null) {
|
||||
return arg0;
|
||||
}
|
||||
return (arg0.compareTo(arg1) > 0) ? arg0 : arg1;
|
||||
}
|
||||
|
||||
public boolean isBefore(DateAndHour dateAndHour) {
|
||||
return (this.compareTo(dateAndHour) < 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -168,7 +168,7 @@ public abstract class DayAssignment extends BaseEntity {
|
|||
@OnCopy(Strategy.SHARE)
|
||||
private Resource resource;
|
||||
|
||||
private Boolean consolidated;
|
||||
private Boolean consolidated = false;
|
||||
|
||||
protected DayAssignment() {
|
||||
|
||||
|
|
@ -237,8 +237,11 @@ public abstract class DayAssignment extends BaseEntity {
|
|||
|
||||
final void detach() {
|
||||
getResource().removeAssignments(Arrays.asList(this));
|
||||
detachFromAllocation();
|
||||
}
|
||||
|
||||
protected abstract void detachFromAllocation();
|
||||
|
||||
public abstract boolean belongsTo(Object allocation);
|
||||
|
||||
/**
|
||||
|
|
@ -247,4 +250,6 @@ public abstract class DayAssignment extends BaseEntity {
|
|||
*/
|
||||
public abstract Scenario getScenario();
|
||||
|
||||
public abstract DayAssignment withHours(int newHours);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,11 @@
|
|||
|
||||
package org.navalplanner.business.planner.entities;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency;
|
||||
|
||||
/**
|
||||
* Entity which represents an associated with properties
|
||||
|
|
@ -33,7 +36,54 @@ import org.navalplanner.business.common.BaseEntity;
|
|||
public class Dependency extends BaseEntity {
|
||||
|
||||
public enum Type {
|
||||
END_START, START_START, END_END, START_END;
|
||||
END_START {
|
||||
@Override
|
||||
public boolean modifiesDestinationStart() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean modifiesDestinationEnd() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
START_START {
|
||||
@Override
|
||||
public boolean modifiesDestinationStart() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean modifiesDestinationEnd() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
END_END {
|
||||
@Override
|
||||
public boolean modifiesDestinationStart() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean modifiesDestinationEnd() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
START_END {
|
||||
@Override
|
||||
public boolean modifiesDestinationStart() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean modifiesDestinationEnd() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public abstract boolean modifiesDestinationStart();
|
||||
|
||||
public abstract boolean modifiesDestinationEnd();
|
||||
}
|
||||
|
||||
public static Dependency create(TaskElement origin,
|
||||
|
|
@ -98,4 +148,17 @@ public class Dependency extends BaseEntity {
|
|||
public boolean hasLimitedQueueDependencyAssociated() {
|
||||
return queueDependency != null;
|
||||
}
|
||||
|
||||
public Date getDateFromOrigin() {
|
||||
switch (type) {
|
||||
case END_START:
|
||||
case END_END:
|
||||
return origin.getEndDate();
|
||||
case START_END:
|
||||
case START_START:
|
||||
return origin.getStartDate();
|
||||
default:
|
||||
throw new RuntimeException("unexpected type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,20 @@ public class DerivedDayAssignment extends DayAssignment {
|
|||
}
|
||||
}
|
||||
|
||||
private class DetachedState extends ParentState {
|
||||
|
||||
@Override
|
||||
protected DerivedAllocation getAllocation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scenario getScenario() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DerivedDayAssignmentsContainer container;
|
||||
|
||||
|
|
@ -145,4 +159,14 @@ public class DerivedDayAssignment extends DayAssignment {
|
|||
return parentState.getScenario();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DayAssignment withHours(int newHours) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void detachFromAllocation() {
|
||||
this.parentState = new DetachedState();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ public class GenericDayAssignment extends DayAssignment {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static GenericDayAssignment create(LocalDate day, int hours,
|
||||
Resource resource) {
|
||||
GenericDayAssignment result = new GenericDayAssignment(day, hours,
|
||||
|
|
@ -127,6 +128,7 @@ public class GenericDayAssignment extends DayAssignment {
|
|||
Set<GenericDayAssignment> result = new HashSet<GenericDayAssignment>();
|
||||
for (GenericDayAssignment a : assignemnts) {
|
||||
GenericDayAssignment created = copy(newParent, a);
|
||||
created.associateToResource();
|
||||
result.add(created);
|
||||
}
|
||||
return result;
|
||||
|
|
@ -137,6 +139,7 @@ public class GenericDayAssignment extends DayAssignment {
|
|||
GenericDayAssignment toBeCopied) {
|
||||
GenericDayAssignment result = create(toBeCopied.getDay(), toBeCopied
|
||||
.getHours(), toBeCopied.getResource());
|
||||
result.setConsolidated(toBeCopied.isConsolidated());
|
||||
result.parentState = result.parentState.setParent(newParent);
|
||||
result.associateToResource();
|
||||
return result;
|
||||
|
|
@ -170,6 +173,7 @@ public class GenericDayAssignment extends DayAssignment {
|
|||
}
|
||||
|
||||
protected void detachFromAllocation() {
|
||||
this.parentState = new ContainerNotSpecified();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -188,4 +192,14 @@ public class GenericDayAssignment extends DayAssignment {
|
|||
return parentState.getScenario();
|
||||
}
|
||||
|
||||
public DayAssignment withHours(int newHours) {
|
||||
GenericDayAssignment result = create(getDay(), newHours, getResource());
|
||||
if (container != null) {
|
||||
result.parentState.setParent(container);
|
||||
} else if (this.getGenericResourceAllocation() != null) {
|
||||
result.parentState.setParent(this.getGenericResourceAllocation());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -406,14 +406,6 @@ public class GenericResourceAllocation extends
|
|||
return result;
|
||||
}
|
||||
|
||||
public List<GenericDayAssignment> getNonConsolidatedAssignments() {
|
||||
return getDayAssignmentsByConsolidated(false);
|
||||
}
|
||||
|
||||
public List<GenericDayAssignment> getConsolidatedAssignments() {
|
||||
return getDayAssignmentsByConsolidated(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<GenericDayAssignment> getDayAssignmentType() {
|
||||
return GenericDayAssignment.class;
|
||||
|
|
@ -532,4 +524,11 @@ public class GenericResourceAllocation extends
|
|||
}
|
||||
}
|
||||
|
||||
public void overrideConsolidatedDayAssignments(
|
||||
GenericResourceAllocation origin) {
|
||||
if (origin != null) {
|
||||
resetAssignmentsTo(origin.getConsolidatedAssignments());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,285 +0,0 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.entities;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.calendars.entities.ResourceCalendar;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.CriterionCompounder;
|
||||
import org.navalplanner.business.resources.entities.ICriterion;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
||||
/**
|
||||
* Handles all the logic related to allocation of
|
||||
* {@link LimitingResourceQueueElement} into {@link LimitingResourceQueue}
|
||||
*
|
||||
* The class does not do the allocation itself but provides methods:
|
||||
* <em>getFirstValidGap</em>, <em>calculateStartAndEndTime</em> or
|
||||
* <em>generateDayAssignments</em>, needed to do the allocation of
|
||||
* {@link LimitingResourceQueueElement}
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class LimitingResourceAllocator {
|
||||
|
||||
private final static ResourcesPerDay ONE_RESOURCE_PER_DAY = ResourcesPerDay
|
||||
.amount(new BigDecimal(1));
|
||||
|
||||
/**
|
||||
* Returns first valid gap in queue for element
|
||||
*
|
||||
* Returns null if there is not a valid gap. This case can only happen on
|
||||
* trying to allocate an element related to a generic resource allocation.
|
||||
* It is possible that queue.resource does not hold element.criteria at any
|
||||
* interval of time
|
||||
*
|
||||
* @param queue search gap inside queue
|
||||
* @param element element to fit into queue
|
||||
* @return
|
||||
*/
|
||||
public static LimitingResourceQueueElementGap getFirstValidGap(LimitingResourceQueue queue,
|
||||
LimitingResourceQueueElement element) {
|
||||
|
||||
final Resource resource = queue.getResource();
|
||||
final List<LimitingResourceQueueElement> elements = new LinkedList<LimitingResourceQueueElement>(
|
||||
queue.getLimitingResourceQueueElements());
|
||||
final int size = elements.size();
|
||||
|
||||
// Iterate through queue elements
|
||||
for (int pos = 0; pos <= size; pos++) {
|
||||
|
||||
LimitingResourceQueueElementGap gap = getGapInQueueAtPosition(
|
||||
resource, elements, element, pos);
|
||||
|
||||
// The queue cannot hold this element (perhaps queue.resource
|
||||
// doesn't meet element.criteria)
|
||||
if (gap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (canFitIntoGap(element, gap, resource)) {
|
||||
return gap;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean canFitIntoGap(LimitingResourceQueueElement element,
|
||||
LimitingResourceQueueElementGap gap, final Resource resource) {
|
||||
|
||||
final boolean canfit = gap.canFit(element);
|
||||
final ResourceAllocation<?> resourceAllocation = element
|
||||
.getResourceAllocation();
|
||||
|
||||
if (resourceAllocation instanceof SpecificResourceAllocation) {
|
||||
return canfit;
|
||||
} else if (resourceAllocation instanceof GenericResourceAllocation) {
|
||||
// Resource must satisfy element.criteria during for the
|
||||
// period of time the element will be allocated in the
|
||||
// queue
|
||||
final GenericResourceAllocation generic = (GenericResourceAllocation) resourceAllocation;
|
||||
List<DayAssignment> dayAssignments = generateDayAssignments(
|
||||
resourceAllocation, resource, gap.getStartTime());
|
||||
DateAndHour[] startAndEndTime = calculateStartAndEndTime(dayAssignments);
|
||||
return canfit
|
||||
&& (satisfiesCriteriaDuringInterval(resource, generic
|
||||
.getCriterions(), startAndEndTime));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates start and end date out of a list of day assignments.
|
||||
*
|
||||
* The first day is the day were the first day assignment happened.
|
||||
* The last day is the day were the last day assignment happened.
|
||||
* @param dayAssignments
|
||||
* @return
|
||||
*/
|
||||
public static DateAndHour[] calculateStartAndEndTime(List<DayAssignment> dayAssignments) {
|
||||
DateAndHour[] result = new DateAndHour[2];
|
||||
|
||||
final DayAssignment start = dayAssignments.get(0);
|
||||
final DayAssignment end = dayAssignments.get(dayAssignments.size() - 1);
|
||||
result[0] = new DateAndHour(start.getDay(), start.getHours());
|
||||
result[1] = new DateAndHour(end.getDay(), end.getHours());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean satisfiesCriteriaDuringInterval(Resource resource, Set<Criterion> criteria, DateAndHour[] interval) {
|
||||
final Date startDate = interval[0].getDate().toDateTimeAtStartOfDay().toDate();
|
||||
final Date endDate = interval[1].getDate().toDateTimeAtStartOfDay().toDate();
|
||||
return satisfiesCriteriaDuringInterval(resource, criteria, startDate, endDate);
|
||||
}
|
||||
|
||||
private static boolean satisfiesCriteriaDuringInterval(Resource resource, Set<Criterion> criteria, Date startDate, Date endDate) {
|
||||
ICriterion compositedCriterion = CriterionCompounder.buildAnd(criteria)
|
||||
.getResult();
|
||||
return compositedCriterion.isSatisfiedBy(resource, startDate, endDate);
|
||||
}
|
||||
|
||||
private static LimitingResourceQueueElementGap getGapInQueueAtPosition(
|
||||
Resource resource, List<LimitingResourceQueueElement> elements,
|
||||
LimitingResourceQueueElement element, int pos) {
|
||||
|
||||
final int size = elements.size();
|
||||
final DateAndHour startTimeBecauseOfGantt = getStartTimeBecauseOfGantt(element);
|
||||
|
||||
if (size > 0) {
|
||||
|
||||
if (pos == size) {
|
||||
return createLastGap(element, elements.get(size - 1), resource);
|
||||
}
|
||||
|
||||
LimitingResourceQueueElement current = elements.get(pos);
|
||||
// First element
|
||||
if (pos == 0
|
||||
&& startTimeBecauseOfGantt.getDate().isBefore(
|
||||
current.getStartDate())) {
|
||||
return LimitingResourceQueueElementGap.create(resource,
|
||||
startTimeBecauseOfGantt, current.getStartTime());
|
||||
}
|
||||
|
||||
// Rest of elements
|
||||
if (pos + 1 < size) {
|
||||
LimitingResourceQueueElement next = elements.get(pos + 1);
|
||||
if (startTimeBecauseOfGantt.isBefore(current.getEndTime())) {
|
||||
return LimitingResourceQueueElementGap.create(resource,
|
||||
current.getEndTime(), next.getStartTime());
|
||||
} else {
|
||||
return LimitingResourceQueueElementGap.create(resource,
|
||||
DateAndHour.Max(current.getEndTime(),
|
||||
startTimeBecauseOfGantt), next
|
||||
.getStartTime());
|
||||
}
|
||||
} else {
|
||||
// Current was the last element
|
||||
return createLastGap(element, current, resource);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DateAndHour getStartTimeBecauseOfGantt(LimitingResourceQueueElement element) {
|
||||
return new DateAndHour(new LocalDate(element.getEarlierStartDateBecauseOfGantt()), 0);
|
||||
}
|
||||
|
||||
private static LimitingResourceQueueElementGap createLastGap(
|
||||
LimitingResourceQueueElement candidate,
|
||||
LimitingResourceQueueElement element, Resource resource) {
|
||||
|
||||
DateAndHour startTime = DateAndHour.Max(
|
||||
getStartTimeBecauseOfGantt(candidate), element.getEndTime());
|
||||
return LimitingResourceQueueElementGap
|
||||
.create(resource, startTime, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of {@link DayAssignment} for {@link Resource} starting
|
||||
* from startTime
|
||||
*
|
||||
* The returned list is not associated to resouceAllocation.
|
||||
*
|
||||
* resourceAllocation is passed to know if the list of day assignments
|
||||
* should be {@link GenericDayAssignment} or {@link SpecificDayAssignment}
|
||||
*
|
||||
* @param resourceAllocation
|
||||
* @param resource
|
||||
* @param startTime
|
||||
* @return
|
||||
*/
|
||||
public static List<DayAssignment> generateDayAssignments(
|
||||
ResourceAllocation<?> resourceAllocation,
|
||||
Resource resource,
|
||||
DateAndHour startTime) {
|
||||
|
||||
List<DayAssignment> assignments = new ArrayList<DayAssignment>();
|
||||
|
||||
LocalDate date = startTime.getDate();
|
||||
int totalHours = resourceAllocation.getIntendedTotalHours();
|
||||
|
||||
// Generate first day assignment
|
||||
int hoursCanAllocate = hoursCanWorkOnDay(resource, date, startTime.getHour());
|
||||
if (hoursCanAllocate > 0) {
|
||||
int hoursToAllocate = Math.min(totalHours, hoursCanAllocate);
|
||||
DayAssignment dayAssignment = createDayAssignment(resourceAllocation, resource, date, hoursToAllocate);
|
||||
totalHours -= addDayAssignment(assignments, dayAssignment);
|
||||
}
|
||||
|
||||
// Generate rest of day assignments
|
||||
for (date = date.plusDays(1); totalHours > 0; date = date.plusDays(1)) {
|
||||
totalHours -= addDayAssignment(assignments, generateDayAssignment(
|
||||
resourceAllocation, resource, date, totalHours));
|
||||
}
|
||||
return assignments;
|
||||
}
|
||||
|
||||
private static DayAssignment createDayAssignment(ResourceAllocation<?> resourceAllocation,
|
||||
Resource resource, LocalDate date, int hoursToAllocate) {
|
||||
if (resourceAllocation instanceof SpecificResourceAllocation) {
|
||||
return SpecificDayAssignment.create(date, hoursToAllocate, resource);
|
||||
} else if (resourceAllocation instanceof GenericResourceAllocation) {
|
||||
return GenericDayAssignment.create(date, hoursToAllocate, resource);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int addDayAssignment(List<DayAssignment> list, DayAssignment dayAssignment) {
|
||||
if (dayAssignment != null) {
|
||||
list.add(dayAssignment);
|
||||
return dayAssignment.getHours();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int hoursCanWorkOnDay(final Resource resource,
|
||||
final LocalDate date, int alreadyWorked) {
|
||||
final ResourceCalendar calendar = resource.getCalendar();
|
||||
int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY);
|
||||
return hoursCanAllocate - alreadyWorked;
|
||||
}
|
||||
|
||||
private static DayAssignment generateDayAssignment(
|
||||
final ResourceAllocation<?> resourceAllocation,
|
||||
Resource resource,
|
||||
final LocalDate date, int intentedHours) {
|
||||
|
||||
final ResourceCalendar calendar = resource.getCalendar();
|
||||
|
||||
int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY);
|
||||
if (hoursCanAllocate > 0) {
|
||||
int hoursToAllocate = Math.min(intentedHours, hoursCanAllocate);
|
||||
return createDayAssignment(resourceAllocation, resource, date, hoursToAllocate);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
package org.navalplanner.business.planner.entities;
|
||||
|
||||
import static org.navalplanner.business.i18n.I18nHelper._;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
|
||||
|
||||
/**
|
||||
* Entity which represents the relationships between two
|
||||
* @{link LimitingResourceQueueElement}. One of the
|
||||
* @{link LimitingResourceQueueElement} is the origin of the relationship
|
||||
* and the other is the destiny of the relationship.
|
||||
*
|
||||
* @author Javier Moran Rua <jmoran@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class LimitingResourceQueueDependency extends BaseEntity {
|
||||
|
||||
public static enum QueueDependencyType {
|
||||
START_START, END_START, END_END, START_END
|
||||
};
|
||||
|
||||
private static
|
||||
EnumMap<Dependency.Type,
|
||||
LimitingResourceQueueDependency.QueueDependencyType> translationMap;
|
||||
|
||||
static {
|
||||
translationMap = new EnumMap<Dependency.Type,
|
||||
LimitingResourceQueueDependency.
|
||||
QueueDependencyType>(Dependency.Type.class);
|
||||
translationMap.put(Dependency.Type.START_START,
|
||||
QueueDependencyType.START_START);
|
||||
translationMap.put(Dependency.Type.START_END,
|
||||
QueueDependencyType.START_END);
|
||||
translationMap.put(Dependency.Type.END_START,
|
||||
QueueDependencyType.END_START);
|
||||
translationMap.put(Dependency.Type.END_END,
|
||||
QueueDependencyType.END_END);
|
||||
}
|
||||
|
||||
private LimitingResourceQueueElement hasAsOrigin;
|
||||
private LimitingResourceQueueElement hasAsDestiny;
|
||||
private Dependency ganttDependency;
|
||||
private QueueDependencyType type;
|
||||
|
||||
public static LimitingResourceQueueDependency create(
|
||||
LimitingResourceQueueElement origin,
|
||||
LimitingResourceQueueElement destiny,
|
||||
Dependency ganttDependency,
|
||||
QueueDependencyType type) {
|
||||
LimitingResourceQueueDependency dependency = new
|
||||
LimitingResourceQueueDependency(origin,destiny,ganttDependency,type);
|
||||
dependency.setNewObject(true);
|
||||
origin.add(dependency);
|
||||
destiny.add(dependency);
|
||||
ganttDependency.setQueueDependency(dependency);
|
||||
return dependency;
|
||||
}
|
||||
|
||||
public static LimitingResourceQueueDependency.QueueDependencyType
|
||||
convertFromTypeToQueueDepedencyType(Dependency.Type type) {
|
||||
return translationMap.get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contructor for Hibernate. Do not use !
|
||||
*/
|
||||
public LimitingResourceQueueDependency() {}
|
||||
|
||||
private LimitingResourceQueueDependency(LimitingResourceQueueElement origin,
|
||||
LimitingResourceQueueElement destiny,
|
||||
Dependency ganttDependency,
|
||||
QueueDependencyType type) {
|
||||
Validate.notNull(origin);
|
||||
Validate.notNull(destiny);
|
||||
Validate.notNull(ganttDependency);
|
||||
Validate.isTrue(!origin.equals(destiny), _("A queue dependency has to " +
|
||||
"have an origin different from destiny"));
|
||||
this.hasAsOrigin = origin;
|
||||
this.hasAsDestiny = destiny;
|
||||
this.ganttDependency = ganttDependency;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElement getHasAsOrigin() {
|
||||
return hasAsOrigin;
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElement getHasAsDestiny() {
|
||||
return hasAsDestiny;
|
||||
}
|
||||
|
||||
public QueueDependencyType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Dependency getGanttDependency() {
|
||||
return ganttDependency;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.entities;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.calendars.entities.ResourceCalendar;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class LimitingResourceQueueElementGap implements Comparable<LimitingResourceQueueElementGap> {
|
||||
|
||||
private DateAndHour startTime;
|
||||
|
||||
private DateAndHour endTime;
|
||||
|
||||
private Integer hoursInGap;
|
||||
|
||||
public LimitingResourceQueueElementGap(Resource resource, DateAndHour startTime,
|
||||
DateAndHour endTime) {
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
hoursInGap = calculateHoursInGap(resource, startTime, endTime);
|
||||
}
|
||||
|
||||
private Integer calculateHoursInGap(Resource resource, DateAndHour startTime, DateAndHour endTime) {
|
||||
return (endTime == null) ? Integer.MAX_VALUE : calculateHoursInGap(
|
||||
resource, startTime.getDate(), startTime.getHour(), endTime
|
||||
.getDate(), endTime.getHour());
|
||||
}
|
||||
|
||||
public int getHoursInGap() {
|
||||
return hoursInGap;
|
||||
}
|
||||
|
||||
private Integer calculateHoursInGap(Resource resource, LocalDate startDate,
|
||||
int startHour, LocalDate endDate, int endHour) {
|
||||
|
||||
final ResourceCalendar calendar = resource.getCalendar();
|
||||
|
||||
if (startDate.equals(endDate)) {
|
||||
return calendar.getCapacityAt(startDate) - Math.max(startHour, endHour);
|
||||
} else {
|
||||
int hoursAtStart = calendar.getCapacityAt(startDate) - startHour;
|
||||
int hoursInBetween = calendar.getWorkableHours(startDate
|
||||
.plusDays(1), endDate.minusDays(1));
|
||||
return hoursAtStart + hoursInBetween + endHour;
|
||||
}
|
||||
}
|
||||
|
||||
public static LimitingResourceQueueElementGap create(Resource resource, DateAndHour startTime,
|
||||
DateAndHour endTime) {
|
||||
return new LimitingResourceQueueElementGap(resource, startTime, endTime);
|
||||
}
|
||||
|
||||
public DateAndHour getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public DateAndHour getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the gap starts after earlierStartDateBecauseOfGantt and
|
||||
* if it's big enough for fitting candidate
|
||||
*
|
||||
* @param hours
|
||||
* @return
|
||||
*/
|
||||
public boolean canFit(LimitingResourceQueueElement candidate) {
|
||||
final LocalDate earlierStartDateBecauseOfGantt = new LocalDate(
|
||||
candidate.getEarlierStartDateBecauseOfGantt());
|
||||
final LocalDate startDate = startTime.getDate();
|
||||
if (earlierStartDateBecauseOfGantt.isBefore(startDate)
|
||||
|| earlierStartDateBecauseOfGantt.isEqual(startDate)) {
|
||||
return hoursInGap - candidate.getIntentedTotalHours() >= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String result = startTime.getDate() + " - " + startTime.getHour();
|
||||
if (endTime != null) {
|
||||
result += "; " + endTime.getDate() + " - " + endTime.getHour();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(LimitingResourceQueueElementGap o) {
|
||||
if (o == null) {
|
||||
return 1;
|
||||
}
|
||||
return this.getStartTime().compareTo(o.getStartTime());
|
||||
}
|
||||
|
||||
public boolean isBefore(LimitingResourceQueueElementGap gap) {
|
||||
return (compareTo(gap) < 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,12 +21,14 @@
|
|||
package org.navalplanner.business.planner.entities;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -49,6 +51,7 @@ import org.navalplanner.business.planner.entities.allocationalgorithms.Allocator
|
|||
import org.navalplanner.business.planner.entities.allocationalgorithms.AllocatorForTaskDurationAndSpecifiedResourcesPerDay;
|
||||
import org.navalplanner.business.planner.entities.allocationalgorithms.HoursModification;
|
||||
import org.navalplanner.business.planner.entities.allocationalgorithms.ResourcesPerDayModification;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.entities.Machine;
|
||||
import org.navalplanner.business.resources.entities.MachineWorkersConfigurationUnit;
|
||||
|
|
@ -307,6 +310,38 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
|
||||
private int originalTotalAssignment = 0;
|
||||
|
||||
private IOnDayAssignmentRemoval dayAssignmenteRemoval = new DoNothing();
|
||||
|
||||
public interface IOnDayAssignmentRemoval {
|
||||
|
||||
public void onRemoval(ResourceAllocation<?> allocation,
|
||||
DayAssignment assignment);
|
||||
}
|
||||
|
||||
public static class DoNothing implements IOnDayAssignmentRemoval {
|
||||
|
||||
@Override
|
||||
public void onRemoval(
|
||||
ResourceAllocation<?> allocation, DayAssignment assignment) {
|
||||
}
|
||||
}
|
||||
|
||||
public static class DetachDayAssignmentOnRemoval implements
|
||||
IOnDayAssignmentRemoval {
|
||||
|
||||
@Override
|
||||
public void onRemoval(ResourceAllocation<?> allocation,
|
||||
DayAssignment assignment) {
|
||||
assignment.detach();
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnDayAssignmentRemoval(
|
||||
IOnDayAssignmentRemoval dayAssignmentRemoval) {
|
||||
Validate.notNull(dayAssignmentRemoval);
|
||||
this.dayAssignmenteRemoval = dayAssignmentRemoval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for hibernate. Do not use!
|
||||
*/
|
||||
|
|
@ -365,8 +400,19 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
return task;
|
||||
}
|
||||
|
||||
public void setOriginalTotalAssigment(int originalTotalAssigment) {
|
||||
this.originalTotalAssignment = originalTotalAssigment;
|
||||
private void updateOriginalTotalAssigment() {
|
||||
if ((task.getConsolidation() == null)
|
||||
|| (task.getConsolidation().getConsolidatedValues().isEmpty())) {
|
||||
originalTotalAssignment = getNonConsolidatedHours();
|
||||
} else {
|
||||
BigDecimal lastConslidation = task.getConsolidation()
|
||||
.getConsolidatedValues().last().getValue();
|
||||
originalTotalAssignment = new BigDecimal(getNonConsolidatedHours())
|
||||
.divide(
|
||||
BigDecimal.ONE.subtract(lastConslidation.divide(
|
||||
new BigDecimal(100), RoundingMode.DOWN)),
|
||||
RoundingMode.DOWN).intValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Min(0)
|
||||
|
|
@ -414,14 +460,18 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
@Override
|
||||
public void allocate(ResourcesPerDay resourcesPerDay) {
|
||||
Task currentTask = getTask();
|
||||
LocalDate startInclusive = new LocalDate(currentTask
|
||||
LocalDate taskStart = LocalDate.fromDateFields(currentTask
|
||||
.getStartDate());
|
||||
LocalDate startInclusive = (currentTask
|
||||
.getFirstDayNotConsolidated().compareTo(taskStart) >= 0) ? currentTask
|
||||
.getFirstDayNotConsolidated()
|
||||
: taskStart;
|
||||
List<T> assignmentsCreated = createAssignments(
|
||||
resourcesPerDay, startInclusive,
|
||||
endExclusive);
|
||||
resourcesPerDay, startInclusive, endExclusive);
|
||||
resetAssignmentsTo(assignmentsCreated);
|
||||
setResourcesPerDay(calculateResourcesPerDayFromAssignments());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -476,7 +526,10 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
}
|
||||
|
||||
private void allocate(LocalDate end, int hours) {
|
||||
LocalDate startInclusive = new LocalDate(getTask().getStartDate());
|
||||
LocalDate taskStart = LocalDate.fromDateFields(task.getStartDate());
|
||||
LocalDate startInclusive = (task.getFirstDayNotConsolidated()
|
||||
.compareTo(taskStart) >= 0) ? task
|
||||
.getFirstDayNotConsolidated() : taskStart;
|
||||
List<T> assignmentsCreated = createAssignments(startInclusive, end,
|
||||
hours);
|
||||
resetAssignmentsTo(assignmentsCreated);
|
||||
|
|
@ -485,12 +538,12 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
|
||||
private void allocate(LocalDate startInclusive, LocalDate endExclusive,
|
||||
int hours) {
|
||||
LocalDate firstDayNotConsolidated = getTask().getFirstDayNotConsolidated();
|
||||
LocalDate start = startInclusive.compareTo(firstDayNotConsolidated) >= 0 ? startInclusive
|
||||
: firstDayNotConsolidated;
|
||||
List<T> assignmentsCreated = createAssignments(startInclusive,
|
||||
endExclusive, hours);
|
||||
removingAssignments(getAssignments(startInclusive, endExclusive));
|
||||
addingAssignments(assignmentsCreated);
|
||||
setResourcesPerDay(calculateResourcesPerDayFromAssignments());
|
||||
setOriginalTotalAssigment(getAssignedHours());
|
||||
resetAssigmentsForInterval(start, endExclusive, assignmentsCreated);
|
||||
}
|
||||
|
||||
protected abstract AvailabilityTimeLine getResourcesAvailability();
|
||||
|
|
@ -596,10 +649,31 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
|
||||
protected abstract void copyAssignments(Scenario from, Scenario to);
|
||||
|
||||
private void resetAssignmentsTo(List<T> assignments) {
|
||||
removingAssignments(getAssignments());
|
||||
protected void resetAssignmentsTo(List<T> assignments) {
|
||||
removingAssignments((List<? extends DayAssignment>) removeConsolidated(getAssignments()));
|
||||
addingAssignments(assignments);
|
||||
setOriginalTotalAssigment(getAssignedHours());
|
||||
updateOriginalTotalAssigment();
|
||||
}
|
||||
|
||||
protected void resetAssigmentsForInterval(LocalDate startInclusive,
|
||||
LocalDate endExclusive, List<T> assignmentsCreated) {
|
||||
removingAssignments(removeConsolidated(getAssignments(startInclusive,
|
||||
endExclusive)));
|
||||
addingAssignments(assignmentsCreated);
|
||||
setResourcesPerDay(calculateResourcesPerDayFromAssignments(getAssignments()));
|
||||
updateOriginalTotalAssigment();
|
||||
}
|
||||
|
||||
private List<? extends DayAssignment> removeConsolidated(
|
||||
List<? extends DayAssignment> assignments) {
|
||||
for (Iterator<? extends DayAssignment> iterator = assignments
|
||||
.iterator(); iterator.hasNext();) {
|
||||
DayAssignment dayAssignment = (DayAssignment) iterator.next();
|
||||
if (dayAssignment.isConsolidated()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return assignments;
|
||||
}
|
||||
|
||||
protected final void addingAssignments(Collection<? extends T> assignments) {
|
||||
|
|
@ -610,13 +684,14 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
allocateLimitingDayAssignments(Collections.<T>emptyList());
|
||||
}
|
||||
|
||||
public void allocateLimitingDayAssignments(List<T> assignments) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void allocateLimitingDayAssignments(List<? extends DayAssignment> assignments) {
|
||||
assert isLimiting();
|
||||
resetAssignmentsTo(assignments);
|
||||
resetAssignmentsTo((List<T>) assignments);
|
||||
}
|
||||
|
||||
protected final void removingAssignments(
|
||||
List<? extends DayAssignment> assignments){
|
||||
private void removingAssignments(
|
||||
List<? extends DayAssignment> assignments) {
|
||||
getDayAssignmentsState().removingAssignments(assignments);
|
||||
}
|
||||
|
||||
|
|
@ -776,6 +851,9 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
List<? extends DayAssignment> assignments){
|
||||
removeAssignments(assignments);
|
||||
clearCachedData();
|
||||
for (DayAssignment each : assignments) {
|
||||
dayAssignmenteRemoval.onRemoval(ResourceAllocation.this, each);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void removeAssignments(
|
||||
|
|
@ -877,11 +955,11 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
return getDayAssignmentsState().getOrderedDayAssignments();
|
||||
}
|
||||
|
||||
public List<? extends T> getNonConsolidatedAssignments(){
|
||||
public List<T> getNonConsolidatedAssignments() {
|
||||
return getDayAssignmentsByConsolidated(false);
|
||||
}
|
||||
|
||||
public List<? extends T> getConsolidatedAssignments() {
|
||||
public List<T> getConsolidatedAssignments() {
|
||||
return getDayAssignmentsByConsolidated(true);
|
||||
}
|
||||
|
||||
|
|
@ -939,6 +1017,14 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
return Collections.unmodifiableSet(derivedAllocations);
|
||||
}
|
||||
|
||||
public LocalDate getStartConsideringAssignments() {
|
||||
List<? extends DayAssignment> assignments = getAssignments();
|
||||
if (assignments.isEmpty()) {
|
||||
return getStartDate();
|
||||
}
|
||||
return assignments.get(0).getDay();
|
||||
}
|
||||
|
||||
public LocalDate getStartDate() {
|
||||
return LocalDate.fromDateFields(task.getStartDate());
|
||||
}
|
||||
|
|
@ -1011,7 +1097,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
switchToScenario(scenario);
|
||||
mergeAssignments(modifications);
|
||||
setResourcesPerDay(modifications.getResourcesPerDay());
|
||||
setOriginalTotalAssigment(modifications.getOriginalTotalAssigment());
|
||||
updateOriginalTotalAssigment();
|
||||
setWithoutApply(modifications.getAssignmentFunction());
|
||||
mergeDerivedAllocations(scenario, modifications.getDerivedAllocations());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ public class SpecificDayAssignment extends DayAssignment {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static Set<SpecificDayAssignment> copy(
|
||||
SpecificDayAssignmentsContainer container,
|
||||
Collection<? extends SpecificDayAssignment> specificDaysAssignment) {
|
||||
|
|
@ -123,6 +124,7 @@ public class SpecificDayAssignment extends DayAssignment {
|
|||
SpecificDayAssignment created = create(s.getDay(), s.getHours(), s
|
||||
.getResource());
|
||||
created.parentState = created.parentState.setParent(container);
|
||||
created.setConsolidated(s.isConsolidated());
|
||||
created.associateToResource();
|
||||
result.add(created);
|
||||
}
|
||||
|
|
@ -173,4 +175,20 @@ public class SpecificDayAssignment extends DayAssignment {
|
|||
public Scenario getScenario() {
|
||||
return parentState.getScenario();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DayAssignment withHours(int newHours) {
|
||||
SpecificDayAssignment result = create(getDay(), newHours, getResource());
|
||||
if (container != null) {
|
||||
result.parentState.setParent(container);
|
||||
} else if (this.getSpecificResourceAllocation() != null) {
|
||||
result.parentState.setParent(this.getSpecificResourceAllocation());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void detachFromAllocation() {
|
||||
this.parentState = new ContainerNotSpecified();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,10 @@ import org.joda.time.LocalDate;
|
|||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine;
|
||||
import org.navalplanner.business.calendars.entities.CombinedWorkHours;
|
||||
import org.navalplanner.business.calendars.entities.IWorkHours;
|
||||
import org.navalplanner.business.common.ProportionalDistributor;
|
||||
import org.navalplanner.business.planner.entities.allocationalgorithms.HoursModification;
|
||||
import org.navalplanner.business.planner.entities.allocationalgorithms.ResourcesPerDayModification;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
|
|
@ -425,4 +427,41 @@ public class SpecificResourceAllocation extends
|
|||
}
|
||||
}
|
||||
|
||||
public void allocateKeepingProportions(LocalDate start,
|
||||
LocalDate endExclusive, int newHoursForInterval) {
|
||||
List<DayAssignment> assignments = getAssignments(start, endExclusive);
|
||||
ProportionalDistributor distributor = ProportionalDistributor
|
||||
.create(asHours(assignments));
|
||||
int[] newHoursPerDay = distributor.distribute(newHoursForInterval);
|
||||
resetAssigmentsForInterval(start, endExclusive, assignmentsForNewHours(
|
||||
assignments, newHoursPerDay));
|
||||
}
|
||||
|
||||
private List<SpecificDayAssignment> assignmentsForNewHours(
|
||||
List<DayAssignment> assignments, int[] newHoursPerDay) {
|
||||
List<SpecificDayAssignment> result = new ArrayList<SpecificDayAssignment>();
|
||||
int i = 0;
|
||||
for (DayAssignment each : assignments) {
|
||||
result.add(SpecificDayAssignment.create(each.getDay(),
|
||||
newHoursPerDay[i++], resource));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int[] asHours(List<DayAssignment> assignments) {
|
||||
int[] result = new int[assignments.size()];
|
||||
int i = 0;
|
||||
for (DayAssignment each : assignments) {
|
||||
result[i++] = each.getHours();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void overrideConsolidatedDayAssignments(
|
||||
SpecificResourceAllocation origin) {
|
||||
if (origin != null) {
|
||||
resetAssignmentsTo(origin.getConsolidatedAssignments());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import org.navalplanner.business.planner.entities.DerivedAllocationGenerator.IWo
|
|||
import org.navalplanner.business.planner.entities.allocationalgorithms.HoursModification;
|
||||
import org.navalplanner.business.planner.entities.allocationalgorithms.ResourcesPerDayModification;
|
||||
import org.navalplanner.business.planner.entities.consolidations.Consolidation;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
|
@ -188,6 +189,14 @@ public class Task extends TaskElement {
|
|||
return (resourceAllocations.size() > 0) ? resourceAllocations.iterator().next() : null;
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElement getAssociatedLimitingResourceQueueElementIfAny() {
|
||||
if (!isLimiting()) {
|
||||
throw new IllegalStateException("this is not a limiting task");
|
||||
}
|
||||
return getAssociatedLimitingResourceAllocation()
|
||||
.getLimitingResourceQueueElement();
|
||||
}
|
||||
|
||||
public boolean isLimitingAndHasDayAssignments() {
|
||||
ResourceAllocation<?> resourceAllocation = getAssociatedLimitingResourceAllocation();
|
||||
return (resourceAllocation != null) ? resourceAllocation.isLimitingAndHasDayAssignments() : false;
|
||||
|
|
@ -449,14 +458,8 @@ public class Task extends TaskElement {
|
|||
reassign(scenario, new WithAnotherResources(resourceDAO));
|
||||
}
|
||||
|
||||
private void reassign(Scenario onScenario,
|
||||
AllocationModificationStrategy strategy) {
|
||||
private void reassign(Scenario onScenario, AllocationModificationStrategy strategy) {
|
||||
if (isLimiting()) {
|
||||
Set<ResourceAllocation<?>> resourceAllocations = getSatisfiedResourceAllocations();
|
||||
ResourceAllocation<?> resourceAlloation = resourceAllocations
|
||||
.iterator().next();
|
||||
resourceAlloation.getLimitingResourceQueueElement()
|
||||
.setEarlierStartDateBecauseOfGantt(getStartDate());
|
||||
return;
|
||||
}
|
||||
List<ModifiedAllocation> copied = ModifiedAllocation.copy(onScenario,
|
||||
|
|
@ -624,4 +627,15 @@ public class Task extends TaskElement {
|
|||
public boolean hasConsolidations() {
|
||||
return ((consolidation != null) && (!consolidation.isEmpty()));
|
||||
}
|
||||
|
||||
public LocalDate getFirstDayNotConsolidated() {
|
||||
if (consolidation != null) {
|
||||
LocalDate until = consolidation.getConsolidatedUntil();
|
||||
if (until != null) {
|
||||
return until.plusDays(1);
|
||||
}
|
||||
}
|
||||
return LocalDate.fromDateFields(getStartDate());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
package org.navalplanner.business.planner.entities;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
|
@ -130,6 +131,8 @@ public abstract class TaskElement extends BaseEntity {
|
|||
|
||||
private TaskSource taskSource;
|
||||
|
||||
private BigDecimal advancePercentage = BigDecimal.ZERO;
|
||||
|
||||
public void initializeEndDateIfDoesntExist() {
|
||||
if (getEndDate() == null) {
|
||||
initializeEndDate();
|
||||
|
|
@ -515,4 +518,13 @@ public abstract class TaskElement extends BaseEntity {
|
|||
}
|
||||
}
|
||||
|
||||
public BigDecimal getAdvancePercentage() {
|
||||
return (advancePercentage == null) ? BigDecimal.ZERO
|
||||
: advancePercentage;
|
||||
}
|
||||
|
||||
public void setAdvancePercentage(BigDecimal advancePercentage) {
|
||||
this.advancePercentage = advancePercentage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,10 @@ public abstract class AllocatorForSpecifiedResourcesPerDayAndHours {
|
|||
}
|
||||
|
||||
public LocalDate untilAllocating(int hoursToAllocate) {
|
||||
LocalDate start = LocalDate.fromDateFields(task.getStartDate());
|
||||
LocalDate taskStart = LocalDate.fromDateFields(task.getStartDate());
|
||||
LocalDate start = (task.getFirstDayNotConsolidated().compareTo(
|
||||
taskStart) >= 0) ? task.getFirstDayNotConsolidated()
|
||||
: taskStart;
|
||||
int i = 0;
|
||||
int maxDaysElapsed = 0;
|
||||
for (HoursPerAllocation each : hoursPerAllocation(start,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
|
|
@ -38,17 +37,13 @@ public class CalculatedConsolidatedValue extends ConsolidatedValue {
|
|||
}
|
||||
|
||||
public static CalculatedConsolidatedValue create(LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
return create(new CalculatedConsolidatedValue(date, value,
|
||||
pendingConsolidatedHours));
|
||||
BigDecimal value, LocalDate taskEndDate) {
|
||||
return create(new CalculatedConsolidatedValue(date, value, taskEndDate));
|
||||
}
|
||||
|
||||
protected CalculatedConsolidatedValue(
|
||||
LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
super(date, value, pendingConsolidatedHours);
|
||||
protected CalculatedConsolidatedValue(LocalDate date, BigDecimal value,
|
||||
LocalDate taskEndDate) {
|
||||
super(date, value, taskEndDate);
|
||||
}
|
||||
|
||||
protected CalculatedConsolidatedValue() {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,10 @@ public class CalculatedConsolidation extends Consolidation {
|
|||
|
||||
@Override
|
||||
public SortedSet<ConsolidatedValue> getConsolidatedValues() {
|
||||
return new TreeSet<ConsolidatedValue>(consolidatedValues);
|
||||
SortedSet<ConsolidatedValue> result = new TreeSet<ConsolidatedValue>(
|
||||
new ConsolidatedValueComparator());
|
||||
result.addAll(consolidatedValues);
|
||||
return result;
|
||||
}
|
||||
|
||||
public SortedSet<CalculatedConsolidatedValue> getCalculatedConsolidatedValues() {
|
||||
|
|
|
|||
|
|
@ -21,13 +21,10 @@
|
|||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.validator.NotNull;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
|
|
@ -37,7 +34,7 @@ public abstract class ConsolidatedValue extends BaseEntity {
|
|||
|
||||
private LocalDate date;
|
||||
private BigDecimal value;
|
||||
private Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours = new HashSet<PendingConsolidatedHoursPerResourceAllocation>();
|
||||
private LocalDate taskEndDate;
|
||||
|
||||
public abstract boolean isCalculated();
|
||||
|
||||
|
|
@ -45,13 +42,11 @@ public abstract class ConsolidatedValue extends BaseEntity {
|
|||
|
||||
}
|
||||
|
||||
protected ConsolidatedValue(
|
||||
LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
protected ConsolidatedValue(LocalDate date, BigDecimal value,
|
||||
LocalDate taskEndDate) {
|
||||
this.date = date;
|
||||
this.value = value;
|
||||
this.pendingConsolidatedHours = pendingConsolidatedHours;
|
||||
this.taskEndDate = taskEndDate;
|
||||
}
|
||||
|
||||
public void setValue(BigDecimal value) {
|
||||
|
|
@ -70,24 +65,9 @@ public abstract class ConsolidatedValue extends BaseEntity {
|
|||
return date;
|
||||
}
|
||||
|
||||
public void setPendingConsolidatedHours(Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
this.pendingConsolidatedHours = pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
public Set<PendingConsolidatedHoursPerResourceAllocation> getPendingConsolidatedHours() {
|
||||
return pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
public static Set<PendingConsolidatedHoursPerResourceAllocation> createPendingConsolidatedHours(
|
||||
LocalDate consolidatedDate,
|
||||
Collection<? extends ResourceAllocation> allocations) {
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours = new HashSet<PendingConsolidatedHoursPerResourceAllocation>();
|
||||
for (ResourceAllocation allocation : allocations) {
|
||||
pendingConsolidatedHours
|
||||
.add(PendingConsolidatedHoursPerResourceAllocation.create(
|
||||
consolidatedDate, allocation));
|
||||
}
|
||||
return pendingConsolidatedHours;
|
||||
@NotNull(message = "task end date not specified")
|
||||
public LocalDate getTaskEndDate() {
|
||||
return taskEndDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ package org.navalplanner.business.planner.entities.consolidations;
|
|||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
|
||||
|
|
@ -54,4 +55,10 @@ public abstract class Consolidation extends BaseEntity {
|
|||
return task;
|
||||
}
|
||||
|
||||
public LocalDate getConsolidatedUntil() {
|
||||
SortedSet<? extends ConsolidatedValue> consolidatedValues = getConsolidatedValues();
|
||||
return (consolidatedValues.isEmpty()) ? null : consolidatedValues
|
||||
.last().getDate();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.advance.entities.AdvanceMeasurement;
|
||||
|
|
@ -41,32 +40,27 @@ public class NonCalculatedConsolidatedValue extends ConsolidatedValue {
|
|||
}
|
||||
|
||||
public static NonCalculatedConsolidatedValue create(LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
BigDecimal value, LocalDate taskEndDate) {
|
||||
return create(new NonCalculatedConsolidatedValue(date, value,
|
||||
pendingConsolidatedHours));
|
||||
taskEndDate));
|
||||
}
|
||||
|
||||
public static NonCalculatedConsolidatedValue create(LocalDate date,
|
||||
BigDecimal value,
|
||||
AdvanceMeasurement advanceMeasurement,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
BigDecimal value, AdvanceMeasurement advanceMeasurement,
|
||||
LocalDate taskEndDate) {
|
||||
return create(new NonCalculatedConsolidatedValue(date, value,
|
||||
advanceMeasurement, pendingConsolidatedHours));
|
||||
advanceMeasurement, taskEndDate));
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidatedValue(LocalDate date, BigDecimal value,
|
||||
AdvanceMeasurement advanceMeasurement,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
this(date, value, pendingConsolidatedHours);
|
||||
AdvanceMeasurement advanceMeasurement, LocalDate taskEndDate) {
|
||||
this(date, value, taskEndDate);
|
||||
this.advanceMeasurement = advanceMeasurement;
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidatedValue(
|
||||
LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
super(date, value, pendingConsolidatedHours);
|
||||
protected NonCalculatedConsolidatedValue(LocalDate date, BigDecimal value,
|
||||
LocalDate taskEndDate) {
|
||||
super(date, value, taskEndDate);
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidatedValue() {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
|
@ -71,7 +72,16 @@ public class NonCalculatedConsolidation extends Consolidation {
|
|||
|
||||
@Override
|
||||
public SortedSet<ConsolidatedValue> getConsolidatedValues() {
|
||||
return new TreeSet<ConsolidatedValue>(consolidatedValues);
|
||||
TreeSet<ConsolidatedValue> result = new TreeSet<ConsolidatedValue>(
|
||||
new Comparator<ConsolidatedValue>() {
|
||||
@Override
|
||||
public int compare(ConsolidatedValue arg0,
|
||||
ConsolidatedValue arg1) {
|
||||
return arg0.getDate().compareTo(arg1.getDate());
|
||||
}
|
||||
});
|
||||
result.addAll(consolidatedValues);
|
||||
return result;
|
||||
}
|
||||
|
||||
public SortedSet<NonCalculatedConsolidatedValue> getNonCalculatedConsolidatedValues() {
|
||||
|
|
|
|||
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.entities.consolidations;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.hibernate.validator.NotNull;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.DayAssignment;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
|
||||
/**
|
||||
* Represents the number of hours per {@link ResourceAllocation} that are not
|
||||
* consolidated.
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public class PendingConsolidatedHoursPerResourceAllocation extends BaseEntity {
|
||||
|
||||
private Integer pendingConsolidatedHours;
|
||||
|
||||
private ResourceAllocation<?> resourceAllocation;
|
||||
|
||||
public static PendingConsolidatedHoursPerResourceAllocation create(
|
||||
LocalDate consolidatedDate,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
return create(new PendingConsolidatedHoursPerResourceAllocation(
|
||||
consolidatedDate,
|
||||
resourceAllocation));
|
||||
}
|
||||
|
||||
public static PendingConsolidatedHoursPerResourceAllocation create(
|
||||
Integer pendingConsolidatedHours,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
return create(new PendingConsolidatedHoursPerResourceAllocation(
|
||||
pendingConsolidatedHours, resourceAllocation));
|
||||
}
|
||||
|
||||
protected PendingConsolidatedHoursPerResourceAllocation(
|
||||
LocalDate consolidatedDate,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
this.setPendingConsolidatedHours(calculatePendingConsolidatedHours(
|
||||
consolidatedDate, resourceAllocation
|
||||
.getAssignments()));
|
||||
this.setResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
protected PendingConsolidatedHoursPerResourceAllocation(
|
||||
Integer pendingConsolidatedHours,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
this.setPendingConsolidatedHours(pendingConsolidatedHours);
|
||||
this.setResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
protected PendingConsolidatedHoursPerResourceAllocation() {
|
||||
|
||||
}
|
||||
|
||||
private Integer calculatePendingConsolidatedHours(LocalDate consolidatedDate,
|
||||
Collection<? extends DayAssignment> assignments) {
|
||||
int result = 0;
|
||||
for (DayAssignment dayAssignment : assignments) {
|
||||
if ((dayAssignment.getDay().toDateTimeAtStartOfDay()
|
||||
.compareTo(consolidatedDate.toDateTimeAtStartOfDay())) > 0) {
|
||||
dayAssignment.setConsolidated(true);
|
||||
result += dayAssignment.getHours();
|
||||
}
|
||||
}
|
||||
return new Integer(result);
|
||||
}
|
||||
|
||||
public void setPendingConsolidatedHours(Integer pendingConsolidatedHours) {
|
||||
this.pendingConsolidatedHours = pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
@NotNull(message = "pending consolidated hours not specified")
|
||||
public Integer getPendingConsolidatedHours() {
|
||||
return pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
public void setResourceAllocation(ResourceAllocation<?> resourceAllocation) {
|
||||
this.resourceAllocation = resourceAllocation;
|
||||
}
|
||||
|
||||
@NotNull(message = "resource allocation not specified")
|
||||
public ResourceAllocation<?> getResourceAllocation() {
|
||||
return resourceAllocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
package org.navalplanner.business.planner.limiting.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package org.navalplanner.business.planner.daos;
|
||||
package org.navalplanner.business.planner.limiting.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDAO;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueDependency;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency;
|
||||
|
||||
/**
|
||||
* Interface for repositories to implement queies related to
|
||||
|
|
@ -18,12 +18,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
package org.navalplanner.business.planner.limiting.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDAO;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
|
||||
/**
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
package org.navalplanner.business.planner.limiting.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package org.navalplanner.business.planner.daos;
|
||||
package org.navalplanner.business.planner.limiting.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.planner.entities.Dependency;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueDependency;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
package org.navalplanner.business.planner.limiting.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ import org.hibernate.Criteria;
|
|||
import org.hibernate.criterion.Order;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.limiting.entities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.planner.entities.DayAssignment;
|
||||
import org.navalplanner.business.planner.entities.GenericDayAssignment;
|
||||
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.SpecificDayAssignment;
|
||||
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
||||
public abstract class AllocationOnGap {
|
||||
|
||||
public static AllocationOnGap invalidOn(Gap gap) {
|
||||
return new InvalidAllocationOnGap(gap);
|
||||
}
|
||||
|
||||
public static AllocationOnGap validOn(Gap gap, DateAndHour start,
|
||||
DateAndHour endExclusive, int[] assignableHours) {
|
||||
return new ValidAllocationOnGap(gap, start, endExclusive,
|
||||
assignableHours);
|
||||
}
|
||||
|
||||
private final Gap originalGap;
|
||||
|
||||
protected AllocationOnGap(Gap originalGap) {
|
||||
Validate.notNull(originalGap);
|
||||
this.originalGap = originalGap;
|
||||
}
|
||||
|
||||
public abstract boolean isValid();
|
||||
|
||||
public abstract List<DayAssignment> getAssignmentsFor(
|
||||
ResourceAllocation<?> allocation, Resource resource)
|
||||
throws IllegalStateException;
|
||||
|
||||
public abstract DateAndHour getStartInclusive()
|
||||
throws IllegalStateException;
|
||||
|
||||
public abstract DateAndHour getEndExclusive() throws IllegalStateException;
|
||||
|
||||
public Gap getOriginalGap() {
|
||||
return originalGap;
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidAllocationOnGap extends AllocationOnGap {
|
||||
|
||||
private static final String INVALID_ALLOCATION_ON_GAP = "invalid allocation on gap";
|
||||
|
||||
InvalidAllocationOnGap(Gap originalGap) {
|
||||
super(originalGap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DayAssignment> getAssignmentsFor(
|
||||
ResourceAllocation<?> allocation, Resource resource) {
|
||||
throw new IllegalStateException(INVALID_ALLOCATION_ON_GAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateAndHour getEndExclusive() throws IllegalStateException {
|
||||
throw new IllegalStateException(INVALID_ALLOCATION_ON_GAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateAndHour getStartInclusive() throws IllegalStateException {
|
||||
throw new IllegalStateException(INVALID_ALLOCATION_ON_GAP);
|
||||
}
|
||||
}
|
||||
|
||||
class ValidAllocationOnGap extends AllocationOnGap {
|
||||
|
||||
private final DateAndHour start;
|
||||
private final DateAndHour end;
|
||||
private final int[] assignableHours;
|
||||
|
||||
public ValidAllocationOnGap(Gap gap, DateAndHour startInclusive,
|
||||
DateAndHour endExclusive, int[] assignableHours) {
|
||||
super(gap);
|
||||
Validate.notNull(startInclusive);
|
||||
Validate.notNull(endExclusive);
|
||||
Validate.notNull(assignableHours);
|
||||
Validate.isTrue(endExclusive.isAfter(startInclusive));
|
||||
this.start = startInclusive;
|
||||
this.end = endExclusive;
|
||||
Validate.isTrue(assignableHours.length == toFiniteList(
|
||||
start.daysUntil(end)).size());
|
||||
this.assignableHours = assignableHours.clone();
|
||||
}
|
||||
|
||||
private List<LocalDate> toFiniteList(Iterable<LocalDate> daysUntil) {
|
||||
List<LocalDate> result = new ArrayList<LocalDate>();
|
||||
for (LocalDate each : daysUntil) {
|
||||
result.add(each);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DayAssignment> getAssignmentsFor(
|
||||
ResourceAllocation<?> allocation, Resource resource)
|
||||
throws IllegalStateException {
|
||||
List<LocalDate> days = toFiniteList(start.daysUntil(end));
|
||||
assert assignableHours.length == days.size();
|
||||
if (allocation instanceof SpecificResourceAllocation) {
|
||||
return createSpecific(days,
|
||||
(SpecificResourceAllocation) allocation, resource);
|
||||
} else {
|
||||
return createGeneric(days, (GenericResourceAllocation) allocation,
|
||||
resource);
|
||||
}
|
||||
}
|
||||
|
||||
private List<DayAssignment> createSpecific(List<LocalDate> days,
|
||||
SpecificResourceAllocation allocation, Resource resource) {
|
||||
List<DayAssignment> result = new ArrayList<DayAssignment>();
|
||||
int i = 0;
|
||||
for (LocalDate each : days) {
|
||||
result.add(SpecificDayAssignment.create(each, assignableHours[i],
|
||||
resource));
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<DayAssignment> createGeneric(List<LocalDate> days,
|
||||
GenericResourceAllocation allocation, Resource resource) {
|
||||
List<DayAssignment> result = new ArrayList<DayAssignment>();
|
||||
int i = 0;
|
||||
for (LocalDate each : days) {
|
||||
result.add(GenericDayAssignment.create(each, assignableHours[i],
|
||||
resource));
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateAndHour getEndExclusive() throws IllegalStateException {
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateAndHour getStartInclusive() throws IllegalStateException {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.limiting.entities;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class DateAndHour implements Comparable<DateAndHour> {
|
||||
|
||||
public static DateAndHour from(LocalDate date) {
|
||||
return new DateAndHour(date, 0);
|
||||
}
|
||||
|
||||
private LocalDate date;
|
||||
|
||||
private Integer hour;
|
||||
|
||||
public DateAndHour(LocalDate date, Integer hour) {
|
||||
Validate.notNull(date);
|
||||
this.date = date;
|
||||
this.hour = hour;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public Integer getHour() {
|
||||
return hour;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(DateAndHour time) {
|
||||
Validate.notNull(time);
|
||||
int compareDate = date.compareTo(getDate(time));
|
||||
return (compareDate != 0) ? compareDate : compareHour(time
|
||||
.getHour());
|
||||
}
|
||||
|
||||
private LocalDate getDate(DateAndHour dateAndHour) {
|
||||
return (dateAndHour != null) ? dateAndHour.getDate() : null;
|
||||
}
|
||||
|
||||
private int compareHour(int hour) {
|
||||
int deltaHour = this.hour - hour;
|
||||
return (deltaHour != 0) ? deltaHour / Math.abs(deltaHour) : 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return date + "; " + hour;
|
||||
}
|
||||
|
||||
public DateTime toDateTime() {
|
||||
return date.toDateTimeAtStartOfDay().plusHours(hour);
|
||||
}
|
||||
|
||||
public static DateAndHour Max(DateAndHour arg0, DateAndHour arg1) {
|
||||
if (arg0 == null) {
|
||||
return arg1;
|
||||
}
|
||||
if (arg1 == null) {
|
||||
return arg0;
|
||||
}
|
||||
return (arg0.compareTo(arg1) > 0) ? arg0 : arg1;
|
||||
}
|
||||
|
||||
public boolean isBefore(DateAndHour dateAndHour) {
|
||||
return (this.compareTo(dateAndHour) < 0);
|
||||
}
|
||||
|
||||
public boolean isAfter(DateAndHour dateAndHour) {
|
||||
return (this.compareTo(dateAndHour) > 0);
|
||||
}
|
||||
|
||||
public boolean isEquals(DateAndHour dateAndHour) {
|
||||
return (this.compareTo(dateAndHour) == 0);
|
||||
}
|
||||
|
||||
public boolean isAfter(LocalDate date) {
|
||||
return isAfter(DateAndHour.from(date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link Iterable} that returns a lazy iterator. If
|
||||
* <code>end</code> is <code>null</code> it will not stop and will keep on
|
||||
* producing days forever
|
||||
*/
|
||||
public Iterable<LocalDate> daysUntil(final DateAndHour end) {
|
||||
Validate.isTrue(end == null || end.isAfter(this));
|
||||
return new Iterable<LocalDate>() {
|
||||
@Override
|
||||
public Iterator<LocalDate> iterator() {
|
||||
return new Iterator<LocalDate>() {
|
||||
|
||||
private LocalDate current = getDate();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return end == null || end.isAfter(current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDate next() {
|
||||
LocalDate result = current;
|
||||
current = current.plusDays(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.limiting.entities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine;
|
||||
import org.navalplanner.business.calendars.entities.BaseCalendar;
|
||||
import org.navalplanner.business.calendars.entities.ResourceCalendar;
|
||||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.DatePoint;
|
||||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.EndOfTime;
|
||||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.FixedPoint;
|
||||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.Interval;
|
||||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine.StartOfTime;
|
||||
import org.navalplanner.business.planner.entities.AvailabilityCalculator;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class Gap implements Comparable<Gap> {
|
||||
|
||||
public static class GapOnQueue {
|
||||
|
||||
public static List<GapOnQueue> onQueue(LimitingResourceQueue queue,
|
||||
Collection<? extends Gap> gaps) {
|
||||
List<GapOnQueue> result = new ArrayList<GapOnQueue>();
|
||||
for (Gap each : gaps) {
|
||||
result.add(each.onQueue(queue));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private final LimitingResourceQueue originQueue;
|
||||
|
||||
private final Gap gap;
|
||||
|
||||
GapOnQueue(LimitingResourceQueue originQueue, Gap gap) {
|
||||
this.originQueue = originQueue;
|
||||
this.gap = gap;
|
||||
}
|
||||
|
||||
public LimitingResourceQueue getOriginQueue() {
|
||||
return originQueue;
|
||||
}
|
||||
|
||||
public Gap getGap() {
|
||||
return gap;
|
||||
}
|
||||
|
||||
public List<GapOnQueue> splitIntoGapsSatisfyingCriteria(
|
||||
Set<Criterion> criteria) {
|
||||
return GapOnQueue.onQueue(originQueue, gap
|
||||
.splitIntoGapsSatisfyingCriteria(originQueue.getResource(),
|
||||
criteria));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DateAndHour startTime;
|
||||
|
||||
private DateAndHour endTime;
|
||||
|
||||
private Integer hoursInGap;
|
||||
|
||||
public Gap(Resource resource, DateAndHour startTime,
|
||||
DateAndHour endTime) {
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
hoursInGap = calculateHoursInGap(resource, startTime, endTime);
|
||||
}
|
||||
|
||||
public GapOnQueue onQueue(LimitingResourceQueue queue) {
|
||||
return new GapOnQueue(queue, this);
|
||||
}
|
||||
|
||||
private Integer calculateHoursInGap(Resource resource, DateAndHour startTime, DateAndHour endTime) {
|
||||
// TODO remove this method. Use GapRequirements instead
|
||||
if (endTime == null || startTime == null) {
|
||||
// startTime is never null when hours in gap is really use
|
||||
return Integer.MAX_VALUE;
|
||||
} else {
|
||||
return calculateHoursInGap(resource, startTime.getDate(), startTime
|
||||
.getHour(), endTime.getDate(), endTime.getHour());
|
||||
}
|
||||
}
|
||||
|
||||
public int getHoursInGap() {
|
||||
return hoursInGap;
|
||||
}
|
||||
|
||||
private Integer calculateHoursInGap(Resource resource, LocalDate startDate,
|
||||
int startHour, LocalDate endDate, int endHour) {
|
||||
|
||||
final ResourceCalendar calendar = resource.getCalendar();
|
||||
|
||||
if (startDate.equals(endDate)) {
|
||||
return calendar.getCapacityAt(startDate) - Math.max(startHour, endHour);
|
||||
} else {
|
||||
int hoursAtStart = calendar.getCapacityAt(startDate) - startHour;
|
||||
int hoursInBetween = calendar.getWorkableHours(startDate
|
||||
.plusDays(1), endDate.minusDays(1));
|
||||
return hoursAtStart + hoursInBetween + endHour;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Integer> getHoursInGapUntilAllocatingAndGoingToTheEnd(
|
||||
BaseCalendar calendar,
|
||||
DateAndHour realStart, DateAndHour allocationEnd, int total) {
|
||||
DateAndHour gapEnd = getEndTime();
|
||||
Validate.isTrue(gapEnd == null || allocationEnd.compareTo(gapEnd) <= 0);
|
||||
Validate.isTrue(startTime == null
|
||||
|| realStart.compareTo(startTime) >= 0);
|
||||
List<Integer> result = new ArrayList<Integer>();
|
||||
Iterator<LocalDate> daysUntilEnd = realStart.daysUntil(gapEnd)
|
||||
.iterator();
|
||||
boolean isFirst = true;
|
||||
while (daysUntilEnd.hasNext()) {
|
||||
LocalDate each = daysUntilEnd.next();
|
||||
final boolean isLast = !daysUntilEnd.hasNext();
|
||||
int hoursAtDay = getHoursAtDay(each, calendar, realStart, isFirst,
|
||||
isLast);
|
||||
final int hours;
|
||||
if (total > 0) {
|
||||
hours = Math.min(hoursAtDay, total);
|
||||
total -= hours;
|
||||
} else {
|
||||
hours = hoursAtDay;
|
||||
}
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
}
|
||||
result.add(hours);
|
||||
if (total == 0
|
||||
&& DateAndHour.from(each).compareTo(allocationEnd) >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int getHoursAtDay(LocalDate day, BaseCalendar calendar,
|
||||
DateAndHour realStart, boolean isFirst, final boolean isLast) {
|
||||
final int capacity = calendar.getCapacityAt(day);
|
||||
if (isLast && isFirst) {
|
||||
return Math.min(endTime.getHour() - realStart.getHour(),
|
||||
capacity);
|
||||
} else if (isFirst) {
|
||||
return capacity - realStart.getHour();
|
||||
} else if (isLast) {
|
||||
return Math.min(endTime.getHour(), capacity);
|
||||
} else {
|
||||
return capacity;
|
||||
}
|
||||
}
|
||||
|
||||
public static Gap create(Resource resource, DateAndHour startTime,
|
||||
DateAndHour endTime) {
|
||||
return new Gap(resource, startTime, endTime);
|
||||
}
|
||||
|
||||
public DateAndHour getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public DateAndHour getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the gap starts after earlierStartDateBecauseOfGantt and
|
||||
* if it's big enough for fitting candidate
|
||||
*
|
||||
* @param hours
|
||||
* @return
|
||||
*/
|
||||
public boolean canFit(LimitingResourceQueueElement candidate) {
|
||||
LocalDate startAfter = LocalDate.fromDateFields(candidate
|
||||
.getEarlierStartDateBecauseOfGantt());
|
||||
LocalDate endsAfter = LocalDate.fromDateFields(candidate
|
||||
.getEarliestEndDateBecauseOfGantt());
|
||||
|
||||
return canSatisfyStartConstraint(startAfter)
|
||||
&& canSatisfyEndConstraint(endsAfter)
|
||||
&& hoursInGap >= candidate.getIntentedTotalHours();
|
||||
}
|
||||
|
||||
private boolean canSatisfyStartConstraint(final LocalDate startsAfter) {
|
||||
return startsAfter.compareTo(startTime.getDate()) <= 0;
|
||||
}
|
||||
|
||||
private boolean canSatisfyEndConstraint(LocalDate endsAfter) {
|
||||
return endTime == null || endsAfter.compareTo(endTime.getDate()) <= 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String result = startTime.getDate() + " - " + startTime.getHour();
|
||||
if (endTime != null) {
|
||||
result += "; " + endTime.getDate() + " - " + endTime.getHour();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Gap other) {
|
||||
if (other == null) {
|
||||
return 1;
|
||||
}
|
||||
if (this.getStartTime() == null && other.getStartTime() == null) {
|
||||
return 0;
|
||||
} else if (this.getStartTime() == null) {
|
||||
return -1;
|
||||
} else if (other.getStartTime() == null) {
|
||||
return 1;
|
||||
}
|
||||
return this.getStartTime().compareTo(other.getStartTime());
|
||||
}
|
||||
|
||||
public boolean isBefore(Gap gap) {
|
||||
return (compareTo(gap) < 0);
|
||||
}
|
||||
|
||||
public List<Gap> splitIntoGapsSatisfyingCriteria(Resource resource,
|
||||
Set<Criterion> criteria) {
|
||||
return splitIntoGapsSatisfyingCriteria(resource, criteria,
|
||||
getStartTime(), getEndTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of {@link Gap} composed by those gaps which satisfy
|
||||
* <em>criteria</em> within the period: <em>gapStartTime</em> till
|
||||
* <em>gapEndTime</em>
|
||||
* @param resource
|
||||
* @param criteria
|
||||
* criteria to be satisfied by resource
|
||||
* @param gapStartTime
|
||||
* start time of gap
|
||||
* @param gapEndTime
|
||||
* end time of gap
|
||||
* @return
|
||||
*/
|
||||
private static List<Gap> splitIntoGapsSatisfyingCriteria(Resource resource,
|
||||
Set<Criterion> criteria, DateAndHour gapStartTime,
|
||||
DateAndHour gapEndTime) {
|
||||
AvailabilityTimeLine criterionsAvailability = AvailabilityCalculator
|
||||
.getCriterionsAvailabilityFor(criteria, resource);
|
||||
if (gapStartTime != null) {
|
||||
criterionsAvailability.invalidUntil(gapStartTime.getDate());
|
||||
}
|
||||
if (gapEndTime != null) {
|
||||
criterionsAvailability.invalidFrom(gapEndTime.getDate());
|
||||
}
|
||||
List<Interval> validPeriods = criterionsAvailability.getValidPeriods();
|
||||
List<Gap> result = new ArrayList<Gap>();
|
||||
for (Interval each : validPeriods) {
|
||||
result.add(createGap(resource, each, gapStartTime, gapEndTime));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Gap createGap(Resource resource, Interval interval,
|
||||
DateAndHour originalGapStartTime, DateAndHour originalGapEndTime) {
|
||||
DateAndHour start = convert(originalGapStartTime, interval.getStart());
|
||||
DateAndHour end = convert(originalGapEndTime, interval.getEnd());
|
||||
return Gap.create(resource, start, end);
|
||||
}
|
||||
|
||||
private static DateAndHour convert(DateAndHour possibleMatch,
|
||||
DatePoint datePoint) {
|
||||
if (datePoint instanceof StartOfTime || datePoint instanceof EndOfTime) {
|
||||
return null;
|
||||
}
|
||||
FixedPoint p = (FixedPoint) datePoint;
|
||||
if (possibleMatch != null
|
||||
&& possibleMatch.getDate().equals(p.getDate())) {
|
||||
return possibleMatch;
|
||||
}
|
||||
return DateAndHour.from(p.getDate());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.limiting.entities;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.planner.limiting.entities.Gap.GapOnQueue;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class GapRequirements {
|
||||
|
||||
private final LimitingResourceQueueElement element;
|
||||
|
||||
private final DateAndHour earliestPossibleStart;
|
||||
|
||||
private final DateAndHour earliestPossibleEnd;
|
||||
|
||||
public static GapRequirements forElement(
|
||||
LimitingResourceQueueElement element,
|
||||
List<LimitingResourceQueueDependency> dependenciesAffectingStart,
|
||||
List<LimitingResourceQueueDependency> dependenciesAffectingEnd) {
|
||||
return new GapRequirements(element, calculateEarliestPossibleStart(
|
||||
element, dependenciesAffectingStart),
|
||||
calculateEarliestPossibleEnd(element, dependenciesAffectingEnd));
|
||||
}
|
||||
|
||||
private static DateAndHour calculateEarliestPossibleEnd(
|
||||
LimitingResourceQueueElement element,
|
||||
List<LimitingResourceQueueDependency> dependenciesAffectingEnd) {
|
||||
return DateAndHour.Max(asDateAndHour(element
|
||||
.getEarliestEndDateBecauseOfGantt()),
|
||||
max(dependenciesAffectingEnd));
|
||||
}
|
||||
|
||||
private static DateAndHour calculateEarliestPossibleStart(
|
||||
LimitingResourceQueueElement element,
|
||||
List<LimitingResourceQueueDependency> dependenciesAffectingStart) {
|
||||
return DateAndHour.Max(asDateAndHour(element
|
||||
.getEarlierStartDateBecauseOfGantt()),
|
||||
max(dependenciesAffectingStart));
|
||||
}
|
||||
|
||||
private static DateAndHour max(
|
||||
List<LimitingResourceQueueDependency> dependencies) {
|
||||
DateAndHour result = null;
|
||||
for (LimitingResourceQueueDependency each : dependencies) {
|
||||
assert !each.getHasAsOrigin().isDetached();
|
||||
result = DateAndHour.Max(result, each.getDateFromOrigin());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static DateAndHour asDateAndHour(Date date) {
|
||||
return DateAndHour.from(LocalDate.fromDateFields(date));
|
||||
}
|
||||
|
||||
private GapRequirements(LimitingResourceQueueElement element,
|
||||
DateAndHour earliestPossibleStart, DateAndHour earliestPossibleEnd) {
|
||||
Validate.notNull(element);
|
||||
Validate.notNull(earliestPossibleStart);
|
||||
Validate.notNull(earliestPossibleEnd);
|
||||
this.element = element;
|
||||
this.earliestPossibleStart = earliestPossibleStart;
|
||||
this.earliestPossibleEnd = earliestPossibleEnd;
|
||||
}
|
||||
|
||||
public boolean isPotentiallyValid(Gap gap) {
|
||||
DateAndHour gapEnd = gap.getEndTime();
|
||||
return gapEnd == null
|
||||
|| (earliestPossibleStart.isBefore(gapEnd) && !earliestPossibleEnd
|
||||
.isAfter(gapEnd));
|
||||
}
|
||||
|
||||
public AllocationOnGap guessValidity(GapOnQueue gapOnQueue) {
|
||||
Gap gap = gapOnQueue.getGap();
|
||||
if (!isPotentiallyValid(gap)) {
|
||||
return AllocationOnGap.invalidOn(gap);
|
||||
}
|
||||
DateAndHour realStart = DateAndHour.Max(earliestPossibleStart, gap
|
||||
.getStartTime());
|
||||
Resource resource = gapOnQueue.getOriginQueue().getResource();
|
||||
List<Integer> hours = gap.getHoursInGapUntilAllocatingAndGoingToTheEnd(
|
||||
resource.getCalendar(), realStart,
|
||||
earliestPossibleEnd, element.getIntentedTotalHours());
|
||||
int total = sum(hours);
|
||||
if (total < element.getIntentedTotalHours()) {
|
||||
return AllocationOnGap.invalidOn(gap);
|
||||
} else if (total == element.getIntentedTotalHours()) {
|
||||
return validAllocation(gap, realStart, hours);
|
||||
} else {
|
||||
assert total > element.getIntentedTotalHours();
|
||||
int hoursSurplus = total - element.getIntentedTotalHours();
|
||||
StartRemoval result = StartRemoval.removeStartSurplus(realStart,
|
||||
hours, hoursSurplus);
|
||||
return validAllocation(gap, result.newStart, result.hours);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private AllocationOnGap validAllocation(Gap gap, DateAndHour realStart,
|
||||
List<Integer> hours) {
|
||||
return AllocationOnGap.validOn(gap, realStart, calculateEnd(realStart,
|
||||
hours), asArray(hours));
|
||||
}
|
||||
|
||||
private DateAndHour calculateEnd(DateAndHour realStart, List<Integer> hours) {
|
||||
if (hours.size() == 1) {
|
||||
return new DateAndHour(realStart.getDate(), hours.get(0)
|
||||
+ realStart.getHour());
|
||||
}
|
||||
return new DateAndHour(realStart.getDate().plusDays(hours.size() - 1),
|
||||
getLast(hours));
|
||||
}
|
||||
|
||||
private int getLast(List<Integer> hours) {
|
||||
return hours.get(hours.size() - 1);
|
||||
}
|
||||
|
||||
private static class StartRemoval {
|
||||
|
||||
/**
|
||||
* removes the initial assignments so the resulting list has
|
||||
* <code>hoursSurplus</code> less hours
|
||||
*/
|
||||
static StartRemoval removeStartSurplus(DateAndHour start,
|
||||
List<Integer> hours, int hoursSurplus) {
|
||||
int previousSize = hours.size();
|
||||
int hoursRemovedAtFirstDayOfNewHours = stripStartAssignments(hours,
|
||||
hoursSurplus);
|
||||
int currentSize = hours.size();
|
||||
int daysRemoved = previousSize - currentSize;
|
||||
LocalDate newStartDay = start.getDate().plusDays(daysRemoved);
|
||||
return new StartRemoval(new DateAndHour(newStartDay,
|
||||
hoursRemovedAtFirstDayOfNewHours), hours);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hours reduced in the resulting first assignment
|
||||
*/
|
||||
private static int stripStartAssignments(List<Integer> hours,
|
||||
int hoursSurplus) {
|
||||
ListIterator<Integer> listIterator = hours.listIterator();
|
||||
while (listIterator.hasNext() && hoursSurplus > 0) {
|
||||
Integer current = listIterator.next();
|
||||
int hoursTaken = Math.min(hoursSurplus, current);
|
||||
hoursSurplus -= hoursTaken;
|
||||
if (hoursTaken == current) {
|
||||
listIterator.remove();
|
||||
} else {
|
||||
listIterator.set(hoursTaken);
|
||||
return current - hoursTaken;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private final DateAndHour newStart;
|
||||
|
||||
private final List<Integer> hours;
|
||||
|
||||
private StartRemoval(DateAndHour newStart, List<Integer> hours) {
|
||||
this.newStart = newStart;
|
||||
this.hours = hours;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] asArray(Collection<Integer> integers) {
|
||||
int[] result = new int[integers.size()];
|
||||
int i = 0;
|
||||
for (Integer each : integers) {
|
||||
result[i++] = each;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int sum(List<Integer> hours) {
|
||||
int result = 0;
|
||||
for (int each : hours) {
|
||||
result += each;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* 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.business.planner.limiting.entities;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.calendars.entities.ResourceCalendar;
|
||||
import org.navalplanner.business.planner.entities.DayAssignment;
|
||||
import org.navalplanner.business.planner.entities.GenericDayAssignment;
|
||||
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.ResourcesPerDay;
|
||||
import org.navalplanner.business.planner.entities.SpecificDayAssignment;
|
||||
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
||||
/**
|
||||
* Handles all the logic related to allocation of
|
||||
* {@link LimitingResourceQueueElement} into {@link LimitingResourceQueue}
|
||||
*
|
||||
* The class does not do the allocation itself but provides methods:
|
||||
* <em>getFirstValidGap</em>, <em>calculateStartAndEndTime</em> or
|
||||
* <em>generateDayAssignments</em>, needed to do the allocation of
|
||||
* {@link LimitingResourceQueueElement}
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class LimitingResourceAllocator {
|
||||
|
||||
private final static ResourcesPerDay ONE_RESOURCE_PER_DAY = ResourcesPerDay
|
||||
.amount(new BigDecimal(1));
|
||||
|
||||
/**
|
||||
* Returns first valid gap in queue for element
|
||||
*
|
||||
* Returns null if there is not a valid gap. This case can only happen on
|
||||
* trying to allocate an element related to a generic resource allocation.
|
||||
* It is possible that queue.resource does not hold element.criteria at any
|
||||
* interval of time
|
||||
*
|
||||
* @param queue search gap inside queue
|
||||
* @param element element to fit into queue
|
||||
* @return
|
||||
*/
|
||||
public static Gap getFirstValidGap(
|
||||
LimitingResourceQueue queue, LimitingResourceQueueElement element) {
|
||||
|
||||
final Resource resource = queue.getResource();
|
||||
final List<LimitingResourceQueueElement> elements = new LinkedList<LimitingResourceQueueElement>(
|
||||
queue.getLimitingResourceQueueElements());
|
||||
final int size = elements.size();
|
||||
final DateAndHour startTime = getStartTimeBecauseOfGantt(element);
|
||||
|
||||
int pos = 0;
|
||||
|
||||
// Iterate through queue elements
|
||||
while (pos <= size) {
|
||||
Gap gap = getGapInQueueAtPosition(
|
||||
resource, elements, startTime, pos++);
|
||||
|
||||
if (gap != null) {
|
||||
List<Gap> subgaps = getFittingSubgaps(
|
||||
element, gap, resource);
|
||||
if (!subgaps.isEmpty()) {
|
||||
return subgaps.get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The queue cannot hold this element (queue.resource
|
||||
// doesn't meet element.criteria)
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<Gap> getFittingSubgaps(
|
||||
LimitingResourceQueueElement element,
|
||||
final Gap gap, final Resource resource) {
|
||||
|
||||
List<Gap> result = new ArrayList<Gap>();
|
||||
|
||||
if (isSpecific(element) && gap.canFit(element)) {
|
||||
result.add(gap);
|
||||
} else if (isGeneric(element)) {
|
||||
final List<Gap> gaps = gap.splitIntoGapsSatisfyingCriteria(
|
||||
resource, element.getCriteria());
|
||||
for (Gap subgap : gaps) {
|
||||
if (subgap.canFit(element)) {
|
||||
result.add(subgap);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Gap getFirstValidGapSince(
|
||||
LimitingResourceQueueElement element, LimitingResourceQueue queue,
|
||||
DateAndHour since) {
|
||||
List<Gap> gaps = getValidGapsForElementSince(element, queue, since);
|
||||
return (!gaps.isEmpty()) ? gaps.get(0) : null;
|
||||
}
|
||||
|
||||
public static List<Gap> getValidGapsForElementSince(
|
||||
LimitingResourceQueueElement element, LimitingResourceQueue queue,
|
||||
DateAndHour since) {
|
||||
|
||||
List<Gap> result = new ArrayList<Gap>();
|
||||
|
||||
final Resource resource = queue.getResource();
|
||||
final List<LimitingResourceQueueElement> elements = new LinkedList<LimitingResourceQueueElement>(
|
||||
queue.getLimitingResourceQueueElements());
|
||||
final int size = elements.size();
|
||||
|
||||
int pos = moveUntil(elements, since);
|
||||
|
||||
// Iterate through queue elements
|
||||
while (pos <= size) {
|
||||
Gap gap = getGapInQueueAtPosition(
|
||||
resource, elements, since, pos++);
|
||||
|
||||
// The queue cannot hold this element (queue.resource
|
||||
// doesn't meet element.criteria)
|
||||
if (gap != null) {
|
||||
List<Gap> subgaps = getFittingSubgaps(
|
||||
element, gap, resource);
|
||||
result.addAll(subgaps);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int moveUntil(List<LimitingResourceQueueElement> elements, DateAndHour until) {
|
||||
int pos = 0;
|
||||
|
||||
if (elements.size() > 0) {
|
||||
// Space between until and first element start time
|
||||
LimitingResourceQueueElement first = elements.get(0);
|
||||
if (until.isBefore(first.getStartTime())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (pos = 0; pos < elements.size(); pos++) {
|
||||
final LimitingResourceQueueElement each = elements.get(pos);
|
||||
final DateAndHour startTime = each.getStartTime();
|
||||
if (until.isAfter(startTime) || until.isEquals(startTime)) {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
private static boolean isGeneric(LimitingResourceQueueElement element) {
|
||||
return element.getResourceAllocation() instanceof GenericResourceAllocation;
|
||||
}
|
||||
|
||||
private static boolean isSpecific(LimitingResourceQueueElement element) {
|
||||
return element.getResourceAllocation() instanceof SpecificResourceAllocation;
|
||||
}
|
||||
|
||||
public static DateAndHour getFirstElementTime(List<DayAssignment> dayAssignments) {
|
||||
final DayAssignment start = dayAssignments.get(0);
|
||||
return new DateAndHour(start.getDay(), start.getHours());
|
||||
}
|
||||
|
||||
public static DateAndHour getLastElementTime(List<DayAssignment> dayAssignments) {
|
||||
final DayAssignment end = dayAssignments.get(dayAssignments.size() - 1);
|
||||
return new DateAndHour(end.getDay(), end.getHours());
|
||||
}
|
||||
|
||||
private static Gap getGapInQueueAtPosition(
|
||||
Resource resource, List<LimitingResourceQueueElement> elements,
|
||||
DateAndHour startTimeBecauseOfGantt, int pos) {
|
||||
|
||||
final int size = elements.size();
|
||||
|
||||
// No elements in queue
|
||||
if (size == 0) {
|
||||
return createLastGap(startTimeBecauseOfGantt, null, resource);
|
||||
}
|
||||
|
||||
// Last element
|
||||
if (pos == size) {
|
||||
return createLastGap(startTimeBecauseOfGantt, elements.get(size - 1), resource);
|
||||
}
|
||||
|
||||
LimitingResourceQueueElement next = elements.get(pos);
|
||||
|
||||
// First element
|
||||
if (pos == 0
|
||||
&& startTimeBecauseOfGantt.getDate().isBefore(
|
||||
next.getStartDate())) {
|
||||
return Gap.create(resource,
|
||||
startTimeBecauseOfGantt, next.getStartTime());
|
||||
}
|
||||
|
||||
// In the middle of two elements
|
||||
if (pos > 0) {
|
||||
LimitingResourceQueueElement previous = elements.get(pos - 1);
|
||||
return Gap.create(resource, DateAndHour
|
||||
.Max(previous.getEndTime(), startTimeBecauseOfGantt), next
|
||||
.getStartTime());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DateAndHour getStartTimeBecauseOfGantt(LimitingResourceQueueElement element) {
|
||||
return new DateAndHour(new LocalDate(element.getEarlierStartDateBecauseOfGantt()), 0);
|
||||
}
|
||||
|
||||
private static Gap createLastGap(
|
||||
DateAndHour _startTime, LimitingResourceQueueElement lastElement,
|
||||
Resource resource) {
|
||||
|
||||
final DateAndHour queueEndTime = (lastElement != null) ? lastElement
|
||||
.getEndTime() : null;
|
||||
DateAndHour startTime = DateAndHour.Max(_startTime, queueEndTime);
|
||||
return Gap
|
||||
.create(resource, startTime, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of {@link DayAssignment} for {@link Resource} starting
|
||||
* from startTime
|
||||
*
|
||||
* The returned list is not associated to resouceAllocation.
|
||||
*
|
||||
* resourceAllocation is passed to know if the list of day assignments
|
||||
* should be {@link GenericDayAssignment} or {@link SpecificDayAssignment}
|
||||
*
|
||||
* @param resourceAllocation
|
||||
* @param resource
|
||||
* @param startTime
|
||||
* @return
|
||||
*/
|
||||
public static List<DayAssignment> generateDayAssignments(
|
||||
ResourceAllocation<?> resourceAllocation,
|
||||
Resource resource,
|
||||
DateAndHour startTime, DateAndHour endsAfter) {
|
||||
|
||||
List<DayAssignment> assignments = new LinkedList<DayAssignment>();
|
||||
|
||||
LocalDate date = startTime.getDate();
|
||||
final int totalHours = resourceAllocation.getIntendedTotalHours();
|
||||
int hoursAssigned = 0;
|
||||
// Generate first day assignment
|
||||
int hoursCanAllocate = hoursCanWorkOnDay(resource, date, startTime.getHour());
|
||||
int hoursToAllocate = Math.min(totalHours, hoursCanAllocate);
|
||||
DayAssignment dayAssignment = createDayAssignment(resourceAllocation,
|
||||
resource, date, hoursToAllocate);
|
||||
hoursAssigned += addDayAssignment(assignments, dayAssignment);
|
||||
|
||||
// Generate rest of day assignments
|
||||
for (date = date.plusDays(1); hoursAssigned < totalHours
|
||||
|| endsAfter.isAfter(date); date = date.plusDays(1)) {
|
||||
hoursAssigned += addDayAssignment(assignments,
|
||||
generateDayAssignment(resourceAllocation, resource, date,
|
||||
totalHours));
|
||||
}
|
||||
if (hoursAssigned > totalHours) {
|
||||
stripStartAssignments(assignments, hoursAssigned - totalHours);
|
||||
}
|
||||
return new ArrayList<DayAssignment>(assignments);
|
||||
}
|
||||
|
||||
private static void stripStartAssignments(List<DayAssignment> assignments,
|
||||
int hoursSurplus) {
|
||||
ListIterator<DayAssignment> listIterator = assignments.listIterator();
|
||||
while (listIterator.hasNext() && hoursSurplus > 0) {
|
||||
DayAssignment current = listIterator.next();
|
||||
int hoursTaken = Math.min(hoursSurplus, current.getHours());
|
||||
hoursSurplus -= hoursTaken;
|
||||
if (hoursTaken == current.getHours()) {
|
||||
listIterator.remove();
|
||||
} else {
|
||||
listIterator.set(current.withHours(hoursTaken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<DayAssignment> generateDayAssignmentsStartingFromEnd(ResourceAllocation<?> resourceAllocation,
|
||||
Resource resource,
|
||||
DateAndHour endTime) {
|
||||
|
||||
List<DayAssignment> assignments = new ArrayList<DayAssignment>();
|
||||
|
||||
LocalDate date = endTime.getDate();
|
||||
int totalHours = resourceAllocation.getIntendedTotalHours();
|
||||
|
||||
// Generate last day assignment
|
||||
int hoursCanAllocate = hoursCanWorkOnDay(resource, date, endTime.getHour());
|
||||
if (hoursCanAllocate > 0) {
|
||||
int hoursToAllocate = Math.min(totalHours, hoursCanAllocate);
|
||||
DayAssignment dayAssignment = createDayAssignment(resourceAllocation, resource, date, hoursToAllocate);
|
||||
totalHours -= addDayAssignment(assignments, dayAssignment);
|
||||
}
|
||||
|
||||
// Generate rest of day assignments
|
||||
for (date = date.minusDays(1); totalHours > 0; date = date.minusDays(1)) {
|
||||
totalHours -= addDayAssignment(assignments, generateDayAssignment(
|
||||
resourceAllocation, resource, date, totalHours));
|
||||
}
|
||||
return assignments;
|
||||
}
|
||||
|
||||
private static DayAssignment createDayAssignment(ResourceAllocation<?> resourceAllocation,
|
||||
Resource resource, LocalDate date, int hoursToAllocate) {
|
||||
if (resourceAllocation instanceof SpecificResourceAllocation) {
|
||||
return SpecificDayAssignment.create(date, hoursToAllocate, resource);
|
||||
} else if (resourceAllocation instanceof GenericResourceAllocation) {
|
||||
return GenericDayAssignment.create(date, hoursToAllocate, resource);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int addDayAssignment(List<DayAssignment> list, DayAssignment dayAssignment) {
|
||||
if (dayAssignment != null) {
|
||||
list.add(dayAssignment);
|
||||
return dayAssignment.getHours();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int hoursCanWorkOnDay(final Resource resource,
|
||||
final LocalDate date, int alreadyWorked) {
|
||||
final ResourceCalendar calendar = resource.getCalendar();
|
||||
int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY);
|
||||
return hoursCanAllocate - alreadyWorked;
|
||||
}
|
||||
|
||||
private static DayAssignment generateDayAssignment(
|
||||
final ResourceAllocation<?> resourceAllocation,
|
||||
Resource resource,
|
||||
final LocalDate date, int intentedHours) {
|
||||
|
||||
final ResourceCalendar calendar = resource.getCalendar();
|
||||
|
||||
int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY);
|
||||
if (hoursCanAllocate > 0) {
|
||||
int hoursToAllocate = Math.min(intentedHours, hoursCanAllocate);
|
||||
return createDayAssignment(resourceAllocation, resource, date, hoursToAllocate);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DateAndHour startTimeToAllocateStartingFromEnd(
|
||||
ResourceAllocation<?> resourceAllocation, Resource resource,
|
||||
Gap gap) {
|
||||
|
||||
// Last element, time is end of last element (gap.starttime)
|
||||
if (gap.getEndTime() == null) {
|
||||
return gap.getStartTime();
|
||||
}
|
||||
|
||||
final List<DayAssignment> dayAssignments = LimitingResourceAllocator
|
||||
.generateDayAssignmentsStartingFromEnd(resourceAllocation,
|
||||
resource, gap.getEndTime());
|
||||
|
||||
return LimitingResourceAllocator.getLastElementTime(dayAssignments);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
package org.navalplanner.business.planner.limiting.entities;
|
||||
|
||||
import static org.navalplanner.business.i18n.I18nHelper._;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.Dependency;
|
||||
import org.navalplanner.business.planner.entities.Dependency.Type;
|
||||
|
||||
|
||||
/**
|
||||
* Entity which represents the relationships between two
|
||||
* @{link LimitingResourceQueueElement}. One of the
|
||||
* @{link LimitingResourceQueueElement} is the origin of the relationship
|
||||
* and the other is the destiny of the relationship.
|
||||
*
|
||||
* @author Javier Moran Rua <jmoran@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class LimitingResourceQueueDependency extends BaseEntity {
|
||||
|
||||
public static enum QueueDependencyType {
|
||||
START_START(Type.START_START),
|
||||
END_START(Type.END_START),
|
||||
END_END(Type.END_END),
|
||||
START_END(Type.START_END);
|
||||
|
||||
private static EnumMap<Type, QueueDependencyType> toQueueDependencyType;
|
||||
|
||||
private static EnumMap<QueueDependencyType, Type> toDependencyType;
|
||||
|
||||
static {
|
||||
toQueueDependencyType = new EnumMap<Type, QueueDependencyType>(
|
||||
Type.class);
|
||||
toDependencyType = new EnumMap<QueueDependencyType, Type>(
|
||||
QueueDependencyType.class);
|
||||
for (QueueDependencyType each : QueueDependencyType.values()) {
|
||||
toQueueDependencyType.put(each.associatedType, each);
|
||||
toDependencyType.put(each, each.associatedType);
|
||||
}
|
||||
}
|
||||
|
||||
public static LimitingResourceQueueDependency.QueueDependencyType toQueueDependencyType(
|
||||
Type type) {
|
||||
return toQueueDependencyType.get(type);
|
||||
}
|
||||
|
||||
public static Type toDependencyType(QueueDependencyType type) {
|
||||
return toDependencyType.get(type);
|
||||
}
|
||||
|
||||
private final Type associatedType;
|
||||
|
||||
private QueueDependencyType(Type associatedType) {
|
||||
this.associatedType = associatedType;
|
||||
}
|
||||
|
||||
boolean propagatesThrough(QueueDependencyType nextType) {
|
||||
switch (this) {
|
||||
case END_START:
|
||||
case START_START:
|
||||
return true;
|
||||
case START_END:
|
||||
case END_END:
|
||||
return nextType.comesFromEnd();
|
||||
default:
|
||||
throw new RuntimeException("unknown type: " + this);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean comesFromEnd() {
|
||||
switch (this) {
|
||||
case START_END:
|
||||
case START_START:
|
||||
return false;
|
||||
case END_START:
|
||||
case END_END:
|
||||
return true;
|
||||
default:
|
||||
throw new RuntimeException("unknown type: " + this);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static LimitingResourceQueueDependency.QueueDependencyType toQueueDependencyType(
|
||||
Dependency.Type type) {
|
||||
return QueueDependencyType.toQueueDependencyType(type);
|
||||
}
|
||||
|
||||
private LimitingResourceQueueElement hasAsOrigin;
|
||||
private LimitingResourceQueueElement hasAsDestiny;
|
||||
private Dependency ganttDependency;
|
||||
private QueueDependencyType type;
|
||||
|
||||
public static LimitingResourceQueueDependency create(
|
||||
LimitingResourceQueueElement origin,
|
||||
LimitingResourceQueueElement destiny,
|
||||
Dependency ganttDependency,
|
||||
QueueDependencyType type) {
|
||||
LimitingResourceQueueDependency dependency = new
|
||||
LimitingResourceQueueDependency(origin,destiny,ganttDependency,type);
|
||||
dependency.setNewObject(true);
|
||||
origin.add(dependency);
|
||||
destiny.add(dependency);
|
||||
ganttDependency.setQueueDependency(dependency);
|
||||
return dependency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contructor for Hibernate. Do not use !
|
||||
*/
|
||||
public LimitingResourceQueueDependency() {}
|
||||
|
||||
private LimitingResourceQueueDependency(LimitingResourceQueueElement origin,
|
||||
LimitingResourceQueueElement destiny,
|
||||
Dependency ganttDependency,
|
||||
QueueDependencyType type) {
|
||||
Validate.notNull(origin);
|
||||
Validate.notNull(destiny);
|
||||
Validate.notNull(ganttDependency);
|
||||
Validate.isTrue(!origin.equals(destiny), _("A queue dependency has to " +
|
||||
"have an origin different from destiny"));
|
||||
this.hasAsOrigin = origin;
|
||||
this.hasAsDestiny = destiny;
|
||||
this.ganttDependency = ganttDependency;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElement getHasAsOrigin() {
|
||||
return hasAsOrigin;
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElement getHasAsDestiny() {
|
||||
return hasAsDestiny;
|
||||
}
|
||||
|
||||
public QueueDependencyType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Dependency getGanttDependency() {
|
||||
return ganttDependency;
|
||||
}
|
||||
|
||||
public boolean isOriginNotDetached() {
|
||||
return !hasAsOrigin.isDetached();
|
||||
}
|
||||
|
||||
private Dependency.Type getDependencyType() {
|
||||
return QueueDependencyType.toDependencyType(type);
|
||||
}
|
||||
|
||||
public boolean modifiesDestinationStart() {
|
||||
return getDependencyType().modifiesDestinationStart();
|
||||
}
|
||||
|
||||
public boolean modifiesDestinationEnd() {
|
||||
return getDependencyType().modifiesDestinationEnd();
|
||||
}
|
||||
|
||||
public DateAndHour getDateFromOrigin() {
|
||||
if (hasAsOrigin.isDetached()) {
|
||||
throw new IllegalStateException("origin detached");
|
||||
}
|
||||
switch (type) {
|
||||
case START_END:
|
||||
case START_START:
|
||||
return hasAsOrigin.getStartTime();
|
||||
case END_END:
|
||||
case END_START:
|
||||
return hasAsOrigin.getEndTime();
|
||||
default:
|
||||
throw new RuntimeException("unknown type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean propagatesThrough(LimitingResourceQueueDependency transitive) {
|
||||
return getHasAsDestiny().equals(transitive.getHasAsOrigin())
|
||||
&& type.propagatesThrough(transitive.getType());
|
||||
}
|
||||
}
|
||||
|
|
@ -18,24 +18,30 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities;
|
||||
package org.navalplanner.business.planner.limiting.entities;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.DayAssignment;
|
||||
import org.navalplanner.business.planner.entities.Dependency;
|
||||
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.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
||||
/**
|
||||
*
|
||||
* Entity which represents an element in the queue which represents
|
||||
* the limiting resources.
|
||||
*
|
||||
* Entity which represents an element in the queue which represents the limiting
|
||||
* resources.
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
* @author Javier Moran Rua <jmoran@igalia.com>
|
||||
*/
|
||||
|
|
@ -47,17 +53,17 @@ public class LimitingResourceQueueElement extends BaseEntity {
|
|||
|
||||
private Date earlierStartDateBecauseOfGantt;
|
||||
|
||||
private Date earliestEndDateBecauseOfGantt;
|
||||
|
||||
private QueuePosition startQueuePosition;
|
||||
|
||||
private QueuePosition endQueuePosition;
|
||||
|
||||
private long creationTimestamp;
|
||||
|
||||
private Set<LimitingResourceQueueDependency> dependenciesAsOrigin =
|
||||
new HashSet<LimitingResourceQueueDependency>();
|
||||
private Set<LimitingResourceQueueDependency> dependenciesAsOrigin = new HashSet<LimitingResourceQueueDependency>();
|
||||
|
||||
private Set<LimitingResourceQueueDependency> dependenciesAsDestiny =
|
||||
new HashSet<LimitingResourceQueueDependency>();
|
||||
private Set<LimitingResourceQueueDependency> dependenciesAsDestiny = new HashSet<LimitingResourceQueueDependency>();
|
||||
|
||||
public static LimitingResourceQueueElement create() {
|
||||
return create(new LimitingResourceQueueElement());
|
||||
|
|
@ -83,7 +89,8 @@ public class LimitingResourceQueueElement extends BaseEntity {
|
|||
return limitingResourceQueue;
|
||||
}
|
||||
|
||||
public void setLimitingResourceQueue(LimitingResourceQueue limitingResourceQueue) {
|
||||
public void setLimitingResourceQueue(
|
||||
LimitingResourceQueue limitingResourceQueue) {
|
||||
this.limitingResourceQueue = limitingResourceQueue;
|
||||
}
|
||||
|
||||
|
|
@ -123,9 +130,12 @@ public class LimitingResourceQueueElement extends BaseEntity {
|
|||
return earlierStartDateBecauseOfGantt;
|
||||
}
|
||||
|
||||
public void setEarlierStartDateBecauseOfGantt(
|
||||
Date earlierStartDateBecauseOfGantt) {
|
||||
this.earlierStartDateBecauseOfGantt = earlierStartDateBecauseOfGantt;
|
||||
public Date getEarliestEndDateBecauseOfGantt() {
|
||||
if (earliestEndDateBecauseOfGantt == null) {
|
||||
// can be null because it's a new column
|
||||
return earlierStartDateBecauseOfGantt;
|
||||
}
|
||||
return earliestEndDateBecauseOfGantt;
|
||||
}
|
||||
|
||||
public long getCreationTimestamp() {
|
||||
|
|
@ -164,9 +174,10 @@ public class LimitingResourceQueueElement extends BaseEntity {
|
|||
} else if (d.getHasAsDestiny().equals(this)) {
|
||||
dependenciesAsDestiny.add(d);
|
||||
} else {
|
||||
throw new IllegalArgumentException("It cannot be added a dependency" +
|
||||
" in which the current queue element is neither origin" +
|
||||
" not desinty");
|
||||
throw new IllegalArgumentException(
|
||||
"It cannot be added a dependency"
|
||||
+ " in which the current queue element is neither origin"
|
||||
+ " not desinty");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,4 +195,84 @@ public class LimitingResourceQueueElement extends BaseEntity {
|
|||
public Set<LimitingResourceQueueDependency> getDependenciesAsDestiny() {
|
||||
return Collections.unmodifiableSet(dependenciesAsDestiny);
|
||||
}
|
||||
|
||||
public void updateDates(Date orderInitDate,
|
||||
Collection<? extends Dependency> incomingDependencies) {
|
||||
this.earlierStartDateBecauseOfGantt = calculateStartDate(orderInitDate,
|
||||
incomingDependencies);
|
||||
this.earliestEndDateBecauseOfGantt = calculateEndDate(orderInitDate,
|
||||
incomingDependencies);
|
||||
}
|
||||
|
||||
private Date calculateStartDate(Date orderInitDate,
|
||||
Collection<? extends Dependency> dependenciesWithThisDestination) {
|
||||
Date result = orderInitDate;
|
||||
for (Dependency each : dependenciesWithThisDestination) {
|
||||
if (!each.isDependencyBetweenLimitedAllocatedTasks()
|
||||
&& each.getType().modifiesDestinationStart()) {
|
||||
result = bigger(result, each.getDateFromOrigin());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Date calculateEndDate(Date orderInitDate,
|
||||
Collection<? extends Dependency> incomingDependencies) {
|
||||
Date result = orderInitDate;
|
||||
for (Dependency each : incomingDependencies) {
|
||||
if (!each.isDependencyBetweenLimitedAllocatedTasks()
|
||||
&& each.getType().modifiesDestinationEnd()) {
|
||||
result = bigger(result, each.getDateFromOrigin());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Date bigger(Date one, Date another) {
|
||||
if (one == null) {
|
||||
return another;
|
||||
}
|
||||
if (another == null) {
|
||||
return one;
|
||||
}
|
||||
return one.compareTo(another) >= 0 ? one : another;
|
||||
}
|
||||
|
||||
public void detach() {
|
||||
setLimitingResourceQueue(null);
|
||||
setStartDate(null);
|
||||
setStartHour(0);
|
||||
setEndDate(null);
|
||||
setEndHour(0);
|
||||
getResourceAllocation().removeLimitingDayAssignments();
|
||||
}
|
||||
|
||||
public boolean isDetached() {
|
||||
return getStartDate() == null;
|
||||
}
|
||||
|
||||
public boolean isSpecific() {
|
||||
return resourceAllocation instanceof SpecificResourceAllocation;
|
||||
}
|
||||
|
||||
public boolean isGeneric() {
|
||||
return resourceAllocation instanceof GenericResourceAllocation;
|
||||
}
|
||||
|
||||
public Set<Criterion> getCriteria() {
|
||||
if (!isGeneric()) {
|
||||
throw new IllegalStateException("this is not a generic element");
|
||||
}
|
||||
final ResourceAllocation<?> resourceAllocation = getResourceAllocation();
|
||||
return ((GenericResourceAllocation) resourceAllocation).getCriterions();
|
||||
}
|
||||
|
||||
public boolean hasDayAssignments() {
|
||||
return !getResourceAllocation().getAssignments().isEmpty();
|
||||
}
|
||||
|
||||
public List<? extends DayAssignment> getDayAssignments() {
|
||||
return resourceAllocation.getAssignments();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities;
|
||||
package org.navalplanner.business.planner.limiting.entities;
|
||||
|
||||
import static org.navalplanner.business.i18n.I18nHelper._;
|
||||
|
||||
|
|
@ -20,12 +20,18 @@
|
|||
|
||||
package org.navalplanner.business.resources.entities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.limiting.entities.DateAndHour;
|
||||
import org.navalplanner.business.planner.limiting.entities.Gap;
|
||||
import org.navalplanner.business.planner.limiting.entities.GapRequirements;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.limiting.entities.Gap.GapOnQueue;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -39,6 +45,8 @@ public class LimitingResourceQueue extends BaseEntity {
|
|||
private SortedSet<LimitingResourceQueueElement> limitingResourceQueueElements =
|
||||
new TreeSet<LimitingResourceQueueElement>(new LimitingResourceQueueElementComparator());
|
||||
|
||||
private List<GapOnQueue> cachedGaps;
|
||||
|
||||
public static LimitingResourceQueue create() {
|
||||
return create(new LimitingResourceQueue());
|
||||
}
|
||||
|
|
@ -58,14 +66,53 @@ public class LimitingResourceQueue extends BaseEntity {
|
|||
public void addLimitingResourceQueueElement(LimitingResourceQueueElement element) {
|
||||
element.setLimitingResourceQueue(this);
|
||||
limitingResourceQueueElements.add(element);
|
||||
cachedGaps = null;
|
||||
}
|
||||
|
||||
public void removeLimitingResourceQueueElement(LimitingResourceQueueElement element) {
|
||||
limitingResourceQueueElements.remove(element);
|
||||
element.detach();
|
||||
cachedGaps = null;
|
||||
}
|
||||
|
||||
public List<GapOnQueue> getGaps() {
|
||||
if (cachedGaps == null) {
|
||||
cachedGaps = calculateGaps();
|
||||
}
|
||||
return cachedGaps;
|
||||
}
|
||||
|
||||
private List<GapOnQueue> calculateGaps() {
|
||||
List<Gap> result = new ArrayList<Gap>();
|
||||
DateAndHour previousEnd = null;
|
||||
for (LimitingResourceQueueElement each : limitingResourceQueueElements) {
|
||||
DateAndHour startTime = each.getStartTime();
|
||||
if (previousEnd == null || startTime.isAfter(previousEnd)) {
|
||||
result.add(Gap.create(resource, previousEnd, startTime));
|
||||
}
|
||||
previousEnd = each.getEndTime();
|
||||
}
|
||||
result.add(Gap.create(resource, previousEnd, null));
|
||||
return GapOnQueue.onQueue(this, result);
|
||||
}
|
||||
|
||||
public SortedSet<LimitingResourceQueueElement> getLimitingResourceQueueElements() {
|
||||
return Collections.unmodifiableSortedSet(limitingResourceQueueElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the gaps that could potentially be valid for
|
||||
* <code>requirements</code> ordered by start date
|
||||
*/
|
||||
public List<GapOnQueue> getGapsPotentiallyValidFor(
|
||||
GapRequirements requirements) {
|
||||
List<GapOnQueue> result = new ArrayList<GapOnQueue>();
|
||||
for (GapOnQueue each : getGaps()) {
|
||||
if (requirements.isPotentiallyValid(each.getGap())) {
|
||||
result.add(each);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ package org.navalplanner.business.resources.entities;
|
|||
import java.util.Comparator;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
|||
|
||||
import org.navalplanner.business.common.daos.IIntegrationEntityDAO;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.workreports.entities.WorkReportLine;
|
||||
|
||||
/**
|
||||
|
|
@ -44,4 +45,6 @@ public interface IWorkReportLineDAO extends
|
|||
|
||||
List<WorkReportLine> findFilteredByDate(Date start, Date end);
|
||||
|
||||
List<WorkReportLine> findByResources(List<Resource> resourcesList);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
package org.navalplanner.business.workreports.daos;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ import org.hibernate.Criteria;
|
|||
import org.hibernate.criterion.Restrictions;
|
||||
import org.navalplanner.business.common.daos.IntegrationEntityDAO;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.workreports.entities.WorkReportLine;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
|
@ -88,4 +90,14 @@ public class WorkReportLineDAO extends IntegrationEntityDAO<WorkReportLine>
|
|||
return criteria.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<WorkReportLine> findByResources(List<Resource> resourcesList) {
|
||||
if (resourcesList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return getSession().createCriteria(WorkReportLine.class).add(
|
||||
Restrictions.in("resource", resourcesList)).list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,17 @@
|
|||
|
||||
<property name="reportGlobalAdvance" access="field"/>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="advanceType" class="AdvanceType" column="ADVANCE_TYPE_ID"/>
|
||||
|
||||
<joined-subclass name="DirectAdvanceAssignment">
|
||||
<key column="ADVANCE_ASSIGNMENT_ID"></key>
|
||||
|
||||
<many-to-one name="orderElement" class="org.navalplanner.business.orders.entities.OrderElement" column="DIRECT_ORDER_ELEMENT_ID"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="orderElement"
|
||||
class="org.navalplanner.business.orders.entities.OrderElement"
|
||||
column="DIRECT_ORDER_ELEMENT_ID"
|
||||
index="idx_directadvanceassigment_on_orderelement"/>
|
||||
|
||||
<property name="maxValue" access="field" scale="2"/>
|
||||
|
||||
|
|
@ -51,6 +56,7 @@
|
|||
<one-to-many class="org.navalplanner.business.advance.entities.AdvanceMeasurement"></one-to-many>
|
||||
</set>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<set name="nonCalculatedConsolidations"
|
||||
cascade="none"
|
||||
inverse="true"
|
||||
|
|
@ -64,8 +70,13 @@
|
|||
<joined-subclass name="IndirectAdvanceAssignment">
|
||||
<key column="ADVANCE_ASSIGNMENT_ID"></key>
|
||||
|
||||
<many-to-one name="orderElement" class="org.navalplanner.business.orders.entities.OrderElement" column="INDIRECT_ORDER_ELEMENT_ID"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="orderElement"
|
||||
class="org.navalplanner.business.orders.entities.OrderElement"
|
||||
column="INDIRECT_ORDER_ELEMENT_ID"
|
||||
index="idx_indirectadvanceassigment_on_orderelement"/>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<set name="calculatedConsolidations"
|
||||
cascade="none"
|
||||
inverse="true"
|
||||
|
|
@ -92,6 +103,7 @@
|
|||
<many-to-one name="advanceAssignment" class="AdvanceAssignment" column="ADVANCE_ASSIGNMENT_ID" access="field" />
|
||||
<property name="communicationDate" access="field" />
|
||||
|
||||
<!-- Not indexed -->
|
||||
<set name="nonCalculatedConsolidatedValues" access="field" cascade="none" inverse="true">
|
||||
<key column="ADVANCE_MEASUREMENT_ID" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.consolidations.NonCalculatedConsolidatedValue" />
|
||||
|
|
@ -108,8 +120,15 @@
|
|||
|
||||
<version name="version" access="property" type="long" />
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="advanceType" class="AdvanceType" column="ADVANCE_TYPE_ID"/>
|
||||
<many-to-one name="template" class="org.navalplanner.business.templates.entities.OrderElementTemplate" column="ORDER_ELEMENT_TEMPLATE_ID"/>
|
||||
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="template"
|
||||
class="org.navalplanner.business.templates.entities.OrderElementTemplate"
|
||||
column="ORDER_ELEMENT_TEMPLATE_ID"
|
||||
index="idx_advanceassigmenttemplate_on_template"/>
|
||||
|
||||
<property name="reportGlobalAdvance" access="field"/>
|
||||
<property name="maxValue" access="field" scale="2"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -16,17 +16,20 @@
|
|||
|
||||
<property name="name" access="field"/>
|
||||
|
||||
<!-- Index created in a database-object section -->
|
||||
<set name="exceptions" access="field" cascade="all-delete-orphan">
|
||||
<key column="BASE_CALENDAR_ID" />
|
||||
<one-to-many class="CalendarException" />
|
||||
</set>
|
||||
|
||||
<!-- Index on the other side -->
|
||||
<list name="calendarDataVersions" access="field" cascade="all-delete-orphan">
|
||||
<key column="BASE_CALENDAR_ID" />
|
||||
<index column="POSITION_IN_CALENDAR" />
|
||||
<one-to-many class="CalendarData" />
|
||||
</list>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<list name="calendarAvailabilities" access="field" cascade="all-delete-orphan">
|
||||
<key column="BASE_CALENDAR_ID" />
|
||||
<index column="POSITION_IN_CALENDAR" />
|
||||
|
|
@ -56,6 +59,7 @@
|
|||
<property name="date" access="field"
|
||||
type="org.joda.time.contrib.hibernate.PersistentLocalDate"/>
|
||||
<property name="hours" access="field"/>
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="type" cascade="none"
|
||||
column="CALENDAR_EXCEPTION_ID" />
|
||||
|
||||
|
|
@ -95,7 +99,9 @@
|
|||
<element column="HOURS" type="integer" />
|
||||
</map>
|
||||
|
||||
<many-to-one name="parent" class="BaseCalendar" access="field"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="parent" class="BaseCalendar" access="field"
|
||||
index="idx_CalendarData_on_BaseCalendar" />
|
||||
|
||||
<property name="expiringDate" access="field"
|
||||
type="org.joda.time.contrib.hibernate.PersistentLocalDate"/>
|
||||
|
|
@ -117,4 +123,11 @@
|
|||
|
||||
</class>
|
||||
|
||||
<!-- Index to boost the search of CalendarExceptions inside BaseCalendar -->
|
||||
<database-object>
|
||||
<create>CREATE INDEX idx_CalendarException_on_BaseCalendar ON CalendarException (BASE_CALENDAR_ID)</create>
|
||||
<drop>DROP INDEX idx_CalendarException_on_BaseCalendar</drop>
|
||||
<dialect-scope name="org.hibernate.dialect.PostgreSQLDialect" />
|
||||
<dialect-scope name="org.hibernate.dialect.MySQLInnoDBDialect" />
|
||||
</database-object>
|
||||
</hibernate-mapping>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
</id>
|
||||
<version name="version" access="property" type="long" />
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="defaultCalendar" cascade="none"
|
||||
column="CONFIGURATION_ID" />
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
<property name="enabled"/>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="hourCosts" inverse="true" cascade="all-delete-orphan">
|
||||
<key column="COST_CATEGORY_ID"/>
|
||||
<one-to-many class="HourCost"/>
|
||||
|
|
@ -40,7 +41,11 @@
|
|||
|
||||
<many-to-one name="type" class="TypeOfWorkHours" column="TYPE_OF_WORK_HOURS_ID" />
|
||||
|
||||
<many-to-one name="category" class="CostCategory" column="COST_CATEGORY_ID"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="category"
|
||||
class="CostCategory"
|
||||
column="COST_CATEGORY_ID"
|
||||
index="idx_hourcost_on_category"/>
|
||||
|
||||
</class>
|
||||
|
||||
|
|
@ -80,9 +85,16 @@
|
|||
|
||||
<property name="endDate" type="org.joda.time.contrib.hibernate.PersistentLocalDate"/>
|
||||
|
||||
<many-to-one name="costCategory" class="CostCategory" column="COST_CATEGORY_ID"/>
|
||||
<!-- Not Indexed -->
|
||||
<many-to-one name="costCategory"
|
||||
class="CostCategory"
|
||||
column="COST_CATEGORY_ID"/>
|
||||
|
||||
<many-to-one name="resource" class="org.navalplanner.business.resources.entities.Resource" column="RESOURCE_ID"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="resource"
|
||||
class="org.navalplanner.business.resources.entities.Resource"
|
||||
column="RESOURCE_ID"
|
||||
index="idx_resourcecostcategoryassigment_on_resource"/>
|
||||
|
||||
</class>
|
||||
</hibernate-mapping>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
<property name="ourCompanyPassword" />
|
||||
|
||||
<!-- Not indexed, navigation from User to this is not even implemented -->
|
||||
<many-to-one name="companyUser" class="org.navalplanner.business.users.entities.User" />
|
||||
</class>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,13 @@
|
|||
<property name="code" access="property" not-null="true" unique="true"/>
|
||||
<properties name="nameAndType" unique="true">
|
||||
<property name="name" />
|
||||
<many-to-one name="type" class="LabelType" column="LABEL_TYPE_ID" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="type" class="LabelType"
|
||||
column="LABEL_TYPE_ID"
|
||||
index="idx_label_on_labeltype"/>
|
||||
</properties>
|
||||
|
||||
<!-- Assess this mapping -->
|
||||
<set name="orderElements" table="ORDER_ELEMENT_LABEL" cascade="all" inverse="true">
|
||||
<key column="LABEL_ID" not-null="false"/>
|
||||
<many-to-many column="ORDER_ELEMENT_ID" class="org.navalplanner.business.orders.entities.OrderElement"/>
|
||||
|
|
@ -36,6 +40,7 @@
|
|||
<property name="name" unique="true"/>
|
||||
<property name="generateCode" not-null="true" />
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="labels" inverse="false" cascade="all">
|
||||
<key column="LABEL_TYPE_ID"/>
|
||||
<one-to-many class="Label"/>
|
||||
|
|
|
|||
|
|
@ -17,11 +17,16 @@
|
|||
|
||||
<property name="defaultUnitPrice" column="default_unit_price" />
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="unitType" class="UnitType" column="unit_type" />
|
||||
|
||||
<property name="disabled"/>
|
||||
|
||||
<many-to-one name="category" class="MaterialCategory" column="CATEGORY_ID" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="category"
|
||||
class="MaterialCategory"
|
||||
column="CATEGORY_ID"
|
||||
index="idx_material_on_category"/>
|
||||
|
||||
</class>
|
||||
|
||||
|
|
@ -56,13 +61,19 @@
|
|||
|
||||
<property name="generateCode" not-null="true" />
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="subcategories" inverse="true" cascade="all-delete-orphan">
|
||||
<key column="PARENT_ID"/>
|
||||
<one-to-many class="MaterialCategory"/>
|
||||
</set>
|
||||
|
||||
<many-to-one name="parent" class="MaterialCategory" column="PARENT_ID" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="parent"
|
||||
class="MaterialCategory"
|
||||
column="PARENT_ID"
|
||||
index="idx_materialcategory_on_parent"/>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="materials" inverse="true" cascade="all">
|
||||
<key column="CATEGORY_ID"/>
|
||||
<one-to-many class="Material"/>
|
||||
|
|
@ -93,7 +104,11 @@
|
|||
</type>
|
||||
</property>
|
||||
|
||||
<many-to-one name="orderElement" class="org.navalplanner.business.orders.entities.OrderElement" column="ORDER_ELEMENT_ID" />
|
||||
<!-- Indexed. -->
|
||||
<many-to-one name="orderElement"
|
||||
class="org.navalplanner.business.orders.entities.OrderElement"
|
||||
column="ORDER_ELEMENT_ID"
|
||||
index="idx_material_assigment_on_orderelement"/>
|
||||
|
||||
</class>
|
||||
|
||||
|
|
@ -111,7 +126,11 @@
|
|||
<many-to-one name="material" class="Material" column="MATERIAL_ID" />
|
||||
</component>
|
||||
|
||||
<many-to-one name="orderElementTemplate" class="org.navalplanner.business.templates.entities.OrderElementTemplate" column="ORDER_ELEMENT_TEMPLATE_ID" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="orderElementTemplate"
|
||||
class="org.navalplanner.business.templates.entities.OrderElementTemplate"
|
||||
column="ORDER_ELEMENT_TEMPLATE_ID"
|
||||
index="idx_materialassigmenttemplate_on_orderelement"/>
|
||||
|
||||
</class>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,42 +9,59 @@
|
|||
</id>
|
||||
<version name="version" access="property" type="long" />
|
||||
<component name="infoComponent" class="org.navalplanner.business.orders.entities.InfoComponent">
|
||||
<property name="name" access="field" />
|
||||
<property name="description" access="field" />
|
||||
<property name="code" access="field" unique="true" />
|
||||
<property name="name" access="field" />
|
||||
<property name="description" access="field" />
|
||||
<property name="code" access="field" unique="true" />
|
||||
</component>
|
||||
<property name="initDate" access="field" />
|
||||
<property name="deadline" access="field" />
|
||||
|
||||
<property name="lastAdvanceMeausurementForSpreading" access="field" />
|
||||
<property name="dirtyLastAdvanceMeasurementForSpreading" access="field" />
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="directAdvanceAssignments" access="field" cascade="all,delete-orphan" inverse="true">
|
||||
<key column="DIRECT_ORDER_ELEMENT_ID" />
|
||||
<one-to-many class="org.navalplanner.business.advance.entities.DirectAdvanceAssignment" />
|
||||
</set>
|
||||
|
||||
<!-- Assess many-to-many bidireccional -->
|
||||
<set name="labels" table="ORDER_ELEMENT_LABEL" access="field" cascade="all">
|
||||
<key column="ORDER_ELEMENT_ID" not-null="true"/>
|
||||
<many-to-many column="LABEL_ID" class="org.navalplanner.business.labels.entities.Label" />
|
||||
<many-to-many column="LABEL_ID" class="org.navalplanner.business.labels.entities.Label"/>
|
||||
</set>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="criterionRequirements" access="field" cascade="all,delete-orphan" inverse="true">
|
||||
<key column="ORDER_ELEMENT_ID" not-null="false"></key>
|
||||
<one-to-many class="org.navalplanner.business.requirements.entities.CriterionRequirement"/>
|
||||
</set>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="materialAssignments" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="ORDER_ELEMENT_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.materials.entities.MaterialAssignment" />
|
||||
</set>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="taskQualityForms" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="ORDER_ELEMENT_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.qualityforms.entities.TaskQualityForm" />
|
||||
</set>
|
||||
|
||||
<!-- Inverse navigation from OrderElement to OrderLineGroup -->
|
||||
<many-to-one name="parent" access="field" cascade="all" class="org.navalplanner.business.orders.entities.OrderLineGroup"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="parent"
|
||||
access="field"
|
||||
cascade="all"
|
||||
class="org.navalplanner.business.orders.entities.OrderLineGroup"
|
||||
index="idx_orderelement_on_parent"/>
|
||||
|
||||
<many-to-one name="template" access="field" cascade="none" class="org.navalplanner.business.templates.entities.OrderElementTemplate"/>
|
||||
<many-to-one name="template"
|
||||
access="field"
|
||||
cascade="none"
|
||||
class="org.navalplanner.business.templates.entities.OrderElementTemplate"
|
||||
index="idx_orderelement_on_template"/>
|
||||
|
||||
<property name="externalCode" access="field" />
|
||||
|
||||
|
|
@ -59,11 +76,15 @@
|
|||
|
||||
<joined-subclass name="OrderLineGroup">
|
||||
<key column="ORDERELEMENTID"></key>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<list name="children" access="field" cascade="all">
|
||||
<key column="parent" not-null="false"></key>
|
||||
<index column="positionInContainer"></index>
|
||||
<one-to-many class="OrderElement" />
|
||||
</list>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="indirectAdvanceAssignments" access="field" cascade="all,delete-orphan" inverse="true">
|
||||
<key column="INDIRECT_ORDER_ELEMENT_ID" />
|
||||
<one-to-many class="org.navalplanner.business.advance.entities.IndirectAdvanceAssignment" />
|
||||
|
|
@ -89,8 +110,10 @@
|
|||
</type>
|
||||
</property>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="customer" access="field" class="org.navalplanner.business.externalcompanies.entities.ExternalCompany"/>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="calendar" column="BASE_CALENDAR_ID" cascade="none"
|
||||
class="org.navalplanner.business.calendars.entities.BaseCalendar"/>
|
||||
|
||||
|
|
@ -113,6 +136,7 @@
|
|||
<joined-subclass name="OrderLine">
|
||||
<key column="ORDERELEMENTID"></key>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="hoursGroups" access="field" cascade="all,delete-orphan" inverse="true">
|
||||
<key column="PARENT_ORDER_LINE" not-null="false"></key>
|
||||
<one-to-many class="HoursGroup" />
|
||||
|
|
@ -143,16 +167,21 @@
|
|||
<property name="percentage" access="field" />
|
||||
<property name="fixedPercentage" access="field" />
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="criterionRequirements" access="field" cascade="save-update,delete-orphan" inverse="true">
|
||||
<key column="HOURS_GROUP_ID" not-null="false"></key>
|
||||
<one-to-many class="org.navalplanner.business.requirements.entities.CriterionRequirement"/>
|
||||
</set>
|
||||
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="parentOrderLine" column="PARENT_ORDER_LINE"
|
||||
class="org.navalplanner.business.orders.entities.OrderLine" />
|
||||
class="org.navalplanner.business.orders.entities.OrderLine"
|
||||
index="idx_hoursgroup_on_parentorderline"/>
|
||||
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="orderLineTemplate" column="ORDER_LINE_TEMPLATE"
|
||||
class="org.navalplanner.business.templates.entities.OrderLineTemplate" />
|
||||
class="org.navalplanner.business.templates.entities.OrderLineTemplate"
|
||||
index="idx_hoursgroup_on_orderlinetemplate"/>
|
||||
|
||||
</class>
|
||||
|
||||
|
|
@ -183,6 +212,7 @@
|
|||
cascade="none" unique="true" access="field" />
|
||||
<one-to-one name="task" class="org.navalplanner.business.planner.entities.TaskElement"
|
||||
constrained="true" cascade="all" access="field" lazy="false"/>
|
||||
|
||||
<set name="hoursGroups" table="task_source_hours_groups" cascade="none" inverse="false" access="field">
|
||||
<key column="TASK_SOURCE_ID"></key>
|
||||
<many-to-many class="HoursGroup" column="HOURS_GROUP_ID"/>
|
||||
|
|
|
|||
|
|
@ -13,22 +13,22 @@
|
|||
|
||||
<property name="date" access="field" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
<property name="value" scale="2" access="field" />
|
||||
|
||||
<set name="pendingConsolidatedHours" table="PENDING_CONSOLIDATED_HOURS">
|
||||
<key column="PENDING_HOURS_ID"/>
|
||||
<composite-element class="org.navalplanner.business.planner.entities.consolidations.PendingConsolidatedHoursPerResourceAllocation">
|
||||
<property name="pendingConsolidatedHours"/>
|
||||
<many-to-one name="resourceAllocation" class="org.navalplanner.business.planner.entities.ResourceAllocation" column="RESOURCE_ALLOCATION_ID" access="field" />
|
||||
</composite-element>
|
||||
</set>
|
||||
<property name="taskEndDate" access="field" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
|
||||
<subclass name="NonCalculatedConsolidatedValue" discriminator-value="NonCalculated">
|
||||
<many-to-one name="consolidation" class="NonCalculatedConsolidation" column="CONSOLIDATION_ID" access="field" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="consolidation" class="NonCalculatedConsolidation"
|
||||
column="CONSOLIDATION_ID" access="field"
|
||||
index="idx_NonCalculatedConsolidatedValue_on_NonCalculatedConsolidation" />
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="advanceMeasurement" class="org.navalplanner.business.advance.entities.AdvanceMeasurement" column="ADVANCE_MEASUREMENT_ID" access="field" />
|
||||
</subclass>
|
||||
|
||||
<subclass name="CalculatedConsolidatedValue" discriminator-value="Calculated">
|
||||
<many-to-one name="consolidation" class="CalculatedConsolidation" column="CONSOLIDATION_ID" access="field" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="consolidation" class="CalculatedConsolidation"
|
||||
column="CONSOLIDATION_ID" access="field"
|
||||
index="idx_CalculatedConsolidatedValue_on_CalculatedConsolidation" />
|
||||
</subclass>
|
||||
|
||||
</class>
|
||||
|
|
@ -46,9 +46,11 @@
|
|||
|
||||
<subclass name="NonCalculatedConsolidation" discriminator-value="NonCalculated">
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="directAdvanceAssignment" column="DIR_ADVANCE_ASSIGNMENT_ID" access="field"
|
||||
class="org.navalplanner.business.advance.entities.DirectAdvanceAssignment" />
|
||||
|
||||
<!-- Indexed on the other side -->
|
||||
<set name="consolidatedValues"
|
||||
access="field"
|
||||
cascade="all,delete-orphan"
|
||||
|
|
@ -62,9 +64,11 @@
|
|||
|
||||
<subclass name="CalculatedConsolidation" discriminator-value="Calculated">
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="indirectAdvanceAssignment" column="IND_ADVANCE_ASSIGNMENT_ID" access="field"
|
||||
class="org.navalplanner.business.advance.entities.IndirectAdvanceAssignment"/>
|
||||
|
||||
<!-- Indexed on the other side -->
|
||||
<set name="consolidatedValues"
|
||||
access="field"
|
||||
cascade="all,delete-orphan"
|
||||
|
|
|
|||
|
|
@ -18,8 +18,12 @@
|
|||
|
||||
<property name="originalTotalAssignment" access="field"/>
|
||||
|
||||
<many-to-one class="Task" name="task" column="TASK" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one class="Task" name="task" column="TASK" index="idx_resourceallocation_on_task"/>
|
||||
|
||||
<!-- It is not included index, navigation from assigment function to
|
||||
ResourceAllocation not useful
|
||||
-->
|
||||
<many-to-one class="AssignmentFunction" name="assignmentFunction"
|
||||
column="ASSIGNMENT_FUNCTION" not-null="false"
|
||||
cascade="all" lazy="false" />
|
||||
|
|
@ -29,9 +33,10 @@
|
|||
<one-to-many class="DerivedAllocation"/>
|
||||
</set>
|
||||
|
||||
<!-- Wrong mapping. A ResourceAllocation only has one limiting resource queue element associated -->
|
||||
<set name="limitingResourceQueueElements" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="RESOURCE_ALLOCATION_ID" />
|
||||
<one-to-many class="LimitingResourceQueueElement"/>
|
||||
<one-to-many class="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement"/>
|
||||
</set>
|
||||
|
||||
<joined-subclass name="SpecificResourceAllocation" table="specific_resource_allocation">
|
||||
|
|
@ -123,7 +128,7 @@
|
|||
</class>
|
||||
|
||||
<!-- LimitingResourceQueueElement -->
|
||||
<class name="LimitingResourceQueueElement" table="limiting_resource_queue_element">
|
||||
<class name="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement" table="limiting_resource_queue_element">
|
||||
<id name="id" type="long" access="property">
|
||||
<generator class="hilo">
|
||||
<param name="max_lo">100</param>
|
||||
|
|
@ -133,36 +138,44 @@
|
|||
|
||||
<many-to-one name="resourceAllocation" column="RESOURCE_ALLOCATION_ID" cascade="all" not-null="false" unique="true" />
|
||||
|
||||
<many-to-one name="limitingResourceQueue" column="LIMITING_RESOURCE_QUEUE_ID" />
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="limitingResourceQueue" column="LIMITING_RESOURCE_QUEUE_ID" index="idx_resourcequeueelement_on_resourcequeue"/>
|
||||
|
||||
<property name="earlierStartDateBecauseOfGantt" column="EARLIER_START_DATE_BECAUSE_OF_GANTT" />
|
||||
|
||||
<property name="earliestEndDateBecauseOfGantt" column="EARLIEST_END_DATE_BECAUSE_OF_GANTT" />
|
||||
|
||||
<property name="creationTimestamp" column="CREATION_TIMESTAMP" />
|
||||
|
||||
<component name="startQueuePosition" class="org.navalplanner.business.planner.entities.QueuePosition">
|
||||
<component name="startQueuePosition" class="org.navalplanner.business.planner.limiting.entities.QueuePosition">
|
||||
<property name="date" column="START_DATE" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
<property name="hour" column="START_HOUR" />
|
||||
</component>
|
||||
|
||||
<component name="endQueuePosition" class="org.navalplanner.business.planner.entities.QueuePosition">
|
||||
<component name="endQueuePosition" class="org.navalplanner.business.planner.limiting.entities.QueuePosition">
|
||||
<property name="date" column="END_DATE" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
<property name="hour" column="END_HOUR" />
|
||||
</component>
|
||||
|
||||
<!-- Indexed the other side. Useful to browse the output dependencies of
|
||||
a LimitingResourceQueueElement -->
|
||||
<set name="dependenciesAsOrigin" cascade="none" lazy="false">
|
||||
<key column="origin_queue_element_id"/>
|
||||
<one-to-many class="LimitingResourceQueueDependency"/>
|
||||
<one-to-many class="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency"/>
|
||||
</set>
|
||||
|
||||
<!-- Indexed the other side. Useful to browse the input dependencies of
|
||||
a LimitingResourceQueueElement -->
|
||||
<set name="dependenciesAsDestiny" cascade="none" lazy="false">
|
||||
<key column="destiny_queue_element_id"/>
|
||||
<one-to-many class="LimitingResourceQueueDependency"/>
|
||||
<one-to-many class="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency"/>
|
||||
</set>
|
||||
|
||||
</class>
|
||||
|
||||
<!-- LimitingResourceQueueDependency -->
|
||||
<class name="LimitingResourceQueueDependency" table="limiting_resource_queue_dependency">
|
||||
<class name="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency"
|
||||
table="limiting_resource_queue_dependency">
|
||||
<id name="id" type="long" access="property">
|
||||
<generator class="hilo">
|
||||
<param name="max_lo">100</param>
|
||||
|
|
@ -171,20 +184,25 @@
|
|||
|
||||
<property name="type">
|
||||
<type name="org.hibernate.type.EnumType">
|
||||
<param name="enumClass">org.navalplanner.business.planner.entities.LimitingResourceQueueDependency$QueueDependencyType</param>
|
||||
<param name="enumClass">org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency$QueueDependencyType</param>
|
||||
</type>
|
||||
</property>
|
||||
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="hasAsOrigin" cascade="none"
|
||||
class="org.navalplanner.business.planner.entities.LimitingResourceQueueElement"
|
||||
class="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement"
|
||||
column="origin_queue_element_id"
|
||||
not-null="false">
|
||||
not-null="false"
|
||||
index="idx_queuedependency_on_originqueue">
|
||||
</many-to-one>
|
||||
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="hasAsDestiny" cascade="none"
|
||||
class="org.navalplanner.business.planner.entities.LimitingResourceQueueElement"
|
||||
class="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement"
|
||||
column="destiny_queue_element_id"
|
||||
not-null="false">
|
||||
not-null="false"
|
||||
index="idx_queuedependency_on_destinyqueue"
|
||||
>
|
||||
</many-to-one>
|
||||
|
||||
<one-to-one name="ganttDependency"
|
||||
|
|
@ -210,6 +228,8 @@
|
|||
|
||||
<property name="day" type="org.joda.time.contrib.hibernate.PersistentLocalDate" not-null="true"/>
|
||||
|
||||
<!-- Not indexed. It is not indexed because it is regarded that to navigate
|
||||
from a resource to all his DayAssigments is not useful -->
|
||||
<many-to-one name="resource" class="org.navalplanner.business.resources.entities.Resource"
|
||||
column="RESOURCE_ID" not-null="true">
|
||||
</many-to-one>
|
||||
|
|
@ -275,4 +295,5 @@
|
|||
<one-to-many class="DerivedDayAssignmentsContainer"/>
|
||||
</set>
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
||||
|
|
|
|||
|
|
@ -14,21 +14,27 @@
|
|||
<property name="startDate" type="timestamp" not-null="true"/>
|
||||
<property name="endDate" type="timestamp" not-null="true"/>
|
||||
<property name="deadline" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
<property name="advancePercentage" column="ADVANCE_PERCENTAGE" />
|
||||
|
||||
<many-to-one name="parent" class="TaskGroup" cascade="none" column="parent"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="parent" class="TaskGroup" cascade="none" column="parent"
|
||||
index="idx_TaskElement_on_TaskGroup" />
|
||||
|
||||
<one-to-one name="taskSource" cascade="none"/>
|
||||
|
||||
<!-- Indexed on the other side -->
|
||||
<set name="dependenciesWithThisOrigin" cascade="all-delete-orphan">
|
||||
<key column="ORIGIN"></key>
|
||||
<one-to-many class="Dependency" />
|
||||
</set>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<set name="dependenciesWithThisDestination" cascade="all-delete-orphan">
|
||||
<key column="DESTINATION"></key>
|
||||
<one-to-many class="Dependency" />
|
||||
</set>
|
||||
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="calendar" column="BASE_CALENDAR_ID" cascade="none"
|
||||
class="org.navalplanner.business.calendars.entities.BaseCalendar"/>
|
||||
|
||||
|
|
@ -51,11 +57,13 @@
|
|||
<one-to-one name="consolidation" class="org.navalplanner.business.planner.entities.consolidations.Consolidation"
|
||||
cascade="all"/>
|
||||
|
||||
<!-- Indexed on the other side -->
|
||||
<set name="resourceAllocations" cascade="all-delete-orphan">
|
||||
<key column="TASK" />
|
||||
<one-to-many class="ResourceAllocation" />
|
||||
</set>
|
||||
|
||||
<!-- Already indexed because it's unique -->
|
||||
<many-to-one name="subcontractedTaskData"
|
||||
column="SUBCONTRATED_TASK_DATA_ID"
|
||||
unique="true" cascade="all" lazy="false" />
|
||||
|
|
@ -66,6 +74,8 @@
|
|||
|
||||
<joined-subclass name="TaskGroup">
|
||||
<key column="TASK_ELEMENT_ID"></key>
|
||||
|
||||
<!-- Indexed on the other side -->
|
||||
<list name="taskElements" cascade="all">
|
||||
<key column="parent" not-null="false"></key>
|
||||
<index column="positionInParent"></index>
|
||||
|
|
@ -83,11 +93,19 @@
|
|||
<generator class="hilo"></generator>
|
||||
</id>
|
||||
<version name="version" access="property" type="long" />
|
||||
|
||||
<!-- Indexed -->
|
||||
<many-to-one class="TaskElement" name="origin"
|
||||
column="ORIGIN" />
|
||||
column="ORIGIN"
|
||||
index="idx_Dependency_on_TaskElement_origin" />
|
||||
|
||||
<!-- Not indexed, navigation in that direction is not useful -->
|
||||
<many-to-one class="TaskElement" name="destination"
|
||||
column="DESTINATION" />
|
||||
<many-to-one class="LimitingResourceQueueDependency" cascade="all"
|
||||
|
||||
<!-- Not indexed, relation from the other side is one-to-one -->
|
||||
<many-to-one class="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency"
|
||||
cascade="all"
|
||||
name="queueDependency"
|
||||
column="queue_dependency"
|
||||
unique="false"
|
||||
|
|
@ -107,6 +125,7 @@
|
|||
</id>
|
||||
<version name="version" access="property" type="long" />
|
||||
|
||||
<!-- Not indexed, navigation from ExternalCompany to this is not even implemented -->
|
||||
<many-to-one name="externalCompany" class="org.navalplanner.business.externalcompanies.entities.ExternalCompany" />
|
||||
|
||||
<one-to-one name="task" class="Task"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
</type>
|
||||
</property>
|
||||
|
||||
<!-- Index created in a database-object section -->
|
||||
<list name="qualityFormItems" table="QUALITY_FORM_ITEMS">
|
||||
<key column="QUALITY_FORM_ID"/>
|
||||
<index column="idx"/>
|
||||
|
|
@ -48,8 +49,13 @@
|
|||
|
||||
<many-to-one name="qualityForm" class="QualityForm" column="QUALITY_FORM_ID"/>
|
||||
|
||||
<many-to-one name="orderElement" class="org.navalplanner.business.orders.entities.OrderElement" column="ORDER_ELEMENT_ID"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="orderElement"
|
||||
class="org.navalplanner.business.orders.entities.OrderElement"
|
||||
column="ORDER_ELEMENT_ID"
|
||||
index="idx_taskqualityform_on_orderelement"/>
|
||||
|
||||
<!-- Index created in a database-object section -->
|
||||
<list name="taskQualityFormItems" table="TASK_QUALITY_FORM_ITEMS">
|
||||
<key column="TASK_QUALITY_FORM_ID"/>
|
||||
<index column="idx"/>
|
||||
|
|
@ -66,4 +72,22 @@
|
|||
|
||||
</class>
|
||||
|
||||
<!-- Index to boost the search of QualityFormItems inside a QualityForm -->
|
||||
<database-object>
|
||||
<create>CREATE INDEX idx_QualityForm_on_QualityFormItems
|
||||
ON QUALITY_FORM_ITEMS (QUALITY_FORM_ID)</create>
|
||||
<drop>DROP INDEX idx_QualityForm_on_QualityFormItems</drop>
|
||||
<dialect-scope name="org.hibernate.dialect.PostgreSQLDialect" />
|
||||
<dialect-scope name="org.hibernate.dialect.MySQLInnoDBDialect" />
|
||||
</database-object>
|
||||
|
||||
<!-- Index to boost the search of TaskQualityFormItems inside a TaskQualityForm -->
|
||||
<database-object>
|
||||
<create>CREATE INDEX idx_TaskQualityForm_on_TaskQualityFormItems
|
||||
ON TASK_QUALITY_FORM_ITEMS (TASK_QUALITY_FORM_ID)</create>
|
||||
<drop>DROP INDEX idx_TaskQualityForm_on_TaskQualityFormItems</drop>
|
||||
<dialect-scope name="org.hibernate.dialect.PostgreSQLDialect" />
|
||||
<dialect-scope name="org.hibernate.dialect.MySQLInnoDBDialect" />
|
||||
</database-object>
|
||||
|
||||
</hibernate-mapping>
|
||||
|
|
|
|||
|
|
@ -14,15 +14,26 @@
|
|||
<version access="property" name="version" type="long"/>
|
||||
|
||||
<!-- Inverse navigation from CriterionRequirement to HoursGroup -->
|
||||
<many-to-one class="org.navalplanner.business.orders.entities.HoursGroup" column="HOURS_GROUP_ID" name="hoursGroup"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one class="org.navalplanner.business.orders.entities.HoursGroup"
|
||||
column="HOURS_GROUP_ID"
|
||||
name="hoursGroup"
|
||||
index="idx_criterionrequirement_on_hoursgroup"
|
||||
/>
|
||||
|
||||
<!-- Inverse navigation from CriterionRequirement to OrderElement -->
|
||||
<many-to-one class="org.navalplanner.business.orders.entities.OrderElement" column="ORDER_ELEMENT_ID" name="orderElement"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one class="org.navalplanner.business.orders.entities.OrderElement"
|
||||
column="ORDER_ELEMENT_ID"
|
||||
name="orderElement"
|
||||
index="idx_criterionrequirement_on_orderelement"
|
||||
/>
|
||||
|
||||
<!-- Inverse navigation from CriterionRequirement to OrderTemplateElement -->
|
||||
<many-to-one class="org.navalplanner.business.templates.entities.OrderElementTemplate" column="ORDER_ELEMENT_TEMPLATE_ID" name="orderElementTemplate"/>
|
||||
|
||||
<!-- Inverse navigation from CriterionRequirement to Criterion -->
|
||||
<!-- Not indexed. Other side navigation not useful -->
|
||||
<many-to-one class="org.navalplanner.business.resources.entities.Criterion" column="CRITERION_ID" name="criterion"/>
|
||||
|
||||
<subclass discriminator-value="DIRECT" name="DirectCriterionRequirement">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
<hibernate-mapping default-access="field" package="org.navalplanner.business.resources.entities">
|
||||
|
||||
<class name="Resource">
|
||||
<id name="id" access="property" type="long">
|
||||
<generator class="hilo">
|
||||
|
|
@ -19,20 +20,25 @@
|
|||
|
||||
<property name="limitingResource" column="LIMITED_RESOURCE" not-null="true"/>
|
||||
|
||||
<!-- It is appropiate the index by the foreign key in the many-to-one side -->
|
||||
<set access="field" cascade="all-delete-orphan" inverse="true" name="criterionSatisfactions">
|
||||
<key column="resource" not-null="true"/>
|
||||
<one-to-many class="CriterionSatisfaction"/>
|
||||
</set>
|
||||
|
||||
<!-- Assess the need of this mapping. It seems very heavy and should not be used. Remove it ¿?-->
|
||||
<set access="field" inverse="true" name="dayAssignments">
|
||||
<key column="RESOURCE_ID" not-null="true"/>
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.DayAssignment"/>
|
||||
</set>
|
||||
|
||||
<!-- Not indexed. Navigation from calendars to all the resources which have that calendar
|
||||
associated not used -->
|
||||
<many-to-one name="calendar" access="field" cascade="all"
|
||||
class="org.navalplanner.business.calendars.entities.ResourceCalendar"
|
||||
column="BASE_CALENDAR_ID" unique="true" />
|
||||
|
||||
<!-- Indexed in the other side -->
|
||||
<set name="resourcesCostCategoryAssignments" inverse="true" cascade="all-delete-orphan">
|
||||
<key column="RESOURCE_ID"/>
|
||||
<one-to-many class="org.navalplanner.business.costcategories.entities.ResourcesCostCategoryAssignment"/>
|
||||
|
|
@ -64,7 +70,6 @@
|
|||
</set>
|
||||
|
||||
</joined-subclass>
|
||||
|
||||
</class>
|
||||
|
||||
<!-- LimitingResourceQueue -->
|
||||
|
|
@ -78,10 +83,11 @@
|
|||
|
||||
<many-to-one name="resource" column="RESOURCE_ID" not-null="false" unique="true" />
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="limitingResourceQueueElements" cascade="all-delete-orphan" inverse="true"
|
||||
sort="org.navalplanner.business.resources.entities.LimitingResourceQueueElementComparator">
|
||||
<key column="LIMITING_RESOURCE_QUEUE_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.LimitingResourceQueueElement" />
|
||||
<one-to-many class="org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement" />
|
||||
</set>
|
||||
|
||||
</class>
|
||||
|
|
@ -99,13 +105,19 @@
|
|||
<property access="field" name="active"/>
|
||||
<many-to-one access="field" name="type" column="id_criterion_type" not-null="true" />
|
||||
|
||||
<many-to-one name="parent" column="parent" access="field" not-null="false"/>
|
||||
<!-- Indexed. It is probable to navigate from a criterion
|
||||
to its children criteria -->
|
||||
<many-to-one name="parent" column="parent" access="field" not-null="false"
|
||||
index="idx_criterion_on_parent"/>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="children" access="field" lazy="true" cascade="save-update">
|
||||
<key column="parent" not-null="false"></key>
|
||||
<one-to-many class="Criterion"/>
|
||||
</set>
|
||||
|
||||
<!-- Assess the removal of this mapping. It is not used frequently. It is not
|
||||
included index in the many-to-one side -->
|
||||
<set name="criterionRequirements" access="field">
|
||||
<key column="CRITERION_ID" not-null="false"></key>
|
||||
<one-to-many class="org.navalplanner.business.requirements.entities.CriterionRequirement"/>
|
||||
|
|
@ -130,8 +142,12 @@
|
|||
<property access="field" name="startDate" not-null="true"/>
|
||||
<property access="field" name="finishDate"/>
|
||||
<property access="field" name="isDeleted"/>
|
||||
|
||||
<!-- Indexed. It is not probable to ask for the criterion satisfactions of a criterion -->
|
||||
<many-to-one access="field" name="criterion" not-null="true"/>
|
||||
<many-to-one access="field" column="resource" name="resource" not-null="true"/>
|
||||
|
||||
<!-- Iindexed. It is useful to know the criterion satisfactoions of a resource -->
|
||||
<many-to-one access="field" name="resource" not-null="true" index="idx_criterionsatisfaction_on_resource" column="resource" />
|
||||
</class>
|
||||
|
||||
<!-- CriterionType -->
|
||||
|
|
@ -152,6 +168,8 @@
|
|||
<param name="enumClass">org.navalplanner.business.resources.entities.ResourceEnum</param>
|
||||
</type>
|
||||
</property>
|
||||
|
||||
<!-- Indexed the other side-->
|
||||
<set name="criterions" cascade="all,delete-orphan" inverse="true">
|
||||
<key column="id_criterion_type" />
|
||||
<one-to-many class="Criterion" />
|
||||
|
|
|
|||
|
|
@ -23,13 +23,19 @@
|
|||
</type>
|
||||
</property>
|
||||
|
||||
<many-to-one name="parent" access="field" class="org.navalplanner.business.templates.entities.OrderLineGroupTemplate"/>
|
||||
<!-- Indexed -->
|
||||
<many-to-one name="parent"
|
||||
access="field"
|
||||
class="org.navalplanner.business.templates.entities.OrderLineGroupTemplate"
|
||||
index="idx_orderelementtemplate_on_parent"/>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="criterionRequirements" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="ORDER_ELEMENT_TEMPLATE_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.requirements.entities.CriterionRequirement" />
|
||||
</set>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="materialAssignments" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="ORDER_ELEMENT_TEMPLATE_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.materials.entities.MaterialAssignmentTemplate" />
|
||||
|
|
@ -45,6 +51,7 @@
|
|||
<many-to-many column="QUALITY_FORM_ID" class="org.navalplanner.business.qualityforms.entities.QualityForm"/>
|
||||
</set>
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="advanceAssignmentTemplates" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="ORDER_ELEMENT_TEMPLATE_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.advance.entities.AdvanceAssignmentTemplate" />
|
||||
|
|
@ -55,11 +62,13 @@
|
|||
<list name="children" access="field" cascade="all">
|
||||
<key column="parent" not-null="false"></key>
|
||||
<index column="positionInContainer"></index>
|
||||
<!-- Indexed the other side -->
|
||||
<one-to-many class="OrderElementTemplate" />
|
||||
</list>
|
||||
|
||||
<joined-subclass name="OrderTemplate">
|
||||
<key column="ORDER_TEMPLATE_ID"></key>
|
||||
<!-- Not indexed -->
|
||||
<many-to-one name="calendar" column="BASE_CALENDAR_ID" cascade="none"
|
||||
class="org.navalplanner.business.calendars.entities.BaseCalendar"/>
|
||||
</joined-subclass>
|
||||
|
|
@ -68,6 +77,7 @@
|
|||
<joined-subclass name="OrderLineTemplate">
|
||||
<key column="ORDER_LINE_TEMPLATE_ID" />
|
||||
|
||||
<!-- Indexed the other side -->
|
||||
<set name="hoursGroups" access="field" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="ORDER_LINE_TEMPLATE" />
|
||||
<one-to-many class="org.navalplanner.business.orders.entities.HoursGroup" />
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue