diff --git a/app/controllers/my_profile/tasks_controller.rb b/app/controllers/my_profile/tasks_controller.rb index db9c061..9cebc23 100644 --- a/app/controllers/my_profile/tasks_controller.rb +++ b/app/controllers/my_profile/tasks_controller.rb @@ -5,15 +5,35 @@ class TasksController < MyProfileController def index @filter_type = params[:filter_type].presence @filter_text = params[:filter_text].presence + @filter_responsible = params[:filter_responsible] @task_types = Task.pending_types_for(profile) - @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) + + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc') + @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present? + @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page]) + @failed = params ? params[:failed] : {} + + @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) end def processed @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at) end + def change_responsible + task = profile.tasks.find(params[:task_id]) + + if task.responsible.present? && task.responsible.id != params[:old_responsible_id].to_i + return render :json => {:notice => _('Task already assigned!'), :success => false, :current_responsible => task.responsible.id} + end + + responsible = profile.members.find(params[:responsible_id]) if params[:responsible_id].present? + task.responsible = responsible + task.save! + render :json => {:notice => _('Task responsible successfully updated!'), :success => true, :new_responsible => {:id => responsible.present? ? responsible.id : nil}} + end + VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] def close diff --git a/app/models/task.rb b/app/models/task.rb index c2c8955..1400e3e 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -33,6 +33,7 @@ class Task < ActiveRecord::Base belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id belongs_to :target, :foreign_key => :target_id, :polymorphic => true + belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id validates_uniqueness_of :code, :on => :create validates_presence_of :code diff --git a/app/views/tasks/_task.html.erb b/app/views/tasks/_task.html.erb index aad9f76..a4a7ea1 100644 --- a/app/views/tasks/_task.html.erb +++ b/app/views/tasks/_task.html.erb @@ -2,6 +2,16 @@ <%= render :partial => 'task_icon', :locals => {:task => task} %> + <% if profile.organization? && @responsible_candidates.present? %> +
+ <%= _('Assign to:') %> + + <% change_responsible_url = url_for :action => :change_responsible, :controller => :tasks %> + <%= select_tag "tasks[#{task.id}][responsible]", options_from_collection_for_select(@responsible_candidates, :id, :name, task.responsible.present? ? task.responsible.id : nil), :include_blank => true, :onchange => "change_task_responsible(this);", 'data-old-responsible' => task.responsible.present? ? task.responsible.id : nil, 'data-task' => task.id, 'data-url' => change_responsible_url %> + +
+ <% end %> +
<%= labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept', diff --git a/app/views/tasks/index.html.erb b/app/views/tasks/index.html.erb index e43d328..301e931 100644 --- a/app/views/tasks/index.html.erb +++ b/app/views/tasks/index.html.erb @@ -30,6 +30,9 @@ <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %>

+ <%= labelled_select(_('Assigned to')+': ', :filter_responsible, :id, :name, @filter_responsible, [OpenStruct.new(:name => _('All'), :id => nil), OpenStruct.new(:name => _('Unassigned'), :id => -1)] + @responsible_candidates) %> +

+

<%= submit_button(:search, _('Search')) %>

<% end %> diff --git a/db/migrate/20150525101430_add_responsible_to_task.rb b/db/migrate/20150525101430_add_responsible_to_task.rb new file mode 100644 index 0000000..bc8ca06 --- /dev/null +++ b/db/migrate/20150525101430_add_responsible_to_task.rb @@ -0,0 +1,7 @@ +class AddResponsibleToTask < ActiveRecord::Migration + + def change + add_column :tasks, :responsible_id, :integer + end + +end diff --git a/public/javascripts/tasks.js b/public/javascripts/tasks.js index 52f450b..3a2947c 100644 --- a/public/javascripts/tasks.js +++ b/public/javascripts/tasks.js @@ -47,3 +47,19 @@ })(jQuery) +function change_task_responsible(el) { + jQuery.post($(el).data('url'), {task_id: $(el).data('task'), + responsible_id: $(el).val(), + old_responsible_id: $(el).data('old-responsible')}, function(data) { + if (data.success) { + $(el).effect("highlight"); + $(el).data('old-responsible', data.new_responsible.id); + } else { + $(el).effect("highlight", {color: 'red'}); + } + if (data.notice) { + display_notice(data.notice); + } + }); +} + diff --git a/public/stylesheets/tasks.css b/public/stylesheets/tasks.css index 39193a9..714947d 100644 --- a/public/stylesheets/tasks.css +++ b/public/stylesheets/tasks.css @@ -49,3 +49,7 @@ text-decoration: underline; font-weight: bold; } + +.task_responsible { + text-align: right; +} diff --git a/test/functional/tasks_controller_test.rb b/test/functional/tasks_controller_test.rb index 74cb51a..dc06032 100644 --- a/test/functional/tasks_controller_test.rb +++ b/test/functional/tasks_controller_test.rb @@ -433,4 +433,82 @@ class TasksControllerTest < ActionController::TestCase post :index, :page => 2 assert_equal [t4], assigns(:tasks) end + + should 'filter tasks by responsible' do + Task.stubs(:per_page).returns(3) + requestor = fast_create(Person) + responsible = fast_create(Person) + t1 = Task.create!(:requestor => requestor, :target => profile, :responsible => responsible) + t2 = Task.create!(:requestor => requestor, :target => profile, :responsible => responsible) + t3 = Task.create!(:requestor => requestor, :target => profile) + + get :index, :filter_responsible => responsible.id + + assert_includes assigns(:tasks), t1 + assert_includes assigns(:tasks), t2 + assert_not_includes assigns(:tasks), t3 + + get :index + + assert_includes assigns(:tasks), t1 + assert_includes assigns(:tasks), t2 + assert_includes assigns(:tasks), t3 + end + + should 'do not display responsible assignment if profile is not an organization' do + profile = create_user('personprofile').person + t1 = Task.create!(:requestor => profile, :target => profile) + @controller.stubs(:profile).returns(profile) + login_as profile.user.login + get :index + + assert_select "#task-#{t1.id}" + assert_select '.task_responsible', 0 + end + + should 'display responsible assignment if profile is an organization' do + profile = fast_create(Community) + person1 = create_user('person1').person + person2 = create_user('person2').person + person3 = create_user('person3').person + profile.add_admin(person1) + profile.add_admin(person2) + profile.add_member(person3) + Task.create!(:requestor => person3, :target => profile) + @controller.stubs(:profile).returns(profile) + + login_as person1.user.login + get :index + assert_equivalent [person1, person2], assigns(:responsible_candidates) + assert_select '.task_responsible' + end + + should 'change task responsible' do + profile = fast_create(Community) + @controller.stubs(:profile).returns(profile) + person = create_user('person1').person + profile.add_admin(person) + task = Task.create!(:requestor => person, :target => profile) + + assert_equal nil, task.responsible + login_as person.user.login + post :change_responsible, :task_id => task.id, :responsible_id => person.id + assert_equal person, task.reload.responsible + end + + should 'not change task responsible if old responsible is not the current' do + profile = fast_create(Community) + @controller.stubs(:profile).returns(profile) + person1 = create_user('person1').person + person2 = create_user('person2').person + profile.add_admin(person1) + task = Task.create!(:requestor => person1, :target => profile, :responsible => person1) + + login_as person1.user.login + post :change_responsible, :task_id => task.id, :responsible_id => person2.id, :old_responsible => nil + assert_equal person1, task.reload.responsible + json_response = ActiveSupport::JSON.decode(response.body) + assert !json_response['success'] + end + end diff --git a/test/unit/task_test.rb b/test/unit/task_test.rb index 18b2bf9..16448ff 100644 --- a/test/unit/task_test.rb +++ b/test/unit/task_test.rb @@ -432,6 +432,14 @@ class TaskTest < ActiveSupport::TestCase assert t1.ham? end + should 'be able to assign a responsible to a task' do + person = fast_create(Person) + task = fast_create(Task) + task.responsible = person + task.save! + assert_equal person, task.responsible + end + protected def sample_user -- libgit2 0.21.2