Coverage for tasks/srs.py: 67%

42 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-15 14:23 +0100

1""" 

2camcops_server/tasks/srs.py 

3 

4=============================================================================== 

5 

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

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

8 

9 This file is part of CamCOPS. 

10 

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. 

15 

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. 

20 

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

23 

24=============================================================================== 

25 

26- By Joe Kearney, Rudolf Cardinal. 

27 

28""" 

29 

30import datetime 

31from typing import List, Optional 

32 

33from sqlalchemy.orm import Mapped 

34 

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 mapped_camcops_column, 

40 ZERO_TO_10_CHECKER, 

41) 

42from camcops_server.cc_modules.cc_summaryelement import SummaryElement 

43from camcops_server.cc_modules.cc_task import Task, TaskHasPatientMixin 

44 

45 

46# ============================================================================= 

47# SRS 

48# ============================================================================= 

49 

50 

51class Srs(TaskHasPatientMixin, Task): # type: ignore[misc] 

52 """ 

53 Server implementation of the SRS task. 

54 """ 

55 

56 __tablename__ = "srs" 

57 shortname = "SRS" 

58 provides_trackers = True 

59 

60 COMPLETED_BY_SELF = 0 

61 COMPLETED_BY_OTHER = 1 

62 

63 VAS_MIN_INT = 0 

64 VAS_MAX_INT = 10 

65 

66 q_session: Mapped[Optional[int]] = mapped_camcops_column( 

67 comment="Session number" 

68 ) 

69 q_date: Mapped[Optional[datetime.date]] = mapped_camcops_column( 

70 comment="Session date" 

71 ) 

72 q_relationship: Mapped[Optional[float]] = mapped_camcops_column( 

73 comment="Rating of patient-therapist relationship (0-10, 10 better)", 

74 permitted_value_checker=ZERO_TO_10_CHECKER, 

75 ) 

76 q_goals: Mapped[Optional[float]] = mapped_camcops_column( 

77 comment="Rating for topics discussed (0-10, 10 better)", 

78 permitted_value_checker=ZERO_TO_10_CHECKER, 

79 ) 

80 q_approach: Mapped[Optional[float]] = mapped_camcops_column( 

81 comment="Rating for therapist's approach (0-10, 10 better)", 

82 permitted_value_checker=ZERO_TO_10_CHECKER, 

83 ) 

84 q_overall: Mapped[Optional[float]] = mapped_camcops_column( 

85 comment="Overall rating (0-10, 10 better)", 

86 permitted_value_checker=ZERO_TO_10_CHECKER, 

87 ) 

88 

89 @staticmethod 

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

91 _ = req.gettext 

92 return _("Session Rating Scale") 

93 

94 def is_complete(self) -> bool: 

95 required_always = [ 

96 "q_session", 

97 "q_date", 

98 "q_relationship", 

99 "q_goals", 

100 "q_approach", 

101 "q_overall", 

102 ] 

103 for field in required_always: 

104 if getattr(self, field) is None: 

105 return False 

106 return True 

107 

108 def get_summaries(self, req: CamcopsRequest) -> List[SummaryElement]: 

109 return self.standard_task_summary_fields() 

110 

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

112 fields = ["q_relationship", "q_goals", "q_approach", "q_overall"] 

113 q_a = "" 

114 for field in fields: 

115 question = field.split("_")[1].capitalize() 

116 q_a += tr_qa(question, getattr(self, field)) 

117 

118 return f""" 

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

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

121 {self.get_is_complete_tr(req)} 

122 {tr_qa("Session number", self.q_session)} 

123 </table> 

124 </div> 

125 <div class="{CssClass.EXPLANATION}"> 

126 Scores represent a selection on a scale from 

127 {self.VAS_MIN_INT} to {self.VAS_MAX_INT} 

128 ({self.VAS_MAX_INT} better). Scores indicate the patient’s 

129 feelings about different aspects of the day’s therapy session. 

130 </div> 

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

132 <tr> 

133 <th width="60%">Question</th> 

134 <th width="40%">Answer</th> 

135 </tr> 

136 {q_a} 

137 </table> 

138 <div class="{CssClass.FOOTNOTES}"> 

139 </div> 

140 """