Commit f4d896de1084cbcddd7dbe3a18241a40028db77e
Exists in
staging
and in
4 other branches
Merge branch 'task_responsible' into production
Showing
9 changed files
with
147 additions
and
1 deletions
Show diff stats
app/controllers/my_profile/tasks_controller.rb
| ... | ... | @@ -5,15 +5,35 @@ class TasksController < MyProfileController |
| 5 | 5 | def index |
| 6 | 6 | @filter_type = params[:filter_type].presence |
| 7 | 7 | @filter_text = params[:filter_text].presence |
| 8 | + @filter_responsible = params[:filter_responsible] | |
| 8 | 9 | @task_types = Task.pending_types_for(profile) |
| 9 | - @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | |
| 10 | + | |
| 11 | + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc') | |
| 12 | + @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present? | |
| 13 | + @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page]) | |
| 14 | + | |
| 10 | 15 | @failed = params ? params[:failed] : {} |
| 16 | + | |
| 17 | + @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) | |
| 11 | 18 | end |
| 12 | 19 | |
| 13 | 20 | def processed |
| 14 | 21 | @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at) |
| 15 | 22 | end |
| 16 | 23 | |
| 24 | + def change_responsible | |
| 25 | + task = profile.tasks.find(params[:task_id]) | |
| 26 | + | |
| 27 | + if task.responsible.present? && task.responsible.id != params[:old_responsible_id].to_i | |
| 28 | + return render :json => {:notice => _('Task already assigned!'), :success => false, :current_responsible => task.responsible.id} | |
| 29 | + end | |
| 30 | + | |
| 31 | + responsible = profile.members.find(params[:responsible_id]) if params[:responsible_id].present? | |
| 32 | + task.responsible = responsible | |
| 33 | + task.save! | |
| 34 | + render :json => {:notice => _('Task responsible successfully updated!'), :success => true} | |
| 35 | + end | |
| 36 | + | |
| 17 | 37 | VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] |
| 18 | 38 | |
| 19 | 39 | def close | ... | ... |
app/models/task.rb
| ... | ... | @@ -33,6 +33,7 @@ class Task < ActiveRecord::Base |
| 33 | 33 | |
| 34 | 34 | belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id |
| 35 | 35 | belongs_to :target, :foreign_key => :target_id, :polymorphic => true |
| 36 | + belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id | |
| 36 | 37 | |
| 37 | 38 | validates_uniqueness_of :code, :on => :create |
| 38 | 39 | validates_presence_of :code | ... | ... |
app/views/tasks/_task.html.erb
| ... | ... | @@ -2,6 +2,16 @@ |
| 2 | 2 | |
| 3 | 3 | <%= render :partial => 'task_icon', :locals => {:task => task} %> |
| 4 | 4 | |
| 5 | + <% if profile.organization? && @responsible_candidates.present? %> | |
| 6 | + <div class="task_responsible"> | |
| 7 | + <span class="label"><%= _('Responsible:') %></span> | |
| 8 | + <span> | |
| 9 | + <% change_responsible_url = url_for :action => :change_responsible, :controller => :tasks %> | |
| 10 | + <%= 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('#{change_responsible_url}', #{task.id}, #{task.responsible.present? ? task.responsible.id : 'null'}, this);" %> | |
| 11 | + </span> | |
| 12 | + </div> | |
| 13 | + <% end %> | |
| 14 | + | |
| 5 | 15 | <div class="task_decisions"> |
| 6 | 16 | <%= |
| 7 | 17 | labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept', | ... | ... |
app/views/tasks/index.html.erb
| ... | ... | @@ -30,6 +30,9 @@ |
| 30 | 30 | <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %> |
| 31 | 31 | </p> |
| 32 | 32 | <p> |
| 33 | + <%= labelled_select(_('Responsible')+': ', :filter_responsible, :id, :name, @filter_responsible, [OpenStruct.new(:name => _('All'), :id => nil), OpenStruct.new(:name => _('Unassigned'), :id => -1)] + @responsible_candidates) %> | |
| 34 | + </p> | |
| 35 | + <p> | |
| 33 | 36 | <%= submit_button(:search, _('Search')) %> |
| 34 | 37 | </p> |
| 35 | 38 | <% end %> | ... | ... |
public/javascripts/tasks.js
| ... | ... | @@ -63,3 +63,18 @@ |
| 63 | 63 | |
| 64 | 64 | })(jQuery) |
| 65 | 65 | |
| 66 | +function change_task_responsible(url, task_id, old_responsible_id, el) { | |
| 67 | + jQuery.post(url, {task_id: task_id, | |
| 68 | + responsible_id: $(el).val(), | |
| 69 | + old_responsible_id: old_responsible_id}, function(data) { | |
| 70 | + if (data.success) { | |
| 71 | + $(el).effect("highlight"); | |
| 72 | + } else { | |
| 73 | + $(el).effect("highlight", {color: 'red'}); | |
| 74 | + } | |
| 75 | + if (data.notice) { | |
| 76 | + display_notice(data.notice); | |
| 77 | + } | |
| 78 | + }); | |
| 79 | +} | |
| 80 | + | ... | ... |
public/stylesheets/tasks.css
test/functional/tasks_controller_test.rb
| ... | ... | @@ -458,4 +458,82 @@ class TasksControllerTest < ActionController::TestCase |
| 458 | 458 | post :index, :page => 2 |
| 459 | 459 | assert_equal [t4], assigns(:tasks) |
| 460 | 460 | end |
| 461 | + | |
| 462 | + should 'filter tasks by responsible' do | |
| 463 | + Task.stubs(:per_page).returns(3) | |
| 464 | + requestor = fast_create(Person) | |
| 465 | + responsible = fast_create(Person) | |
| 466 | + t1 = Task.create!(:requestor => requestor, :target => profile, :responsible => responsible) | |
| 467 | + t2 = Task.create!(:requestor => requestor, :target => profile, :responsible => responsible) | |
| 468 | + t3 = Task.create!(:requestor => requestor, :target => profile) | |
| 469 | + | |
| 470 | + get :index, :filter_responsible => responsible.id | |
| 471 | + | |
| 472 | + assert_includes assigns(:tasks), t1 | |
| 473 | + assert_includes assigns(:tasks), t2 | |
| 474 | + assert_not_includes assigns(:tasks), t3 | |
| 475 | + | |
| 476 | + get :index | |
| 477 | + | |
| 478 | + assert_includes assigns(:tasks), t1 | |
| 479 | + assert_includes assigns(:tasks), t2 | |
| 480 | + assert_includes assigns(:tasks), t3 | |
| 481 | + end | |
| 482 | + | |
| 483 | + should 'do not display responsible assignment if profile is not an organization' do | |
| 484 | + profile = create_user('personprofile').person | |
| 485 | + t1 = Task.create!(:requestor => profile, :target => profile) | |
| 486 | + @controller.stubs(:profile).returns(profile) | |
| 487 | + login_as profile.user.login | |
| 488 | + get :index | |
| 489 | + | |
| 490 | + assert_select "#task-#{t1.id}" | |
| 491 | + assert_select '.task_responsible', 0 | |
| 492 | + end | |
| 493 | + | |
| 494 | + should 'display responsible assignment if profile is an organization' do | |
| 495 | + profile = fast_create(Community) | |
| 496 | + person1 = create_user('person1').person | |
| 497 | + person2 = create_user('person2').person | |
| 498 | + person3 = create_user('person3').person | |
| 499 | + profile.add_admin(person1) | |
| 500 | + profile.add_admin(person2) | |
| 501 | + profile.add_member(person3) | |
| 502 | + Task.create!(:requestor => person3, :target => profile) | |
| 503 | + @controller.stubs(:profile).returns(profile) | |
| 504 | + | |
| 505 | + login_as person1.user.login | |
| 506 | + get :index | |
| 507 | + assert_equivalent [person1, person2], assigns(:responsible_candidates) | |
| 508 | + assert_select '.task_responsible' | |
| 509 | + end | |
| 510 | + | |
| 511 | + should 'change task responsible' do | |
| 512 | + profile = fast_create(Community) | |
| 513 | + @controller.stubs(:profile).returns(profile) | |
| 514 | + person = create_user('person1').person | |
| 515 | + profile.add_admin(person) | |
| 516 | + task = Task.create!(:requestor => person, :target => profile) | |
| 517 | + | |
| 518 | + assert_equal nil, task.responsible | |
| 519 | + login_as person.user.login | |
| 520 | + post :change_responsible, :task_id => task.id, :responsible_id => person.id | |
| 521 | + assert_equal person, task.reload.responsible | |
| 522 | + end | |
| 523 | + | |
| 524 | + should 'not change task responsible if old responsible is not the current' do | |
| 525 | + profile = fast_create(Community) | |
| 526 | + @controller.stubs(:profile).returns(profile) | |
| 527 | + person1 = create_user('person1').person | |
| 528 | + person2 = create_user('person2').person | |
| 529 | + profile.add_admin(person1) | |
| 530 | + task = Task.create!(:requestor => person1, :target => profile, :responsible => person1) | |
| 531 | + | |
| 532 | + login_as person1.user.login | |
| 533 | + post :change_responsible, :task_id => task.id, :responsible_id => person2.id, :old_responsible => nil | |
| 534 | + assert_equal person1, task.reload.responsible | |
| 535 | + json_response = ActiveSupport::JSON.decode(response.body) | |
| 536 | + assert !json_response['success'] | |
| 537 | + end | |
| 538 | + | |
| 461 | 539 | end | ... | ... |
test/unit/task_test.rb
| ... | ... | @@ -444,6 +444,14 @@ class TaskTest < ActiveSupport::TestCase |
| 444 | 444 | assert t1.ham? |
| 445 | 445 | end |
| 446 | 446 | |
| 447 | + should 'be able to assign a responsible to a task' do | |
| 448 | + person = fast_create(Person) | |
| 449 | + task = fast_create(Task) | |
| 450 | + task.responsible = person | |
| 451 | + task.save! | |
| 452 | + assert_equal person, task.responsible | |
| 453 | + end | |
| 454 | + | |
| 447 | 455 | protected |
| 448 | 456 | |
| 449 | 457 | def sample_user | ... | ... |