2009-01-08 10:18:03 +01:00
class TodosController < ApplicationController
helper :todos
skip_before_filter :login_required , :only = > [ :index , :calendar ]
prepend_before_filter :login_or_feed_token_required , :only = > [ :index , :calendar ]
2010-04-27 10:18:07 -04:00
append_before_filter :find_and_activate_ready , :only = > [ :index , :list_deferred ]
2011-01-01 18:55:53 +01:00
append_before_filter :init , :except = > [ :tag , :destroy , :completed ,
2009-05-02 16:43:00 -04:00
:completed_archive , :check_deferred , :toggle_check , :toggle_star ,
2010-03-14 16:48:28 -04:00
:edit , :update , :create , :calendar , :auto_complete_for_predecessor , :remove_predecessor , :add_predecessor ]
2010-08-03 22:27:54 +02:00
append_before_filter :get_todo_from_params , :only = > [ :edit , :toggle_check , :toggle_star , :show , :update , :destroy , :remove_predecessor , :show_notes ]
2010-03-14 16:48:28 -04:00
protect_from_forgery :except = > [ :auto_complete_for_predecessor ]
2009-01-08 10:18:03 +01:00
def index
@projects = current_user . projects . find ( :all , :include = > [ :default_context ] )
@contexts = current_user . contexts . find ( :all )
@contexts_to_show = current_user . contexts . active
respond_to do | format |
format . html & render_todos_html
format . m & render_todos_mobile
format . xml { render :xml = > @todos . to_xml ( :except = > :user_id ) }
format . rss & render_rss_feed
format . atom & render_atom_feed
format . text & render_text_feed
format . ics & render_ical_feed
end
end
def new
@projects = current_user . projects . active
@contexts = current_user . contexts . find ( :all )
respond_to do | format |
format . m {
@new_mobile = true
2009-06-02 22:03:17 +02:00
@return_path = cookies [ :mobile_url ] ? cookies [ :mobile_url ] : mobile_path
2009-01-08 10:18:03 +01:00
@mobile_from_context = current_user . contexts . find_by_id ( params [ :from_context ] ) if params [ :from_context ]
@mobile_from_project = current_user . projects . find_by_id ( params [ :from_project ] ) if params [ :from_project ]
if params [ :from_project ] && ! params [ :from_context ]
# we have a project but not a context -> use the default context
@mobile_from_context = @mobile_from_project . default_context
end
render :action = > " new "
}
end
end
def create
@source_view = params [ '_source_view' ] || 'todo'
2010-12-17 16:01:22 +01:00
@default_context = current_user . contexts . find_by_name ( params [ 'default_context_name' ] )
2010-07-14 20:20:55 +02:00
@tag_name = params [ '_tag_name' ]
2010-07-28 16:27:52 +02:00
is_multiple = params [ :todo ] && params [ :todo ] [ :multiple_todos ] && ! params [ :todo ] [ :multiple_todos ] . nil?
if is_multiple
2010-07-14 20:20:55 +02:00
create_multiple
else
p = TodoCreateParamsHelper . new ( params , prefs )
p . parse_dates ( ) unless mobile?
tag_list = p . tag_list
predecessor_list = p . predecessor_list
2009-01-08 10:18:03 +01:00
2010-07-14 20:20:55 +02:00
@todo = current_user . todos . build ( p . attributes )
2010-05-08 19:30:58 -04:00
2010-07-14 20:20:55 +02:00
if p . project_specified_by_name?
project = current_user . projects . find_or_create_by_name ( p . project_name )
@new_project_created = project . new_record_before_save?
@todo . project_id = project . id
end
2009-01-08 10:18:03 +01:00
2010-07-14 20:20:55 +02:00
if p . context_specified_by_name?
context = current_user . contexts . find_or_create_by_name ( p . context_name )
@new_context_created = context . new_record_before_save?
@not_done_todos = [ @todo ] if @new_context_created
@todo . context_id = context . id
end
2009-01-08 10:18:03 +01:00
2010-07-14 20:20:55 +02:00
@todo . add_predecessor_list ( predecessor_list )
2010-05-08 19:30:58 -04:00
2010-07-14 20:20:55 +02:00
# Fix for #977 because AASM overrides @state on creation
specified_state = @todo . state
@saved = @todo . save
# Fix for #977 because AASM overrides @state on creation
@todo . update_attribute ( 'state' , specified_state ) unless specified_state == " immediate "
2011-01-01 18:55:53 +01:00
@todo . update_state_from_project
@saved = @todo . save
2010-05-08 19:30:58 -04:00
2010-07-14 20:20:55 +02:00
unless ( @saved == false ) || tag_list . blank?
@todo . tag_with ( tag_list )
@todo . tags . reload
end
2011-01-01 18:55:53 +01:00
if @saved
2010-07-14 20:20:55 +02:00
unless @todo . uncompleted_predecessors . empty? || @todo . state == 'project_hidden'
@todo . state = 'pending'
end
@todo . save
end
2011-01-01 18:55:53 +01:00
@todo . reload
2010-07-14 20:20:55 +02:00
respond_to do | format |
format . html { redirect_to :action = > " index " }
format . m do
@return_path = cookies [ :mobile_url ] ? cookies [ :mobile_url ] : mobile_path
if @saved
redirect_to @return_path
else
@projects = current_user . projects . find ( :all )
@contexts = current_user . contexts . find ( :all )
render :action = > " new "
end
end
format . js do
determine_down_count if @saved
@contexts = current_user . contexts . find ( :all ) if @new_context_created
@projects = current_user . projects . find ( :all ) if @new_project_created
@initial_context_name = params [ 'default_context_name' ]
@initial_project_name = params [ 'default_project_name' ]
@default_tags = @todo . project . default_tags unless @todo . project . nil?
2010-12-20 18:20:37 +01:00
@status_message = 'Added new next action'
@status_message += ' to tickler' if @todo . deferred?
@status_message += ' in pending state' if @todo . pending?
2011-01-01 18:55:53 +01:00
@status_message += ' in hidden state' if @todo . hidden?
2010-12-20 18:20:37 +01:00
@status_message = 'Added new project / ' + status_message if @new_project_created
@status_message = 'Added new context / ' + status_message if @new_context_created
2010-07-14 20:20:55 +02:00
render :action = > 'create'
end
format . xml do
if @saved
head :created , :location = > todo_url ( @todo )
else
render :xml = > @todo . errors . to_xml , :status = > 422
end
end
end
end
end
2010-05-08 19:30:58 -04:00
2010-07-14 20:20:55 +02:00
def create_multiple
if project_specified_by_name ( params [ :project_name ] )
project = current_user . projects . find_or_create_by_name ( params [ :project_name ] )
@new_project_created = project . new_record_before_save?
@project_id = project . id
2009-01-08 10:18:03 +01:00
end
2009-06-09 13:45:39 +02:00
2010-07-14 20:20:55 +02:00
if context_specified_by_name ( params [ :context_name ] )
context = current_user . contexts . find_or_create_by_name ( params [ :context_name ] )
@new_context_created = context . new_record_before_save?
@not_done_todos = [ ] if @new_context_created
@context_id = context . id
end
tag_list = params [ :tag_list ]
@todos = [ ]
params [ :todo ] [ :multiple_todos ] . split ( " \n " ) . map do | line |
@todo = current_user . todos . build (
:description = > line )
@todo . project_id = @project_id
@todo . context_id = @context_id
puts " TODO: #{ @todo . description } , #{ @todo . project_id } , #{ @todo . context_id } "
@saved = @todo . save
puts " NOT SAVED " unless @saved
unless ( @saved == false ) || tag_list . blank?
@todo . tag_with ( tag_list )
@todo . tags . reload
2009-11-04 22:45:38 -05:00
end
2010-07-14 20:20:55 +02:00
@todos << @todo
@not_done_todos << @todo if @new_context_created
2009-11-04 22:45:38 -05:00
end
2009-01-08 10:18:03 +01:00
respond_to do | format |
format . html { redirect_to :action = > " index " }
format . js do
determine_down_count if @saved
@contexts = current_user . contexts . find ( :all ) if @new_context_created
@projects = current_user . projects . find ( :all ) if @new_project_created
@initial_context_name = params [ 'default_context_name' ]
@initial_project_name = params [ 'default_project_name' ]
2010-07-16 13:11:01 +02:00
if @todos . size > 0
@default_tags = @todos [ 0 ] . project . default_tags unless @todos [ 0 ] . project . nil?
else
2011-01-16 18:14:07 +01:00
@multiple_error = t ( 'todos.next_action_needed' )
2010-07-16 13:11:01 +02:00
@saved = false ;
@default_tags = current_user . projects . find_by_name ( @initial_project_name ) . default_tags unless @initial_project_name . blank?
end
2010-07-14 20:20:55 +02:00
render :action = > 'create_multiple'
2009-01-08 10:18:03 +01:00
end
format . xml do
if @saved
2010-07-14 20:20:55 +02:00
head :created , :location = > context_url ( @todos [ 0 ] . context )
2009-01-08 10:18:03 +01:00
else
2010-07-14 20:20:55 +02:00
render :xml = > @todos [ 0 ] . errors . to_xml , :status = > 422
2009-01-08 10:18:03 +01:00
end
end
end
end
def edit
@projects = current_user . projects . find ( :all )
@contexts = current_user . contexts . find ( :all )
@source_view = params [ '_source_view' ] || 'todo'
@tag_name = params [ '_tag_name' ]
respond_to do | format |
format . js
end
end
def show
respond_to do | format |
format . m do
@projects = current_user . projects . active
@contexts = current_user . contexts . find ( :all )
@edit_mobile = true
2009-06-02 22:03:17 +02:00
@return_path = cookies [ :mobile_url ] ? cookies [ :mobile_url ] : mobile_path
2009-01-08 10:18:03 +01:00
render :action = > 'show'
end
format . xml { render :xml = > @todo . to_xml ( :root = > 'todo' , :except = > :user_id ) }
end
end
2009-06-10 00:07:23 +02:00
def add_predecessor
2009-07-19 15:41:34 +02:00
@source_view = params [ '_source_view' ] || 'todo'
2010-03-02 11:14:45 +01:00
@predecessor = current_user . todos . find ( params [ 'predecessor' ] )
@todo = current_user . todos . find ( params [ 'successor' ] )
2009-06-12 22:09:46 +02:00
@original_state = @todo . state
# Add predecessor
2009-06-30 23:51:41 +02:00
@todo . add_predecessor ( @predecessor )
2009-06-12 22:09:46 +02:00
@todo . state = 'pending'
@saved = @todo . save
2009-06-10 00:07:23 +02:00
respond_to do | format |
format . js
end
end
2009-01-08 10:18:03 +01:00
2009-08-11 10:16:56 +02:00
def remove_predecessor
@source_view = params [ '_source_view' ] || 'todo'
2010-03-02 11:14:45 +01:00
@predecessor = current_user . todos . find ( params [ 'predecessor' ] )
2009-08-11 10:16:56 +02:00
@successor = @todo
@removed = @successor . remove_predecessor ( @predecessor )
respond_to do | format |
format . js
end
end
2009-01-08 10:18:03 +01:00
# Toggles the 'done' status of the action
#
def toggle_check
@source_view = params [ '_source_view' ] || 'todo'
@original_item_due = @todo . due
2009-04-14 21:36:57 +02:00
@original_item_was_deferred = @todo . deferred?
2009-01-08 10:18:03 +01:00
@saved = @todo . toggle_completion!
# check if this todo has a related recurring_todo. If so, create next todo
@new_recurring_todo = check_for_next_todo ( @todo ) if @saved
2009-05-20 13:02:28 +02:00
if @todo . completed?
2009-11-10 22:10:52 -05:00
@pending_to_activate = @todo . pending_to_activate
@pending_to_activate . each do | t |
2010-07-14 20:20:55 +02:00
t . activate!
2009-05-20 13:02:28 +02:00
end
else
2009-11-10 22:10:52 -05:00
@active_to_block = @todo . active_to_block
@active_to_block . each do | t |
2010-07-14 20:20:55 +02:00
t . block!
2009-05-20 13:02:28 +02:00
end
end
2009-01-08 10:18:03 +01:00
respond_to do | format |
format . js do
if @saved
determine_remaining_in_context_count ( @todo . context_id )
determine_down_count
2010-07-14 20:20:55 +02:00
determine_completed_count
2009-04-14 21:36:57 +02:00
determine_deferred_tag_count ( params [ '_tag_name' ] ) if @source_view == 'tag'
2009-01-08 10:18:03 +01:00
if source_view_is :calendar
@original_item_due_id = get_due_id_for_calendar ( @original_item_due )
@old_due_empty = is_old_due_empty ( @original_item_due_id )
end
end
render
end
format . xml { render :xml = > @todo . to_xml ( :except = > :user_id ) }
format . html do
if @saved
# TODO: I think this will work, but can't figure out how to test it
2011-01-16 18:14:07 +01:00
notify ( :notice , t ( " todos.action_marked_complete " , :description = > @todo . description , :completed = > @todo . completed? ? 'complete' : 'incomplete' ) )
2009-01-08 10:18:03 +01:00
redirect_to :action = > " index "
else
2011-01-16 18:14:07 +01:00
notify ( :notice , t ( " todos.action_marked_complete_error " , :description = > @todo . description , :completed = > @todo . completed? ? 'complete' : 'incomplete' ) , " index " )
2009-01-08 10:18:03 +01:00
redirect_to :action = > " index "
end
end
end
end
def toggle_star
@todo . toggle_star!
@saved = @todo . save!
respond_to do | format |
format . js
format . xml { render :xml = > @todo . to_xml ( :except = > :user_id ) }
2010-12-20 18:20:37 +01:00
format . html { redirect_to request . referrer }
2009-01-08 10:18:03 +01:00
end
end
2010-05-17 11:36:41 -04:00
def change_context
@todo = Todo . find ( params [ :todo ] [ :id ] )
@original_item_context_id = @todo . context_id
@context = Context . find ( params [ :todo ] [ :context_id ] )
@todo . context = @context
@saved = @todo . save
@context_changed = true
2011-01-16 18:14:07 +01:00
@message = t ( 'todos.context_changed' , :name = > @context . name )
2010-05-17 11:36:41 -04:00
determine_remaining_in_context_count ( @original_item_context_id )
respond_to do | format |
format . js { render :action = > :update }
format . xml { render :xml = > @todo . to_xml ( :except = > :user_id ) }
end
end
2009-01-08 10:18:03 +01:00
def update
@source_view = params [ '_source_view' ] || 'todo'
init_data_for_sidebar unless mobile?
2010-12-25 16:28:53 +01:00
cache_attributes_from_before_update
update_tags
2011-01-01 18:55:53 +01:00
update_project
update_context
2010-12-25 16:28:53 +01:00
update_due_and_show_from_dates
update_completed_state
2011-01-01 18:55:53 +01:00
update_dependencies
update_attributes_of_todo
2009-01-08 10:18:03 +01:00
2010-12-25 16:28:53 +01:00
@saved = @todo . save
2011-01-01 18:55:53 +01:00
@todo . reload # refresh context and project object too (not only their id's)
2009-06-30 23:17:33 +02:00
2011-01-01 18:55:53 +01:00
update_todo_state_if_project_changed
2009-06-30 23:17:33 +02:00
2010-12-25 16:28:53 +01:00
determine_changes_by_this_update
determine_remaining_in_context_count ( @context_changed ? @original_item_context_id : @todo . context_id )
2009-01-08 10:18:03 +01:00
determine_down_count
2009-04-07 17:14:51 +02:00
determine_deferred_tag_count ( params [ '_tag_name' ] ) if @source_view == 'tag'
2009-01-08 10:18:03 +01:00
respond_to do | format |
2010-12-25 16:28:53 +01:00
format . js {
@status_message = @todo . deferred? ? t ( 'todos.action_saved_to_tickler' ) : t ( 'todos.action_saved' )
@status_message = t ( 'todos.added_new_project' ) + ' / ' + @status_message if @new_project_created
@status_message = t ( 'todos.added_new_context' ) + ' / ' + @status_message if @new_context_created
}
2009-01-08 10:18:03 +01:00
format . xml { render :xml = > @todo . to_xml ( :except = > :user_id ) }
format . m do
if @saved
if cookies [ :mobile_url ]
2009-06-02 22:03:17 +02:00
old_path = cookies [ :mobile_url ]
2009-01-23 13:13:28 -05:00
cookies [ :mobile_url ] = { :value = > nil , :secure = > SITE_CONFIG [ 'secure_cookies' ] }
2009-06-02 22:03:17 +02:00
redirect_to old_path
2009-01-08 10:18:03 +01:00
else
2009-12-07 23:16:21 -05:00
redirect_to todos_path ( :format = > 'm' )
2009-01-08 10:18:03 +01:00
end
else
render :action = > " edit " , :format = > :m
end
end
end
end
def destroy
2010-12-20 18:20:37 +01:00
@source_view = params [ '_source_view' ] || 'todo'
2009-01-08 10:18:03 +01:00
@todo = get_todo_from_params
@original_item_due = @todo . due
@context_id = @todo . context_id
@project_id = @todo . project_id
2009-06-09 13:45:39 +02:00
# activate successors if they only depend on this todo
activated_successor_count = 0
2009-12-01 23:39:07 -05:00
@pending_to_activate = [ ]
2009-06-09 13:45:39 +02:00
@todo . pending_successors . each do | successor |
successor . uncompleted_predecessors . delete ( @todo )
if successor . uncompleted_predecessors . empty?
successor . activate!
2009-12-01 23:39:07 -05:00
@pending_to_activate << successor
2009-06-09 13:45:39 +02:00
activated_successor_count += 1
end
end
2009-01-08 10:18:03 +01:00
@saved = @todo . destroy
# check if this todo has a related recurring_todo. If so, create next todo
@new_recurring_todo = check_for_next_todo ( @todo ) if @saved
2009-06-09 13:45:39 +02:00
2009-01-08 10:18:03 +01:00
respond_to do | format |
format . html do
if @saved
2011-01-16 18:14:07 +01:00
message = t ( 'todos.action_deleted_success' )
2009-06-09 13:45:39 +02:00
if activated_successor_count > 0
message += " activated #{ pluralize ( activated_successor_count , 'pending action' ) } "
end
notify :notice , message , 2 . 0
2009-01-08 10:18:03 +01:00
redirect_to :action = > 'index'
else
2011-01-16 18:14:07 +01:00
notify :error , t ( 'todos.action_deleted_error' ) , 2 . 0
2009-01-08 10:18:03 +01:00
redirect_to :action = > 'index'
end
2010-07-14 20:20:55 +02:00
end
2009-01-08 10:18:03 +01:00
format . js do
if @saved
determine_down_count
if source_view_is_one_of ( :todo , :deferred )
determine_remaining_in_context_count ( @context_id )
elsif source_view_is :calendar
2010-07-14 20:20:55 +02:00
@original_item_due_id = get_due_id_for_calendar ( @original_item_due )
2009-01-08 10:18:03 +01:00
@old_due_empty = is_old_due_empty ( @original_item_due_id )
end
end
render
end
format . xml { render :text = > '200 OK. Action deleted.' , :status = > 200 }
end
end
def completed
2011-01-16 18:14:07 +01:00
@page_title = t ( 'todos.completed_tasks_title' )
2009-01-08 10:18:03 +01:00
@done = current_user . completed_todos
@done_today = @done . completed_within Time . zone . now - 1 . day
@done_this_week = @done . completed_within Time . zone . now - 1 . week
@done_this_month = @done . completed_within Time . zone . now - 4 . week
@count = @done_today . size + @done_this_week . size + @done_this_month . size
end
def completed_archive
2011-01-16 18:14:07 +01:00
@page_title = t ( 'todos.archived_tasks_title' )
2009-01-08 10:18:03 +01:00
@done = current_user . completed_todos
@count = @done . size
@done_archive = @done . completed_more_than Time . zone . now - 28 . days
end
def list_deferred
@source_view = 'deferred'
2011-01-16 18:14:07 +01:00
@page_title = t ( 'todos.deferred_tasks_title' )
2009-01-08 10:18:03 +01:00
2010-08-06 16:33:02 +02:00
@contexts_to_show = @contexts = current_user . contexts . find ( :all )
2009-01-08 10:18:03 +01:00
2010-08-06 16:33:02 +02:00
@not_done_todos = current_user . deferred_todos ( :include = > [ :tags , :taggings , :projects ] ) + current_user . pending_todos ( :include = > [ :tags , :taggings , :projects ] )
@down_count = @count = @not_done_todos . size
2009-01-08 10:18:03 +01:00
respond_to do | format |
format . html
format . m { render :action = > 'mobile_list_deferred' }
end
end
# Check for any due tickler items, activate them Called by
# periodically_call_remote
def check_deferred
@due_tickles = current_user . deferred_todos . find_and_activate_ready
respond_to do | format |
format . html { redirect_to home_path }
format . js
end
end
def filter_to_context
context = current_user . contexts . find ( params [ 'context' ] [ 'id' ] )
2009-12-07 23:16:21 -05:00
redirect_to context_todos_path ( context , :format = > 'm' )
2009-01-08 10:18:03 +01:00
end
def filter_to_project
project = current_user . projects . find ( params [ 'project' ] [ 'id' ] )
2009-12-07 23:16:21 -05:00
redirect_to project_todos_path ( project , :format = > 'm' )
2009-01-08 10:18:03 +01:00
end
# /todos/tag/[tag_name] shows all the actions tagged with tag_name
def tag
2011-01-01 18:55:53 +01:00
init_data_for_sidebar unless mobile?
2009-01-08 10:18:03 +01:00
@source_view = params [ '_source_view' ] || 'tag'
@tag_name = params [ :name ]
2011-01-16 18:14:07 +01:00
@page_title = t ( 'todos.tagged_page_title' , :tag_name = > @tag_name )
2009-01-08 10:18:03 +01:00
# mobile tags are routed with :name ending on .m. So we need to chomp it
@tag_name = @tag_name . chomp ( '.m' ) if mobile?
@tag = Tag . find_by_name ( @tag_name )
@tag = Tag . new ( :name = > @tag_name ) if @tag . nil?
2011-01-01 18:55:53 +01:00
@not_done_todos = current_user . todos . with_tag ( @tag ) . active . find ( :all ,
:order = > 'todos.due IS NULL, todos.due ASC, todos.created_at ASC' , :include = > [ :context ] )
@hidden_todos = current_user . todos . with_tag ( @tag ) . hidden . find ( :all ,
2010-07-14 20:20:55 +02:00
:include = > [ :taggings , :tags , :context ] ,
2009-01-08 10:18:03 +01:00
:order = > 'todos.completed_at DESC, todos.created_at DESC' )
2011-01-01 18:55:53 +01:00
@deferred = current_user . todos . with_tag ( @tag ) . deferred . find ( :all ,
:order = > 'show_from ASC, todos.created_at DESC' , :include = > [ :context ] )
@pending = current_user . todos . with_tag ( @tag ) . blocked . find ( :all ,
:order = > 'show_from ASC, todos.created_at DESC' , :include = > [ :context ] )
2009-01-08 10:18:03 +01:00
# If you've set no_completed to zero, the completed items box isn't shown on
# the tag page
max_completed = current_user . prefs . show_number_completed
2011-01-01 18:55:53 +01:00
@done = current_user . todos . with_tag ( @tag ) . completed . find ( :all ,
2010-07-14 20:20:55 +02:00
:limit = > max_completed ,
2009-01-08 10:18:03 +01:00
:order = > 'todos.completed_at DESC' )
@projects = current_user . projects
@contexts = current_user . contexts
@contexts_to_show = @contexts . reject { | x | x . hide? }
2009-09-19 19:53:30 -04:00
# Set defaults for new_action
@initial_tag_name = @tag_name
unless @not_done_todos . empty?
@context = current_user . contexts . find_by_id ( @not_done_todos [ 0 ] . context_id )
end
2009-01-08 10:18:03 +01:00
# Set count badge to number of items with this tag
@not_done_todos . empty? ? @count = 0 : @count = @not_done_todos . size
2010-07-14 20:20:55 +02:00
@down_count = @count
2009-01-08 10:18:03 +01:00
respond_to do | format |
2009-10-02 15:48:24 -04:00
format . html
2010-07-14 20:20:55 +02:00
format . m {
2009-01-23 13:13:28 -05:00
cookies [ :mobile_url ] = { :value = > request . request_uri , :secure = > SITE_CONFIG [ 'secure_cookies' ] }
2010-07-14 20:20:55 +02:00
render :action = > " mobile_tag "
2009-01-08 10:18:03 +01:00
}
end
end
2010-04-02 13:23:24 -04:00
def tags
@tags = Tag . all
respond_to do | format |
2011-01-01 18:55:53 +01:00
format . autocomplete { render :text = > for_autocomplete ( @tags , params [ :term ] ) }
2010-04-02 13:23:24 -04:00
end
end
2009-01-08 10:18:03 +01:00
def defer
@source_view = params [ '_source_view' ] || 'todo'
numdays = params [ 'days' ] . to_i
@todo = Todo . find ( params [ :id ] )
2009-03-18 22:34:40 +01:00
@original_item_context_id = @todo . context_id
2009-01-08 10:18:03 +01:00
@todo . show_from = ( @todo . show_from || @todo . user . date ) + numdays . days
@saved = @todo . save
2009-04-07 17:14:51 +02:00
2009-01-08 10:18:03 +01:00
determine_down_count
determine_remaining_in_context_count ( @todo . context_id )
2009-04-07 19:57:19 +02:00
if @source_view == 'project'
2009-04-19 14:29:21 +02:00
@remaining_undone_in_project = current_user . projects . find ( @todo . project_id ) . not_done_todos . count
2009-04-07 19:57:19 +02:00
@original_item_project_id = @todo . project_id
end
2009-01-08 10:18:03 +01:00
respond_to do | format |
format . html { redirect_to :back }
format . js { render :action = > 'update' }
end
end
def calendar
@source_view = params [ '_source_view' ] || 'calendar'
2011-01-16 18:14:07 +01:00
@page_title = t ( 'todos.calendar_page_title' )
2009-03-24 22:25:50 +01:00
@projects = current_user . projects . find ( :all )
2009-01-08 10:18:03 +01:00
due_today_date = Time . zone . now
due_this_week_date = Time . zone . now . end_of_week
due_next_week_date = due_this_week_date + 7 . days
due_this_month_date = Time . zone . now . end_of_month
@due_today = current_user . todos . not_completed . find ( :all ,
2010-07-14 20:20:55 +02:00
:include = > [ :taggings , :tags ] ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due <= ?' , due_today_date ] ,
:order = > " due " )
@due_this_week = current_user . todos . not_completed . find ( :all ,
2010-07-14 20:20:55 +02:00
:include = > [ :taggings , :tags ] ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ? AND todos.due <= ?' , due_today_date , due_this_week_date ] ,
:order = > " due " )
@due_next_week = current_user . todos . not_completed . find ( :all ,
2010-07-14 20:20:55 +02:00
:include = > [ :taggings , :tags ] ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ? AND todos.due <= ?' , due_this_week_date , due_next_week_date ] ,
:order = > " due " )
@due_this_month = current_user . todos . not_completed . find ( :all ,
2010-07-14 20:20:55 +02:00
:include = > [ :taggings , :tags ] ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ? AND todos.due <= ?' , due_next_week_date , due_this_month_date ] ,
:order = > " due " )
@due_after_this_month = current_user . todos . not_completed . find ( :all ,
2010-07-14 20:20:55 +02:00
:include = > [ :taggings , :tags ] ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ?' , due_this_month_date ] ,
:order = > " due " )
@count = current_user . todos . not_completed . are_due . count
respond_to do | format |
format . html
format . ics {
@due_all = current_user . todos . not_completed . are_due . find ( :all , :order = > " due " )
render :action = > 'calendar' , :layout = > false , :content_type = > Mime :: ICS
}
end
2009-05-02 16:43:00 -04:00
end
2009-01-08 10:18:03 +01:00
2009-11-04 22:39:19 -05:00
def auto_complete_for_predecessor
2009-11-04 22:45:38 -05:00
unless params [ 'id' ] . nil?
get_todo_from_params
# Begin matching todos in current project
2010-07-14 20:20:55 +02:00
@items = current_user . todos . find ( :all ,
2009-08-19 22:15:38 +02:00
:select = > 'description, project_id, context_id, created_at' ,
2009-12-20 13:27:32 -05:00
:conditions = > [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND ' +
2010-07-14 20:20:55 +02:00
'NOT (id = ?) AND lower(description) LIKE ? AND project_id = ?' ,
'active' , 'pending' , 'deferred' ,
@todo . id ,
'%' + params [ :predecessor_list ] . downcase + '%' ,
@todo . project_id ] ,
2009-11-04 22:45:38 -05:00
:order = > 'description ASC' ,
:limit = > 10
)
if @items . empty? # Match todos in other projects
2010-07-14 20:20:55 +02:00
@items = current_user . todos . find ( :all ,
:select = > 'description, project_id, context_id, created_at' ,
2009-12-20 13:27:32 -05:00
:conditions = > [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND ' +
2010-07-14 20:20:55 +02:00
'NOT (id = ?) AND lower(description) LIKE ?' ,
'active' , 'pending' , 'deferred' ,
params [ :id ] , '%' + params [ :q ] . downcase + '%' ] ,
2009-11-04 22:45:38 -05:00
:order = > 'description ASC' ,
:limit = > 10
)
end
else
# New todo - TODO: Filter on project
2010-07-14 20:20:55 +02:00
@items = current_user . todos . find ( :all ,
2009-08-19 22:15:38 +02:00
:select = > 'description, project_id, context_id, created_at' ,
2010-07-14 20:20:55 +02:00
:conditions = > [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND lower(description) LIKE ?' ,
'active' , 'pending' , 'deferred' ,
'%' + params [ :q ] . downcase + '%' ] ,
2009-11-04 22:39:19 -05:00
:order = > 'description ASC' ,
:limit = > 10
)
end
2009-08-19 22:15:38 +02:00
render :inline = > " <%= auto_complete_result2(@items) %> "
2009-11-04 22:39:19 -05:00
end
2009-12-20 13:36:05 -05:00
def convert_to_project
2010-02-05 09:51:50 +01:00
@todo = current_user . todos . find ( params [ :id ] )
@project = current_user . projects . new ( :name = > @todo . description , :description = > @todo . notes ,
2010-07-14 20:20:55 +02:00
:default_context = > @todo . context )
2009-12-20 13:36:05 -05:00
@todo . destroy
@project . save!
redirect_to project_url ( @project )
end
2010-08-03 22:27:54 +02:00
def show_notes
@return_path = cookies [ :mobile_url ] ? cookies [ :mobile_url ] : mobile_path
respond_to do | format |
format . html {
redirect_to home_path , " Viewing note of todo is not implemented "
}
format . m {
render : action = > " mobile_show_notes "
}
end
end
2009-01-08 10:18:03 +01:00
private
def get_todo_from_params
@todo = current_user . todos . find ( params [ 'id' ] )
end
2010-04-27 10:18:07 -04:00
def find_and_activate_ready
current_user . deferred_todos . find_and_activate_ready
end
2009-01-08 10:18:03 +01:00
def init
@source_view = params [ '_source_view' ] || 'todo'
init_data_for_sidebar unless mobile?
2010-04-27 10:18:07 -04:00
init_todos
2009-01-08 10:18:03 +01:00
end
def with_feed_query_scope ( & block )
unless TodosController . is_feed_request ( request )
Todo . send ( :with_scope , :find = > { :conditions = > [ 'todos.state = ?' , 'active' ] } ) do
yield
return
end
end
condition_builder = FindConditionBuilder . new
if params . key? ( 'done' )
condition_builder . add 'todos.state = ?' , 'completed'
else
condition_builder . add 'todos.state = ?' , 'active'
end
2011-01-16 18:14:07 +01:00
@title = t ( 'todos.next_actions_title' )
@description = t ( 'todos.next_actions_description' )
2009-01-08 10:18:03 +01:00
if params . key? ( 'due' )
due_within = params [ 'due' ] . to_i
due_within_when = Time . zone . now + due_within . days
condition_builder . add ( 'todos.due <= ?' , due_within_when )
due_within_date_s = due_within_when . strftime ( " %Y-%m-%d " )
2011-01-16 18:14:07 +01:00
@title << t ( 'todos.next_actions_title_additions.due_today' ) if ( due_within == 0 )
@title << t ( 'todos.next_actions_title_additions.due_within_a_week' ) if ( due_within == 6 )
@description << t ( 'todos.next_actions_description_additions.due_date' , :due_date = > due_within_date_s )
2009-01-08 10:18:03 +01:00
end
if params . key? ( 'done' )
done_in_last = params [ 'done' ] . to_i
condition_builder . add ( 'todos.completed_at >= ?' , Time . zone . now - done_in_last . days )
2011-01-16 18:14:07 +01:00
@title << t ( 'todos.next_actions_title_additions.completed' )
@description << t ( 'todos.next_actions_description_additions.completed' , :count = > done_in_last . to_s )
2009-01-08 10:18:03 +01:00
end
if params . key? ( 'tag' )
tag = Tag . find_by_name ( params [ 'tag' ] )
if tag . nil?
tag = Tag . new ( :name = > params [ 'tag' ] )
end
condition_builder . add ( 'taggings.tag_id = ?' , tag . id )
end
Todo . send :with_scope , :find = > { :conditions = > condition_builder . to_conditions } do
yield
end
end
def with_parent_resource_scope ( & block )
2011-01-16 18:26:00 +01:00
@feed_title = t ( 'common.actions' )
2009-01-08 10:18:03 +01:00
if ( params [ :context_id ] )
@context = current_user . contexts . find_by_params ( params )
2011-01-16 18:14:07 +01:00
@feed_title = @feed_title + t ( 'todos.feed_title_in_context' , :context = > @context . name )
2009-01-08 10:18:03 +01:00
Todo . send :with_scope , :find = > { :conditions = > [ 'todos.context_id = ?' , @context . id ] } do
yield
end
elsif ( params [ :project_id ] )
@project = current_user . projects . find_by_params ( params )
2011-01-16 18:14:07 +01:00
@feed_title = @feed_title + t ( 'todos.feed_title_in_project' , :project = > @project . name )
2009-01-08 10:18:03 +01:00
@project_feed = true
Todo . send :with_scope , :find = > { :conditions = > [ 'todos.project_id = ?' , @project . id ] } do
yield
end
else
yield
2010-07-14 20:20:55 +02:00
end
2009-01-08 10:18:03 +01:00
end
def with_limit_scope ( & block )
if params . key? ( 'limit' )
Todo . send :with_scope , :find = > { :limit = > params [ 'limit' ] } do
yield
end
if TodosController . is_feed_request ( request ) && @description
if params . key? ( 'limit' )
2011-01-16 18:14:07 +01:00
@description << t ( 'todos.list_incomplete_next_actions_with_limit' , :count = > params [ 'limit' ] )
2009-01-08 10:18:03 +01:00
else
2011-01-16 18:14:07 +01:00
@description << t ( 'todos.list_incomplete_next_actions' )
2009-01-08 10:18:03 +01:00
end
end
else
yield
end
end
def init_todos
with_feed_query_scope do
with_parent_resource_scope do # @context or @project may get defined here
with_limit_scope do
if mobile?
2010-07-14 20:20:55 +02:00
init_todos_for_mobile_view
2009-01-08 10:18:03 +01:00
else
# Note: these next two finds were previously using
# current_users.todos.find but that broke with_scope for :limit
# Exclude hidden projects from count on home page
2010-12-17 16:01:22 +01:00
@todos = current_user . todos . find ( :all , :include = > [ :project , :context , :tags ] )
2009-01-08 10:18:03 +01:00
# Exclude hidden projects from the home page
2010-12-17 16:01:22 +01:00
@not_done_todos = current_user . todos . find ( :all ,
:conditions = > [ 'contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)' , false , 'active' ] ,
2010-07-14 20:20:55 +02:00
:order = > " todos.due IS NULL, todos.due ASC, todos.created_at ASC " ,
2009-01-08 10:18:03 +01:00
:include = > [ :project , :context , :tags ] )
end
end
end
end
end
def init_todos_for_mobile_view
# Note: these next two finds were previously using current_users.todos.find
# but that broke with_scope for :limit
# Exclude hidden projects from the home page
2010-12-17 16:01:22 +01:00
@not_done_todos = current_user . todos . find ( :all ,
:conditions = > [ 'todos.state = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)' , 'active' , false , 'active' ] ,
2010-07-14 20:20:55 +02:00
:order = > " todos.due IS NULL, todos.due ASC, todos.created_at ASC " ,
2009-01-08 10:18:03 +01:00
:include = > [ :project , :context , :tags ] )
end
def determine_down_count
source_view do | from |
from . todo do
2011-01-01 18:55:53 +01:00
@down_count = current_user . todos . not_hidden . count ( :all )
2009-01-08 10:18:03 +01:00
end
from . context do
2010-12-25 16:28:53 +01:00
@down_count = current_user . contexts . find ( @todo . context_id ) . todos . not_completed . count ( :all )
2009-01-08 10:18:03 +01:00
end
from . project do
unless @todo . project_id == nil
2009-04-18 23:50:12 +02:00
@down_count = current_user . projects . find ( @todo . project_id ) . not_done_todos_including_hidden . count
2009-01-08 10:18:03 +01:00
end
end
from . deferred do
2010-12-25 16:28:53 +01:00
@down_count = current_user . todos . deferred_or_blocked . count ( :all )
2009-01-08 10:18:03 +01:00
end
from . tag do
@tag_name = params [ '_tag_name' ]
@tag = Tag . find_by_name ( @tag_name )
if @tag . nil?
@tag = Tag . new ( :name = > @tag_name )
end
2011-01-01 18:55:53 +01:00
@not_done_todos = current_user . todos . with_tag ( @tag ) . active . find ( :all )
2009-01-08 10:18:03 +01:00
@not_done_todos . empty? ? @down_count = 0 : @down_count = @not_done_todos . size
end
end
2010-07-14 20:20:55 +02:00
end
2009-01-08 10:18:03 +01:00
def determine_remaining_in_context_count ( context_id = @todo . context_id )
source_view do | from |
2010-12-25 16:28:53 +01:00
from . deferred {
# force reload to todos to get correct count and not a cached one
2011-01-01 18:55:53 +01:00
@remaining_in_context = current_user . contexts . find ( context_id ) . todos ( true ) . deferred_or_blocked . count
@target_context_count = current_user . contexts . find ( @todo . context_id ) . todos ( true ) . deferred_or_blocked . count
2010-12-25 16:28:53 +01:00
}
2011-01-01 18:55:53 +01:00
from . tag {
2009-01-08 10:18:03 +01:00
tag = Tag . find_by_name ( params [ '_tag_name' ] )
if tag . nil?
tag = Tag . new ( :name = > params [ 'tag' ] )
end
2011-01-01 18:55:53 +01:00
@remaining_in_context = current_user . contexts . find ( context_id ) . todos . not_hidden . with_tag ( tag ) . count
@target_context_count = current_user . contexts . find ( @todo . context_id ) . todos . not_hidden . with_tag ( tag ) . count
if ! @todo . hidden? && @todo_hidden_state_changed
@remaining_hidden_count = current_user . todos . hidden . with_tag ( tag ) . count
end
2009-01-08 10:18:03 +01:00
}
2011-01-01 18:55:53 +01:00
from . project {
@remaining_deferred_or_pending_count = current_user . projects . find ( @todo . project_id ) . todos . deferred_or_blocked . count
@remaining_in_context = current_user . projects . find ( @todo . project_id ) . todos . active . count
@target_context_count = current_user . projects . find ( @todo . project_id ) . todos . active . count
}
from . calendar {
@target_context_count = count_old_due_empty ( @new_due_id )
}
end
@remaining_in_context = current_user . contexts . find ( context_id ) . not_done_todo_count if ! @remaining_in_context
@target_context_count = current_user . contexts . find ( @todo . context_id ) . not_done_todo_count if ! @target_context_count
puts " @remaining_in_context = #{ @remaining_in_context } "
puts " @target_context_count = #{ @target_context_count } "
puts " @remaining_hidden_count = #{ @remaining_hidden_count } "
puts " @remaining_deferred_or_pending_count = #{ @remaining_deferred_or_pending_count } "
2010-07-14 20:20:55 +02:00
end
2009-01-08 10:18:03 +01:00
def determine_completed_count
source_view do | from |
from . todo do
@completed_count = Todo . count_by_sql ( [ 'SELECT COUNT(*) FROM todos, contexts WHERE todos.context_id = contexts.id and todos.user_id = ? and todos.state = ? and contexts.hide = ?' , current_user . id , 'completed' , false ] )
end
from . context do
2009-04-20 11:26:45 +02:00
@completed_count = current_user . contexts . find ( @todo . context_id ) . done_todo_count
2009-01-08 10:18:03 +01:00
end
from . project do
unless @todo . project_id == nil
2009-04-19 00:18:12 +02:00
@completed_count = current_user . projects . find ( @todo . project_id ) . done_todos . count
2009-01-08 10:18:03 +01:00
end
end
end
end
2011-01-01 18:55:53 +01:00
def determine_deferred_tag_count ( tag_name )
tag = Tag . find_by_name ( tag_name )
# tag.nil? should normally not happen, but is a workaround for #929
@remaining_deferred_or_pending_count = tag . nil? ? 0 : current_user . todos . deferred . with_tag ( tag ) . count
2009-04-07 17:14:51 +02:00
end
2009-01-08 10:18:03 +01:00
def render_todos_html
lambda do
2011-01-16 18:14:07 +01:00
@page_title = t ( 'todos.task_list_title' )
2009-01-08 10:18:03 +01:00
# If you've set no_completed to zero, the completed items box isn't shown
# on the home page
max_completed = current_user . prefs . show_number_completed
@done = current_user . completed_todos . find ( :all , :limit = > max_completed , :include = > [ :context , :project , :tags ] ) unless max_completed == 0
# Set count badge to number of not-done, not hidden context items
@count = 0
@todos . each do | x |
if x . active?
if x . project . nil?
@count += 1 if ! x . context . hide?
else
@count += 1 if x . project . active? && ! x . context . hide?
end
end
end
render
end
end
def render_todos_mobile
lambda do
2011-01-16 18:14:07 +01:00
@page_title = t ( 'todos.mobile_todos_page_title' )
2009-01-08 10:18:03 +01:00
@home = true
2009-01-23 13:13:28 -05:00
cookies [ :mobile_url ] = { :value = > request . request_uri , :secure = > SITE_CONFIG [ 'secure_cookies' ] }
2009-01-08 10:18:03 +01:00
determine_down_count
render :action = > 'index'
end
end
def render_rss_feed
lambda do
render_rss_feed_for @todos , :feed = > todo_feed_options ,
:item = > {
:title = > :description ,
:link = > lambda { | t | @project_feed . nil? ? context_url ( t . context ) : project_url ( t . project ) } ,
:guid = > lambda { | t | todo_url ( t ) } ,
:description = > todo_feed_content
}
end
end
def todo_feed_options
options = Todo . feed_options ( current_user )
options [ :title ] = @feed_title
return options
end
def todo_feed_content
lambda do | i |
item_notes = sanitize ( markdown ( i . notes ) ) if i . notes?
2011-01-16 18:14:07 +01:00
due = " <div> #{ t ( 'todos.feeds.due' , :date = > format_date ( i . due ) ) } </div> \n " if i . due?
done = " <div> #{ t ( 'todos.feeds.completed' , :date = > format_date ( i . completed_at ) ) } </div> \n " if i . completed?
2009-01-08 10:18:03 +01:00
context_link = " <a href= \" #{ context_url ( i . context ) } \" > #{ i . context . name } </a> "
if i . project_id?
project_link = " <a href= \" #{ project_url ( i . project ) } \" > #{ i . project . name } </a> "
else
2011-01-16 18:14:07 +01:00
project_link = " <em> #{ t ( 'common.none' ) } </em> "
2009-01-08 10:18:03 +01:00
end
2011-01-16 18:14:07 +01:00
" #{ done || '' } #{ due || '' } #{ item_notes || '' } \n <div> #{ t ( 'common.project' ) } : #{ project_link } </div> \n <div> #{ t ( 'common.context' ) } : #{ context_link } </div> "
2009-01-08 10:18:03 +01:00
end
end
def render_atom_feed
lambda do
render_atom_feed_for @todos , :feed = > todo_feed_options ,
:item = > {
:title = > :description ,
:link = > lambda { | t | context_url ( t . context ) } ,
:description = > todo_feed_content ,
:author = > lambda { | p | nil }
}
end
end
def render_text_feed
lambda do
render :action = > 'index' , :layout = > false , :content_type = > Mime :: TEXT
end
end
def render_ical_feed
lambda do
render :action = > 'index' , :layout = > false , :content_type = > Mime :: ICS
end
end
def self . is_feed_request ( req )
[ 'rss' , 'atom' , 'txt' , 'ics' ] . include? ( req . parameters [ :format ] )
end
def check_for_next_todo ( todo )
# check if this todo has a related recurring_todo. If so, create next todo
new_recurring_todo = nil
recurring_todo = nil
if todo . from_recurring_todo?
recurring_todo = todo . recurring_todo
# check if there are active todos belonging to this recurring todo. only
# add new one if all active todos are completed
if recurring_todo . todos . active . count == 0
# check for next todo either from the due date or the show_from date
date_to_check = todo . due . nil? ? todo . show_from : todo . due
# if both due and show_from are nil, check for a next todo from now
date_to_check = Time . zone . now if date_to_check . nil?
if recurring_todo . active? && recurring_todo . has_next_todo ( date_to_check )
# shift the reference date to yesterday if date_to_check is furher in
# the past. This is to make sure we do not get older todos for overdue
# todos. I.e. checking a daily todo that is overdue with 5 days will
# create a new todo which is overdue by 4 days if we don't shift the
# date. Discard the time part in the compare. We pick yesterday so
# that new todos due for today will be created instead of new todos
# for tomorrow.
date = date_to_check . at_midnight > = Time . zone . now . at_midnight ? date_to_check : Time . zone . now - 1 . day
2009-02-16 20:48:27 +01:00
new_recurring_todo = create_todo_from_recurring_todo ( recurring_todo , date . at_midnight )
2009-01-08 10:18:03 +01:00
end
end
end
2010-07-14 20:20:55 +02:00
return new_recurring_todo
2009-01-08 10:18:03 +01:00
end
def get_due_id_for_calendar ( due )
return " " if due . nil?
due_today_date = Time . zone . now
due_this_week_date = Time . zone . now . end_of_week
due_next_week_date = due_this_week_date + 7 . days
due_this_month_date = Time . zone . now . end_of_month
if due < = due_today_date
new_due_id = " due_today "
elsif due < = due_this_week_date
new_due_id = " due_this_week "
elsif due < = due_next_week_date
new_due_id = " due_next_week "
elsif due < = due_this_month_date
new_due_id = " due_this_month "
else
new_due_id = " due_after_this_month "
end
return new_due_id
end
def is_old_due_empty ( id )
2011-01-01 18:55:53 +01:00
return 0 == count_old_due_empty ( id )
end
def count_old_due_empty ( id )
2009-01-08 10:18:03 +01:00
due_today_date = Time . zone . now
due_this_week_date = Time . zone . now . end_of_week
due_next_week_date = due_this_week_date + 7 . days
due_this_month_date = Time . zone . now . end_of_month
case id
when " due_today "
2011-01-01 18:55:53 +01:00
return current_user . todos . not_completed . count ( :all ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due <= ?' , due_today_date ] )
when " due_this_week "
2011-01-01 18:55:53 +01:00
return current_user . todos . not_completed . count ( :all ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ? AND todos.due <= ?' , due_today_date , due_this_week_date ] )
when " due_next_week "
2011-01-01 18:55:53 +01:00
return current_user . todos . not_completed . count ( :all ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ? AND todos.due <= ?' , due_this_week_date , due_next_week_date ] )
when " due_this_month "
2011-01-01 18:55:53 +01:00
return current_user . todos . not_completed . count ( :all ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ? AND todos.due <= ?' , due_next_week_date , due_this_month_date ] )
2010-07-14 20:20:55 +02:00
when " due_after_this_month "
2011-01-01 18:55:53 +01:00
return current_user . todos . not_completed . count ( :all ,
2009-01-08 10:18:03 +01:00
:conditions = > [ 'todos.due > ?' , due_this_month_date ] )
else
2010-07-14 20:20:55 +02:00
raise Exception . new , " unknown due id for calendar: ' #{ id } ' "
2009-01-08 10:18:03 +01:00
end
end
class FindConditionBuilder
def initialize
@queries = Array . new
@params = Array . new
end
def add ( query , param )
@queries << query
@params << param
end
def to_conditions
[ @queries . join ( ' AND ' ) ] + @params
end
end
class TodoCreateParamsHelper
def initialize ( params , prefs )
@params = params [ 'request' ] || params
@prefs = prefs
@attributes = params [ 'request' ] && params [ 'request' ] [ 'todo' ] || params [ 'todo' ]
end
def attributes
@attributes
end
def show_from
@attributes [ 'show_from' ]
end
def due
@attributes [ 'due' ]
end
def project_name
@params [ 'project_name' ] . strip unless @params [ 'project_name' ] . nil?
end
def context_name
@params [ 'context_name' ] . strip unless @params [ 'context_name' ] . nil?
end
def tag_list
@params [ 'tag_list' ]
end
2009-11-04 22:45:38 -05:00
def predecessor_list
@params [ 'predecessor_list' ]
end
2009-01-08 10:18:03 +01:00
def parse_dates ( )
@attributes [ 'show_from' ] = @prefs . parse_date ( show_from )
@attributes [ 'due' ] = @prefs . parse_date ( due )
@attributes [ 'due' ] || = ''
end
def project_specified_by_name?
return false unless @attributes [ 'project_id' ] . blank?
return false if project_name . blank?
return false if project_name == 'None'
true
end
def context_specified_by_name?
return false unless @attributes [ 'context_id' ] . blank?
return false if context_name . blank?
true
end
end
2010-07-14 20:20:55 +02:00
private
2010-12-25 16:28:53 +01:00
def cache_attributes_from_before_update
@original_item_context_id = @todo . context_id
@original_item_project_id = @todo . project_id
@original_item_was_deferred = @todo . deferred?
2011-01-01 18:55:53 +01:00
@original_item_was_hidden = @todo . hidden?
2010-12-25 16:28:53 +01:00
@original_item_due = @todo . due
@original_item_due_id = get_due_id_for_calendar ( @todo . due )
@original_item_predecessor_list = @todo . predecessors . map { | t | t . specification } . join ( ', ' )
2011-01-01 18:55:53 +01:00
puts " wh = #{ @original_item_was_hidden } "
2010-12-25 16:28:53 +01:00
end
def update_project
2011-01-01 18:55:53 +01:00
if params [ 'todo' ] [ 'project_id' ] . blank? && ! params [ 'project_name' ] . nil?
if params [ 'project_name' ] == 'None'
project = Project . null_object
else
project = current_user . projects . find_by_name ( params [ 'project_name' ] . strip )
unless project
project = current_user . projects . build
project . name = params [ 'project_name' ] . strip
project . save
@new_project_created = true
end
2010-12-25 16:28:53 +01:00
end
2011-01-01 18:55:53 +01:00
params [ " todo " ] [ " project_id " ] = project . id
2010-12-25 16:28:53 +01:00
end
2011-01-01 18:55:53 +01:00
@project_changed = @original_item_project_id != params [ " todo " ] [ " project_id " ] = project . id
2010-12-25 16:28:53 +01:00
end
def update_todo_state_if_project_changed
2011-01-01 18:55:53 +01:00
if ( @project_changed ) then
2010-12-25 16:28:53 +01:00
@todo . update_state_from_project
2011-01-01 18:55:53 +01:00
@remaining_undone_in_project = current_user . projects . find ( @original_item_project_id ) . todos . active . count if source_view_is :project
2010-12-25 16:28:53 +01:00
end
end
def update_context
2011-01-01 18:55:53 +01:00
if params [ 'todo' ] [ 'context_id' ] . blank? && ! params [ 'context_name' ] . blank?
context = current_user . contexts . find_by_name ( params [ 'context_name' ] . strip )
unless context
@new_context = current_user . contexts . build
@new_context . name = params [ 'context_name' ] . strip
@new_context . save
@new_context_created = true
@not_done_todos = [ @todo ]
context = @new_context
end
params [ " todo " ] [ " context_id " ] = context . id
2010-12-25 16:28:53 +01:00
end
2011-01-01 18:55:53 +01:00
@context_changed = @original_item_context_id != params [ " todo " ] [ " context_id " ] = context . id
puts " context changed into ' #{ context . name } ' "
2010-12-25 16:28:53 +01:00
end
def update_tags
if params [ :tag_list ]
@todo . tag_with ( params [ :tag_list ] )
@todo . tags ( true ) #force a reload for proper rendering
end
end
def update_due_and_show_from_dates
if params [ " todo " ] . has_key? ( " due " )
params [ " todo " ] [ " due " ] = parse_date_per_user_prefs ( params [ " todo " ] [ " due " ] )
else
params [ " todo " ] [ " due " ] = " "
end
if params [ 'todo' ] [ 'show_from' ]
params [ 'todo' ] [ 'show_from' ] = parse_date_per_user_prefs ( params [ 'todo' ] [ 'show_from' ] )
end
end
def update_completed_state
if params [ 'done' ] == '1' && ! @todo . completed?
@todo . complete!
@todo . pending_to_activate . each do | t |
t . activate!
end
end
# strange. if checkbox is not checked, there is no 'done' in params.
# Therefore I've used the negation
if ! ( params [ 'done' ] == '1' ) && @todo . completed?
@todo . activate!
@todo . active_to_block . each do | t |
t . block!
end
end
end
2011-01-01 18:55:53 +01:00
def update_dependencies
@todo . add_predecessor_list ( params [ :predecessor_list ] )
2010-12-25 16:28:53 +01:00
if @original_item_predecessor_list != params [ :predecessor_list ]
# Possible state change with new dependencies
2011-01-01 18:55:53 +01:00
if @todo . uncompleted_predecessors . empty?
@todo . activate! if @todo . state == 'pending' # Activate pending if no uncompleted predecessors
2010-12-25 16:28:53 +01:00
else
2011-01-01 18:55:53 +01:00
@todo . block! if @todo . state == 'active' # Block active if we got uncompleted predecessors
2010-12-25 16:28:53 +01:00
end
end
2011-01-01 18:55:53 +01:00
end
def update_attributes_of_todo
@todo . attributes = params [ " todo " ]
2010-12-25 16:28:53 +01:00
end
def determine_changes_by_this_update
@todo_was_activated_from_deferred_state = @original_item_was_deferred && @todo . active?
2011-01-01 18:55:53 +01:00
@todo_was_deferred_from_active_state = @todo . deferred? && ! @original_item_was_deferred
@todo_deferred_state_changed = @todo_was_deferred_from_active_state || @todo_was_activated_from_deferred_state
@due_date_changed = @original_item_due != @todo . due
@todo_hidden_state_changed = @original_item_was_hidden != @todo . hidden?
puts " @context_changed = #{ @context_changed } "
puts " @project_changed = #{ @project_changed } "
puts " @todo_was_activated_from_deferred_state #{ @todo_was_activated_from_deferred_state } "
puts " @todo_was_deferred_from_active_state = #{ @todo_was_deferred_from_active_state } "
puts " @due_date_changed = #{ @due_date_changed } "
puts " @todo_hidden_state_changed = #{ @todo_hidden_state_changed } @todo.hidden?= #{ @todo . hidden? } "
source_view do | page |
page . calendar do
@old_due_empty = is_old_due_empty ( @original_item_due_id )
@new_due_id = get_due_id_for_calendar ( @todo . due ) if @due_date_changed
end
page . tag do
@tag_name = params [ '_tag_name' ]
@tag_was_removed = ! @todo . has_tag? ( @tag_name )
puts " @tag_was_removed = #{ @tag_was_removed } "
end
2010-12-25 16:28:53 +01:00
end
end
2010-07-14 20:20:55 +02:00
def project_specified_by_name ( project_name )
return false unless params [ 'project_id' ] . blank?
return false if project_name . blank?
return false if project_name == 'None'
true
end
def context_specified_by_name ( context_name )
return false unless params [ 'context_id' ] . blank?
return false if context_name . blank?
true
end
2009-01-08 10:18:03 +01:00
end