Source code for camcops_server.tasks.apeqpt

#!/usr/bin/env python

"""
camcops_server/tasks/apeqpt.py

===============================================================================

    Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CamCOPS.

    CamCOPS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CamCOPS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.

===============================================================================

- By Joe Kearney, Rudolf Cardinal.

"""

from typing import Dict, List

from sqlalchemy.sql.sqltypes import Integer, UnicodeText

from camcops_server.cc_modules.cc_constants import CssClass
from camcops_server.cc_modules.cc_fhir import (
    FHIRAnsweredQuestion,
    FHIRAnswerType,
    FHIRQuestionType,
)
from camcops_server.cc_modules.cc_html import tr_qa
from camcops_server.cc_modules.cc_request import CamcopsRequest
from camcops_server.cc_modules.cc_sqla_coltypes import (
    CamcopsColumn,
    PendulumDateTimeAsIsoTextColType,
    ZERO_TO_ONE_CHECKER,
    ZERO_TO_TWO_CHECKER,
    ZERO_TO_FOUR_CHECKER,
)
from camcops_server.cc_modules.cc_summaryelement import SummaryElement
from camcops_server.cc_modules.cc_task import get_from_dict, Task


# =============================================================================
# APEQPT
# =============================================================================


[docs]class Apeqpt(Task): """ Server implementation of the APEQPT task. """ __tablename__ = "apeqpt" shortname = "APEQPT" provides_trackers = True # todo: remove q_datetime (here and in the C++) -- it duplicates when_created # noqa q_datetime = CamcopsColumn( "q_datetime", PendulumDateTimeAsIsoTextColType, comment="Date/time the assessment tool was completed", ) N_CHOICE_QUESTIONS = 3 q1_choice = CamcopsColumn( "q1_choice", Integer, comment="Enough information was provided (0 no, 1 yes)", permitted_value_checker=ZERO_TO_ONE_CHECKER, ) q2_choice = CamcopsColumn( "q2_choice", Integer, comment="Treatment preference (0 no, 1 yes)", permitted_value_checker=ZERO_TO_ONE_CHECKER, ) q3_choice = CamcopsColumn( "q3_choice", Integer, comment="Preference offered (0 no, 1 yes, 2 N/A)", permitted_value_checker=ZERO_TO_TWO_CHECKER, ) q1_satisfaction = CamcopsColumn( "q1_satisfaction", Integer, comment=( "Patient satisfaction (0 not at all satisfied - " "4 completely satisfied)" ), permitted_value_checker=ZERO_TO_FOUR_CHECKER, ) q2_satisfaction = CamcopsColumn( "q2_satisfaction", UnicodeText, comment="Service experience" ) MAIN_QUESTIONS = [ "q_datetime", "q1_choice", "q2_choice", "q3_choice", "q1_satisfaction", ]
[docs] @staticmethod def longname(req: "CamcopsRequest") -> str: _ = req.gettext return _( "Assessment Patient Experience Questionnaire " "for Psychological Therapies" )
[docs] def is_complete(self) -> bool: if self.any_fields_none(self.MAIN_QUESTIONS): return False if not self.field_contents_valid(): return False return True
[docs] def get_summaries(self, req: CamcopsRequest) -> List[SummaryElement]: return self.standard_task_summary_fields()
[docs] def get_task_html(self, req: CamcopsRequest) -> str: c_dict = { 0: "0 — " + self.wxstring(req, "a0_choice"), 1: "1 — " + self.wxstring(req, "a1_choice"), 2: "2 — " + self.wxstring(req, "a2_choice"), } s_dict = { 0: "0 — " + self.wxstring(req, "a0_satisfaction"), 1: "1 — " + self.wxstring(req, "a1_satisfaction"), 2: "2 — " + self.wxstring(req, "a2_satisfaction"), 3: "3 — " + self.wxstring(req, "a3_satisfaction"), 4: "4 — " + self.wxstring(req, "a4_satisfaction"), } q_a = "" for i in range(1, self.N_CHOICE_QUESTIONS + 1): nstr = str(i) q_a += tr_qa( self.wxstring(req, "q" + nstr + "_choice"), get_from_dict(c_dict, getattr(self, "q" + nstr + "_choice")), ) q_a += tr_qa( self.wxstring(req, "q1_satisfaction"), get_from_dict(s_dict, self.q1_satisfaction), ) q_a += tr_qa( self.wxstring(req, "q2_satisfaction"), self.q2_satisfaction, default="", ) return f""" <div class="{CssClass.SUMMARY}"> <table class="{CssClass.SUMMARY}"> {self.get_is_complete_tr(req)} </table> </div> <div class="{CssClass.EXPLANATION}"> Patient satisfaction rating for service provided. The service is rated on choice offered and general satisfaction. </div> <table class="{CssClass.TASKDETAIL}"> <tr> <th width="60%">Question</th> <th width="40%">Answer</th> </tr> {q_a} </table> """
[docs] def get_fhir_questionnaire( self, req: "CamcopsRequest" ) -> List[FHIRAnsweredQuestion]: items = [] # type: List[FHIRAnsweredQuestion] yes_no_options = {} # type: Dict[int, str] for index in range(2): yes_no_options[index] = self.wxstring(req, f"a{index}_choice") items.append( FHIRAnsweredQuestion( qname="q1_choice", qtext=self.wxstring(req, "q1_choice"), qtype=FHIRQuestionType.CHOICE, answer_type=FHIRAnswerType.INTEGER, answer=self.q1_choice, answer_options=yes_no_options, ) ) items.append( FHIRAnsweredQuestion( qname="q2_choice", qtext=self.wxstring(req, "q2_choice"), qtype=FHIRQuestionType.CHOICE, answer_type=FHIRAnswerType.INTEGER, answer=self.q2_choice, answer_options=yes_no_options, ) ) yes_no_na_options = yes_no_options.copy() yes_no_na_options[2] = self.wxstring(req, "a2_choice") items.append( FHIRAnsweredQuestion( qname="q3_choice", qtext=self.wxstring(req, "q3_choice"), qtype=FHIRQuestionType.CHOICE, answer_type=FHIRAnswerType.INTEGER, answer=self.q3_choice, answer_options=yes_no_na_options, ) ) satisfaction_options = {} # type: Dict[int, str] for index in range(5): satisfaction_options[index] = self.wxstring( req, f"a{index}_satisfaction" ) items.append( FHIRAnsweredQuestion( qname="q1_satisfaction", qtext=self.xstring(req, "q1_satisfaction"), qtype=FHIRQuestionType.CHOICE, answer_type=FHIRAnswerType.INTEGER, answer=self.q1_satisfaction, answer_options=satisfaction_options, ) ) items.append( FHIRAnsweredQuestion( qname="q2_satisfaction", qtext=self.xstring(req, "q2_satisfaction"), qtype=FHIRQuestionType.STRING, answer_type=FHIRAnswerType.STRING, answer=self.q2_satisfaction, ) ) return items