meta-edc 1.1.17__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.
- meta_consent/admin/__init__.py +1 -0
- meta_consent/admin/subject_consent_spfq_admin.py +58 -0
- meta_consent/forms/__init__.py +2 -0
- meta_consent/forms/subject_consent_spfq_form.py +55 -0
- meta_consent/migrations/0033_historicalsubjectconsentspfq_subjectconsentspfq.py +615 -0
- meta_consent/models/__init__.py +2 -0
- meta_consent/models/subject_consent_spfq.py +103 -0
- meta_edc/settings/defaults.py +1 -1
- {meta_edc-1.1.17.dist-info → meta_edc-1.1.19.dist-info}/METADATA +5 -5
- {meta_edc-1.1.17.dist-info → meta_edc-1.1.19.dist-info}/RECORD +31 -16
- meta_labs/list_data.py +2 -2
- meta_rando/migrations/0007_spfqlist.py +197 -0
- meta_rando/models/__init__.py +2 -0
- meta_rando/{models.py → models/randomization_list.py} +3 -3
- meta_rando/models/spfq_list.py +26 -0
- meta_subject/admin/__init__.py +2 -0
- meta_subject/admin/spfg_admin.py +103 -0
- meta_subject/choices.py +37 -0
- meta_subject/constants.py +14 -0
- meta_subject/forms/__init__.py +2 -0
- meta_subject/forms/spfq_form.py +65 -0
- meta_subject/migrations/0228_bloodresultshba1c_hba1c_datetime_and_more.py +1 -6780
- meta_subject/migrations/0229_alter_glucosefbg_consent_model_and_more.py +1918 -0
- meta_subject/migrations/0230_alter_historicaldelivery_action_identifier_and_more.py +1733 -0
- meta_subject/migrations/0231_alter_historicalmedicationadherence_consent_model_and_more.py +2054 -0
- meta_subject/migrations/0232_alter_patienthistory_concomitant_conditions_and_more.py +1170 -0
- meta_subject/migrations/0233_historicalspfq_spfq.py +1066 -0
- meta_subject/models/__init__.py +2 -0
- meta_subject/models/spfq.py +190 -0
- {meta_edc-1.1.17.dist-info → meta_edc-1.1.19.dist-info}/WHEEL +0 -0
- {meta_edc-1.1.17.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"
|
meta_subject/forms/__init__.py
CHANGED
|
@@ -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__"
|