tracks/app/models/project.rb

155 lines
3.7 KiB
Ruby
Raw Normal View History

class Project < ActiveRecord::Base
has_many :todos, :dependent => :delete_all
has_many :notes, :dependent => :delete_all, :order => "created_at DESC"
has_many :recurring_todos
belongs_to :default_context, :class_name => "Context", :foreign_key => "default_context_id"
belongs_to :user
named_scope :active, :conditions => { :state => 'active' }
named_scope :hidden, :conditions => { :state => 'hidden' }
named_scope :completed, :conditions => { :state => 'completed'}
named_scope :uncompleted, :conditions => ["NOT(state = ?)", 'completed']
validates_presence_of :name
validates_length_of :name, :maximum => 255
validates_uniqueness_of :name, :scope => "user_id"
acts_as_list :scope => 'user_id = #{user_id} AND state = \'#{state}\'', :top_of_list => 0
2011-05-16 15:42:47 +08:00
include AASM
aasm_column :state
aasm_initial_state :active
extend NamePartFinder
#include Tracks::TodoList
2011-05-16 15:42:47 +08:00
aasm_state :active
aasm_state :hidden, :enter => :hide_todos, :exit => :unhide_todos
aasm_state :completed, :enter => :set_completed_at_date, :exit => :clear_completed_at_date
2011-05-16 15:42:47 +08:00
aasm_event :activate do
transitions :to => :active, :from => [:active, :hidden, :completed]
end
2011-05-16 15:42:47 +08:00
aasm_event :hide do
transitions :to => :hidden, :from => [:active, :completed]
end
2011-05-16 15:42:47 +08:00
aasm_event :complete do
transitions :to => :completed, :from => [:active, :hidden]
end
attr_protected :user
attr_accessor :cached_note_count
def self.null_object
NullProject.new
end
def self.feed_options(user)
{
2010-11-09 10:47:09 +01:00
:title => I18n.t('models.project.feed_title'),
:description => I18n.t('models.project.feed_description', :username => user.display_name)
}
end
def hide_todos
todos.each do |t|
unless t.completed? || t.deferred?
t.hide!
t.save
end
end
end
def unhide_todos
todos.each do |t|
if t.project_hidden?
t.unhide!
t.save
end
end
end
def set_completed_at_date
self.completed_at = Time.zone.now
end
def clear_completed_at_date
self.completed_at = nil
end
def note_count
# TODO: test this for eager and not eager loading!!!
return 0 if notes.size == 0
cached_note_count || notes.count
end
alias_method :original_default_context, :default_context
def default_context
original_default_context.nil? ? Context.null_object : original_default_context
end
# would prefer to call this method state=(), but that causes an endless loop
# as a result of acts_as_state_machine calling state=() to update the attribute
def transition_to(candidate_state)
case candidate_state.to_sym
2011-05-16 15:42:47 +08:00
when aasm_current_state
return
when :hidden
hide!
when :active
activate!
when :completed
complete!
end
end
2011-09-16 15:07:58 -04:00
def needs_review?(current_user)
return false if self.completed?
2011-09-16 23:34:09 -04:00
return true if last_reviewed.nil?
2011-09-28 13:54:50 +02:00
return (active? && (last_reviewed < current_user.time - current_user.prefs.review_period.days))
2011-09-16 23:34:09 -04:00
end
def blocked?
## mutually exclusive for stalled and blocked
2011-09-28 13:54:50 +02:00
# blocked is uncompleted project with deferred or pending todos, but no next actions
2011-09-28 15:34:15 +02:00
return false if self.completed?
return !self.todos.deferred_or_blocked.empty? && self.todos.not_deferred_or_blocked.empty?
2011-09-16 23:34:09 -04:00
end
2011-09-28 13:54:50 +02:00
2011-09-16 23:34:09 -04:00
def stalled?
2011-09-28 13:54:50 +02:00
# stalled is active/hidden project with no active todos
return false if self.completed?
2011-09-28 15:34:15 +02:00
return self.todos.deferred_or_blocked.empty? && self.todos.not_deferred_or_blocked.empty?
2011-09-16 15:07:58 -04:00
end
def name=(value)
self[:name] = value.gsub(/\s{2,}/, " ").strip
end
def new_record_before_save?
@new_record_before_save
end
end
class NullProject
def hidden?
false
end
def nil?
true
end
def id
nil
end
2009-04-19 00:18:12 +02:00
end