Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into 190382_Create_Indi…
Browse files Browse the repository at this point in the history
…vidual_FSP_data_handler
  • Loading branch information
marekbiczysko committed May 9, 2024
2 parents b65fbc3 + 6c387e2 commit 8d796b1
Show file tree
Hide file tree
Showing 32 changed files with 1,247 additions and 707 deletions.
2 changes: 2 additions & 0 deletions backend/.coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ omit =
hct_mis_api/libs/*,
hct_mis_api/settings/*,
hct_mis_api/settings.py,
hct_mis_api/conftest.py,
hct_mis_api/config/settings.py
hct_mis_api/apps/core/management/commands/*

Expand All @@ -34,6 +35,7 @@ exclude_lines =
#if 0:
if __name__ == .__main__.:
if TYPE_CHECKING
^\s*(import\s.+|from\s+.+import\s+.+) # skip imports

fail_under = 15

Expand Down
15 changes: 10 additions & 5 deletions backend/hct_mis_api/apps/account/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django_filters import BooleanFilter, CharFilter, FilterSet, MultipleChoiceFilter

from hct_mis_api.apps.account.models import USER_STATUS_CHOICES, Partner, Role
from hct_mis_api.apps.core.utils import CustomOrderingFilter
from hct_mis_api.apps.core.utils import CustomOrderingFilter, decode_id_string

if TYPE_CHECKING:
from uuid import UUID
Expand All @@ -19,6 +19,7 @@

class UsersFilter(FilterSet):
business_area = CharFilter(required=True, method="business_area_filter")
program = CharFilter(required=False, method="program_filter")
search = CharFilter(method="search_filter")
status = MultipleChoiceFilter(field_name="status", choices=USER_STATUS_CHOICES)
partner = MultipleChoiceFilter(choices=Partner.get_partners_as_choices(), method="partners_filter")
Expand Down Expand Up @@ -65,10 +66,11 @@ def search_filter(self, qs: "QuerySet", name: str, value: str) -> "QuerySet[User
return qs.filter(q_obj)

def business_area_filter(self, qs: "QuerySet", name: str, value: str) -> "QuerySet[User]":
return qs.filter(
Q(user_roles__business_area__slug=value)
| Q(partner__business_area_partner_through__business_area__slug=value)
)
return qs.filter(Q(user_roles__business_area__slug=value) | Q(partner__business_areas__slug=value))

def program_filter(self, qs: "QuerySet", name: str, value: str) -> "QuerySet[User]":
program_id = decode_id_string(value)
return qs.filter(partner__programs__id=program_id)

def partners_filter(self, qs: "QuerySet", name: str, values: List["UUID"]) -> "QuerySet[User]":
q_obj = Q()
Expand All @@ -83,5 +85,8 @@ def roles_filter(self, qs: "QuerySet", name: str, values: List) -> "QuerySet[Use
q_obj |= Q(
user_roles__role__id=value,
user_roles__business_area__slug=business_area_slug,
) | Q(
partner__business_area_partner_through__roles__id=value,
partner__business_areas__slug=business_area_slug,
)
return qs.filter(q_obj)
30 changes: 29 additions & 1 deletion backend/hct_mis_api/apps/account/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
from functools import lru_cache
from typing import Any, List, Optional, Tuple, Union
from typing import Any, Dict, List, Optional, Tuple, Union
from uuid import UUID

from django import forms
Expand Down Expand Up @@ -31,6 +31,7 @@
from hct_mis_api.apps.core.mixins import LimitBusinessAreaModelMixin
from hct_mis_api.apps.core.models import BusinessArea, BusinessAreaPartnerThrough
from hct_mis_api.apps.geo.models import Area
from hct_mis_api.apps.utils.mailjet import MailjetClient
from hct_mis_api.apps.utils.models import TimeStampedUUIDModel
from hct_mis_api.apps.utils.validators import (
DoubleSpaceValidator,
Expand Down Expand Up @@ -264,6 +265,33 @@ def can_add_business_area_to_partner(self) -> bool:
for role in self.cached_user_roles()
)

def email_user( # type: ignore
self,
subject: str,
html_body: Optional[str] = None,
text_body: Optional[str] = None,
mailjet_template_id: Optional[int] = None,
body_variables: Optional[Dict[str, Any]] = None,
from_email: Optional[str] = None,
from_email_display: Optional[str] = None,
ccs: Optional[list[str]] = None,
) -> None:
"""
Send email to this user via Mailjet.
"""
email = MailjetClient(
recipients=[self.email],
subject=subject,
html_body=html_body,
text_body=text_body,
mailjet_template_id=mailjet_template_id,
variables=body_variables,
ccs=ccs,
from_email=from_email,
from_email_display=from_email_display,
)
email.send_email()

class Meta:
permissions = (
("can_load_from_ad", "Can load users from ActiveDirectory"),
Expand Down
13 changes: 12 additions & 1 deletion backend/hct_mis_api/apps/account/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
hopeOneOfPermissionClass,
)
from hct_mis_api.apps.core.extended_connection import ExtendedConnection
from hct_mis_api.apps.core.models import BusinessArea
from hct_mis_api.apps.core.models import BusinessArea, BusinessAreaPartnerThrough
from hct_mis_api.apps.core.schema import ChoiceObject
from hct_mis_api.apps.core.utils import decode_id_string, to_choice_object
from hct_mis_api.apps.geo.models import Area
Expand Down Expand Up @@ -66,6 +66,13 @@ class Meta:
exclude = ("id",)


class PartnerRoleNode(DjangoObjectType):

class Meta:
model = BusinessAreaPartnerThrough
exclude = ("id",)


class RoleChoiceObject(graphene.ObjectType):
name = graphene.String()
value = graphene.String()
Expand Down Expand Up @@ -96,10 +103,14 @@ class Meta:

class UserNode(DjangoObjectType):
business_areas = DjangoFilterConnectionField(UserBusinessAreaNode)
partner_roles = graphene.List(PartnerRoleNode)

def resolve_business_areas(self, info: Any) -> "QuerySet[BusinessArea]":
return info.context.user.business_areas

def resolve_partner_roles(self, info: Any) -> "QuerySet[Role]":
return self.partner.business_area_partner_through.all()

class Meta:
model = get_user_model()
exclude = ("password",)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,127 @@
{
'node': {
'partner': {
'name': 'UNICEF'
'name': 'Default Empty Partner'
},
'username': 'unicef_user'
'partnerRoles': [
],
'userRoles': [
{
'businessArea': {
'name': 'Afghanistan'
},
'role': {
'name': 'Test Role',
'permissions': None
}
}
],
'username': 'user_with_test_role'
}
},
{
'node': {
'partner': {
'name': 'Partner With Test Role'
},
'partnerRoles': [
{
'businessArea': {
'name': 'Afghanistan'
},
'roles': [
{
'name': 'Test Role',
'permissions': None
},
{
'name': 'User Management View Role',
'permissions': [
'USER_MANAGEMENT_VIEW_LIST'
]
}
]
}
],
'userRoles': [
],
'username': 'user_with_partner_with_test_role'
}
}
]
}
}
}

snapshots['TestUserFilter::test_users_by_program 1'] = {
'data': {
'allUsers': {
'edges': [
{
'node': {
'partner': {
'name': 'Partner With Test Role'
},
'username': 'user_with_partner_with_test_role'
}
}
]
}
}
}

snapshots['TestUserFilter::test_users_by_roles 1'] = {
'data': {
'allUsers': {
'edges': [
{
'node': {
'partner': {
'name': 'Default Empty Partner'
},
'username': 'user_in_ba'
'partnerRoles': [
],
'userRoles': [
{
'businessArea': {
'name': 'Afghanistan'
},
'role': {
'name': 'Test Role',
'permissions': None
}
}
],
'username': 'user_with_test_role'
}
},
{
'node': {
'partner': {
'name': 'Test Partner'
'name': 'Partner With Test Role'
},
'username': 'user_with_partner_in_ba'
'partnerRoles': [
{
'businessArea': {
'name': 'Afghanistan'
},
'roles': [
{
'name': 'Test Role',
'permissions': None
},
{
'name': 'User Management View Role',
'permissions': [
'USER_MANAGEMENT_VIEW_LIST'
]
}
]
}
],
'userRoles': [
],
'username': 'user_with_partner_with_test_role'
}
}
]
Expand Down
Loading

0 comments on commit 8d796b1

Please sign in to comment.