class Task

File

task.rb

(C)

Hipposoft 2007

Purpose

Describe the behaviour of Task objects. See below for more details.


24-Dec-2007 (ADH): Created.

Constants

DEFAULT_SORT_COLUMN
DEFAULT_SORT_DIRECTION
DEFAULT_SORT_ORDER
USED_RANGE_COLUMN

Public Class Methods

generate_xml_code( id ) click to toggle source

Given an ID, generate a task code for an XML-imported task based on the current date.

# File app/models/task.rb, line 121
def self.generate_xml_code( id )
  today = Date.current
  "XML-%04d%02d%02d-#{ id }" % [ today.year, today.month, today.day ]
end
new( params = nil, user = nil ) click to toggle source

Some default properties are dynamic, so assign these here rather than as defaults in a migration.

Parameters:

Optional hash used for instance initialisation in the traditional way
for an ActiveRecord subclass.

Optional User object. A default project is taken from that user's
control panel data, if available.
# File app/models/task.rb, line 89
def initialize( params = nil, user = nil )
  super( params )

  self.duration = 0
  self.active   = true
  self.code     = "TID%05d" % Task.count

  if ( user and user.control_panel )
    cp = user.control_panel
    self.project = cp.project if ( cp.project and cp.project.active )
  end
end
sort_by_augmented_title( list ) click to toggle source

Class method - sort an array of tasks by the augmented title. Since this isn’t done by the database, it’s slow.

# File app/models/task.rb, line 144
def self.sort_by_augmented_title( list )
  list.sort! { | x, y | x.augmented_title <=> y.augmented_title }
end

Public Instance Methods

augmented_title() click to toggle source

Return the ‘augmented’ task title; that is, the task name, with the project and customer names appended if available.

# File app/models/task.rb, line 129
def augmented_title
  if ( self.project )
    if ( self.project.customer )
      return "#{ self.project.customer.title } - #{ self.project.title }: #{ self.title }"
    end

    return "#{ self.project.title }: #{ self.title }"
  end

  return "#{ self.title }"
end
can_be_modified_by?( user ) click to toggle source

Is the given user permitted to update this task? Restricted users cannot modify tasks. Administrators always can. Managers only can if the task is still active.

# File app/models/task.rb, line 112
def can_be_modified_by?( user )
  return false if ( user.restricted? )
  return true  if ( user.admin?      )
  return self.active
end
committed_worked() click to toggle source

Number of committed hours worked on this task.

# File app/models/task.rb, line 213
def committed_worked
  sum = 0.0

  self.work_packets.each do | work_packet |
    sum += work_packet.worked_hours if ( work_packet.timesheet_row.timesheet.committed )
  end

  return sum
end
is_permitted_for?( user ) click to toggle source

Is the given user permitted to do anything with this task?

# File app/models/task.rb, line 104
def is_permitted_for?( user )
  return ( user.privileged? or user.tasks.include?( self ) )
end
not_committed_worked() click to toggle source

Number of not committed hours worked on this task.

# File app/models/task.rb, line 225
def not_committed_worked
  sum = 0.0

  self.work_packets.each do | work_packet |
    sum += work_packet.worked_hours unless ( work_packet.timesheet_row.timesheet.committed )
  end

  return sum
end
split_user_types() click to toggle source

Return an array with two elements - the first is the restricted associated users, the second the unrestricted associated users. Arrays will be empty if there are no associated users. Does this the slow way, asking each user if it is restricted, rather than making assumptions about how to quickly find restricted types.

# File app/models/task.rb, line 154
def split_user_types
  restricted   = []
  unrestricted = []

  self.users.each do | user |
    if ( user.restricted? )
      restricted.push( user )
    else
      unrestricted.push( user )
    end
  end

  return [ restricted, unrestricted ]
end
sum_hours_over_range( date_range, user = nil ) click to toggle source

Number of hours worked on the task between the given start and end Dates as a Range. Optionally pass a User object; work packets will only be counted if they’re in a timesheet belonging to that user.

Returns an object with fields ‘committed’ and ‘not_committed’, giving sums for those types of hours.

# File app/models/task.rb, line 243
def sum_hours_over_range( date_range, user = nil )
  committed_sum     = 0.0
  not_committed_sum = 0.0
  work_packets      = self.work_packets.all( :conditions => { :date => date_range } )

  work_packets.each do | work_packet |
    timesheet = work_packet.timesheet_row.timesheet

    if ( user.nil? or timesheet.user == user )
      if ( timesheet.committed )
        committed_sum     += work_packet.worked_hours
      else
        not_committed_sum += work_packet.worked_hours
      end
    end
  end

  return { :committed => committed_sum, :not_committed => not_committed_sum }
end
total_worked() click to toggle source

Number of hours worked on this task, committed or otherwise

# File app/models/task.rb, line 207
def total_worked
  return self.work_packets.sum( :worked_hours ) || 0.0
end
update_with_side_effects!( attrs ) click to toggle source

Update an object with the given attributes. This is done by a special model method because changes of the ‘active’ flag have side effects for other associated objects. THE CALLER *MUST* USE A TRANSACTION around a call to this method. There is no need to call here unless the ‘active’ flag state is changing.

# File app/models/task.rb, line 175
def update_with_side_effects!( attrs )
  active = self.active
  self.update_attributes!( attrs )

  # If the active flag has changed and it *was* 'true', then the task
  # has just been made inactive.

  if ( attrs[ :active ] != active and active == true )

    # When tasks are made inactive, remove them from each of the Task lists
    # in User and ControlPanel objects. There are checks for this elsewhere,
    # but they're only to try and catch cases where this code has gone wrong.
    #
    # Although only restricted users make use of this list, other user types
    # may have a list set up either accidentally or because the user's type
    # is due to be changed to one with lower permissions. As a result, we
    # must update every user.

    User.all.each do | user |
      user.remove_inactive_tasks()
      user.save!
    end

    ControlPanel.all.each do | cp |
      cp.remove_inactive_tasks()
      cp.save!
    end
  end
end