Skip to content

Commit 0a76037

Browse files
authored
Merge pull request #3664 from unicef/staging
Staging
2 parents 34486ff + 7dda348 commit 0a76037

File tree

97 files changed

+4850
-2747
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+4850
-2747
lines changed

Pipfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ etools-validator = "==0.5.0"
6464
flower = "==1.2.0" # issue when locking
6565
GDAL = "==3.0.2"
6666
gunicorn = "<20.0"
67+
jsonschema = "*"
6768
newrelic = "*"
6869
Pillow = "==9.3.0"
6970
psycopg2-binary = "==2.9.1"
@@ -87,4 +88,4 @@ pyyaml = "==5.3.1"
8788
reportlab = "==3.6.6" # freeze: getStringIO from 'reportlab.lib.utils'
8889

8990
[requires]
90-
python_version = "3.9"
91+
python_version = "3.9"

Pipfile.lock

Lines changed: 154 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/etools/applications/audit/conditions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,13 @@ def __init__(self, user):
3636

3737
def is_satisfied(self):
3838
return self.user.is_unicef_user()
39+
40+
41+
class EngagementUnicefCommentsReceivedCondition(SimpleCondition):
42+
predicate = 'audit_engagement.date_of_comments_by_unicef'
43+
44+
def __init__(self, engagement):
45+
self.engagement = engagement
46+
47+
def is_satisfied(self):
48+
return self.engagement.date_of_comments_by_unicef is not None

src/etools/applications/audit/management/commands/update_audit_permissions.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
AuditModuleCondition,
1212
AuditStaffMemberCondition,
1313
EngagementStaffMemberCondition,
14+
EngagementUnicefCommentsReceivedCondition,
1415
IsUnicefUserCondition,
1516
)
1617
from etools.applications.audit.models import (
@@ -133,7 +134,7 @@ class Command(BaseCommand):
133134
follow_up_page = follow_up_editable_page + [
134135
'audit.spotcheck.total_amount_tested',
135136
'audit.spotcheck.total_amount_of_ineligible_expenditure',
136-
] + action_points_block
137+
]
137138

138139
engagement_overview_editable_page = (engagement_overview_editable_block + special_audit_block +
139140
partner_block + staff_members_block + users_notified_block)
@@ -231,6 +232,9 @@ def engagement_status(self, status):
231232
obj = get_model_target(Engagement)
232233
return [ObjectStatusCondition.predicate_template.format(obj=obj, status=status)]
233234

235+
def engagement_comments_received_by_unicef(self):
236+
return [EngagementUnicefCommentsReceivedCondition.predicate]
237+
234238
def new_engagement(self):
235239
model = get_model_target(Engagement)
236240
return [NewObjectCondition.predicate_template.format(model=model)]
@@ -391,6 +395,11 @@ def assign_permissions(self):
391395
self.follow_up_page,
392396
condition=final_engagement_condition
393397
)
398+
self.add_permissions(
399+
self.all_unicef_users, 'view',
400+
self.action_points_block,
401+
condition=self.engagement_comments_received_by_unicef()
402+
)
394403
self.add_permissions(
395404
self.focal_point, 'edit',
396405
self.follow_up_editable_page,
@@ -404,13 +413,13 @@ def assign_permissions(self):
404413
self.all_unicef_users,
405414
'edit',
406415
'audit.engagement.action_points',
407-
condition=final_engagement_condition
416+
condition=self.engagement_comments_received_by_unicef()
408417
)
409418
self.add_permissions(
410419
self.all_unicef_users,
411420
'edit',
412421
'audit.engagementactionpoint.*',
413-
condition=final_engagement_condition + self.new_action_point(),
422+
condition=self.engagement_comments_received_by_unicef() + self.new_action_point(),
414423
)
415424
self.add_permissions(
416425
self.action_points_editors, 'edit',

src/etools/applications/audit/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from etools.applications.action_points.models import ActionPoint
2121
from etools.applications.audit.purchase_order.models import PurchaseOrder, PurchaseOrderItem
2222
from etools.applications.audit.transitions.conditions import (
23+
ActionPointsProvidedForHighPriorityFindingsCheck,
2324
AuditSubmitReportRequiredFieldsCheck,
2425
EngagementHasReportAttachmentsCheck,
2526
EngagementSubmitReportRequiredFieldsCheck,
@@ -468,6 +469,9 @@ def submit(self, *args, **kwargs):
468469
return super().submit(*args, **kwargs)
469470

470471
@transition('status', source=Engagement.STATUSES.report_submitted, target=Engagement.STATUSES.final,
472+
conditions=[
473+
ActionPointsProvidedForHighPriorityFindingsCheck.as_condition(),
474+
],
471475
permission=has_action_permission(action='finalize'))
472476
def finalize(self, *args, **kwargs):
473477
return super().finalize(*args, **kwargs)

src/etools/applications/audit/tests/test_transitions.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
from rest_framework import status
88
from unicef_attachments.models import Attachment
99

10-
from etools.applications.audit.models import SpecificProcedure
10+
from etools.applications.action_points.tests.factories import ActionPointFactory
11+
from etools.applications.audit.models import Finding, SpecificProcedure
1112
from etools.applications.audit.tests.base import EngagementTransitionsTestCaseMixin
1213
from etools.applications.audit.tests.factories import (
1314
AuditFactory,
15+
FindingFactory,
1416
KeyInternalControlFactory,
1517
MicroAssessmentFactory,
1618
SpecialAuditFactory,
@@ -221,6 +223,11 @@ def test_finalize_auditor(self):
221223
self._init_submitted_engagement()
222224
self._test_finalize(self.auditor, status.HTTP_403_FORBIDDEN)
223225

226+
def test_finalize_focal_point_high_priority_findings(self):
227+
self._init_submitted_engagement()
228+
FindingFactory(spot_check=self.engagement, priority=Finding.PRIORITIES.high)
229+
self._test_finalize(self.unicef_focal_point, status.HTTP_400_BAD_REQUEST)
230+
224231
def test_finalize_focal_point(self):
225232
self._init_submitted_engagement()
226233
content_type = ContentType.objects.get_for_model(self.engagement)
@@ -230,6 +237,8 @@ def test_finalize_focal_point(self):
230237
content_type=content_type,
231238
object_id=self.engagement.pk,
232239
)
240+
FindingFactory(spot_check=self.engagement, priority=Finding.PRIORITIES.high)
241+
ActionPointFactory(engagement=self.engagement, high_priority=True)
233242
with patch(self.filepath, self.mock_filepath):
234243
self._test_finalize(self.unicef_focal_point, status.HTTP_200_OK)
235244
self.assertTrue(attachment_qs.exists())

src/etools/applications/audit/transitions/conditions.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,20 @@ def get_categories_to_validate_before_submit(self, instance):
180180
categories = self.VALIDATE_CATEGORIES_BEFORE_SUBMIT
181181
categories[MicroAssessment.get_subject_areas_code(instance.questionnaire_version)] = 'test_subject_areas'
182182
return categories
183+
184+
185+
class ActionPointsProvidedForHighPriorityFindingsCheck(BaseTransitionCheck):
186+
def get_errors(self, instance, *args, **kwargs):
187+
from etools.applications.audit.models import EngagementActionPoint, Finding
188+
189+
errors = super().get_errors(instance, *args, **kwargs)
190+
191+
if (
192+
instance.findings.filter(priority=Finding.PRIORITIES.high).exists() and
193+
not EngagementActionPoint.objects.filter(engagement=instance, high_priority=True).exists()
194+
):
195+
errors['action_points'] = _(
196+
'Action Points with High Priority to be opened if High Priority findings provided.'
197+
)
198+
199+
return errors

0 commit comments

Comments
 (0)