Coverage for tasks/progressnote.py: 70%
33 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-15 14:23 +0100
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-15 14:23 +0100
1"""
2camcops_server/tasks/progressnote.py
4===============================================================================
6 Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
7 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
9 This file is part of CamCOPS.
11 CamCOPS is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 CamCOPS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
24===============================================================================
26"""
28from typing import Dict, List, Optional
30import cardinal_pythonlib.rnc_web as ws
31from sqlalchemy.orm import Mapped, mapped_column
32from sqlalchemy.sql.sqltypes import UnicodeText
34from camcops_server.cc_modules.cc_constants import CssClass
35from camcops_server.cc_modules.cc_ctvinfo import CtvInfo
36from camcops_server.cc_modules.cc_html import answer
37from camcops_server.cc_modules.cc_request import CamcopsRequest
38from camcops_server.cc_modules.cc_snomed import (
39 SnomedConcept,
40 SnomedExpression,
41 SnomedLookup,
42)
43from camcops_server.cc_modules.cc_task import (
44 Task,
45 TaskHasClinicianMixin,
46 TaskHasPatientMixin,
47)
48from camcops_server.cc_modules.cc_text import SS
51# =============================================================================
52# ProgressNote
53# =============================================================================
56class ProgressNote(TaskHasPatientMixin, TaskHasClinicianMixin, Task): # type: ignore[misc] # noqa: E501
57 """
58 Server implementation of the ProgressNote task.
59 """
61 __tablename__ = "progressnote"
62 shortname = "ProgressNote"
63 info_filename_stem = "clinical"
65 location: Mapped[Optional[str]] = mapped_column(
66 UnicodeText, comment="Location"
67 )
68 note: Mapped[Optional[str]] = mapped_column(
69 UnicodeText, comment="Clinical note"
70 )
72 @staticmethod
73 def longname(req: "CamcopsRequest") -> str:
74 _ = req.gettext
75 return _("Clinical progress note")
77 def get_clinical_text(self, req: CamcopsRequest) -> List[CtvInfo]:
78 return [CtvInfo(content=ws.webify(self.note))]
80 def is_complete(self) -> bool:
81 return bool(self.note)
83 def get_task_html(self, req: CamcopsRequest) -> str:
84 # Avoid tables - PDF generator crashes if text is too long.
85 return f"""
86 <div class="{CssClass.HEADING}">
87 {req.sstring(SS.LOCATION)}
88 </div>
89 <div>
90 {answer(ws.webify(self.location),
91 default_for_blank_strings=True)}
92 </div>
93 <div class="{CssClass.HEADING}">
94 {req.sstring(SS.NOTE)}
95 </div>
96 <div>
97 {answer(self.note, default_for_blank_strings=True)}
98 </div>
99 """
101 def get_snomed_codes(self, req: CamcopsRequest) -> List[SnomedExpression]:
102 refinement = {} # type: Dict[SnomedConcept, str]
103 if self.note:
104 refinement[req.snomed(SnomedLookup.CLINICAL_NOTE)] = self.note
105 codes = [
106 SnomedExpression(
107 req.snomed(SnomedLookup.PROGRESS_NOTE_PROCEDURE),
108 refinement=refinement or None, # type: ignore[arg-type]
109 )
110 ]
111 return codes