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

1#!/usr/bin/env python 

2 

3""" 

4camcops_server/tasks/cpft_research_preferences.py 

5 

6=============================================================================== 

7 

8 Copyright (C) 2012, University of Cambridge, Department of Psychiatry. 

9 Created by Rudolf Cardinal (rnc1001@cam.ac.uk). 

10 

11 This file is part of CamCOPS. 

12 

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. 

17 

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. 

22 

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/>. 

25 

26=============================================================================== 

27 

28**CPFT Research Preferences task.** 

29 

30""" 

31 

32from typing import Any, Dict, Optional, Tuple, Type 

33 

34from sqlalchemy.ext.declarative import DeclarativeMeta 

35 

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 

46 

47 

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 ) 

73 

74 super().__init__(name, bases, classdict) 

75 

76 

77class CpftResearchPreferences( 

78 TaskHasPatientMixin, Task, metaclass=CpftResearchPreferencesMetaclass 

79): 

80 """ 

81 Server implementation of the CPFT_Research_Preferences task 

82 """ 

83 

84 __tablename__ = "cpft_research_preferences" 

85 shortname = "CPFT_Research_Preferences" 

86 provides_trackers = False 

87 

88 FN_CONTACT_PREFERENCE = "contact_preference" 

89 FN_CONTACT_BY_EMAIL = "contact_by_email" 

90 FN_RESEARCH_OPT_OUT = "research_opt_out" 

91 

92 MANDATORY_FIELD_NAMES = [ 

93 FN_CONTACT_PREFERENCE, 

94 FN_CONTACT_BY_EMAIL, 

95 FN_RESEARCH_OPT_OUT, 

96 ] 

97 

98 @staticmethod 

99 def longname(req: "CamcopsRequest") -> str: 

100 _ = req.gettext 

101 return _("CPFT Research Preferences") 

102 

103 def is_complete(self) -> bool: 

104 if not self.field_contents_valid(): 

105 return False 

106 

107 contact_preference = getattr(self, self.FN_CONTACT_PREFERENCE) 

108 if contact_preference is None: 

109 return False 

110 

111 if contact_preference != "R": 

112 return getattr(self, self.FN_CONTACT_BY_EMAIL) is not None 

113 

114 return True 

115 

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 ] 

131 

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 """ 

146 

147 return html 

148 

149 def get_contact_preference_answer( 

150 self, req: CamcopsRequest 

151 ) -> Optional[str]: 

152 

153 answer = getattr(self, self.FN_CONTACT_PREFERENCE) 

154 if answer is None: 

155 return None 

156 

157 return self.xstring(req, answer) 

158 

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)) 

163 

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))