diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DateAndHour.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DateAndHour.java
index ff5b37930..393cff5e2 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DateAndHour.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/DateAndHour.java
@@ -1,3 +1,23 @@
+/*
+ * 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 .
+ */
+
package org.navalplanner.business.planner.entities;
import org.joda.time.LocalDate;
@@ -47,7 +67,17 @@ public class DateAndHour implements Comparable {
}
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);
+ }
+
}
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceQueueElementGap.java b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceQueueElementGap.java
index a10bad800..b74e51ff2 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceQueueElementGap.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/LimitingResourceQueueElementGap.java
@@ -1,3 +1,23 @@
+/*
+ * 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 .
+ */
+
package org.navalplanner.business.planner.entities;
import org.joda.time.LocalDate;
@@ -9,7 +29,7 @@ import org.navalplanner.business.resources.entities.Resource;
* @author Diego Pino Garcia
*
*/
-public class LimitingResourceQueueElementGap {
+public class LimitingResourceQueueElementGap implements Comparable {
private DateAndHour startTime;
@@ -19,28 +39,34 @@ public class LimitingResourceQueueElementGap {
public LimitingResourceQueueElementGap(Resource resource, DateAndHour startTime,
DateAndHour endTime) {
- this(resource, startTime.getDate(), startTime.getHour(), endTime.getDate(), endTime.getHour());
+ this.startTime = startTime;
+ this.endTime = endTime;
+ hoursInGap = calculateHoursInGap(resource, startTime, endTime);
}
- public LimitingResourceQueueElementGap(Resource resource, LocalDate startDate,
+ 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();
- // Calculate hours in range of dates
if (startDate.equals(endDate)) {
- hoursInGap = endHour - startHour;
+ return calendar.getCapacityAt(startDate) - Math.max(startHour, endHour);
} else {
- int hoursAtStart = calendar.getCapacityAt(startDate)
- - startHour;
+ int hoursAtStart = calendar.getCapacityAt(startDate) - startHour;
int hoursInBetween = calendar.getWorkableHours(startDate
.plusDays(1), endDate.minusDays(1));
- hoursInGap = hoursAtStart + hoursInBetween + endHour;
+ return hoursAtStart + hoursInBetween + endHour;
}
-
- // Set start and end time for gap
- startTime = new DateAndHour(startDate, startHour);
- endTime = new DateAndHour(endDate, endHour);
}
public static LimitingResourceQueueElementGap create(Resource resource, DateAndHour startTime,
@@ -75,8 +101,23 @@ public class LimitingResourceQueueElementGap {
}
public String toString() {
- return startTime.getDate() + " - " + startTime.getHour() + "; "
- + endTime.getDate() + " - " + endTime.getHour();
+ 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);
}
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/ILimitingResourceQueueModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/ILimitingResourceQueueModel.java
index e60e8ab3f..114492aef 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/ILimitingResourceQueueModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/ILimitingResourceQueueModel.java
@@ -65,12 +65,17 @@ public interface ILimitingResourceQueueModel {
* that fits the initial intented hours assigned to
* element.resourceallocation.
*
- * The method also generates {@link DayAssignment} once ne the allocation is
+ * The method also generates {@link DayAssignment} once the allocation is
* done
*
+ * Returns true if the process was successful. The only case were an
+ * allocation cannot be done is if there's not any queue that can hold the
+ * element (only for a generic allocation, there's not any queue that
+ * matches the criteria of the element)
+ *
* @param element
*/
- void assignLimitingResourceQueueElement(LimitingResourceQueueElement element);
+ boolean assignLimitingResourceQueueElement(LimitingResourceQueueElement element);
ZoomLevel calculateInitialZoomLevel();
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourceQueueModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourceQueueModel.java
index 67351874e..2163dacd5 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourceQueueModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourceQueueModel.java
@@ -25,9 +25,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@@ -50,6 +52,7 @@ import org.navalplanner.business.planner.daos.ITaskElementDAO;
import org.navalplanner.business.planner.entities.DateAndHour;
import org.navalplanner.business.planner.entities.DayAssignment;
import org.navalplanner.business.planner.entities.Dependency;
+import org.navalplanner.business.planner.entities.GenericDayAssignment;
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
import org.navalplanner.business.planner.entities.LimitingResourceQueueDependency;
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
@@ -61,6 +64,9 @@ import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
import org.navalplanner.business.planner.entities.Task;
import org.navalplanner.business.planner.entities.TaskElement;
import org.navalplanner.business.resources.entities.Criterion;
+import org.navalplanner.business.resources.entities.CriterionCompounder;
+import org.navalplanner.business.resources.entities.CriterionSatisfaction;
+import org.navalplanner.business.resources.entities.ICriterion;
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.users.daos.IOrderAuthorizationDAO;
@@ -206,7 +212,7 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
resourceAllocation = initializeResourceAllocationIfNecessary(resourceAllocation);
element.setResourceAllocation(resourceAllocation);
initializeTask(resourceAllocation.getTask());
- initializeCalendarIfAny(element.getResource());
+ initializeResourceIfAny(element.getResource());
}
private void initializeTask(Task task) {
@@ -222,13 +228,6 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
}
}
- private void initializeCalendarIfAny(Resource resource) {
- if (resource != null) {
- resource.getName();
- initializeCalendarIfAny(resource.getCalendar());
- }
- }
-
private void initializeCalendarIfAny(BaseCalendar calendar) {
if (calendar != null) {
Hibernate.initialize(calendar);
@@ -276,11 +275,15 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
private void initializeCriteria(Set criteria) {
for (Criterion each: criteria) {
- Hibernate.initialize(each);
- Hibernate.initialize(each.getType());
+ initializeCriterion(each);
}
}
+ private void initializeCriterion(Criterion criterion) {
+ Hibernate.initialize(criterion);
+ Hibernate.initialize(criterion.getType());
+ }
+
private void loadLimitingResourceQueues() {
limitingResourceQueues.clear();
limitingResourceQueues
@@ -297,13 +300,25 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
}
private void initializeLimitingResourceQueue(LimitingResourceQueue queue) {
- Hibernate.initialize(queue.getResource());
+ initializeResourceIfAny(queue.getResource());
for (LimitingResourceQueueElement each : queue
.getLimitingResourceQueueElements()) {
initializeLimitingResourceQueueElement(each);
}
}
+ private void initializeResourceIfAny(Resource resource) {
+ if (resource != null) {
+ Hibernate.initialize(resource);
+ for (CriterionSatisfaction each : resource
+ .getCriterionSatisfactions()) {
+ Hibernate.initialize(each);
+ initializeCriterion(each.getCriterion());
+ initializeCalendarIfAny(resource.getCalendar());
+ }
+ }
+ }
+
@Override
@Transactional(readOnly = true)
public Order getOrderByTask(TaskElement task) {
@@ -357,19 +372,198 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
}
@Override
- public void assignLimitingResourceQueueElement(
- final LimitingResourceQueueElement element) {
+ public boolean assignLimitingResourceQueueElement(
+ LimitingResourceQueueElement element) {
+
+ LimitingResourceQueue queue = null;
+ DateAndHour startTime = null;
LimitingResourceQueueElement queueElement = retrieveQueueElementFromModel(element);
- LimitingResourceQueue queue = retrieveQueueByResourceFromModel(queueElement
- .getResource());
+ final DateAndHour startDateBecauseOfGantt = getStartTimeBecauseOfGantt(element);
- DateAndHour startTime = findStartTimeInQueueForQueueElement(queue, queueElement);
- DateAndHour[] startAndEndTime = allocateDayAssignments(queueElement
- .getResourceAllocation(), startTime);
+ final ResourceAllocation> resourceAllocation = queueElement.getResourceAllocation();
+ if (resourceAllocation instanceof SpecificResourceAllocation) {
+ // Retrieve queue
+ queue = retrieveQueueByResourceFromModel(queueElement.getResource());
+ // Set start time
+ final LimitingResourceQueueElementGap firstGap = getFirstValidGap(queue, queueElement);
+ startTime = firstGap.getStartTime();
+ } else if (resourceAllocation instanceof GenericResourceAllocation) {
+ // Get the first gap for all the queues that can allocate the
+ // element during a certain interval of time
+ Map firstGapsForQueues = findFirstGapsInAllQueues(
+ element, startDateBecauseOfGantt);
+ // Among those queues, get the earliest gap
+ LimitingResourceQueueElementGap earliestGap = findEarliestGap(firstGapsForQueues
+ .keySet());
+ if (earliestGap == null) {
+ return false;
+ }
+ // Select queue and start time
+ queue = firstGapsForQueues.get(earliestGap);
+ startTime = earliestGap.getStartTime();
+ }
+
+ // Generate day assignments and adjust start and end times for element
+ List dayAssignments = generateDayAssignments(queueElement
+ .getResourceAllocation(), queue.getResource(), startTime);
+ DateAndHour[] startAndEndTime = calculateStartAndEndTime(dayAssignments);
updateStartAndEndTimes(queueElement, startAndEndTime);
+ // Add element to queue
addLimitingResourceQueueElement(queue, queueElement);
markAsModified(queueElement);
+ return true;
+ }
+
+ private LimitingResourceQueueElementGap getFirstValidGap(LimitingResourceQueue queue,
+ LimitingResourceQueueElement element) {
+
+ final Resource resource = queue.getResource();
+ final List elements = new LinkedList(
+ 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 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 dayAssignments = generateDayAssignments(
+ resourceAllocation, resource, gap.getStartTime());
+ DateAndHour[] startAndEndTime = calculateStartAndEndTime(dayAssignments);
+ return canfit
+ && (satisfiesCriteriaDuringInterval(resource, generic
+ .getCriterions(), startAndEndTime));
+ }
+ return false;
+ }
+
+ private boolean satisfiesCriteriaDuringInterval(Resource resource, Set 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 boolean satisfiesCriteriaDuringInterval(Resource resource, Set criteria, Date startDate, Date endDate) {
+ ICriterion compositedCriterion = CriterionCompounder.buildAnd(criteria)
+ .getResult();
+ return compositedCriterion.isSatisfiedBy(resource, startDate, endDate);
+ }
+
+ private LimitingResourceQueueElementGap getGapInQueueAtPosition(
+ Resource resource, List 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 LimitingResourceQueueElementGap createLastGap(
+ LimitingResourceQueueElement candidate,
+ LimitingResourceQueueElement element, Resource resource) {
+
+ DateAndHour startTime = DateAndHour.Max(
+ getStartTimeBecauseOfGantt(candidate), element.getEndTime());
+ return LimitingResourceQueueElementGap
+ .create(resource, startTime, null);
+ }
+
+ private Map findFirstGapsInAllQueues(
+ LimitingResourceQueueElement element,
+ DateAndHour startDateBecauseOfGantt) {
+
+ Map result = new HashMap();
+
+ for (LimitingResourceQueue each : limitingResourceQueues) {
+ LimitingResourceQueueElementGap gap = getFirstValidGap(each, element);
+ if (gap != null) {
+ result.put(gap, each);
+ }
+ }
+ return result;
+ }
+
+ private LimitingResourceQueueElementGap findEarliestGap(Set gaps) {
+ LimitingResourceQueueElementGap earliestGap = null;
+ for (LimitingResourceQueueElementGap each: gaps) {
+ if (earliestGap == null || each.isBefore(earliestGap)) {
+ earliestGap = each;
+ }
+ }
+ return earliestGap;
+ }
+
+ private DateAndHour[] calculateStartAndEndTime(List 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 void markAsModified(LimitingResourceQueueElement element) {
@@ -378,78 +572,10 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
}
}
- private DateAndHour findStartTimeInQueueForQueueElement(
- LimitingResourceQueue queue, LimitingResourceQueueElement candidate) {
-
- final SortedSet elements = queue.getLimitingResourceQueueElements();
- if (!elements.isEmpty()) {
- final List gapList = buildGapList(candidate, elements);
- final DateAndHour startTime = findStartTimeInGapList(candidate, gapList);
- return (startTime != null) ? startTime : afterLastElement(candidate, elements);
- }
- return getStartTimeBecauseOfGantt(candidate);
- }
-
- private DateAndHour afterLastElement(LimitingResourceQueueElement candidate,
- SortedSet elements) {
- final DateAndHour lastElementEndTime = elements.last().getEndTime();
- final DateAndHour candidateStartTime = getStartTimeBecauseOfGantt(candidate);
- return DateAndHour.Max(lastElementEndTime, candidateStartTime);
- }
-
private DateAndHour getStartTimeBecauseOfGantt(LimitingResourceQueueElement element) {
return new DateAndHour(new LocalDate(element.getEarlierStartDateBecauseOfGantt()), 0);
}
- private DateAndHour findStartTimeInGapList(LimitingResourceQueueElement candidate,
- List gapList) {
- for (LimitingResourceQueueElementGap each : gapList) {
- if (each.canFit(candidate)) {
- return each.getStartTime();
- }
- }
- return null;
- }
-
- private List buildGapList(LimitingResourceQueueElement candidate,
- final SortedSet elements) {
- List result = new ArrayList();
-
- // If start time of candidate element to fit in queue is before first
- // element, create a gap between candidate and the first element of the
- // queue
- DateAndHour startTimeBecauseOfGantt = getStartTimeBecauseOfGantt(candidate);
- final LimitingResourceQueueElement firstElement = elements.first();
- if (startTimeBecauseOfGantt.compareTo(firstElement.getStartTime()) < 0) {
- result.add(createGap(firstElement.getResource(), startTimeBecauseOfGantt,
- firstElement.getStartTime()));
- }
-
- LimitingResourceQueueElement current, next;
- // Only include gaps from candidate start time on
- for (Iterator i = elements.iterator(); i
- .hasNext();) {
-
- current = i.next();
- if (i.hasNext()) {
- next = i.next();
- DateAndHour startTime = current.getEndTime();
- final DateAndHour endTime = next.getStartTime();
-
- if (startTime.compareTo(startTimeBecauseOfGantt) <= 0) {
- if (endTime.compareTo(startTimeBecauseOfGantt) <= 0) {
- // Start and end of the gap are before earlierStartDateBecauseOfGanttTime
- continue;
- }
- // earliestStartDateBecauseOfGantt is in between
- startTime = startTimeBecauseOfGantt;
- }
- result.add(createGap(current.getResource(), startTime, endTime));
- }
- }
- return result;
- }
-
public LimitingResourceQueueElementGap createGap(Resource resource, DateAndHour startTime,
DateAndHour endTime) {
return LimitingResourceQueueElementGap.create(resource, startTime, endTime);
@@ -540,62 +666,43 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
return null;
}
- private DateAndHour[] allocateDayAssignments(
- ResourceAllocation> resourceAllocation, DateAndHour startingTime) {
+ private DayAssignment createDayAssignment(ResourceAllocation> resourceAllocation,
+ Resource resource, LocalDate date, int hoursToAllocate) {
if (resourceAllocation instanceof SpecificResourceAllocation) {
- return allocateDayAssignments(
- (SpecificResourceAllocation) resourceAllocation,
- startingTime);
- }
- if (resourceAllocation instanceof GenericResourceAllocation) {
- // TODO: Generate day assignments for generic resource allocation
+ return SpecificDayAssignment.create(date, hoursToAllocate, resource);
+ } else if (resourceAllocation instanceof GenericResourceAllocation) {
+ return GenericDayAssignment.create(date, hoursToAllocate, resource);
}
return null;
}
- private DateAndHour[] allocateDayAssignments(
- SpecificResourceAllocation resourceAllocation,
+ private List generateDayAssignments(
+ ResourceAllocation> resourceAllocation,
+ Resource resource,
DateAndHour startTime) {
- List assignments = new ArrayList();
-
- DateAndHour newStartTime = startTime;
+ List assignments = new ArrayList();
LocalDate date = startTime.getDate();
int totalHours = resourceAllocation.getIntendedTotalHours();
// Generate first day assignment
- int hoursCanAllocate = hoursCanWorkOnDay(resourceAllocation, date, startTime.getHour());
+ int hoursCanAllocate = hoursCanWorkOnDay(resource, date, startTime.getHour());
if (hoursCanAllocate > 0) {
int hoursToAllocate = Math.min(totalHours, hoursCanAllocate);
- SpecificDayAssignment dayAssignment = SpecificDayAssignment.create(
- date, hoursToAllocate, resourceAllocation.getResource());
+ DayAssignment dayAssignment = createDayAssignment(resourceAllocation, resource, date, hoursToAllocate);
totalHours -= addDayAssignment(assignments, dayAssignment);
- } else {
- newStartTime = new DateAndHour(date.plusDays(1), 0);
}
// Generate rest of day assignments
for (date = date.plusDays(1); totalHours > 0; date = date.plusDays(1)) {
totalHours -= addDayAssignment(assignments, generateDayAssignment(
- resourceAllocation, date, totalHours));
+ resourceAllocation, resource, date, totalHours));
}
- resourceAllocation.allocateLimitingDayAssignments(assignments);
-
- DateAndHour newEndTime = new DateAndHour(date, getEndingTime(assignments));
- DateAndHour[] startAndEndTime = {newStartTime, newEndTime};
- return startAndEndTime;
+ return assignments;
}
- private DayAssignment getLastDayAssignment(List dayAssignments) {
- return dayAssignments.get(dayAssignments.size() - 1);
- }
-
- private int getEndingTime(List dayAssignments) {
- return (dayAssignments.isEmpty()) ? 0 : getLastDayAssignment(dayAssignments).getHours();
- }
-
- private int addDayAssignment(List list, SpecificDayAssignment dayAssignment) {
+ private int addDayAssignment(List list, DayAssignment dayAssignment) {
if (dayAssignment != null) {
list.add(dayAssignment);
return dayAssignment.getHours();
@@ -603,26 +710,24 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
return 0;
}
- private int hoursCanWorkOnDay(final SpecificResourceAllocation resourceAllocation,
+ private int hoursCanWorkOnDay(final Resource resource,
final LocalDate date, int alreadyWorked) {
- final ResourceCalendar calendar = resourceAllocation.getResource()
- .getCalendar();
+ final ResourceCalendar calendar = resource.getCalendar();
int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY);
return hoursCanAllocate - alreadyWorked;
}
- private SpecificDayAssignment generateDayAssignment(
- final SpecificResourceAllocation resourceAllocation,
+ private DayAssignment generateDayAssignment(
+ final ResourceAllocation> resourceAllocation,
+ Resource resource,
final LocalDate date, int intentedHours) {
- final ResourceCalendar calendar = resourceAllocation.getResource()
- .getCalendar();
+ final ResourceCalendar calendar = resource.getCalendar();
int hoursCanAllocate = calendar.toHours(date, ONE_RESOURCE_PER_DAY);
if (hoursCanAllocate > 0) {
int hoursToAllocate = Math.min(intentedHours, hoursCanAllocate);
- return SpecificDayAssignment.create(date, hoursToAllocate,
- resourceAllocation.getResource());
+ return createDayAssignment(resourceAllocation, resource, date, hoursToAllocate);
}
return null;
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourcesController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourcesController.java
index 85436bfd8..2abcb21ff 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourcesController.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/LimitingResourcesController.java
@@ -358,15 +358,22 @@ public class LimitingResourcesController implements Composer {
LimitingResourceQueueElementDTO dto) {
LimitingResourceQueueElement element = dto.getOriginal();
- if (element.getResourceAllocation() instanceof GenericResourceAllocation) {
- // TODO: Generic resources allocation
- Log.error("Allocation of generic resources is not supported yet");
- return;
+ if (limitingResourceQueueModel
+ .assignLimitingResourceQueueElement(element)) {
+ Util.reloadBindings(gridUnassignedLimitingResourceQueueElements);
+ limitingResourcesPanel.appendQueueElementToQueue(element);
+ } else {
+ showErrorMessage(_("Cannot allocate selected element. There is not any queue " +
+ "that matches resource allocation criteria at any interval of time"));
+ }
+ }
+
+ private void showErrorMessage(String error) {
+ try {
+ Messagebox.show(error, _("Error"), Messagebox.OK, Messagebox.ERROR);
+ } catch (InterruptedException e) {
+
}
- limitingResourceQueueModel
- .assignLimitingResourceQueueElement(element);
- Util.reloadBindings(gridUnassignedLimitingResourceQueueElements);
- limitingResourcesPanel.appendQueueElementToQueue(element);
}
private Checkbox automaticQueueing(