Coverage for tasks/ors.py : 58%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python
3"""
4camcops_server/tasks/ors.py
6===============================================================================
8 Copyright (C) 2012-2020 Rudolf Cardinal (rudolf@pobox.com).
10 This file is part of CamCOPS.
12 CamCOPS is free software: you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation, either version 3 of the License, or
15 (at your option) any later version.
17 CamCOPS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
25===============================================================================
27- By Joe Kearney, Rudolf Cardinal.
29"""
31from typing import List
33from sqlalchemy.sql.sqltypes import Date, Float, Integer, UnicodeText
35from camcops_server.cc_modules.cc_constants import CssClass
36from camcops_server.cc_modules.cc_html import tr_qa
37from camcops_server.cc_modules.cc_request import CamcopsRequest
38from camcops_server.cc_modules.cc_sqla_coltypes import (
39 CamcopsColumn,
40 ZERO_TO_10_CHECKER
41)
42from camcops_server.cc_modules.cc_summaryelement import SummaryElement
43from camcops_server.cc_modules.cc_task import (
44 Task,
45 TaskHasPatientMixin,
46)
49# =============================================================================
50# ORS
51# =============================================================================
53class Ors(TaskHasPatientMixin, Task):
54 """
55 Server implementation of the PHQ9 task.
56 """
57 __tablename__ = "ors"
58 shortname = "ORS"
59 provides_trackers = True
61 COMPLETED_BY_SELF = 0
62 COMPLETED_BY_OTHER = 1
64 VAS_MIN_INT = 0
65 VAS_MAX_INT = 10
67 q_session = CamcopsColumn("q_session", Integer, comment="Session number")
68 q_date = CamcopsColumn("q_date", Date, comment="Session date")
69 q_who = CamcopsColumn("q_who", Integer, comment="Completed by")
70 q_who_other = CamcopsColumn(
71 "q_who_other", UnicodeText, comment="Completed by other: who?")
72 q_individual = CamcopsColumn(
73 "q_individual", Float,
74 comment="Individual rating (0-10, 10 better)",
75 permitted_value_checker=ZERO_TO_10_CHECKER)
76 q_interpersonal = CamcopsColumn(
77 "q_interpersonal", Float,
78 comment="Interpersonal rating (0-10, 10 better)",
79 permitted_value_checker=ZERO_TO_10_CHECKER)
80 q_social = CamcopsColumn(
81 "q_social", Float,
82 comment="Social rating (0-10, 10 better)",
83 permitted_value_checker=ZERO_TO_10_CHECKER)
84 q_overall = CamcopsColumn(
85 "q_overall", Float,
86 comment="Overall rating (0-10, 10 better)",
87 permitted_value_checker=ZERO_TO_10_CHECKER)
89 @staticmethod
90 def longname(req: "CamcopsRequest") -> str:
91 _ = req.gettext
92 return _("Outcome Rating Scale")
94 def is_complete(self) -> bool:
95 required_always = [
96 "q_session",
97 "q_date",
98 "q_who",
99 "q_individual",
100 "q_interpersonal",
101 "q_social",
102 "q_overall",
103 ]
104 for field in required_always:
105 if getattr(self, field) is None:
106 return False
107 if self.q_who == self.COMPLETED_BY_OTHER:
108 if not self.q_who_other:
109 return False
110 return True
112 def get_summaries(self, req: CamcopsRequest) -> List[SummaryElement]:
113 return self.standard_task_summary_fields()
115 def who(self) -> str:
116 if self.q_who == self.COMPLETED_BY_OTHER:
117 return "Other: " + (self.q_who_other or "Unknown")
118 if self.q_who == self.COMPLETED_BY_SELF:
119 return "Patient"
120 return "Unknown"
122 def get_task_html(self, req: CamcopsRequest) -> str:
123 fields = ["q_individual", "q_interpersonal", "q_social", "q_overall"]
124 q_a = ""
125 for field in fields:
126 question = field.split("_")[1].capitalize()
127 q_a += tr_qa(question, getattr(self, field))
129 return f"""
130 <div class="{CssClass.SUMMARY}">
131 <table class="{CssClass.SUMMARY}">
132 {self.get_is_complete_tr(req)}
133 {tr_qa("Session number", self.q_session)}
134 {tr_qa("Completed by", self.who())}
135 </table>
136 </div>
137 <div class="{CssClass.EXPLANATION}">
138 Scores represent a selection on a scale from
139 {self.VAS_MIN_INT} to {self.VAS_MAX_INT}
140 ({self.VAS_MAX_INT} better). Scores reflect the patient’s
141 feelings about the indicated life areas over the past week.
142 </div>
143 <table class="{CssClass.TASKDETAIL}">
144 <tr>
145 <th width="60%">Question</th>
146 <th width="40%">Answer</th>
147 </tr>
148 {q_a}
149 </table>
150 <div class="{CssClass.FOOTNOTES}">
151 </div>
152 """