Skip to content

Commit

Permalink
Merge pull request #3080 from unicef/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ntrncic authored Sep 3, 2021
2 parents dabecec + 6f8a6e8 commit c41e1a4
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 134 deletions.
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ djangorestframework-xml = "==2.0.0"
djangorestframework = "==3.12.4"
drf-nested-routers = "==0.93.3"
drf-querystringfilter = "==1.0.0"
etools-validator = "==0.3.4"
etools-validator = "==0.5.0"
flower = "==0.9.5" # issue when locking
GDAL = "==3.0.2"
gunicorn = "<20.0"
Expand All @@ -83,6 +83,7 @@ xhtml2pdf = "==0.2.5"
unicef-vision = "==0.6"
etools-offline = "==0.1.0"
openpyxl = "==3.0.5"
pyyaml = "==5.4.1"

[requires]
python_version = "3.9"
199 changes: 99 additions & 100 deletions Pipfile.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ def filter_hact_for_partner(self, partner_id: int):
is_hact=Exists(question_sq),
has_finding_for_partner=Exists(finding_sq),
).filter(
status=MonitoringActivity.STATUS_COMPLETED,
is_hact=True,
has_finding_for_partner=True,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def test_filter_by_visit_lead(self):

def test_filter_by_partner_hact(self):
partner = PartnerFactory()
activity1 = MonitoringActivityFactory(partners=[partner])
activity1 = MonitoringActivityFactory(partners=[partner], status='completed')
MonitoringActivityFactory(partners=[partner])
MonitoringActivityFactory(partners=[partner])
ActivityQuestionOverallFinding.objects.create(
Expand All @@ -147,6 +147,25 @@ def test_filter_by_partner_hact(self):
)
ActivityOverallFinding.objects.create(partner=partner, narrative_finding='test',
monitoring_activity=activity1)

# not completed
activity2 = MonitoringActivityFactory(partners=[partner], status='report_finalization')
MonitoringActivityFactory(partners=[partner])
MonitoringActivityFactory(partners=[partner])
ActivityQuestionOverallFinding.objects.create(
activity_question=ActivityQuestionFactory(
question__is_hact=True,
question__level='partner',
monitoring_activity=activity2,
),
value='ok',
)
ActivityOverallFinding.objects.create(partner=partner, narrative_finding='test',
monitoring_activity=activity2)

# not hact
MonitoringActivityFactory(partners=[partner], status='completed')

self._test_list(self.unicef_user, [activity1], data={'hact_for_partner': partner.id})

def test_details(self):
Expand Down
2 changes: 1 addition & 1 deletion src/etools/applications/partners/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ def programmatic_visits(self, event_date=None, update_one=False):
partner=self
).values_list('monitoring_activities__id', flat=True)
fmvqs = MonitoringActivity.objects.filter(
partners=self, status="completed",
partners=self,
end_date__year=datetime.datetime.now().year,
).filter_hact_for_partner(self.id).exclude(
id__in=grouped_activities,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,19 @@ def to_internal_value(self, data):
if not isinstance(data, list):
self.fail('bad_value', type=type(data))

if not hasattr(self.root, 'instance'):
return []

partner = self.root.instance
hact_activities = MonitoringActivity.objects.filter(partners=partner).filter_hact_for_partner(partner.id)
activities = {
activity.id: activity
for activity in MonitoringActivity.objects.filter(id__in=itertools.chain(*data))
for activity in hact_activities.filter(id__in=itertools.chain(*data))
}

result = []
for group in data:
result.append([activities[activity] for activity in group])
result.append([activities[activity] for activity in group if activity in activities])
result = list(filter(lambda x: x, result))

return result
Expand Down Expand Up @@ -536,7 +541,7 @@ def save_monitoring_activity_groups(self, instance, groups):
group_object = instance_groups[i]
instance_activities = instance_groups[i].monitoring_activities.all()

if set(instance_activities).difference(set(groups[i])):
if set(instance_activities).symmetric_difference(set(groups[i])):
updated = True

group_object.monitoring_activities.set(groups[i])
Expand Down
110 changes: 83 additions & 27 deletions src/etools/applications/partners/tests/test_api_partners.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,9 +565,31 @@ def test_get_partner_monitoring_activity_groups(self):
)
self.assertEqual(response.data['monitoring_activity_groups'], [[activity1.id, activity2.id], [activity3.id]])

def _add_hact_finding_for_activity(self, activity):
ActivityQuestionOverallFinding.objects.create(
activity_question=ActivityQuestionFactory(
monitoring_activity=activity,
question__is_hact=True,
question__level='partner',
),
value=True
)
ActivityOverallFinding.objects.create(
narrative_finding='ok',
monitoring_activity=activity,
partner=self.partner,
)

def test_add_partner_monitoring_activity_groups(self):
activity1 = MonitoringActivityFactory(partners=[self.partner], status='completed')
activity2 = MonitoringActivityFactory(partners=[self.partner], status='completed')
today = datetime.date.today()
activity1 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
activity2 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
self._add_hact_finding_for_activity(activity1)
self._add_hact_finding_for_activity(activity2)

self.partner.programmatic_visits()
response = self.forced_auth_req('get', self.url, user=self.unicef_staff)
self.assertEqual(response.data['hact_values']['programmatic_visits']['completed'][get_quarter()], 2)

response = self.forced_auth_req(
'patch',
Expand All @@ -578,33 +600,66 @@ def test_add_partner_monitoring_activity_groups(self):
}
)
self.assertEqual(len(response.data['monitoring_activity_groups']), 1)
self.assertCountEqual(response.data['monitoring_activity_groups'][0], [activity1.id, activity2.id])
self.assertEqual(response.data['hact_values']['programmatic_visits']['completed'][get_quarter()], 1)

def test_update_partner_monitoring_activity_groups(self):
def test_add_partner_monitoring_activity_into_group(self):
today = datetime.date.today()
activity1 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
activity2 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
activity3 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
self._add_hact_finding_for_activity(activity1)
self._add_hact_finding_for_activity(activity2)
self._add_hact_finding_for_activity(activity3)

MonitoringActivityGroupFactory(partner=self.partner, monitoring_activities=[activity1, activity2])

self.partner.programmatic_visits()
response = self.forced_auth_req('get', self.url, user=self.unicef_staff)
self.assertEqual(response.data['hact_values']['programmatic_visits']['completed'][get_quarter()], 2)

response = self.forced_auth_req(
'patch',
self.url,
user=self.unicef_staff,
data={
'monitoring_activity_groups': [[activity1.id, activity2.id, activity3.id]],
}
)
self.assertEqual(len(response.data['monitoring_activity_groups']), 1)
self.assertCountEqual(response.data['monitoring_activity_groups'][0],
[activity1.id, activity2.id, activity3.id])
self.assertEqual(response.data['hact_values']['programmatic_visits']['completed'][get_quarter()], 1)

def test_add_partner_monitoring_activity_groups_not_completed_or_not_hact(self):
activity1 = MonitoringActivityFactory(partners=[self.partner], status='completed')
activity2 = MonitoringActivityFactory(partners=[self.partner], status='completed')
activity2 = MonitoringActivityFactory(partners=[self.partner], status='report_finalization')
activity3 = MonitoringActivityFactory(partners=[self.partner], status='completed')
activity4 = MonitoringActivityFactory(partners=[self.partner], status='completed')
MonitoringActivityFactory(partners=[self.partner])
ActivityQuestionOverallFinding.objects.create(
activity_question=ActivityQuestionFactory(
question__is_hact=True,
question__level='partner',
monitoring_activity=activity1,
),
value='ok',
)
ActivityOverallFinding.objects.create(partner=self.partner, narrative_finding='test',
monitoring_activity=activity1)
ActivityQuestionOverallFinding.objects.create(
activity_question=ActivityQuestionFactory(
question__is_hact=True,
question__level='partner',
monitoring_activity=activity3,
),
value='ok',
self._add_hact_finding_for_activity(activity1)
self._add_hact_finding_for_activity(activity2)

response = self.forced_auth_req(
'patch',
self.url,
user=self.unicef_staff,
data={
'monitoring_activity_groups': [[activity1.id, activity2.id, activity3.id]],
}
)
ActivityOverallFinding.objects.create(partner=self.partner, narrative_finding='test',
monitoring_activity=activity3)
self.assertEqual(len(response.data['monitoring_activity_groups']), 1)
self.assertEqual(response.data['monitoring_activity_groups'], [[activity1.id]])

def test_update_partner_monitoring_activity_groups(self):
today = datetime.date.today()
activity1 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
activity2 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
activity3 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
activity4 = MonitoringActivityFactory(partners=[self.partner], end_date=today, status='completed')
self._add_hact_finding_for_activity(activity1)
self._add_hact_finding_for_activity(activity2)
self._add_hact_finding_for_activity(activity3)
self._add_hact_finding_for_activity(activity4)
MonitoringActivityFactory(partners=[self.partner])

MonitoringActivityGroupFactory(
partner=self.partner,
Expand All @@ -616,7 +671,8 @@ def test_update_partner_monitoring_activity_groups(self):
)
self.partner.programmatic_visits()
# 2 groups
self.assertEqual(self.partner.hact_values['programmatic_visits']['completed'][get_quarter()], 2)
response = self.forced_auth_req('get', self.url, user=self.unicef_staff)
self.assertEqual(response.data['hact_values']['programmatic_visits']['completed'][get_quarter()], 2)

response = self.forced_auth_req(
'patch',
Expand All @@ -631,7 +687,7 @@ def test_update_partner_monitoring_activity_groups(self):
self.assertEqual(self.partner.monitoring_activity_groups.count(), 1)
self.partner.refresh_from_db()
# 1 group + 2 ungrouped
self.assertEqual(self.partner.hact_values['programmatic_visits']['completed'][get_quarter()], 3)
self.assertEqual(response.data['hact_values']['programmatic_visits']['completed'][get_quarter()], 3)


class TestPartnerOrganizationHactAPIView(BaseTenantTestCase):
Expand Down
8 changes: 8 additions & 0 deletions src/etools/applications/users/tests/test_views_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ def test_forced_pagination_custom_page_size(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data['results']), 5)

def test_search(self):
UserFactory(is_staff=True, email='[email protected]')
UserFactory(is_staff=True, email='[email protected]')
response = self.forced_auth_req('get', self.url, user=self.unicef_staff, data={'search': 'test_user_email'})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]['email'], '[email protected]')

def test_users_api_list_values(self):
response = self.forced_auth_req(
'get',
Expand Down
3 changes: 2 additions & 1 deletion src/etools/applications/users/views_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ class UsersListAPIView(QueryStringFilterMixin, ListAPIView):
Country is determined by the currently logged in user.
"""
model = get_user_model()
queryset = get_user_model().objects.all()
queryset = get_user_model().objects.all().select_related('profile')
serializer_class = MinimalUserSerializer
permission_classes = (IsAdminUser, )
pagination_class = AppendablePageNumberPagination
search_terms = ('email__icontains', 'first_name__icontains', 'middle_name__icontains', 'last_name__icontains')

filters = (
('group', 'groups__name__in'),
Expand Down

0 comments on commit c41e1a4

Please sign in to comment.