Skip to content

Commit

Permalink
Added django admin logic to allow staff members to revert reports bac…
Browse files Browse the repository at this point in the history
…k to in progress once flagged for removal
  • Loading branch information
sambodeme committed Dec 17, 2024
1 parent f247ffb commit ca9a605
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 4 deletions.
78 changes: 77 additions & 1 deletion backend/audit/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
UeiValidationWaiver,
)
from audit.models.models import STATUS
from audit.models.viewflow import sac_transition
from audit.models.viewflow import (
sac_flag_for_removal,
sac_revert_from_flagged_for_removal,
sac_transition,
)
from audit.validators import (
validate_auditee_certification_json,
validate_auditor_certification_json,
Expand All @@ -24,6 +28,76 @@
logger = logging.getLogger(__name__)


@admin.action(description="Revert selected report(s) to In Progress")
def revert_to_in_progress(modeladmin, request, queryset):
successful_reverts = []
errors = []

for sac in queryset:
if sac.submission_status == STATUS.FLAGGED_FOR_REMOVAL:
try:
sac_revert_from_flagged_for_removal(sac, request.user)
sac.save()
successful_reverts.append(sac.report_id)
except Exception as e:
modeladmin.message_user(
request,
f"Error reverting {sac.report_id}: {str(e)}",
level=messages.ERROR,
)
errors.append(sac.report_id)
else:
modeladmin.message_user(
request,
f"Report {sac.report_id} is not flagged for removal.",
level=messages.WARNING,
)
errors.append(sac.report_id)

if successful_reverts:
modeladmin.message_user(
request,
f"Successfully reverted report(s) ({", ".join(successful_reverts)}) back to In Progress.",
level=messages.SUCCESS,
)

if errors:
modeladmin.message_user(
request,
f"Unable to revert report(s) ({", ".join(errors)}) back to In Progress.",
level=messages.ERROR,
)


@admin.action(description="Flag selected report(s) for removal")
def flag_for_removal(modeladmin, request, queryset):

flagged = []
already_flagged = []

for sac in queryset:
if sac.submission_status != STATUS.FLAGGED_FOR_REMOVAL:
sac_flag_for_removal(sac, request.user)
sac.save()
flagged.append(sac.report_id)
else:
already_flagged.append(sac.report_id)

if flagged:
modeladmin.message_user(
request,
f"Successfully flagged report(s) ({", ".join(flagged)}) for removal.",
level=messages.SUCCESS,
)

if already_flagged:
modeladmin.message_user(
request,
f"Report(s) ({", ".join(already_flagged)}) were already flagged.",
level=messages.WARNING,
)


class SACAdmin(admin.ModelAdmin):
"""
Support for read-only staff access, and control of what fields are present and
Expand All @@ -41,6 +115,7 @@ def has_view_permission(self, request, obj=None):
"report_id",
"cognizant_agency",
"oversight_agency",
"submission_status",
)
list_filter = [
"cognizant_agency",
Expand All @@ -50,6 +125,7 @@ def has_view_permission(self, request, obj=None):
]
readonly_fields = ("submitted_by",)
search_fields = ("general_information__auditee_uei", "report_id")
actions = [revert_to_in_progress, flag_for_removal]


class AccessAdmin(admin.ModelAdmin):
Expand Down
67 changes: 66 additions & 1 deletion backend/audit/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
from django.contrib.messages.storage.fallback import FallbackStorage
from .models import SacValidationWaiver, SingleAuditChecklist
from .models.models import STATUS
from .admin import SacValidationWaiverAdmin
from .admin import (
SACAdmin,
SacValidationWaiverAdmin,
flag_for_removal,
revert_to_in_progress,
)
from django.utils import timezone
from model_bakery import baker
from django.contrib.sessions.middleware import SessionMiddleware
Expand Down Expand Up @@ -161,3 +166,63 @@ def test_handle_auditee_certification(self):
# Checking results
self.sac.refresh_from_db()
self.assertEqual(self.sac.submission_status, STATUS.AUDITEE_CERTIFIED)


class TestAdminActions(TestCase):
def setUp(self):
self.site = AdminSite()
self.admin = SACAdmin(SingleAuditChecklist, self.site)
self.request = RequestFactory().get("/admin/audit/singleauditchecklist/")
self.request.user = baker.make(User, is_staff=True)
self.request.session = {}
self.request._messages = FallbackStorage(self.request)

# Sample records
self.report1 = baker.make(
SingleAuditChecklist,
report_id="RPT001",
submission_status=STATUS.FLAGGED_FOR_REMOVAL,
)
self.report2 = baker.make(
SingleAuditChecklist,
report_id="RPT002",
submission_status=STATUS.IN_PROGRESS,
)

def test_revert_to_in_progress_success(self):
queryset = SingleAuditChecklist.objects.filter(report_id="RPT001")
revert_to_in_progress(self.admin, self.request, queryset)

self.report1.refresh_from_db()
self.assertEqual(self.report1.submission_status, STATUS.IN_PROGRESS)
messages = [m.message for m in self.request._messages]
self.assertIn(
"Successfully reverted report(s) (RPT001) back to In Progress.", messages
)

def test_revert_to_in_progress_failure(self):
queryset = SingleAuditChecklist.objects.filter(report_id="RPT002")
revert_to_in_progress(self.admin, self.request, queryset)

self.report2.refresh_from_db()
self.assertEqual(self.report2.submission_status, STATUS.IN_PROGRESS)
messages = [m.message for m in self.request._messages]
self.assertIn("Report RPT002 is not flagged for removal.", messages)

def test_flag_for_removal_success(self):
queryset = SingleAuditChecklist.objects.filter(report_id="RPT002")
flag_for_removal(self.admin, self.request, queryset)

self.report2.refresh_from_db()
self.assertEqual(self.report2.submission_status, STATUS.FLAGGED_FOR_REMOVAL)
messages = [m.message for m in self.request._messages]
self.assertIn("Successfully flagged report(s) (RPT002) for removal.", messages)

def test_flag_for_removal_already_flagged(self):
queryset = SingleAuditChecklist.objects.filter(report_id="RPT001")
flag_for_removal(self.admin, self.request, queryset)

self.report1.refresh_from_db()
self.assertEqual(self.report1.submission_status, STATUS.FLAGGED_FOR_REMOVAL)
messages = [m.message for m in self.request._messages]
self.assertIn("Report(s) (RPT001) were already flagged.", messages)
6 changes: 4 additions & 2 deletions backend/audit/views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render, redirect
from django.db import transaction
from django.db.models import F
from django.db.models import F, Q
from django.db.transaction import TransactionManagementError
from django.core.exceptions import BadRequest, PermissionDenied, ValidationError
from django.contrib.auth.mixins import LoginRequiredMixin
Expand Down Expand Up @@ -125,7 +125,9 @@ def fetch_my_submissions(cls, user):
"""
accesses = Access.objects.filter(user=user)
sac_ids = [access.sac.id for access in accesses]
data = SingleAuditChecklist.objects.filter(id__in=sac_ids).values(
data = SingleAuditChecklist.objects.filter(
Q(id__in=sac_ids) & ~Q(submission_status=STATUS.FLAGGED_FOR_REMOVAL)
).values(
"report_id",
"submission_status",
auditee_uei=F("general_information__auditee_uei"),
Expand Down

0 comments on commit ca9a605

Please sign in to comment.