Skip to content

Commit

Permalink
Merge branch 'master' into user_dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanseymour committed Jul 11, 2016
2 parents 60cb383 + 9fb2cf4 commit f634703
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 2 deletions.
14 changes: 13 additions & 1 deletion casepro/cases/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ def search(cls, org, user, search):

@classmethod
def get_or_open(cls, org, user, message, summary, assignee):
from casepro.profiles.models import Notification

r = get_redis_connection()
with r.lock(CASE_LOCK_KEY % (org.pk, message.contact.uuid)):
message.refresh_from_db()
Expand All @@ -240,7 +242,11 @@ def get_or_open(cls, org, user, message, summary, assignee):
message.case = case
message.save(update_fields=('case',))

CaseAction.create(case, user, CaseAction.OPEN, assignee=assignee)
action = CaseAction.create(case, user, CaseAction.OPEN, assignee=assignee)

for assignee_user in assignee.get_users():
if assignee_user != user:
Notification.new_case_assignment(org, assignee_user, action)

return case

Expand Down Expand Up @@ -323,13 +329,19 @@ def reopen(self, user, note=None, update_contact=True):

@case_action()
def reassign(self, user, partner, note=None):
from casepro.profiles.models import Notification

self.assignee = partner
self.save(update_fields=('assignee',))

action = CaseAction.create(self, user, CaseAction.REASSIGN, assignee=partner, note=note)

self.notify_watchers(action=action)

# also notify users in the assigned partner that this case has been assigned to them
for user in partner.get_users():
Notification.new_case_assignment(self.org, user, action)

@case_action()
def label(self, user, label):
self.labels.add(label)
Expand Down
13 changes: 13 additions & 0 deletions casepro/cases/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,16 @@ def test_lifecycle(self, mock_remove_from_group, mock_add_to_group, mock_stop_ru
self.assertFalse(case2.is_new)
self.assertEqual(case, case2)

# user #2 should be notified of this new case assignment
self.assertEqual(Notification.objects.count(), 1)
Notification.objects.get(user=self.user2, type=Notification.TYPE_CASE_ASSIGNMENT, case_action=actions[0])

# contact sends a reply
msg3 = self.create_message(self.unicef, 432, self.ann, "OK", created_on=d2)
handle_messages(self.unicef.pk)

# user #1 should be notified of this reply
self.assertEqual(Notification.objects.count(), 2)
Notification.objects.get(user=self.user1, type=Notification.TYPE_CASE_REPLY, message=msg3)

# which will have been archived and added to the case
Expand All @@ -132,6 +137,7 @@ def test_lifecycle(self, mock_remove_from_group, mock_add_to_group, mock_stop_ru
self.assertEqual(set(case.watchers.all()), {self.user1, self.user2})

# user #1 should be notified of this new note
self.assertEqual(Notification.objects.count(), 3)
Notification.objects.get(user=self.user1, type=Notification.TYPE_CASE_ACTION, case_action=actions[1])

# user from other partner org can't re-assign or close case
Expand All @@ -152,6 +158,7 @@ def test_lifecycle(self, mock_remove_from_group, mock_add_to_group, mock_stop_ru
self.assertEqual(actions[2].created_on, d3)

# user #2 should be notified
self.assertEqual(Notification.objects.count(), 4)
Notification.objects.get(user=self.user2, type=Notification.TYPE_CASE_ACTION, case_action=actions[2])

# check that contacts groups were restored
Expand Down Expand Up @@ -186,6 +193,7 @@ def test_lifecycle(self, mock_remove_from_group, mock_add_to_group, mock_stop_ru
self.assertEqual(actions[3].created_on, d4)

# user #1 should be notified
self.assertEqual(Notification.objects.count(), 5)
Notification.objects.get(user=self.user1, type=Notification.TYPE_CASE_ACTION, case_action=actions[3])

# check that re-opening the case archived the contact's messages again
Expand All @@ -207,6 +215,11 @@ def test_lifecycle(self, mock_remove_from_group, mock_add_to_group, mock_stop_ru
self.assertEqual(actions[4].created_on, d5)
self.assertEqual(actions[4].assignee, self.who)

# users #1 (a watcher) and #3 (a new assignee) should be notified of this re-assignment
self.assertEqual(Notification.objects.count(), 7)
Notification.objects.get(user=self.user1, type=Notification.TYPE_CASE_ACTION, case_action=actions[4])
Notification.objects.get(user=self.user3, type=Notification.TYPE_CASE_ASSIGNMENT, case_action=actions[4])

with patch.object(timezone, 'now', return_value=d6):
# user from that partner re-labels it
case.update_labels(self.user3, [self.pregnancy])
Expand Down
14 changes: 14 additions & 0 deletions casepro/profiles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,13 @@ class Notification(models.Model):
A notification sent to a user
"""
TYPE_MESSAGE_LABELLING = 'L'
TYPE_CASE_ASSIGNMENT = 'C'
TYPE_CASE_ACTION = 'A'
TYPE_CASE_REPLY = 'R'

TYPE_NAME = {
TYPE_MESSAGE_LABELLING: 'message_labelling',
TYPE_CASE_ASSIGNMENT: 'case_assignment',
TYPE_CASE_ACTION: 'case_action',
TYPE_CASE_REPLY: 'case_reply',
}
Expand All @@ -151,6 +153,10 @@ class Notification(models.Model):
def new_message_labelling(cls, org, user, message):
return cls.objects.get_or_create(org=org, user=user, type=cls.TYPE_MESSAGE_LABELLING, message=message)

@classmethod
def new_case_assignment(cls, org, user, case_action):
return cls.objects.get_or_create(org=org, user=user, type=cls.TYPE_CASE_ASSIGNMENT, case_action=case_action)

@classmethod
def new_case_action(cls, org, user, case_action):
return cls.objects.get_or_create(org=org, user=user, type=cls.TYPE_CASE_ACTION, case_action=case_action)
Expand Down Expand Up @@ -180,6 +186,14 @@ def _build_message_labelling_email(self):
}
return _("New labelled message"), 'message_labelling', context

def _build_case_assignment_email(self):
case = self.case_action.case
context = {
'user': self.case_action.created_by,
'case_url': self.org.make_absolute_url(reverse('cases.case_read', args=[case.pk]))
}
return _("New case assignment #%d") % case.pk, 'case_assignment', context

def _build_case_action_email(self):
case = self.case_action.case
context = {
Expand Down
11 changes: 10 additions & 1 deletion casepro/profiles/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def test_send_all(self, mock_send_email):

send_notifications()

self.assertEqual(len(mock_send_email.mock_calls), 4)
self.assertEqual(len(mock_send_email.mock_calls), 5)
mock_send_email.assert_has_calls([
call(
[self.admin],
Expand Down Expand Up @@ -123,6 +123,15 @@ def test_send_all(self, mock_send_email):
'assignee': self.who,
'case_url': "http://unicef.localhost:8000/case/read/%d/" % case1.pk
}
),
call(
[self.user3],
"New case assignment #%d" % case1.pk,
'profiles/email/case_assignment',
{
'user': self.admin,
'case_url': "http://unicef.localhost:8000/case/read/%d/" % case1.pk
}
)
])
mock_send_email.reset_mock()
Expand Down
6 changes: 6 additions & 0 deletions templates/profiles/email/case_assignment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% load i18n %}
{% blocktrans with user=user.email %}User {{ user }} assigned this case to your organization.{% endblocktrans %}<br/>
<br/>
<br/>
{% blocktrans with case_url as case_url %}Click <a href="{{ case_url }}">here</a> to view the case.{% endblocktrans %}
<br/>
4 changes: 4 additions & 0 deletions templates/profiles/email/case_assignment.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% load i18n %}
{% blocktrans with user=user.email %}User {{ user }} assigned this case to your organization.{% endblocktrans %}

{% blocktrans with case_url as case_url %}Go to {{ case_url }} to view the case.{% endblocktrans %}

0 comments on commit f634703

Please sign in to comment.