class TasksController < ApplicationController skip_before_filter :populate_layout, :except => [:edit, :grab, :list_started, :move_down, :move_to_bottom, :move_to_top, :move_up, :new, :specify] verify :method => :post, :except => [ :invite, :new, :show, :edit, :grab, :list_started, :move_to_next_period, :notes], :redirect_to => { :controller => 'backlogs' } def list_started @tasks = Task.find_started @selected_task = Task.find_by_id(params[:id]) back_or_redirect_to('/') if @tasks.empty? end def new redirect_to params if request.post? params[:task].delete :file if params[:task] @task = Task.new params[:task] @task.backlog_id ||= @task.period && @task.period.most_frequent_backlog @backlogs = Backlog.find(:all, :order => 'name') @periods = Period.find_active_or_future @customers = Customer.find(:all) end def create if params[:task] && params[:task][:period_id] && params[:task][:period_id][0..0] == 'G' detour_to :controller => 'periods', :action => :new, :group_id => params[:task][:period_id][1..-1].to_i return end file = params[:task].delete(:file) @task = Task.new(params[:task]) if @task.save flash[:notice] = 'Task was successfully created.' if file && file.respond_to?(:read) && file.respond_to?(:content_type) && file.respond_to?(:original_filename) @task.task_files.create! :name => file.original_filename, :content_data => file.read, :content_type => file.content_type end @task.move_to_top @task.grab if @task.period back_or_redirect_to :controller => 'periods', :action => 'show', :id => @task.period, :task => @task.id else back_or_redirect_to :controller => 'backlogs', :action => :edit, :id => @task.backlog, :task => @task.id end else populate_layout @backlogs = Backlog.find(:all, :order => 'name') @periods = Period.find_active_or_future @customers = Customer.find(:all) render :action => 'new' end end def edit @task ||= Task.find(params[:id]) @task.backlog_id = params[:task][:backlog_id] if params[:task] && params[:task][:backlog_id] @task.period_id = params[:task][:period_id] if params[:task] && params[:task][:period_id] @periods = Period.find_active_or_future @backlogs = Backlog.find(:all, :order => 'name') @customers = Customer.find(:all) end def update redirect_to(:controller => 'backlogs', :action => :index) unless params[:id] if params[:task] && params[:task][:description] == '' destroy return end @task = Task.find(params[:id]) unless @task.period.nil? || @task.period.active_or_future? || (params[:task] && params[:task][:period_id] && params[:task][:period_id].to_i > 0 && (period = Period.find_by_id(params[:task][:period_id])) && period.active?) @task.errors.add(:period_id, "You may not update a task in an inactive period. Move the task to an active period first.") back_or_redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task => @task.id return end # TODO (uwe): This should be moved to the Task model: Task#period= if params[:task] && params[:task][:period_id] if params[:task][:period_id] != '' if params[:task][:period_id].to_i != @task.period_id @task.remove_from_list params[:task][:position] = Period.find(params[:task][:period_id]).tasks.size end else if @task.period_id != nil @task.remove_from_list @task.period = nil new_pos = @task.backlog.tasks.count(:conditions => 'period_id IS NULL AND parent_id IS NULL') + 1 params[:task].delete(:period_id) params[:task][:position] = new_pos end end end file = params[:task] && params[:task].delete(:file) if params[:task] && @task.update_attributes(params[:task]) flash[:notice] = 'Task was successfully updated.' if params[:estimate] @task.estimates.create! params[:estimate] end if file && file.respond_to?(:read) && file.respond_to?(:content_type) && file.respond_to?(:original_filename) @task.task_files.create! :name => file.original_filename, :content_data => file.read, :content_type => file.content_type end if params[:estimate] && params[:estimate][:todo] && params[:estimate][:todo].to_i == 0 unless @task.finished_at next_task = @task.lower_item || @task.higher_item @task.finish Task::COMPLETED, true @task.save! back_or_redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task => next_task ? next_task.id : nil else back_or_redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task => @task.id end else if @task.finished_at @task.reopen flash[:notice] += 'Task was reopened.' populate_layout render :action => 'edit' else if @task.period back_or_redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task => @task.id else back_or_redirect_to :controller => 'backlogs', :action => :show, :id => @task.backlog, :task => @task.id end end end else flash[:notice] = 'Task was not saved.' populate_layout edit render :action => 'edit' end end def update_task_estimate update end def destroy task = Task.find(params[:id]) lower_item = task.lower_item task.destroy flash[:notice] = 'Task was successfully deleted.' redirect_to :controller => 'periods', :action => :show, :id => task.period, :task => lower_item ? lower_item.id : nil end def move_up task = Task.find(params[:id]) task.move_higher flash[:notice] = "Task #{@focus_id} was successfully moved." redirect_to :controller => 'periods', :action => :show, :id => task.period, :task => task.id end def move_down task = Task.find(params[:id]) task.move_lower redirect_to :controller => 'periods', :action => :show, :id => task.period, :task => task.id end def move_to_top task = Task.find(params[:id]) task.move_to_top redirect_to :action => :list, :id => task end def move_to_bottom task = Task.find(params[:id]) task.move_to_bottom redirect_to :action => :list, :id => task end # Move the indicated task to the indicated position. def move_to params[:id] = $1 if params[:id] =~ /^task_(\d*)/ if params[:id] && task = Task.find(params[:id]) if params[:target_id] if target_task = Task.find_by_id(params[:target_id]) if task.parent_id != target_task.parent_id task.remove_from_list task.position = nil task.parent_id = target_task.parent_id task.backlog_id = target_task.backlog_id task.period_id = target_task.period_id end task.insert_at target_task.position end elsif params[:period_id] && params[:period_id].to_i != task.period_id task.remove_from_list task.period_id = params[:period_id] task.insert_at 1 task.save! else flash[:notice] = "Target position is missing for move." end else flash[:notice] = "Task not found" end redirect_to :controller => 'periods', :action => :show_no_layout, :id => task.period_id, :task => task.id end def grab @task = Task.find(params[:id]) @task.grab detour = pop_detour params.update(detour) if detour render :template => '/tasks/_update.rjs' if request.xhr? end def invite @task = Task.find(params[:id]) @invitee = User.find(params[:user_id]) task_url = url_for(:action => 'edit', :id => @task.id) grab_url = url_for(:action => 'grab', :id => @task.id) TaskNotify.deliver_invite(current_user, @invitee, @task, task_url, grab_url) detour = pop_detour params.update(detour) if detour render :template => '/tasks/_invite.rjs' if request.xhr? end def release @task = Task.find(params[:id]) @task.release detour = pop_detour params.update(detour) if detour render :template => '/tasks/_update.rjs' end def start_work @task = Task.find(params[:id]) @task.start_work detour = pop_detour params.update(detour) if detour end def end_work @task = Task.find(params[:id]) next_quarter = Time.next_quarter if started_work = @task.started_work redirect_to({ :controller => 'works', :action => :edit, :id => started_work, 'work[task_id]' => @task.id, 'work[started_on]' => started_work.started_on.to_s, 'work[start_time]' => started_work.start_time.to_s, 'work[completed_at]' => [next_quarter, started_work.started_on.at(started_work.start_time || TimeOfDay.new(0, 0))].max.iso8601, 'work[hours]' => "%0.2f" % ((next_quarter - started_work.started_on.at(started_work.start_time || TimeOfDay.new(0, 0))).to_f / 3600), 'estimate[todo]' => @task.todo }) else @task.update_attributes(params[:task]) redirect_to({ :controller => 'works', :action => :new, 'work[task_id]' => @task.id, 'work[started_on]' => Time.previous_quarter.to_date.to_s, 'work[start_time]' => Time.previous_quarter.time_of_day.to_s, 'work[completed_at]' => next_quarter.iso8601, 'work[hours]' => "0.25", 'estimate[todo]' => @task.todo }) end end def specify parent_task = Task.find(params[:id]) raise "Task is not open" unless parent_task.active? && (parent_task.period.nil? || parent_task.period.active_or_future?) if parent_task.children.empty? subtask_estimate = (parent_task.todo).ceil no_of_subtasks = (parent_task.todo / subtask_estimate).to_i subtask_estimate = parent_task.todo / no_of_subtasks (1..no_of_subtasks).each do |index| subtask = parent_task.children.build subtask.description = "#{parent_task.description} ##{parent_task.children.size}" subtask.initial_estimate = subtask_estimate subtask.save! end redirect_to :controller => 'periods', :action => :show, :id => parent_task.period, :task => parent_task.children.first else average_estimate = parent_task.children.reduce {|value, task, size| value + (task.initial_estimate / size)} subtask = parent_task.children.build subtask.description = "#{parent_task.description} ##{parent_task.children.size}" subtask.initial_estimate = average_estimate subtask.save! redirect_to :controller => 'periods', :action => :show, :id => parent_task.period, :task => parent_task.children.first end if started_work = parent_task.started_work flash[:notice] = "Pågående arbeid er flyttet til subtask" started_work.task = parent_task.children.last started_work.save! end end def set_task_description task = Task.find(params[:id]) task.description = params[:value] task.save! render :text => task.description end def notes @task = Task.find(params[:id]) render :layout => 'wide' end end