Skip to content

Commit

Permalink
Agency: Allows ticket notifications to target parent organisations
Browse files Browse the repository at this point in the history
TYPE: Feature
LINK: OGC-1658
  • Loading branch information
Daverball authored Dec 10, 2024
1 parent 597a6cc commit 0250a72
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 19 deletions.
47 changes: 28 additions & 19 deletions src/onegov/agency/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from datetime import datetime
from onegov.agency.request import AgencyRequest
from onegov.core.orm.mixins import TimestampMixin
from onegov.user import RoleMapping
from onegov.user import UserGroup
from sqlalchemy.orm import Query
from typing import TypeVar

Expand Down Expand Up @@ -65,27 +65,23 @@ def emails_for_new_ticket(

# we try to minimize the amount of e-mail address parsing we
# perform by de-duplicating the raw usernames as we get them
role_mapping: RoleMapping
agency: Agency | None
for agency in agencies:
for role_mapping in getattr(agency, 'role_mappings', ()):
if role_mapping.role != 'editor':
continue

# we only care about group role mappings
group = role_mapping.group
if group is None:
continue

# if the group does not have permission to manage this
# type of ticket then we need to skip it
if groupids is not None and group.id.hex not in groupids:
continue

# if there are no user groups which can handle our ticket
# then look if there are groups in one of the parent agencies
while not (
agency is None
or (groups := ticket_groups(agency, groupids))
):
agency = agency.parent

if agency is None or not groups:
continue

for group in groups:
# if the group does not have immediate notification
# turned on, then skip it
if not group.meta:
continue
if group.meta.get('immediate_notification') != 'yes':
if (group.meta or {}).get('immediate_notification') != 'yes':
continue

for user in group.users:
Expand All @@ -104,6 +100,19 @@ def emails_for_new_ticket(
pass


def ticket_groups(
agency: Agency,
groupids: list[str] | None
) -> list['UserGroup']:
return [
group
for role_mapping in getattr(agency, 'role_mappings', ())
if role_mapping.role == 'editor'
if (group := role_mapping.group)
if groupids is None or group.id.hex in groupids
]


def get_html_paragraph_with_line_breaks(text: str | None) -> Markup:
if not text:
return Markup('')
Expand Down
79 changes: 79 additions & 0 deletions tests/onegov/agency/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,85 @@ def test_emails_for_new_ticket_PER(agency_app):
}


def test_emails_for_new_ticket_parent_agency(agency_app):
session = agency_app.session()

parent_agency = ExtendedAgency(
title="Test Parent Agency",
name="test-parent-agency",
portrait="This is a test\nparent agency."
)
agency = ExtendedAgency(
title="Test Agency",
name="test-agency",
portrait="This is a test\nagency.",
)
user_1 = User(
username='[email protected]',
password_hash='password_hash',
role='member',
)
user_2 = User(
username='[email protected]',
password_hash='password_hash',
role='member',
)
user_3 = User(
username='[email protected]',
password_hash='password_hash',
role='member',
)
group_1 = UserGroup(name='group1')
group_2 = UserGroup(name='group2')
session.add_all(
(parent_agency, agency, user_1, user_2, user_3, group_1, group_2)
)
session.flush()

agency.parent = parent_agency
group_1.meta = {'immediate_notification': 'yes'}
group_2.meta = {'immediate_notification': 'yes'}
user_1.group = group_1
user_2.group = group_1
user_3.group = group_2

request = Bunch(
app=agency_app,
email_for_new_tickets=None
)
assert condense(emails_for_new_ticket(agency, request)) == set()

group_mapping = RoleMapping(
group_id=group_1.id,
content_type='agencies',
content_id=str(parent_agency.id),
role='editor'
)
session.add(group_mapping)
session.flush()

# since no groups are mapped to agency, the tickets should
# go to the group mapped to agency.parent instead
assert condense(emails_for_new_ticket(agency, request)) == {
'[email protected]', '[email protected]'
}

# but if we map group 2 to the affected agency then
# they should get the notification without the parent
# agency being notified
group_mapping = RoleMapping(
group_id=group_2.id,
content_type='agencies',
content_id=str(agency.id),
role='editor'
)
session.add(group_mapping)
session.flush()
assert condense(emails_for_new_ticket(agency, request)) == {
'[email protected]'
}


def test_get_html_paragraph_with_line_breaks():
assert get_html_paragraph_with_line_breaks(None) == ''
assert get_html_paragraph_with_line_breaks('') == ''
Expand Down

0 comments on commit 0250a72

Please sign in to comment.