class TaskJuggler::LogicalFunction

The LogicalFunction is a specialization of the LogicalOperation. It models a function call in a LogicalExpression.

Attributes

arguments[RW]
name[RW]

Public Class Methods

new(opnd) click to toggle source

Create a new LogicalFunction. opnd is the name of the function.

# File lib/taskjuggler/LogicalFunction.rb, line 42
def initialize(opnd)
  if opnd[-1] == _
    # Function names with a trailing _ are like their counterparts without
    # the _. But during evaluation the property and the scope properties
    # will be switched.
    @name = opnd[0..-2]
    @invertProperties = true
  else
    @name = opnd
    @invertProperties = false
  end
  @arguments = []
end

Public Instance Methods

eval(expr) click to toggle source

Evaluate the function by calling it with the arguments.

# File lib/taskjuggler/LogicalFunction.rb, line 74
def eval(expr)
  # Call the function and return the result.
  send(name, expr, @arguments)
end
setArgumentsAndCheck(args) click to toggle source

Register the arguments of the function and check if the name is a known function and the number of arguments match this function. If not, return an [ id, message ] error. Otherwise nil.

# File lib/taskjuggler/LogicalFunction.rb, line 59
def setArgumentsAndCheck(args)
  unless @@functions.include?(@name)
    return [ 'unknown_function',
             "Unknown function #{@name} used in logical expression." ]
  end
  if @@functions[@name] != args.length
    return [ 'wrong_no_func_arguments',
             "Wrong number of arguments for function #{@name}. Got " +
             "#{args.length} instead of #{@@functions[@name]}." ]
  end
  @arguments = args
  nil
end
to_s() click to toggle source

Return a textual expression of the function call.

# File lib/taskjuggler/LogicalFunction.rb, line 80
def to_s
  "#{@name}(#{@arguments.join(', ')})"
end

Private Instance Methods

hasalert(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 96
def hasalert(expr, args)
  property = properties(expr)[0]
  query = expr.query
  project = property.project
  !project['journal'].currentEntries(query.end, property,
                                     args[0], query.start,
                                     query.hideJournalEntry).empty?
end
isactive(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 105
def isactive(expr, args)
  property, scopeProperty = properties(expr)
  # The result can only be true when called for a Task property.
  return false unless property.is_a?(Task) ||
                      property.is_a?(Resource)
  project = property.project
  # 1st arg must be a scenario index.
  if (scenarioIdx = project.scenarioIdx(args[0])).nil?
    expr.error("Unknown scenario '#{args[0]}' used for function isactive()")
  end

  query = expr.query
  property.getAllocatedTime(scenarioIdx, query.startIdx, query.endIdx,
                            scopeProperty) > 0.0
end
ischildof(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 121
def ischildof(expr, args)
  # The the context property.
  property = properties(expr)[0]
  # Find the prospective parent ID in the current PropertySet.
  return false unless (parent = property.propertySet[args[0]])

  property.isChildOf?(parent)
end
isdependencyof(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 130
def isdependencyof(expr, args)
  property = properties(expr)[0]
  # The result can only be true when called for a Task property.
  return false unless property.is_a?(Task)
  project = property.project
  # 1st arg must be a task ID.
  return false if (task = project.task(args[0])).nil?
  # 2nd arg must be a scenario index.
  return false if (scenarioIdx = project.scenarioIdx(args[1])).nil?
  # 3rd arg must be an integer number.
  return false unless args[2].is_a?(Fixnum)

  property.isDependencyOf(scenarioIdx, task, args[2])
end
isdutyof(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 145
def isdutyof(expr, args)
  property = properties(expr)[0]
  # The result can only be true when called for a Task property.
  return false unless (task = property).is_a?(Task)
  project = task.project
  # 1st arg must be a resource ID.
  return false if (resource = project.resource(args[0])).nil?
  # 2nd arg must be a scenario index.
  return false if (scenarioIdx = project.scenarioIdx(args[1])).nil?

  task['assignedresources', scenarioIdx].include?(resource)
end
isfeatureof(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 158
def isfeatureof(expr, args)
  property = properties(expr)[0]
  # The result can only be true when called for a Task property.
  return false unless property.is_a?(Task)
  project = property.project
  # 1st arg must be a task ID.
  return false if (task = project.task(args[0])).nil?
  # 2nd arg must be a scenario index.
  return false if (scenarioIdx = project.scenarioIdx(args[1])).nil?

  property.isFeatureOf(scenarioIdx, task)
end
isleaf(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 171
def isleaf(expr, args)
  property = properties(expr)[0]
  return false unless property
  property.leaf?
end
ismilestone(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 177
def ismilestone(expr, args)
  property = properties(expr)[0]
  return false unless property
  # 1st arg must be a scenario index.
  return false if (scenarioIdx = property.project.scenarioIdx(args[0])).nil?

  property.is_a?(Task) && property['milestone', scenarioIdx]
end
isongoing(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 186
def isongoing(expr, args)
  property = properties(expr)[0]
  # The result can only be true when called for a Task property.
  return false unless (task = property).is_a?(Task)
  project = task.project
  # 1st arg must be a scenario index.
  if (scenarioIdx = project.scenarioIdx(args[0])).nil?
    expr.error("Unknown scenario '#{args[0]}' used for function " +
               "isongoing()")
  end

  query = expr.query
  iv1 = TimeInterval.new(query.start, query.end)
  tStart = task['start', scenarioIdx]
  tEnd = task['end', scenarioIdx]
  # This helps to show tasks with scheduling errors.
  return true unless tStart && tEnd
  iv2 = TimeInterval.new(tStart, tEnd)

  return iv1.overlaps?(iv2)
end
isresource(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 208
def isresource(expr, args)
  property = properties(expr)[0]
  return false unless property
  property.is_a?(Resource)
end
isresponsibilityof(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 214
def isresponsibilityof(expr, args)
  property = properties(expr)[0]
  # The result can only be true when called for a Task property.
  return false unless (task = property).is_a?(Task)
  project = task.project
  # 1st arg must be a resource ID.
  return false if (resource = project.resource(args[0])).nil?
  # 2nd arg must be a scenario index.
  return false if (scenarioIdx = project.scenarioIdx(args[1])).nil?

  task['responsible', scenarioIdx].include?(resource)
end
istask(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 227
def istask(expr, args)
  property = properties(expr)[0]
  return false unless property
  property.is_a?(Task)
end
properties(expr) click to toggle source

Return the property and scope property as determined by the @invertProperties setting.

# File lib/taskjuggler/LogicalFunction.rb, line 88
def properties(expr)
  if @invertProperties
    return expr.query.scopeProperty, nil
  else
    return expr.query.property, expr.query.scopeProperty
  end
end
treelevel(expr, args) click to toggle source
# File lib/taskjuggler/LogicalFunction.rb, line 233
def treelevel(expr, args)
  property = properties(expr)[0]
  return 0 unless property
  property.level + 1
end