lib/taskjuggler/ResourceScenario.rb in taskjuggler-3.2.0 vs lib/taskjuggler/ResourceScenario.rb in taskjuggler-3.3.0
- old
+ new
@@ -182,37 +182,29 @@
end
#puts "Booking resource #{@property.fullId} at " +
# "#{@scoreboard.idxToDate(sbIdx)}/#{sbIdx} for task #{task.fullId}\n"
@scoreboard[sbIdx] = task
- # Track the total allocated slots for this resource and all parent
- # resources.
- t = @property
- while t
- t['effort', @scenarioIdx] += 1
- t = t.parent
- end
+ # Track the total allocated slots for this resource.
+ @effort += @efficiency
@limits.inc(sbIdx) if @limits
# Scoreboard iterations are fairly expensive but they are very frequent
# operations in later processing. To limit the interations to the
# relevant intervals, we store the interval for all bookings and for
# each individual task.
if @firstBookedSlot.nil? || @firstBookedSlot > sbIdx
- @firstBookedSlot = sbIdx
+ @firstBookedSlot = @firstBookedSlots[task] = sbIdx
+ elsif @firstBookedSlots[task].nil? || @firstBookedSlots[task] > sbIdx
+ @firstBookedSlots[task] = sbIdx
end
if @lastBookedSlot.nil? || @lastBookedSlot < sbIdx
- @lastBookedSlot = sbIdx
+ @lastBookedSlot = @lastBookedSlots[task] = sbIdx
+ elsif @lastBookedSlots[task].nil? || @lastBookedSlots[task] < sbIdx
+ @lastBookedSlots[task] = sbIdx
end
- if task
- if @firstBookedSlots[task].nil? || @firstBookedSlots[task] > sbIdx
- @firstBookedSlots[task] = sbIdx
- end
- if @lastBookedSlots[task].nil? || @lastBookedSlots[task] < sbIdx
- @lastBookedSlots[task] = sbIdx
- end
- end
+
true
end
def bookBooking(sbIdx, booking)
initScoreboard if @scoreboard.nil?
@@ -251,10 +243,25 @@
end
book(sbIdx, booking.task, true)
end
+ # @effort only trackes the already allocated effort for leaf resources. It's
+ # too expensive to propagate this to the group resources on every booking.
+ # If a value for a group effort is needed, it's computed here.
+ def bookedEffort
+ if @property.leaf?
+ @effort
+ else
+ effort = 0
+ @property.kids.each do |r|
+ effort += r.bookedEffort(@scenarioIdx)
+ end
+ effort
+ end
+ end
+
# Compute the annual leave days within the period specified by the
# _query_. The result is in days.
def query_annualleave(query)
query.sortable = query.numerical = val =
getLeave(query.startIdx, query.endIdx, :annual)
@@ -294,10 +301,35 @@
query.sortable = query.numerical = effort =
getEffectiveWork(query.startIdx, query.endIdx, query.scopeProperty)
query.string = query.scaleLoad(effort)
end
+ # The completed (as of 'now') effort allocated for the resource in the
+ # specified interval. In case a Task is given as scope property only
+ # the effort allocated for this Task is taken into account.
+ def query_effortdone(query)
+ # For this query, we always override the query period.
+ query.sortable = query.numerical = effort =
+ getEffectiveWork(@project.dateToIdx(@project['start'], false),
+ @project.dateToIdx(@project['now']),
+ query.scopeProperty)
+ query.string = query.scaleLoad(effort)
+ end
+
+
+ # The remaining (as of 'now') effort allocated for the resource in the
+ # specified interval. In case a Task is given as scope property only
+ # the effort allocated for this Task is taken into account.
+ def query_effortleft(query)
+ # For this query, we always override the query period.
+ query.sortable = query.numerical = effort =
+ getEffectiveWork(@project.dateToIdx(@project['now']),
+ @project.dateToIdx(@project['end'], false),
+ query.scopeProperty)
+ query.string = query.scaleLoad(effort)
+ end
+
# The unallocated work time of the Resource during the specified interval.
def query_freetime(query)
query.sortable = query.numerical = time =
getEffectiveFreeTime(query.startIdx, query.endIdx) / (60 * 60 * 24)
query.string = query.scaleDuration(time)
@@ -447,13 +479,14 @@
# Make sure we have the real Task and not a proxy.
task = task.ptn if task
# There can't be any effective work if the start is after the end or the
# todo list doesn't contain the specified task.
return 0.0 if startIdx >= endIdx || (task && !@duties.include?(task))
+ # Temporary workaround until @duties is fixed again.
# The unique key we use to address the result in the cache.
- @dCache.cached(self, :ResourceScenarioEffectiveWork, startIdx, endIdx,
+ @dCache.cached(self, :ResourceScenarioGetEffectiveWork, startIdx, endIdx,
task) do
work = 0.0
if @property.container?
@property.kids.each do |resource|
work += resource.getEffectiveWork(@scenarioIdx, startIdx, endIdx,
@@ -514,17 +547,17 @@
amount += child.turnover(@scenarioIdx, startIdx, endIdx, account,
task)
end
else
if task
- # If we have a know task, we only include the amount that is
+ # If we have a known task, we only include the amount that is
# specific to this resource, this task and the chargeset of the
# task.
amount += task.turnover(@scenarioIdx, startIdx, endIdx, account,
@property)
elsif !@chargeset.empty?
# If no tasks was provided, we include the amount of this resource,
- # weighted by the charset of this resource.
+ # weighted by the chargeset of this resource.
totalResourceCost = cost(startIdx, endIdx)
@chargeset.each do |set|
set.each do |accnt, share|
if share > 0.0 && (accnt == account || accnt.isChildOf?(account))
amount += totalResourceCost * share