Coverage for postrfp/buyer/api/endpoints/reports/qtextxlsx.py: 100%
37 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
1from io import BytesIO
3from sqlalchemy.orm import subqueryload
4from sqlalchemy.orm.session import Session
5import xlsxwriter # type: ignore[import]
7from postrfp.authorisation import perms
8from postrfp.shared import fetch
9from postrfp.shared.decorators import http
10from postrfp.model.project import Project
11from postrfp.model import QuestionInstance, Label, User
12from postrfp.buyer.api import authorise
13from postrfp.shared.constants import MimeTypes
14from postrfp.shared.response import XAccelResponse
16from .responses import attachment
19def _generate_xlsx(session: Session, project: Project) -> BytesIO:
20 q = (
21 session.query(QuestionInstance)
22 .filter(QuestionInstance.project == project)
23 .options(subqueryload(QuestionInstance.question_def))
24 .order_by(QuestionInstance.b36_number)
25 )
27 buff = BytesIO()
28 workbook = xlsxwriter.Workbook(buff, {"in_memory": True})
29 worksheet = workbook.add_worksheet()
31 for idx, qi in enumerate(q):
32 worksheet.write(idx, 0, qi.number)
33 worksheet.write(idx, 1, qi.question_def.title)
34 elements = qi.question_def.elements
35 col = 2
36 for element in elements:
37 if isinstance(element, Label):
38 worksheet.write(idx, col, element.label)
39 col = col + 1
40 workbook.close()
41 buff.seek(0)
42 return buff
45@http
46def get_project_report_qtext(
47 session: Session, user: User, project_id: int
48) -> XAccelResponse:
49 """
50 Generate a spreadsheet with one row for each question and one column for title and then each
51 Label (question text) element in the question.
53 Useful for checking all the text in a questionnaire.
54 """
55 project = fetch.project(session, project_id)
56 authorise.check(user, perms.PROJECT_ACCESS, project=project, deny_restricted=True)
57 buff = _generate_xlsx(session, project)
58 buff.seek(0)
59 return attachment(buff.read(), MimeTypes.XLSX.value, f"{project.title[:25]}.xlsx")