Commit 9e766d4036b94c0f92b84fa80b22bb02dacbf7a9
1 parent
24bb5d14
Exists in
master
and in
29 other branches
ActionItem628: Squashed commit of the following:
enhancement pending task mail message list pending tasks in communities/groups where the user is a member and can solve the tasks loop through users with pending tasks and notify them determine wheter a user has pending tasks
Showing
7 changed files
with
158 additions
and
0 deletions
Show diff stats
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +class PendingTaskNotifier < ActionMailer::Base | ||
2 | + | ||
3 | + def notification(person) | ||
4 | + recipients person.email | ||
5 | + from "#{person.environment.name} <#{person.environment.contact_email}>" | ||
6 | + subject _("%s - Pending tasks") % person.environment.name | ||
7 | + body :person => person, | ||
8 | + :tasks => person.tasks.pending, | ||
9 | + :organizations_with_pending_tasks => person.organizations_with_pending_tasks, | ||
10 | + :environment => person.environment.name, | ||
11 | + :url => url_for(:host => person.environment.default_hostname, :controller => 'home'), | ||
12 | + :default_hostname => person.environment.default_hostname, | ||
13 | + :url_for_pending_tasks => url_for(:host => person.environment.default_hostname, :controller => 'tasks', :profile => person.identifier) | ||
14 | + end | ||
15 | + | ||
16 | +end |
app/models/person.rb
@@ -119,4 +119,22 @@ class Person < Profile | @@ -119,4 +119,22 @@ class Person < Profile | ||
119 | environment.person_template | 119 | environment.person_template |
120 | end | 120 | end |
121 | 121 | ||
122 | + def self.with_pending_tasks | ||
123 | + Person.find(:all).select{ |person| !person.tasks.pending.empty? or person.has_organization_pending_tasks? } | ||
124 | + end | ||
125 | + | ||
126 | + def has_organization_pending_tasks? | ||
127 | + self.memberships.any?{ |group| group.tasks.pending.any?{ |task| self.has_permission?(task.permission, group) } } | ||
128 | + end | ||
129 | + | ||
130 | + def organizations_with_pending_tasks | ||
131 | + self.memberships.select do |organization| | ||
132 | + organization.tasks.pending.any?{|task| self.has_permission?(task.permission, organization)} | ||
133 | + end | ||
134 | + end | ||
135 | + | ||
136 | + def pending_tasks_for_organization(organization) | ||
137 | + organization.tasks.pending.select{|task| self.has_permission?(task.permission, organization)} | ||
138 | + end | ||
139 | + | ||
122 | end | 140 | end |
@@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
1 | +<%= _("Dear %s") % @person.name %>, | ||
2 | + | ||
3 | +<%= _("You have %d pending task(s).") % @tasks.size %> | ||
4 | + | ||
5 | +<%= @tasks.map{|i| " * #{i.description}"}.join("\n") %> | ||
6 | + | ||
7 | +<%= _("Click in address below to process task(s):") %> | ||
8 | + | ||
9 | +<%= @url_for_pending_tasks %> | ||
10 | +<% @organizations_with_pending_tasks.each do |organization| %> | ||
11 | +<% pending_tasks = @person.pending_tasks_for_organization(organization) %> | ||
12 | +<%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %> | ||
13 | + | ||
14 | +<%= pending_tasks.map{|i| " * #{i.description}"}.join("\n") %> | ||
15 | + | ||
16 | +<%= _("Click in address below to process task(s):") %> | ||
17 | + | ||
18 | +<%= url_for(:host => @default_hostname, :controller => 'tasks', :profile => organization.identifier) %> | ||
19 | +<% end %> | ||
20 | +-- | ||
21 | +<%= _('%s environment system') % @environment %> | ||
22 | +<%= @url %> |
test/fixtures/roles.yml
@@ -28,6 +28,7 @@ four: | @@ -28,6 +28,7 @@ four: | ||
28 | - manage_environment_roles | 28 | - manage_environment_roles |
29 | - manage_environment_validators | 29 | - manage_environment_validators |
30 | - moderate_comments | 30 | - moderate_comments |
31 | + - perform_task | ||
31 | profile_admin: | 32 | profile_admin: |
32 | id: 5 | 33 | id: 5 |
33 | key: 'profile_admin' | 34 | key: 'profile_admin' |
@@ -37,6 +38,7 @@ profile_admin: | @@ -37,6 +38,7 @@ profile_admin: | ||
37 | - edit_profile_design | 38 | - edit_profile_design |
38 | - moderate_comments | 39 | - moderate_comments |
39 | - destroy_profile | 40 | - destroy_profile |
41 | + - perform_task | ||
40 | profile_member: | 42 | profile_member: |
41 | id: 6 | 43 | id: 6 |
42 | key: 'profile_member' | 44 | key: 'profile_member' |
@@ -0,0 +1,43 @@ | @@ -0,0 +1,43 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class PendingTaskNotifierTest < Test::Unit::TestCase | ||
4 | + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' | ||
5 | + CHARSET = "utf-8" | ||
6 | + | ||
7 | + def setup | ||
8 | + ActionMailer::Base.delivery_method = :test | ||
9 | + ActionMailer::Base.perform_deliveries = true | ||
10 | + ActionMailer::Base.deliveries = [] | ||
11 | + | ||
12 | + @expected = TMail::Mail.new | ||
13 | + @expected.set_content_type "text", "plain", { "charset" => CHARSET } | ||
14 | + end | ||
15 | + | ||
16 | + should 'be able to deliver notification' do | ||
17 | + p = create_user('maelcum').person | ||
18 | + response = PendingTaskNotifier.deliver_notification(p) | ||
19 | + assert_equal 'Pending tasks', response.subject | ||
20 | + assert_equal p.email, response.to[0] | ||
21 | + end | ||
22 | + | ||
23 | + should 'list organization pending tasks' do | ||
24 | + p = create_user('maelcum').person | ||
25 | + c = Community.create!(:name => 'my test community') | ||
26 | + c.add_admin(p) | ||
27 | + c.tasks << Task.new | ||
28 | + | ||
29 | + response = PendingTaskNotifier.deliver_notification(p) | ||
30 | + assert_match /Generic task/, response.body | ||
31 | + end | ||
32 | + | ||
33 | + private | ||
34 | + | ||
35 | + def read_fixture(action) | ||
36 | + IO.readlines("#{FIXTURES_PATH}/mail_sender/#{action}") | ||
37 | + end | ||
38 | + | ||
39 | + def encode(subject) | ||
40 | + quoted_printable(subject, CHARSET) | ||
41 | + end | ||
42 | + | ||
43 | +end |
test/unit/person_test.rb
@@ -326,4 +326,54 @@ class PersonTest < Test::Unit::TestCase | @@ -326,4 +326,54 @@ class PersonTest < Test::Unit::TestCase | ||
326 | end | 326 | end |
327 | end | 327 | end |
328 | 328 | ||
329 | + should 'person has pending tasks' do | ||
330 | + p1 = create_user('user_with_tasks').person | ||
331 | + p1.tasks << Task.new | ||
332 | + p2 = create_user('user_without_tasks').person | ||
333 | + assert_includes Person.with_pending_tasks, p1 | ||
334 | + assert_not_includes Person.with_pending_tasks, p2 | ||
335 | + end | ||
336 | + | ||
337 | + should 'person has group with pending tasks' do | ||
338 | + p1 = create_user('user_with_tasks').person | ||
339 | + c1 = Community.create!(:name => 'my test community') | ||
340 | + c1.tasks << Task.new | ||
341 | + assert !c1.tasks.pending.empty? | ||
342 | + c1.add_admin(p1) | ||
343 | + | ||
344 | + c2 = Community.create!(:name => 'my other test community') | ||
345 | + p2 = create_user('user_without_tasks').person | ||
346 | + c2.add_admin(p2) | ||
347 | + | ||
348 | + assert_includes Person.with_pending_tasks, p1 | ||
349 | + assert_not_includes Person.with_pending_tasks, p2 | ||
350 | + end | ||
351 | + | ||
352 | + should 'not allow simple member to view group pending tasks' do | ||
353 | + c = Community.create!(:name => 'my test community') | ||
354 | + c.tasks << Task.new | ||
355 | + p = create_user('user_without_tasks').person | ||
356 | + c.add_member(p) | ||
357 | + | ||
358 | + assert_not_includes Person.with_pending_tasks, p | ||
359 | + end | ||
360 | + | ||
361 | + should 'person has organization pending tasks' do | ||
362 | + c = Community.create!(:name => 'my test community') | ||
363 | + c.tasks << Task.new | ||
364 | + p = create_user('user_with_tasks').person | ||
365 | + c.add_admin(p) | ||
366 | + | ||
367 | + assert p.has_organization_pending_tasks? | ||
368 | + end | ||
369 | + | ||
370 | + should 'select organization pending tasks' do | ||
371 | + c = Community.create!(:name => 'my test community') | ||
372 | + c.tasks << Task.new | ||
373 | + p = create_user('user_with_tasks').person | ||
374 | + c.add_admin(p) | ||
375 | + | ||
376 | + assert_equal p.pending_tasks_for_organization(c), c.tasks | ||
377 | + end | ||
378 | + | ||
329 | end | 379 | end |