Coverage for tasks/srs.py: 67%

1"""

2 camcops_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

30 import datetime

31 from typing import List, Optional

32

33 from sqlalchemy.orm import Mapped

34

35 from camcops_server.cc_modules.cc_constants import CssClass

36 from camcops_server.cc_modules.cc_html import tr_qa

37 from camcops_server.cc_modules.cc_request import CamcopsRequest

38 from camcops_server.cc_modules.cc_sqla_coltypes import (

39 mapped_camcops_column,

40 ZERO_TO_10_CHECKER,

41)

42 from camcops_server.cc_modules.cc_summaryelement import SummaryElement

43 from camcops_server.cc_modules.cc_task import Task, TaskHasPatientMixin

44

45

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

47# SRS

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

49

50

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