diff --git a/backend/core/generators.py b/backend/core/generators.py new file mode 100644 index 000000000..ec85c8976 --- /dev/null +++ b/backend/core/generators.py @@ -0,0 +1,44 @@ +import os +from icecream import ic +from .models import * +from math import ceil + + +def gen_audit_context(id): + context = dict() + audit = ComplianceAssessment.objects.get(id=id) + + authors = ", ".join([a.email for a in audit.authors.all()]) + reviewers = ", ".join([a.email for a in audit.reviewers.all()]) + + cnt_per_result = audit.get_requirements_result_count() + ic(cnt_per_result) + total = sum([res[0] for res in cnt_per_result]) + perc_res = [ + ceil((res[0] / total) * 100) if total > 0 else 0 for res in cnt_per_result + ] + ic(perc_res) + context = { + "name": audit.name, + "framework": audit.framework.name, + "date": now().strftime("%Y-%m-%d %H:%M"), + "contributors": f"{authors}\n{reviewers}", + "description": audit.description, + "domain": audit.project, + "observation": audit.observation, + "req": { + "total": total, + "compliant": cnt_per_result[3][0], + "part_compliant": cnt_per_result[1][0], + "non_compliant": cnt_per_result[2][0], + "not_applicable": cnt_per_result[4][0], + "not_assessed": cnt_per_result[0][0], + "compliant_p": perc_res[3], + "part_compliant_p": perc_res[1], + "non_compliant_p": perc_res[2], + "not_applicable_p": perc_res[4], + "not_assessed_p": perc_res[0], + }, + } + + return context diff --git a/backend/core/templates/core/audit_report_template.docx b/backend/core/templates/core/audit_report_template.docx new file mode 100644 index 000000000..78768e133 Binary files /dev/null and b/backend/core/templates/core/audit_report_template.docx differ diff --git a/backend/core/views.py b/backend/core/views.py index 1a380c553..9e89c3a97 100644 --- a/backend/core/views.py +++ b/backend/core/views.py @@ -28,6 +28,7 @@ import base64 from docxtpl import DocxTemplate +from .generators import gen_audit_context from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page @@ -2157,20 +2158,18 @@ def compliance_assessment_csv(self, request, pk): @action(detail=True, methods=["get"]) def word_report(self, request, pk): - document = Document() - document.add_heading("Sales Performance Report", 0) - document.add_heading(f"ID: {pk}", 1) - - document.add_paragraph( - "Report generated on: {}".format(now().strftime("%Y-%m-%d %H:%M:%S")) - ) - - document.add_page_break() - - document.add_paragraph("ok then.") - + template_path = ( + Path(settings.BASE_DIR) + / "core" + / "templates" + / "core" + / "audit_report_template.docx" + ) + doc = DocxTemplate(template_path) + context = gen_audit_context(pk) + doc.render(context) buffer_doc = io.BytesIO() - document.save(buffer_doc) + doc.save(buffer_doc) buffer_doc.seek(0) response = HttpResponse( diff --git a/frontend/src/routes/(app)/(internal)/compliance-assessments/[id=uuid]/export/word/+server.ts b/frontend/src/routes/(app)/(internal)/compliance-assessments/[id=uuid]/export/word/+server.ts index a41550235..1a32f73d3 100644 --- a/frontend/src/routes/(app)/(internal)/compliance-assessments/[id=uuid]/export/word/+server.ts +++ b/frontend/src/routes/(app)/(internal)/compliance-assessments/[id=uuid]/export/word/+server.ts @@ -12,7 +12,7 @@ export const GET: RequestHandler = async ({ fetch, params }) => { error(400, 'Error fetching the Word file'); } - const fileName = `audit-${params.id}-${new Date().toISOString()}.docx`; + const fileName = `audit-report-${new Date().toISOString()}.docx`; return new Response(await res.blob(), { headers: {