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 @@ |
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 | 119 | environment.person_template |
120 | 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 | 140 | end | ... | ... |
... | ... | @@ -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 | 28 | - manage_environment_roles |
29 | 29 | - manage_environment_validators |
30 | 30 | - moderate_comments |
31 | + - perform_task | |
31 | 32 | profile_admin: |
32 | 33 | id: 5 |
33 | 34 | key: 'profile_admin' |
... | ... | @@ -37,6 +38,7 @@ profile_admin: |
37 | 38 | - edit_profile_design |
38 | 39 | - moderate_comments |
39 | 40 | - destroy_profile |
41 | + - perform_task | |
40 | 42 | profile_member: |
41 | 43 | id: 6 |
42 | 44 | key: 'profile_member' | ... | ... |
... | ... | @@ -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 | 326 | end |
327 | 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 | 379 | end | ... | ... |