Skip to content

Commit

Permalink
feat: create action plan pdf
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohamed-Hacene committed May 15, 2024
1 parent 274a8ea commit d0346a3
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
60 changes: 60 additions & 0 deletions backend/core/templates/core/action_plan_pdf.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{% extends 'core/base_pdf.html' %}
{% block content %}
{% load i18n core_extras %}

<style>
table, th, td {
border: 1px solid black;
}
</style>

<main class="p-2 m-2 main">
<h1 class="flex justify-center">Action plan</h1>
<div class="bg-white p-2 m-2 space-x-3 flex flex-row justify-center">
<p class="font-semibold text-lg"> {% trans "Domain" %}: {{ compliance_assessment.project.folder }}</p>
<p class="font-semibold text-lg">/</p>
<p class="font-semibold text-lg"> {% trans "Project" %}: {{ compliance_assessment.project.name }}</p>
<p class="font-semibold text-lg">/</p>
<p class="font-semibold text-lg"> {% trans "Audit" %}: {{ compliance_assessment.name }} - {{ compliance_assessment.version }}</p>
</div>
<p class="p-2 m-2 text-lg font-semibold"> {% trans "Associated applied controls" %}: </p>
<p class="m-2 p-2">{% trans "Separated by status and sorted by eta" %}</p>
{% for status, applied_controls in context.items%}
{% for status_color, color in color_map.items %}
{% if status_color == status %}
<p class="flex p-2 m-2 text-lg font-semibold justify-center" style="background-color: {{color}}">{% trans status|title %}:</p>
{% endif %}
{% endfor %}
<div class="bg-white p-2 m-2 shadow overflow-hidden rounded-lg flex flex-row">
<div class="flex w-full">
<table class="w-full p-2 mt-2">
<thead>
<tr class="uppercase">
<th class="text-md p-2 text-center">{% trans "Name" %}</th>
<th class="text-md p-2 text-center">{% trans "Description" %}</th>
<th class="text-md p-2 text-center">{% trans "Category" %}</th>
<th class="text-md p-2 text-center">{% trans "ETA" %}</th>
<th class="text-md p-2 text-center">{% trans "Expiry date" %}</th>
<th class="text-md p-2 text-center">{% trans "Effort" %}</th>
<th class="text-md p-2 text-center">{% trans "Requirements count" %}</th>
</tr>
</thead>
<tbody>
{% for applied_control in applied_controls %}
<tr>
<td class="text-md p-2 text-center">{{ applied_control.name }}</td>
<td class="text-md p-2 text-center">{{ applied_control.description }}</td>
<td class="text-md p-2 text-center">{{ applied_control.category }}</td>
<td class="text-md p-2 text-center">{{ applied_control.eta }}</td>
<td class="text-md p-2 text-center">{{ applied_control.expiry_date }}</td>
<td class="text-md p-2 text-center">{{ applied_control.effort }}</td>
<td class="text-md p-2 text-center">{% get_requirements_count applied_control compliance_assessment %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endfor %}
</main>
{% endblock %}
7 changes: 7 additions & 0 deletions backend/core/templatetags/core_extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from ciso_assistant.settings import VERSION, BUILD, DEBUG
from core.utils import COUNTRY_FLAGS, LANGUAGES
from core.models import RequirementAssessment

register = template.Library()

Expand All @@ -15,6 +16,12 @@ def app_version():
def app_build():
return f"{BUILD} (dev)" if DEBUG else BUILD

@register.simple_tag()
def get_requirements_count(applied_control, compliance_assessment):
return RequirementAssessment.objects.filter(
compliance_assessment=compliance_assessment
).filter(applied_controls=applied_control).count()


@register.filter("class")
def _class(obj):
Expand Down
43 changes: 43 additions & 0 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,49 @@ def action_plan(self, request, pk):
applied_control
)
return Response(response)

@action(detail=True, name="Get action plan PDF")
def action_plan_pdf(self, request, pk):
(object_ids_view, _, _) = RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), request.user, ComplianceAssessment
)
if UUID(pk) in object_ids_view:
context = {
"planned": list(),
"active": list(),
"inactive": list(),
"no status": list(),
}
color_map = {
"planned": "#93c5fd",
"active": "#86efac",
"inactive": "#fca5a5",
"no status": "#e5e7eb",
}
compliance_assessment_object = self.get_object()
requirement_assessments_objects = (
compliance_assessment_object.get_requirement_assessments()
)
applied_controls = AppliedControl.objects.filter(
requirement_assessments__in=requirement_assessments_objects
).distinct().order_by("eta")
for applied_control in applied_controls:
context[applied_control.status].append(
applied_control
) if applied_control.status else context["no status"].append(
applied_control
)
data = {
"color_map": color_map,
"context": context,
"compliance_assessment": compliance_assessment_object,
}
html = render_to_string("core/action_plan_pdf.html", data)
pdf_file = HTML(string=html).write_pdf()
response = HttpResponse(pdf_file, content_type="application/pdf")
return response
else:
return Response({"error": "Permission denied"})

def perform_create(self, serializer):
"""
Expand Down

0 comments on commit d0346a3

Please sign in to comment.