meta-edc 1.1.18__py3-none-any.whl → 1.1.19__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of meta-edc might be problematic. Click here for more details.

Files changed (30) hide show
  1. meta_consent/admin/__init__.py +1 -0
  2. meta_consent/admin/subject_consent_spfq_admin.py +58 -0
  3. meta_consent/forms/__init__.py +2 -0
  4. meta_consent/forms/subject_consent_spfq_form.py +55 -0
  5. meta_consent/migrations/0033_historicalsubjectconsentspfq_subjectconsentspfq.py +615 -0
  6. meta_consent/models/__init__.py +2 -0
  7. meta_consent/models/subject_consent_spfq.py +103 -0
  8. {meta_edc-1.1.18.dist-info → meta_edc-1.1.19.dist-info}/METADATA +5 -5
  9. {meta_edc-1.1.18.dist-info → meta_edc-1.1.19.dist-info}/RECORD +30 -15
  10. meta_labs/list_data.py +2 -2
  11. meta_rando/migrations/0007_spfqlist.py +197 -0
  12. meta_rando/models/__init__.py +2 -0
  13. meta_rando/{models.py → models/randomization_list.py} +3 -3
  14. meta_rando/models/spfq_list.py +26 -0
  15. meta_subject/admin/__init__.py +2 -0
  16. meta_subject/admin/spfg_admin.py +103 -0
  17. meta_subject/choices.py +37 -0
  18. meta_subject/constants.py +14 -0
  19. meta_subject/forms/__init__.py +2 -0
  20. meta_subject/forms/spfq_form.py +65 -0
  21. meta_subject/migrations/0228_bloodresultshba1c_hba1c_datetime_and_more.py +1 -6780
  22. meta_subject/migrations/0229_alter_glucosefbg_consent_model_and_more.py +1918 -0
  23. meta_subject/migrations/0230_alter_historicaldelivery_action_identifier_and_more.py +1733 -0
  24. meta_subject/migrations/0231_alter_historicalmedicationadherence_consent_model_and_more.py +2054 -0
  25. meta_subject/migrations/0232_alter_patienthistory_concomitant_conditions_and_more.py +1170 -0
  26. meta_subject/migrations/0233_historicalspfq_spfq.py +1066 -0
  27. meta_subject/models/__init__.py +2 -0
  28. meta_subject/models/spfq.py +190 -0
  29. {meta_edc-1.1.18.dist-info → meta_edc-1.1.19.dist-info}/WHEEL +0 -0
  30. {meta_edc-1.1.18.dist-info → meta_edc-1.1.19.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,103 @@
1
+ from django.contrib import admin
2
+ from django.utils.safestring import mark_safe
3
+ from django_audit_fields import audit_fieldset_tuple
4
+ from edc_crf.fieldset import crf_status_fieldset
5
+ from edc_model_admin.history import SimpleHistoryAdmin
6
+
7
+ from ..admin_site import meta_subject_admin
8
+ from ..forms import SpfqForm
9
+ from ..models import Spfq
10
+ from .modeladmin import CrfModelAdminMixin
11
+
12
+
13
+ @admin.register(Spfq, site=meta_subject_admin)
14
+ class SpfqAdmin(CrfModelAdminMixin, SimpleHistoryAdmin):
15
+ additional_instructions = mark_safe(
16
+ "The Study Participant Feedback Questionnaire Toolkit (SPFQ) is a set of three "
17
+ "brief validated patient questionnaires designed to capture patients’ experiences "
18
+ "at the beginning, during, and end of each clinical study, independent of disease "
19
+ "and treatment.<BR>"
20
+ "<B><font color='orange'>Interviewer to read</font></B>: Thank you for your "
21
+ "participation. Your experiences in this trial are important to us and we "
22
+ "would like to hear about them. Your answers will help us improve future trials. "
23
+ "There are no right or wrong answers. Your answers will be kept anonymous and "
24
+ "will not impact your participation in this trial."
25
+ )
26
+
27
+ form = SpfqForm
28
+
29
+ fieldsets = (
30
+ (None, {"fields": ("subject_visit", "report_datetime")}),
31
+ (
32
+ "Section A: Your experience before you started the study",
33
+ {
34
+ "description": "Please select one response for each of the following items.",
35
+ "fields": ("a01", "a02", "a03", "a04"),
36
+ },
37
+ ),
38
+ (
39
+ "Section B: Your experience during the trial",
40
+ {
41
+ "description": "Please select one response for each of the following items.",
42
+ "fields": (
43
+ "b01",
44
+ "b02",
45
+ "b03",
46
+ "b04",
47
+ "b05",
48
+ "b06",
49
+ "b07",
50
+ "b08",
51
+ "b09",
52
+ "b10",
53
+ ),
54
+ },
55
+ ),
56
+ (
57
+ "Section C: Your experience at the end of the trial",
58
+ {
59
+ "description": "Please select one response for each of the following items.",
60
+ "fields": (
61
+ "c01",
62
+ "c02",
63
+ "c03",
64
+ "c04",
65
+ "c05",
66
+ "c06",
67
+ "c07",
68
+ "c08",
69
+ "c09",
70
+ "c10",
71
+ ),
72
+ },
73
+ ),
74
+ crf_status_fieldset,
75
+ audit_fieldset_tuple,
76
+ )
77
+
78
+ radio_fields = { # noqa: RUF012
79
+ "a01": admin.VERTICAL,
80
+ "a02": admin.VERTICAL,
81
+ "a03": admin.VERTICAL,
82
+ "a04": admin.VERTICAL,
83
+ "b01": admin.VERTICAL,
84
+ "b02": admin.VERTICAL,
85
+ "b03": admin.VERTICAL,
86
+ "b04": admin.VERTICAL,
87
+ "b05": admin.VERTICAL,
88
+ "b06": admin.VERTICAL,
89
+ "b07": admin.VERTICAL,
90
+ "b08": admin.VERTICAL,
91
+ "b09": admin.VERTICAL,
92
+ "b10": admin.VERTICAL,
93
+ "c01": admin.VERTICAL,
94
+ "c02": admin.VERTICAL,
95
+ "c03": admin.VERTICAL,
96
+ "c04": admin.VERTICAL,
97
+ "c05": admin.VERTICAL,
98
+ "c06": admin.VERTICAL,
99
+ "c07": admin.VERTICAL,
100
+ "c08": admin.VERTICAL,
101
+ "c09": admin.VERTICAL,
102
+ "c10": admin.VERTICAL,
103
+ }
meta_subject/choices.py CHANGED
@@ -26,14 +26,28 @@ from .constants import (
26
26
  ALL_OF_THE_TIME,
27
27
  APPT,
28
28
  APPT_OTHER,
29
+ EXTREME,
29
30
  GOOD_BIT_OF_THE_TIME,
31
+ HIGHLY,
30
32
  LITTLE_OF_THE_TIME,
31
33
  LIVE_AT_TERM,
32
34
  LIVE_PRETERM,
35
+ MODERATE,
36
+ MODERATELY,
33
37
  MOST_OF_THE_TIME,
38
+ MUCH_LESS_EXPECTED,
39
+ MUCH_MORE_EXPECTED,
34
40
  NO_COMPLICATIONS,
35
41
  NONE_OF_THE_TIME,
42
+ NOT_AT_ALL,
43
+ SAME_AS_EXPECTED,
44
+ SEVERE,
45
+ SLIGHT,
46
+ SLIGHTLY,
36
47
  SOME_OF_THE_TIME,
48
+ SOMEWHAT_LESS_EXPECTED,
49
+ SOMEWHAT_MORE_EXPECTED,
50
+ VERY_HIGHLY,
37
51
  )
38
52
 
39
53
  ACTIVITY_CHOICES = (
@@ -242,3 +256,26 @@ YES_NO_NO_EXAM = (
242
256
  (NO, _(NO)),
243
257
  (NO_EXAM, _("Exam not performed")),
244
258
  )
259
+
260
+ NOT_AT_ALL_TO_SEVERE_CHOICE = (
261
+ (NOT_AT_ALL, _("Not at all")),
262
+ (SLIGHT, _("Slight")),
263
+ (MODERATE, _("Moderate")),
264
+ (EXTREME, _("Extreme")),
265
+ (SEVERE, _("Severe")),
266
+ )
267
+
268
+ NOT_AT_ALL_TO_HIGHLY_CHOICE = (
269
+ (NOT_AT_ALL, _("Not at all")),
270
+ (SLIGHTLY, _("Slightly")),
271
+ (MODERATELY, _("Moderately")),
272
+ (HIGHLY, _("Highly")),
273
+ (VERY_HIGHLY, _("Very highly")),
274
+ )
275
+ LESS_EXPECTED_TO_MORE_EXPECTED_CHOICE = (
276
+ (MUCH_LESS_EXPECTED, _("Much less than expected")),
277
+ (SOMEWHAT_LESS_EXPECTED, _("Somewhat less than expected")),
278
+ (SAME_AS_EXPECTED, _("Same as expected")),
279
+ (SOMEWHAT_MORE_EXPECTED, _("Somewhat more than expected")),
280
+ (MUCH_MORE_EXPECTED, _("Much more than expected")),
281
+ )
meta_subject/constants.py CHANGED
@@ -6,15 +6,29 @@ APPT = "appt"
6
6
  APPT_OTHER = "other_routine_appt"
7
7
  DELIVERY_ACTION = "delivery_action"
8
8
  DM_FOLLOWUP_ACTION = "dm_followup_action"
9
+ EXTREME = "extreme"
9
10
  FOLLOWUP_EXAMINATION_ACTION = "followup-examination-ae"
10
11
  GOOD_BIT_OF_THE_TIME = "good_bit_of_the_time"
12
+ HIGHLY = "highly"
11
13
  LITTLE_OF_THE_TIME = "little_of_the_time"
12
14
  LIVE_AT_TERM = "live_at_term"
13
15
  LIVE_PRETERM = "live_preterm"
14
16
  LOW_EGFR_ACTION = "low-egfr"
15
17
  MISSED_VISIT_ACTION = "missed_visit_action"
18
+ MODERATE = "moderate"
19
+ MODERATELY = "moderately"
16
20
  MOST_OF_THE_TIME = "most_of_the_time"
21
+ MUCH_LESS_EXPECTED = "much_less_expected"
22
+ MUCH_MORE_EXPECTED = "much_more_expected"
17
23
  NONE_OF_THE_TIME = "none_of_the_time"
24
+ NOT_AT_ALL = "not_at_all"
18
25
  NO_COMPLICATIONS = "no_complications"
26
+ SAME_AS_EXPECTED = "same_as_expected"
27
+ SEVERE = "severe"
28
+ SLIGHT = "slight"
29
+ SLIGHTLY = "slightly"
30
+ SOMEWHAT_LESS_EXPECTED = "somewhat_less_expected"
31
+ SOMEWHAT_MORE_EXPECTED = "somewhat_more_expected"
19
32
  SOME_OF_THE_TIME = "some_of_the_time"
20
33
  URINE_PREGNANCY_ACTION = "urine_pregnancy_action"
34
+ VERY_HIGHLY = "very_highly"
@@ -29,6 +29,7 @@ from .patient_history_form import PatientHistoryForm
29
29
  from .physical_exam_form import PhysicalExamForm
30
30
  from .pregnancy_update_form import PregnancyUpdateForm
31
31
  from .sf12_form import Sf12Form
32
+ from .spfq_form import SpfqForm
32
33
  from .study_medication_form import StudyMedicationForm
33
34
  from .subject_requisition_form import SubjectRequisitionForm
34
35
  from .subject_visit_form import SubjectVisitForm
@@ -69,6 +70,7 @@ __all__ = [
69
70
  "PhysicalExamForm",
70
71
  "PregnancyUpdateForm",
71
72
  "Sf12Form",
73
+ "SpfqForm",
72
74
  "StudyMedicationForm",
73
75
  "SubjectRequisitionForm",
74
76
  "SubjectVisitForm",
@@ -0,0 +1,65 @@
1
+ from django import forms
2
+ from django.core.exceptions import ObjectDoesNotExist
3
+ from edc_crf.crf_form_validator import CrfFormValidator
4
+ from edc_crf.modelform_mixins import CrfModelFormMixin
5
+ from edc_registration.models import RegisteredSubject
6
+
7
+ from meta_consent.models import SubjectConsentSpfq
8
+ from meta_rando.models import SpfqList
9
+
10
+ from ..models import Spfq
11
+
12
+
13
+ class SpfqFormValidator(CrfFormValidator):
14
+ pass
15
+
16
+
17
+ class SpfqForm(CrfModelFormMixin, forms.ModelForm):
18
+ form_validator_cls = SpfqFormValidator
19
+
20
+ def clean(self):
21
+ cleaned_data = super().clean()
22
+
23
+ try:
24
+ RegisteredSubject.objects.get(
25
+ subject_identifier=cleaned_data.get("subject_identifier"),
26
+ initials=cleaned_data.get("initials"),
27
+ gender=cleaned_data.get("gender"),
28
+ )
29
+ except ObjectDoesNotExist as e:
30
+ raise forms.ValidationError(
31
+ {
32
+ "__all__": (
33
+ "Subject not known to the META trial. "
34
+ "Check that the identifier, initials and gender match the patient "
35
+ "register from the main META trial."
36
+ )
37
+ }
38
+ ) from e
39
+ try:
40
+ SpfqList.objects.get(
41
+ subject_identifier=cleaned_data.get("subject_identifier"),
42
+ )
43
+ except ObjectDoesNotExist as e:
44
+ raise forms.ValidationError(
45
+ {
46
+ "__all__": (
47
+ "Subject not found. A subject with this identifier "
48
+ "has not been selected for the sub-study."
49
+ )
50
+ }
51
+ ) from e
52
+
53
+ try:
54
+ SubjectConsentSpfq.objects.get(
55
+ subject_identifier=cleaned_data.get("subject_identifier"),
56
+ )
57
+ except ObjectDoesNotExist as e:
58
+ raise forms.ValidationError(
59
+ {"__all__": "Subject not consented for the sub-study."}
60
+ ) from e
61
+ return cleaned_data
62
+
63
+ class Meta:
64
+ model = Spfq
65
+ fields = "__all__"