Coverage for tasks/khandaker_insight_medical.py: 62%

63 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/khandaker_insight_medical.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""" 

29 

30# ============================================================================= 

31# Imports 

32# ============================================================================= 

33 

34from typing import Any, Dict, Tuple, Type 

35 

36import cardinal_pythonlib.rnc_web as ws 

37from sqlalchemy.ext.declarative import DeclarativeMeta 

38from sqlalchemy.sql.schema import Column 

39from sqlalchemy.sql.sqltypes import UnicodeText 

40 

41from camcops_server.cc_modules.cc_constants import CssClass 

42from camcops_server.cc_modules.cc_html import ( 

43 bold, 

44 get_yes_no_none, 

45 tr_span_col, 

46) 

47from camcops_server.cc_modules.cc_request import CamcopsRequest 

48from camcops_server.cc_modules.cc_sqla_coltypes import BoolColumn 

49from camcops_server.cc_modules.cc_task import Task, TaskHasPatientMixin 

50 

51 

52# ============================================================================= 

53# Constants 

54# ============================================================================= 

55 

56 

57class KQInfo(object): 

58 def __init__(self, stem: str, heading_xml: str = "") -> None: 

59 self.fieldname_yn = stem + "_yn" 

60 self.fieldname_comment = stem + "_comment" 

61 self.question_xmlstr = "q_" + stem 

62 self.heading_xmlstr = heading_xml 

63 

64 def has_heading(self) -> bool: 

65 return bool(self.heading_xmlstr) 

66 

67 

68QUESTIONS = [ 

69 KQInfo("cancer", "heading_cancer"), 

70 KQInfo("epilepsy", "heading_brain"), 

71 KQInfo("cva_headinjury_braintumour"), 

72 KQInfo("ms_pd_dementia"), 

73 KQInfo("cerebralpalsy_otherbrain"), 

74 KQInfo("visual_impairment"), 

75 KQInfo("heart_disorder", "heading_cardiovascular"), 

76 KQInfo("respiratory", "heading_respiratory"), 

77 KQInfo("gastrointestinal", "heading_gastrointestinal"), 

78 KQInfo("other_inflammatory", "heading_inflammatory"), 

79 KQInfo("musculoskeletal", "heading_musculoskeletal"), 

80 KQInfo("renal_urinary", "heading_renal_urinary"), 

81 KQInfo("dermatological", "heading_dermatological"), 

82 KQInfo("diabetes", "heading_endocrinological"), 

83 KQInfo("other_endocrinological"), 

84 KQInfo("haematological", "heading_haematological"), 

85 KQInfo("infections", "heading_infections"), 

86] 

87 

88X_TITLE = "title" 

89X_INSTRUCTION = "instruction" 

90X_HEADING_CONDITION = "heading_condition" 

91X_HEADING_YN = "heading_yn" 

92X_HEADING_COMMENT = "heading_comment" 

93X_COMMENT_HINT = "comment_hint" 

94 

95 

96# ============================================================================= 

97# Khandaker_1_MedicalHistory 

98# ============================================================================= 

99 

100 

101class KhandakerInsightMedicalMetaclass(DeclarativeMeta): 

102 # noinspection PyInitNewSignature 

103 def __init__( 

104 cls: Type["KhandakerInsightMedical"], 

105 name: str, 

106 bases: Tuple[Type, ...], 

107 classdict: Dict[str, Any], 

108 ) -> None: 

109 for qinfo in QUESTIONS: 

110 setattr(cls, qinfo.fieldname_yn, BoolColumn(qinfo.fieldname_yn)) 

111 setattr( 

112 cls, 

113 qinfo.fieldname_comment, 

114 Column(qinfo.fieldname_comment, UnicodeText), 

115 ) 

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

117 

118 

119class KhandakerInsightMedical( 

120 TaskHasPatientMixin, Task, metaclass=KhandakerInsightMedicalMetaclass 

121): 

122 """ 

123 Server implementation of the Khandaker_1_MedicalHistory task. 

124 """ 

125 

126 __tablename__ = "khandaker_1_medicalhistory" # NB historical name 

127 shortname = "Khandaker_Insight_Medical" 

128 info_filename_stem = "khandaker_insight_medical" 

129 

130 @staticmethod 

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

132 _ = req.gettext 

133 return _("Khandaker GM — Insight — Medical history") 

134 

135 def is_complete(self) -> bool: 

136 for qinfo in QUESTIONS: 

137 yn_value = getattr(self, qinfo.fieldname_yn) 

138 if yn_value is None: 

139 return False 

140 if yn_value: 

141 comment = getattr(self, qinfo.fieldname_comment) 

142 if not comment: 

143 return False 

144 return True 

145 

146 def get_task_html(self, req: CamcopsRequest) -> str: 

147 html = f""" 

148 <div class="{CssClass.SUMMARY}"> 

149 <table class="{CssClass.SUMMARY}"> 

150 {self.get_is_complete_tr(req)} 

151 </table> 

152 </div> 

153 <table class="{CssClass.TASKDETAIL}"> 

154 <tr> 

155 <th width="40%">{self.xstring(req, 

156 X_HEADING_CONDITION)}</th> 

157 <th width="20%">{self.xstring(req, X_HEADING_YN)}</th> 

158 <th width="40%">{self.xstring(req, X_HEADING_COMMENT)}</th> 

159 </tr> 

160 """ 

161 

162 for qinfo in QUESTIONS: 

163 if qinfo.has_heading(): 

164 html += tr_span_col( 

165 self.xstring(req, qinfo.heading_xmlstr), 

166 cols=3, 

167 tr_class=CssClass.SUBHEADING, 

168 ) 

169 yn_value = getattr(self, qinfo.fieldname_yn) 

170 yn_str = get_yes_no_none(req, yn_value) 

171 if yn_value: 

172 yn_str = bold(yn_str) 

173 comment_value = getattr(self, qinfo.fieldname_comment) 

174 html += f""" 

175 <tr> 

176 <td>{self.xstring(req, qinfo.question_xmlstr)}</td> 

177 <td>{yn_str}</td> 

178 <td>{bold(ws.webify(comment_value)) 

179 if comment_value else ""}</td> 

180 </tr> 

181 """ 

182 

183 html += "</table>" 

184 return html