Class: Trajectory::Project

Inherits:
Object
  • Object
show all
Includes:
Virtus
Defined in:
lib/trajectory/domain/project.rb

Constant Summary collapse

NUMBER_OF_WORKING_DAYS_BY_WEEK =
5.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#iterations_collection=(value) ⇒ Object (writeonly)



8
9
10
# File 'lib/trajectory/domain/project.rb', line 8

def iterations_collection=(value)
  @iterations_collection = value
end

#storiesStories

Fetch all stories that belongs to the project

Returns:

  • (Stories)

    the stories collection



46
47
48
# File 'lib/trajectory/domain/project.rb', line 46

def stories
  @stories ||= DataStore.stories_for_project(self)
end

#users_collection=(value) ⇒ Object (writeonly)



8
9
10
# File 'lib/trajectory/domain/project.rb', line 8

def users_collection=(value)
  @users_collection = value
end

Instance Method Details

#==(other) ⇒ true, false

Returns true if two projects are the sames i.e they share the same id attribute

Parameters:

  • other (Project)

    the other object to compare

Returns:

  • (true, false)


39
40
41
# File 'lib/trajectory/domain/project.rb', line 39

def ==(other)
  id == other.id
end

#accepted_pointsInteger

Returns the sum of accepted story points

Returns:

  • (Integer)

    the number of points



179
180
181
# File 'lib/trajectory/domain/project.rb', line 179

def accepted_points
  total_points - remaining_points
end

#archived?true, false

Returns true if the project has been archived, false otherwise.

Returns:

  • (true, false)

    true if the project has been archived, false otherwise



18
# File 'lib/trajectory/domain/project.rb', line 18

attribute :archived, Boolean

#completed_iterations_countInteger

Returns number of completed iterations in the project.

Returns:

  • (Integer)

    number of completed iterations in the project



30
# File 'lib/trajectory/domain/project.rb', line 30

attribute :completed_iterations_count, Integer

#completed_stories_countInteger

Returns number of completed stories in the project.

Returns:

  • (Integer)

    number of completed stories in the project



32
# File 'lib/trajectory/domain/project.rb', line 32

attribute :completed_stories_count, Integer

#created_atDateTime

Returns creation date of the project.

Returns:

  • (DateTime)

    creation date of the project



20
# File 'lib/trajectory/domain/project.rb', line 20

attribute :created_at, DateTime

#estimated_end_dateDate

Returns estimated end date of the project with the actual estimated velocity

Returns:

  • (Date)

    the estimated date



113
114
115
# File 'lib/trajectory/domain/project.rb', line 113

def estimated_end_date
  Date.today + remaining_days
end

#estimated_velocityInteger

Returns the current velocity of the project.

Returns:

  • (Integer)

    the current velocity of the project



22
# File 'lib/trajectory/domain/project.rb', line 22

attribute :estimated_velocity, Integer

#estimated_velocity_per_dayInteger

Returns the estimated velocity by day over a week

Returns:

  • (Integer)

    the estimated velocity



147
148
149
# File 'lib/trajectory/domain/project.rb', line 147

def estimated_velocity_per_day
  estimated_velocity / 7.0
end

#estimated_velocity_per_working_dayInteger

Returns the estimated velocity by day over billable days (actually 5 days)

Returns:

  • (Integer)

    the estimated velocity



165
166
167
# File 'lib/trajectory/domain/project.rb', line 165

def estimated_velocity_per_working_day
  estimated_velocity / NUMBER_OF_WORKING_DAYS_BY_WEEK
end

#find_iteration_by_id(id) ⇒ Iteration, false

Fetch a iteration from the project given its id or false if it does not exist

Returns:

  • (Iteration, false)

    the iteration or false



89
90
91
# File 'lib/trajectory/domain/project.rb', line 89

def find_iteration_by_id(id)
  iterations.find_by_id(id)
end

#find_user_by_id(id) ⇒ User, false

Fetch a user from the project given its id or false if it does not exist

Returns:

  • (User, false)

    the user or false



82
83
84
# File 'lib/trajectory/domain/project.rb', line 82

def find_user_by_id(id)
  users.find_by_id(id)
end

#has_started?true, false

Returns true if the project has already started some development (i.e stories have been accepted and a velocity has been evaluated). It returns false otherwise

Returns:

  • (true, false)


201
202
203
204
205
# File 'lib/trajectory/domain/project.rb', line 201

def has_started?
  historic_velocity.any? do |velocity|
    velocity != 0
  end
end

#historic_velocityArray<Integer>

Returns the velocities of past iterations.

Returns:

  • (Array<Integer>)

    the velocities of past iterations



24
# File 'lib/trajectory/domain/project.rb', line 24

attribute :historic_velocity, Array[Integer]

#idInteger

Returns the unique identifier of the project.

Returns:

  • (Integer)

    the unique identifier of the project.

Raises:



12
# File 'lib/trajectory/domain/project.rb', line 12

attribute :id, Integer, default: lambda { |project, attribute| raise MissingAttributeError.new(project, :id) }

#ideasIdeas

Fetch all ideas that belongs to the project

Returns:

  • (Ideas)

    the ideas collection



60
61
62
# File 'lib/trajectory/domain/project.rb', line 60

def ideas
  @ideas ||= DataStore.ideas_for_project(self)
end

#iterationsIterations

Fetch all iterations that belongs to the project

Returns:



53
54
55
# File 'lib/trajectory/domain/project.rb', line 53

def iterations
  @iterations_collection ||= DataStore.iterations_for_project(self)
end

#keywordString

Returns project keyword identifier.

Returns:

  • (String)

    project keyword identifier



26
# File 'lib/trajectory/domain/project.rb', line 26

attribute :keyword, String

#last_non_null_velocityInteger

Returns the last non null velocity of the project or raise an error if the project never started

(i.e the project has not yet started)

Returns:

  • (Integer)

    a non null velocity

Raises:



189
190
191
192
193
194
# File 'lib/trajectory/domain/project.rb', line 189

def last_non_null_velocity
  raise VelocityAlwaysEqualToZero if !has_started?
  historic_velocity.reverse.find do |velocity|
    velocity != 0
  end
end

#nameString

Returns the project name.

Returns:

  • (String)

    the project name



15
# File 'lib/trajectory/domain/project.rb', line 15

attribute :name, String

#percent_completeFloat

Returns the completion percentage of the project

Returns:

  • (Float)

    the percentage



172
173
174
# File 'lib/trajectory/domain/project.rb', line 172

def percent_complete
  (accepted_points.to_f / total_points * 100.0).round(1)
end

#remaining_daysInteger

Returns the estimated number of days (weekend included) remaining before the end of the project.

This is usefull to estimate the project end date.

Returns:

  • (Integer)

    the number of days

Raises:

  • (VelocityEqualToZeroError)

    if estimated velocity is equal to zero (i.e the project can’t be finished because no one actually works on it)



130
131
132
133
# File 'lib/trajectory/domain/project.rb', line 130

def remaining_days
  raise VelocityEqualToZeroError.new(self) if estimated_velocity_per_day == 0
  (remaining_points / estimated_velocity_per_day).ceil
end

#remaining_iterationsInteger

Returns the number of needed iterations to complete the project

Returns:

  • (Integer)

    the number of iterations



120
121
122
# File 'lib/trajectory/domain/project.rb', line 120

def remaining_iterations
  (remaining_points.to_f / estimated_velocity.to_f).ceil
end

#remaining_pointsInteger

Returns sum of points of not completed stories

Returns:

  • (Integer)

    the number of points



138
139
140
141
142
# File 'lib/trajectory/domain/project.rb', line 138

def remaining_points
  stories.not_completed.inject(0) do |accumulator, story|
    accumulator += story.points
  end
end

#remaining_working_daysInteger

Returns the estimated number of working days (weekend excluded) remaining before the end of the project.

This is usefull to be able to evaluate project budget as not all days are billable.

Returns:

  • (Integer)

    the number of days

Raises:

  • (VelocityEqualToZeroError)

    if estimated velocity is equal to zero (i.e the project can’t be finished because no one actually works on it)



157
158
159
160
# File 'lib/trajectory/domain/project.rb', line 157

def remaining_working_days
  raise VelocityEqualToZeroError.new(self) if estimated_velocity_per_working_day == 0
  (remaining_points / estimated_velocity_per_working_day).ceil
end

#stories_in_iteration(iteration) ⇒ Stories

Fetch the stories in a given iteration of a project

Parameters:

Returns:



97
98
99
# File 'lib/trajectory/domain/project.rb', line 97

def stories_in_iteration(iteration)
  stories.in_iteration(iteration)
end

#total_pointsInteger

Returns the sum of all points of each story of the project

Returns:

  • (Integer)

    the points accumulation



104
105
106
107
108
# File 'lib/trajectory/domain/project.rb', line 104

def total_points
  stories.inject(0) do |accumulator, story|
    accumulator += story.points
  end
end

#updated_atDateTime

Returns last modification date of the project.

Returns:

  • (DateTime)

    last modification date of the project



28
# File 'lib/trajectory/domain/project.rb', line 28

attribute :updated_at, DateTime

#updates(since = DateTime.now) ⇒ Updates

Fetch updates that belongs to the project since a given date

Parameters:

  • since (DateTime) (defaults to: DateTime.now)

    the date

Returns:

  • (Updates)

    the updates collection



75
76
77
# File 'lib/trajectory/domain/project.rb', line 75

def updates(since = DateTime.now)
  DataStore.updates_for_project(self, since)
end

#usersUsers

Fetch all users that belongs to the project

Returns:

  • (Users)

    the users collection



67
68
69
# File 'lib/trajectory/domain/project.rb', line 67

def users
  @users_collection ||= DataStore.users_for_project(self)
end