Coverage for tasks/cpft_research_preferences.py: 60%
48 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-08 23:14 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-08 23:14 +0000
1#!/usr/bin/env python
3"""
4camcops_server/tasks/cpft_research_preferences.py
6===============================================================================
8 Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
9 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
11 This file is part of CamCOPS.
13 CamCOPS is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
18 CamCOPS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
26===============================================================================
28**CPFT Research Preferences task.**
30"""
32from typing import Any, Dict, Optional, Tuple, Type
34from sqlalchemy.ext.declarative import DeclarativeMeta
36from camcops_server.cc_modules.cc_constants import CssClass, PV
37from camcops_server.cc_modules.cc_html import tr_qa, get_yes_no_unknown
38from camcops_server.cc_modules.cc_request import CamcopsRequest
39from camcops_server.cc_modules.cc_sqla_coltypes import (
40 BoolColumn,
41 CamcopsColumn,
42 CharColType,
43 PermittedValueChecker,
44)
45from camcops_server.cc_modules.cc_task import Task, TaskHasPatientMixin
48class CpftResearchPreferencesMetaclass(DeclarativeMeta):
49 # noinspection PyInitNewSignature
50 def __init__(
51 cls: Type["CpftResearchPreferences"],
52 name: str,
53 bases: Tuple[Type, ...],
54 classdict: Dict[str, Any],
55 ) -> None:
56 setattr(
57 cls,
58 cls.FN_CONTACT_PREFERENCE,
59 CamcopsColumn(
60 cls.FN_CONTACT_PREFERENCE,
61 CharColType,
62 permitted_value_checker=PermittedValueChecker(
63 permitted_values=PV.RYG
64 ),
65 ),
66 )
67 setattr(
68 cls, cls.FN_CONTACT_BY_EMAIL, BoolColumn(cls.FN_CONTACT_BY_EMAIL)
69 )
70 setattr(
71 cls, cls.FN_RESEARCH_OPT_OUT, BoolColumn(cls.FN_RESEARCH_OPT_OUT)
72 )
74 super().__init__(name, bases, classdict)
77class CpftResearchPreferences(
78 TaskHasPatientMixin, Task, metaclass=CpftResearchPreferencesMetaclass
79):
80 """
81 Server implementation of the CPFT_Research_Preferences task
82 """
84 __tablename__ = "cpft_research_preferences"
85 shortname = "CPFT_Research_Preferences"
86 provides_trackers = False
88 FN_CONTACT_PREFERENCE = "contact_preference"
89 FN_CONTACT_BY_EMAIL = "contact_by_email"
90 FN_RESEARCH_OPT_OUT = "research_opt_out"
92 MANDATORY_FIELD_NAMES = [
93 FN_CONTACT_PREFERENCE,
94 FN_CONTACT_BY_EMAIL,
95 FN_RESEARCH_OPT_OUT,
96 ]
98 @staticmethod
99 def longname(req: "CamcopsRequest") -> str:
100 _ = req.gettext
101 return _("CPFT Research Preferences")
103 def is_complete(self) -> bool:
104 if not self.field_contents_valid():
105 return False
107 contact_preference = getattr(self, self.FN_CONTACT_PREFERENCE)
108 if contact_preference is None:
109 return False
111 if contact_preference != "R":
112 return getattr(self, self.FN_CONTACT_BY_EMAIL) is not None
114 return True
116 def get_task_html(self, req: CamcopsRequest) -> str:
117 rows = [
118 tr_qa(
119 self.wxstring(req, f"q_{self.FN_CONTACT_PREFERENCE}_short"),
120 self.get_contact_preference_answer(req),
121 ),
122 tr_qa(
123 self.wxstring(req, f"q_{self.FN_CONTACT_BY_EMAIL}_short"),
124 self.get_contact_by_email_answer(req),
125 ),
126 tr_qa(
127 self.wxstring(req, f"q_{self.FN_RESEARCH_OPT_OUT}_short"),
128 self.get_research_opt_out_answer(req),
129 ),
130 ]
132 html = f"""
133 <div class="{CssClass.SUMMARY}">
134 <table class="{CssClass.SUMMARY}">
135 {self.get_is_complete_tr(req)}
136 </table>
137 </div>
138 <table class="{CssClass.TASKDETAIL}">
139 <tr>
140 <th width="60%">Question</th>
141 <th width="40%">Answer</th>
142 </tr>
143 {''.join(rows)}
144 </table>
145 """
147 return html
149 def get_contact_preference_answer(
150 self, req: CamcopsRequest
151 ) -> Optional[str]:
153 answer = getattr(self, self.FN_CONTACT_PREFERENCE)
154 if answer is None:
155 return None
157 return self.xstring(req, answer)
159 def get_contact_by_email_answer(
160 self, req: CamcopsRequest
161 ) -> Optional[str]:
162 return get_yes_no_unknown(req, getattr(self, self.FN_CONTACT_BY_EMAIL))
164 def get_research_opt_out_answer(
165 self, req: CamcopsRequest
166 ) -> Optional[str]:
167 return get_yes_no_unknown(req, getattr(self, self.FN_RESEARCH_OPT_OUT))