meta-edc 1.1.19__py3-none-any.whl → 1.2.0__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 +0 -1
- meta_consent/forms/__init__.py +0 -2
- meta_consent/migrations/0034_remove_subjectconsentspfq_site_and_more.py +23 -0
- meta_consent/models/__init__.py +0 -2
- meta_consent/models/signals.py +13 -16
- meta_edc/settings/defaults.py +14 -10
- meta_edc/urls.py +1 -0
- {meta_edc-1.1.19.dist-info → meta_edc-1.2.0.dist-info}/METADATA +6 -5
- {meta_edc-1.1.19.dist-info → meta_edc-1.2.0.dist-info}/RECORD +22 -25
- meta_prn/baker_recipes.py +6 -6
- meta_prn/migrations/0069_alter_historicaloffstudymedication_singleton_field_and_more.py +37 -0
- meta_rando/migrations/0008_delete_spfqlist.py +16 -0
- meta_rando/models/__init__.py +0 -1
- meta_subject/admin/__init__.py +0 -2
- meta_subject/choices.py +0 -37
- meta_subject/constants.py +0 -14
- meta_subject/forms/__init__.py +0 -2
- meta_subject/migrations/0234_remove_spfq_site_remove_spfq_subject_visit_and_more.py +27 -0
- meta_subject/models/__init__.py +0 -2
- meta_subject/models/health_economics/health_economics_simple.py +2 -2
- meta_consent/admin/subject_consent_spfq_admin.py +0 -58
- meta_consent/forms/subject_consent_spfq_form.py +0 -55
- meta_consent/models/subject_consent_spfq.py +0 -103
- meta_rando/models/spfq_list.py +0 -26
- meta_subject/admin/spfg_admin.py +0 -103
- meta_subject/forms/spfq_form.py +0 -65
- meta_subject/models/spfq.py +0 -190
- {meta_edc-1.1.19.dist-info → meta_edc-1.2.0.dist-info}/WHEEL +0 -0
- {meta_edc-1.1.19.dist-info → meta_edc-1.2.0.dist-info}/licenses/LICENSE +0 -0
meta_consent/admin/__init__.py
CHANGED
meta_consent/forms/__init__.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
from .subject_consent_form import SubjectConsentForm
|
|
2
|
-
from .subject_consent_spfq_form import SubjectConsentSpfqForm
|
|
3
2
|
from .subject_consent_v1_ext_form import SubjectConsentV1ExtForm
|
|
4
3
|
from .subject_consent_v1_form import SubjectConsentV1Form
|
|
5
4
|
from .subject_reconsent_form import SubjectReconsentForm
|
|
6
5
|
|
|
7
6
|
__all__ = [
|
|
8
7
|
"SubjectConsentForm",
|
|
9
|
-
"SubjectConsentSpfqForm",
|
|
10
8
|
"SubjectConsentV1ExtForm",
|
|
11
9
|
"SubjectConsentV1Form",
|
|
12
10
|
"SubjectReconsentForm",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-30 22:50
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("meta_consent", "0033_historicalsubjectconsentspfq_subjectconsentspfq"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.RemoveField(
|
|
14
|
+
model_name="subjectconsentspfq",
|
|
15
|
+
name="site",
|
|
16
|
+
),
|
|
17
|
+
migrations.DeleteModel(
|
|
18
|
+
name="HistoricalSubjectConsentSpfq",
|
|
19
|
+
),
|
|
20
|
+
migrations.DeleteModel(
|
|
21
|
+
name="SubjectConsentSpfq",
|
|
22
|
+
),
|
|
23
|
+
]
|
meta_consent/models/__init__.py
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
from .signals import subject_consent_on_post_delete, subject_consent_on_post_save
|
|
2
2
|
from .subject_consent import SubjectConsent
|
|
3
|
-
from .subject_consent_spfq import SubjectConsentSpfq
|
|
4
3
|
from .subject_consent_v1 import SubjectConsentV1
|
|
5
4
|
from .subject_consent_v1_ext import SubjectConsentV1Ext
|
|
6
5
|
from .subject_reconsent import SubjectReconsent
|
|
7
6
|
|
|
8
7
|
__all__ = [
|
|
9
8
|
"SubjectConsent",
|
|
10
|
-
"SubjectConsentSpfq",
|
|
11
9
|
"SubjectConsentV1",
|
|
12
10
|
"SubjectConsentV1Ext",
|
|
13
11
|
"SubjectReconsent",
|
meta_consent/models/signals.py
CHANGED
|
@@ -4,7 +4,6 @@ from django.core.exceptions import ValidationError
|
|
|
4
4
|
from django.db.models.signals import post_delete, post_save
|
|
5
5
|
from django.dispatch import receiver
|
|
6
6
|
from edc_action_item.delete_action_item import ActionItemDeleteError, delete_action_item
|
|
7
|
-
from edc_appointment.utils import refresh_appointments
|
|
8
7
|
from edc_constants.constants import YES
|
|
9
8
|
from edc_pharmacy.exceptions import PrescriptionAlreadyExists
|
|
10
9
|
from edc_pharmacy.prescribe import create_prescription
|
|
@@ -14,12 +13,10 @@ from edc_visit_schedule.site_visit_schedules import site_visit_schedules
|
|
|
14
13
|
from meta_edc.meta_version import get_meta_version
|
|
15
14
|
from meta_screening.models import SubjectScreening
|
|
16
15
|
from meta_subject.models import SubjectVisit
|
|
17
|
-
from meta_visit_schedule.constants import SCHEDULE, VISIT_SCHEDULE
|
|
18
16
|
|
|
19
17
|
from ..action_items import ReconsentAction
|
|
20
18
|
from .subject_consent import SubjectConsent
|
|
21
19
|
from .subject_consent_v1 import SubjectConsentV1
|
|
22
|
-
from .subject_consent_v1_ext import SubjectConsentV1Ext
|
|
23
20
|
|
|
24
21
|
|
|
25
22
|
@receiver(
|
|
@@ -85,19 +82,19 @@ def subject_consent_on_post_save(sender, instance, raw, created, **kwargs): # n
|
|
|
85
82
|
)
|
|
86
83
|
|
|
87
84
|
|
|
88
|
-
@receiver(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)
|
|
94
|
-
def subject_consent_v1_ext_on_post_save(sender, instance, raw, created, **kwargs):
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
85
|
+
# @receiver(
|
|
86
|
+
# post_save,
|
|
87
|
+
# weak=False,
|
|
88
|
+
# sender=SubjectConsentV1Ext,
|
|
89
|
+
# dispatch_uid="subject_consent_v1_ext_on_post_save",
|
|
90
|
+
# )
|
|
91
|
+
# def subject_consent_v1_ext_on_post_save(sender, instance, raw, created, **kwargs):
|
|
92
|
+
# if not raw:
|
|
93
|
+
# refresh_appointments(
|
|
94
|
+
# subject_identifier=instance.subject_identifier,
|
|
95
|
+
# visit_schedule_name=VISIT_SCHEDULE,
|
|
96
|
+
# schedule_name=SCHEDULE,
|
|
97
|
+
# )
|
|
101
98
|
|
|
102
99
|
|
|
103
100
|
@receiver(
|
meta_edc/settings/defaults.py
CHANGED
|
@@ -38,7 +38,7 @@ if os.getenv("DJANGO_BASE_DIR"):
|
|
|
38
38
|
BASE_DIR = Path(os.getenv("DJANGO_BASE_DIR"))
|
|
39
39
|
else:
|
|
40
40
|
# when running from a repo
|
|
41
|
-
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
|
41
|
+
BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent
|
|
42
42
|
|
|
43
43
|
if os.getenv("DJANGO_ENV_DIR"):
|
|
44
44
|
ENV_DIR = Path(os.getenv("DJANGO_ENV_DIR"))
|
|
@@ -54,6 +54,15 @@ else:
|
|
|
54
54
|
raise FileExistsError(f"Environment file does not exist. Got `{(ENV_DIR / '.env')}`")
|
|
55
55
|
env.read_env(ENV_DIR / ".env")
|
|
56
56
|
|
|
57
|
+
# django_revision
|
|
58
|
+
GIT_DIR = Path(env.str("EDC_REVISION_GIT_DIR", default=BASE_DIR))
|
|
59
|
+
|
|
60
|
+
# django_crypto_fields
|
|
61
|
+
KEY_PATH = env.str("DJANGO_KEY_FOLDER")
|
|
62
|
+
AUTO_CREATE_KEYS = env("DJANGO_AUTO_CREATE_KEYS")
|
|
63
|
+
|
|
64
|
+
EXPORT_FOLDER = env.str("DJANGO_EXPORT_FOLDER") or Path("~/").expanduser()
|
|
65
|
+
|
|
57
66
|
|
|
58
67
|
LOGGING_ENABLED = env("DJANGO_LOGGING_ENABLED")
|
|
59
68
|
if LOGGING_ENABLED:
|
|
@@ -188,6 +197,7 @@ INSTALLED_APPS = [
|
|
|
188
197
|
"meta_pharmacy.apps.AppConfig",
|
|
189
198
|
"meta_screening.apps.AppConfig",
|
|
190
199
|
"meta_sites.apps.AppConfig",
|
|
200
|
+
"meta_spfq.apps.AppConfig",
|
|
191
201
|
"meta_edc.apps.AppConfig",
|
|
192
202
|
"edc_appconfig.apps.AppConfig",
|
|
193
203
|
]
|
|
@@ -485,15 +495,6 @@ if TWILIO_ENABLED:
|
|
|
485
495
|
TWILIO_AUTH_TOKEN = env.str("TWILIO_AUTH_TOKEN")
|
|
486
496
|
TWILIO_SENDER = env.str("TWILIO_SENDER")
|
|
487
497
|
|
|
488
|
-
# django_revision
|
|
489
|
-
GIT_DIR = BASE_DIR.parent
|
|
490
|
-
|
|
491
|
-
# django_crypto_fields
|
|
492
|
-
KEY_PATH = env.str("DJANGO_KEY_FOLDER")
|
|
493
|
-
AUTO_CREATE_KEYS = env("DJANGO_AUTO_CREATE_KEYS")
|
|
494
|
-
|
|
495
|
-
EXPORT_FOLDER = env.str("DJANGO_EXPORT_FOLDER") or Path("~/").expanduser()
|
|
496
|
-
|
|
497
498
|
# django_simple_history
|
|
498
499
|
SIMPLE_HISTORY_ENFORCE_HISTORY_MODEL_PERMISSIONS = True
|
|
499
500
|
|
|
@@ -592,3 +593,6 @@ if "test" in sys.argv:
|
|
|
592
593
|
MIGRATION_MODULES = DisableMigrations()
|
|
593
594
|
PASSWORD_HASHERS = ("django.contrib.auth.hashers.MD5PasswordHasher",)
|
|
594
595
|
DEFAULT_FILE_STORAGE = "inmemorystorage.InMemoryStorage"
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
META_SPFQ_LIST_FILENAME = env.str("META_SPFQ_LIST_FILENAME")
|
meta_edc/urls.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meta-edc
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: META Trial EDC (https://www.isrctn.com/ISRCTN76157257)
|
|
5
5
|
Keywords: django,clinicedc,META EDC,EDC,clinical trials,META Trial,ISRCTN76157257
|
|
6
6
|
Author: Erik van Widenfelt, Jonathan Willitts
|
|
@@ -15,12 +15,13 @@ Classifier: Intended Audience :: Science/Research
|
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
-
Requires-Dist: clinicedc>=2.0.
|
|
18
|
+
Requires-Dist: clinicedc>=2.0.30
|
|
19
19
|
Requires-Dist: edc-he>=1.2.0
|
|
20
20
|
Requires-Dist: edc-microscopy>=1.2.0
|
|
21
21
|
Requires-Dist: edc-mnsi>=1.2.0
|
|
22
22
|
Requires-Dist: edc-phq9>=1.1.0
|
|
23
23
|
Requires-Dist: edc-qol>=1.2.0
|
|
24
|
+
Requires-Dist: notebook>=7.4.7
|
|
24
25
|
Requires-Python: >=3.12, <3.14
|
|
25
26
|
Description-Content-Type: text/x-rst
|
|
26
27
|
|
|
@@ -88,8 +89,8 @@ Assuming you are logged into the account ``myaccount``:
|
|
|
88
89
|
mkdir ~/edc && \
|
|
89
90
|
cd ~/edc && \
|
|
90
91
|
uv venv && \
|
|
91
|
-
uv pip install -U meta-edc==1.1.
|
|
92
|
-
wget https://raw.githubusercontent.com/meta-trial/meta-edc/1.1.
|
|
92
|
+
uv pip install -U meta-edc==1.1.19 && \
|
|
93
|
+
wget https://raw.githubusercontent.com/meta-trial/meta-edc/1.1.19/manage.py && \
|
|
93
94
|
uv pip freeze | grep meta-edc
|
|
94
95
|
|
|
95
96
|
Copy your ``.env`` file to ``~/.etc``.
|
|
@@ -139,7 +140,7 @@ From the above example:
|
|
|
139
140
|
|
|
140
141
|
cd ~/edc && \
|
|
141
142
|
uv venv --clear && \
|
|
142
|
-
uv pip install -U meta-edc==1.1.
|
|
143
|
+
uv pip install -U meta-edc==1.1.19 && \
|
|
143
144
|
wget -O manage.py https://raw.githubusercontent.com/meta-trial/meta-edc/1.1.10/manage.py && \
|
|
144
145
|
uv pip freeze | grep meta-edc && \
|
|
145
146
|
python manage.py check
|
|
@@ -109,13 +109,12 @@ meta_auth/auths.py,sha256=EBdK6b5b2yduDvqYmnmJFRvuJ0fLDQ_q226iuwHA_QU,3008
|
|
|
109
109
|
meta_auth/urls.py,sha256=_sVCnQeiAFRYKhxga3_DjoKj_4bgs1s2gjcynDiapvA,111
|
|
110
110
|
meta_consent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
111
111
|
meta_consent/action_items.py,sha256=tSt9PsKWommXY59d65gvT8YxJc55mwp5RDlRH6RqHZY,1425
|
|
112
|
-
meta_consent/admin/__init__.py,sha256=
|
|
112
|
+
meta_consent/admin/__init__.py,sha256=d_6yWMi1yGgKxq4kFQIr7NNj96GqLDppXE0P83A14WQ,285
|
|
113
113
|
meta_consent/admin/actions/__init__.py,sha256=dxQmm21wkVYcznzBeQU6cBEfPRnkEsBQLwptJr2xoYI,113
|
|
114
114
|
meta_consent/admin/actions/create_missing_prescriptions.py,sha256=mksb9aAL8FK0KN3Z2a5N-QRrUSiilObUMCqoWCTlfv8,1500
|
|
115
115
|
meta_consent/admin/list_filters.py,sha256=gVKcHW1YHT3X0fYDDgCI_PDY9F7A3Z3z8CRq2ZRC9MA,775
|
|
116
116
|
meta_consent/admin/modeladmin_mixins.py,sha256=AWGHMjjZleGtE4UhfL_1hykiT1qpBkndgKbgeEo3ilo,5387
|
|
117
117
|
meta_consent/admin/subject_consent_admin.py,sha256=IfGANb9TFvVs9yga8WOTxHxy2yRHP--KgsVUWEg30MQ,647
|
|
118
|
-
meta_consent/admin/subject_consent_spfq_admin.py,sha256=Om1rkJSCfxLfHuTZ4K-q5pCSS5ZXnRfpeuJOrrM73lQ,1720
|
|
119
118
|
meta_consent/admin/subject_consent_v1_admin.py,sha256=nmssuWL7eomQfXi3mVrszs3Ghufhz46JAwr9wFU3gkI,657
|
|
120
119
|
meta_consent/admin/subject_consent_v1_ext_admin.py,sha256=o0XiCiyFr7ARV6f3Y-TLVknljomsoKrVFDxQfCRgEaY,2849
|
|
121
120
|
meta_consent/admin_site.py,sha256=r5FtGwonVpqhyGekVNplmHr2mwbEGilJBiyvsIz2_lY,169
|
|
@@ -125,9 +124,8 @@ meta_consent/consents.py,sha256=JkO2dlt7Fn7ckWRGgdicAaXWgtIANo1amwxK5ykL5uk,1185
|
|
|
125
124
|
meta_consent/constants.py,sha256=w5n3B4jwUDDZEc4gMpkKeffsHqi724GnoABFtjmvbQk,78
|
|
126
125
|
meta_consent/form_validators/__init__.py,sha256=3xf1nNmydleMyROWyHvwI8-HC5y7gMYQW_bTeStiI7Q,115
|
|
127
126
|
meta_consent/form_validators/subject_consent_form_validator.py,sha256=2f4FY1VZ1qU4u35LSoRtBIhmRhrflOhs0Zal8z1Ogo8,1258
|
|
128
|
-
meta_consent/forms/__init__.py,sha256=
|
|
127
|
+
meta_consent/forms/__init__.py,sha256=owYPqBIxjy6U58sdWHrCgxqBY0ObE_tlIOXOcnTy7LM,361
|
|
129
128
|
meta_consent/forms/subject_consent_form.py,sha256=Dwnwn7y-8AABvzgTa1zfs2b2Mli0OKnNMsx0VOxO9n0,1293
|
|
130
|
-
meta_consent/forms/subject_consent_spfq_form.py,sha256=NGC7HhL2uCqrDGnO7boe0Cq_2ZbVJYB9qeecu5aMZyY,2016
|
|
131
129
|
meta_consent/forms/subject_consent_v1_ext_form.py,sha256=jkm3bDrmepChP2OsmiAalhCW-IwhsR7BhR_qcycrTlc,1735
|
|
132
130
|
meta_consent/forms/subject_consent_v1_form.py,sha256=XHrklzP-wh6ny3VJ2Bf9v7BTaUlfTToYVrpIAm3JZFc,766
|
|
133
131
|
meta_consent/forms/subject_reconsent_form.py,sha256=hR2c1SgBXDXbL2gv33ArACr6UoGsM22C03uyCtuwT8o,1350
|
|
@@ -169,12 +167,12 @@ meta_consent/migrations/0030_auto_20250120_2114.py,sha256=Unk3dddqbNTog5VZOmq-68
|
|
|
169
167
|
meta_consent/migrations/0031_alter_historicalsubjectconsent_guardian_name_and_more.py,sha256=a3-_1ls36Z8UXe3v2U44SqPVeNiCgUjJX6jOWsk1EoQ,5645
|
|
170
168
|
meta_consent/migrations/0032_alter_historicalsubjectconsent_device_created_and_more.py,sha256=Ty4I6TSHw_rHRKyrYQUMDuZmCSe9_rC4PMD8PM6EdB0,24682
|
|
171
169
|
meta_consent/migrations/0033_historicalsubjectconsentspfq_subjectconsentspfq.py,sha256=6GKEKT1BbPqqq2U2rHMQWl1VITtB3Inzl3aJGiy26ro,25192
|
|
170
|
+
meta_consent/migrations/0034_remove_subjectconsentspfq_site_and_more.py,sha256=RbTC6Oo2pOLYaOMkhPtdM612nyZwnOXdWVZ769WGF4o,546
|
|
172
171
|
meta_consent/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
173
|
-
meta_consent/models/__init__.py,sha256=
|
|
172
|
+
meta_consent/models/__init__.py,sha256=qDfnpsbAP3hr5oKa80hkr5u9P2PN6KV8P5EMujfgt_8,465
|
|
174
173
|
meta_consent/models/model_mixins.py,sha256=mEN2gDycLKoZiExM2_H3Dxz8AMAwRSrCq4vu3afr5hA,275
|
|
175
|
-
meta_consent/models/signals.py,sha256=
|
|
174
|
+
meta_consent/models/signals.py,sha256=qjzBtnLR5qcOrn39sFrleUm6a9DG2yZnHGLnKQ-tLkc,5030
|
|
176
175
|
meta_consent/models/subject_consent.py,sha256=Ssr94mZijpseoer-APH0jhh54cLeoUI0TPUah3od91c,3804
|
|
177
|
-
meta_consent/models/subject_consent_spfq.py,sha256=vXMRfEU9AeOqKDGUzTNnZl6D_hM-H4_uEfcx3QjJlzc,3038
|
|
178
176
|
meta_consent/models/subject_consent_v1.py,sha256=ELkFhv_6eRiuuoJOohdLwq3b2e2YXngK5omkGwMoRQE,457
|
|
179
177
|
meta_consent/models/subject_consent_v1_ext.py,sha256=MpK5TlUqf2JuYRpmRLzYBClOFstC_6pIGwDRUckIztU,1033
|
|
180
178
|
meta_consent/models/subject_reconsent.py,sha256=CqkrnThqjfnJnIj-k5QEEijue3gqp-0YvzcqKHjC8Gs,3605
|
|
@@ -233,14 +231,14 @@ meta_edc/models.py,sha256=DLA-hDdFszAVNCe1sZqVoLmIXifFW0HeZsipP9D1Ic4,46
|
|
|
233
231
|
meta_edc/navbars.py,sha256=Rl2a62elRVTbkGVV9toYwwT388TE1BI7-1j1w2v1m-I,1208
|
|
234
232
|
meta_edc/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
235
233
|
meta_edc/settings/debug.py,sha256=XfYEL34kzpyiXQkTil34-r-NVKhmxs_kVQP2u5XtfVE,1313
|
|
236
|
-
meta_edc/settings/defaults.py,sha256=
|
|
234
|
+
meta_edc/settings/defaults.py,sha256=lXN6DoEbUudUQSqJ1BJ8dVcAo4q-ZoEMxbnN8xkMSro,20381
|
|
237
235
|
meta_edc/settings/live.py,sha256=A4gDWiUIgcRDUWaT4oEOHkGmaeLRPNsr7MPrl0r8AuI,289
|
|
238
236
|
meta_edc/settings/logging.py,sha256=7RQ2guyuMhK3MtoojmnD0CVqiFZZ6ZT6zc7Rwn0nYGk,2115
|
|
239
237
|
meta_edc/settings/minimal.py,sha256=ZZM7hZ-3AH33nGpLJLbYgs50oa5meKv_aGShidnm9G0,511
|
|
240
238
|
meta_edc/settings/uat.py,sha256=kA6Aw2qDeh6gXNJgtiR93D0rWmBNHswcrufPk40RYhc,295
|
|
241
239
|
meta_edc/templates/meta_edc/base.html,sha256=SRsitjNhwDyPueJXm8gAyz9MsqDKFfhs50zl4dGBGsU,154
|
|
242
240
|
meta_edc/templates/meta_edc/home.html,sha256=EMdNWUw3NURSrC8xlKCkxuV0SxVLcmB8kyy2N6LgFLQ,4579
|
|
243
|
-
meta_edc/urls.py,sha256=
|
|
241
|
+
meta_edc/urls.py,sha256=XEqI0_flKCQO7_E8WQ_La_YhMnsx2c7N5mluAohEm1w,3681
|
|
244
242
|
meta_edc/utils.py,sha256=BX6KQNiygI17TftUx-08-b1K30Kooxg0Kg1E5Auys5s,367
|
|
245
243
|
meta_edc/views/__init__.py,sha256=8kC2jsMR87Hhtw86MHJD8hS_8k6ZqPSr9E4-dcRQmUM,56
|
|
246
244
|
meta_edc/views/home_view.py,sha256=BXydy77TcdcM0-R3S_uHI4DtfnLMIzPJMyqjFJZFSsA,916
|
|
@@ -346,7 +344,7 @@ meta_prn/admin/protocol_incident_admin.py,sha256=42XTm6Z9EyKtSXWnIep3DmYwibCtMHx
|
|
|
346
344
|
meta_prn/admin/subject_transfer_admin.py,sha256=ixYbel84vXwFuBaczTJBscpau3iMjHEzhpHvGRRXLD0,741
|
|
347
345
|
meta_prn/admin_site.py,sha256=E4dJ6ofu9Kp-1SIWIuY3PraVPbEJSWBBqhorJPGUNqU,161
|
|
348
346
|
meta_prn/apps.py,sha256=NEqrwzEW277BAPGeL1H1KdK9e74FqXfYHK6o46BtaJA,280
|
|
349
|
-
meta_prn/baker_recipes.py,sha256=
|
|
347
|
+
meta_prn/baker_recipes.py,sha256=MgTdr_2wawEMSQifsgXpP7LS_8va9HjlXXE2etpq8sM,715
|
|
350
348
|
meta_prn/choices.py,sha256=QmWGz2zpWIt5Uqa3QP_YC-Ky8eKYDPdA5R8vPsOP22Q,3318
|
|
351
349
|
meta_prn/constants.py,sha256=Z0atxRnTIj-_bWbfYY0vZIwfmbwaFRpSZqb1-K1B4Jo,1018
|
|
352
350
|
meta_prn/form_validators/__init__.py,sha256=bHMDsNInx7AEghhcU2_2Bmc5pgP_Y7p4fbklXiugjYQ,194
|
|
@@ -432,6 +430,7 @@ meta_prn/migrations/0065_alter_historicaloffstudymedication_subject_identifier_a
|
|
|
432
430
|
meta_prn/migrations/0066_alter_historicallosstofollowup_subject_identifier_and_more.py,sha256=hUTNf3oiIxJODNXXwjTeVZS-xEMBsCn3XyR2aPcfO7o,662
|
|
433
431
|
meta_prn/migrations/0067_alter_offschedule_managers_and_more.py,sha256=FgwTeEgMbvyH3G6C7p3O9jUcUf7aX0dOmTuULlpWHKU,95266
|
|
434
432
|
meta_prn/migrations/0068_alter_dmreferral_referral_note_and_more.py,sha256=CKbtUdAVA4r74WTHMh_lAh7Fm7YC23A0aPD0mWs59sU,8347
|
|
433
|
+
meta_prn/migrations/0069_alter_historicaloffstudymedication_singleton_field_and_more.py,sha256=oM6nxwAZOkJ0wjuNzVH-KrNEYUjLR97c1BTXY1lxab4,1085
|
|
435
434
|
meta_prn/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
436
435
|
meta_prn/models/__init__.py,sha256=RTi_GFeNhZEnB7_WR5bahlanI7BGR9rTC47TveoRrR4,1224
|
|
437
436
|
meta_prn/models/dm_referral.py,sha256=_5sVeT9A2mnmbkv2LvbTkS4G-QYPWqR5zMRGDAWCENA,1153
|
|
@@ -457,10 +456,10 @@ meta_rando/migrations/0004_alter_randomizationlist_options_and_more.py,sha256=_U
|
|
|
457
456
|
meta_rando/migrations/0005_alter_randomizationlist_options_and_more.py,sha256=GBaNqwy4SlmQ88lYX2uEqAI0FIUQem-C8qJLI6d6SfI,3248
|
|
458
457
|
meta_rando/migrations/0006_alter_historicalrandomizationlist_allocated_user_and_more.py,sha256=XS6srUOHPAJWqsTLLPCHmcIKlOkEky95JrH1739gL2w,4584
|
|
459
458
|
meta_rando/migrations/0007_spfqlist.py,sha256=UbzXuvNy3EuapG0ZQktiEVOM3BVjLgeAmTqViAh9cKg,7276
|
|
459
|
+
meta_rando/migrations/0008_delete_spfqlist.py,sha256=hF6G6B5kMirD_W8xOCRe_IA2IIq2xkKEYcF5KTSgnSY,290
|
|
460
460
|
meta_rando/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
461
|
-
meta_rando/models/__init__.py,sha256=
|
|
461
|
+
meta_rando/models/__init__.py,sha256=Y723EYwgR2rCsy6GKK8uEh0V1-a3L1mr-n-vk6ZkQVs,50
|
|
462
462
|
meta_rando/models/randomization_list.py,sha256=IBj1kSui1tHNgZdVbHvgmunw9BwBZ4ZZnft98x1B-Gg,510
|
|
463
|
-
meta_rando/models/spfq_list.py,sha256=Ba0nasvtMAPnJVukOCFZ1EvVuyEeXxiPjDX0N1t4C9w,839
|
|
464
463
|
meta_rando/randomizers.py,sha256=GpsV3kkqd-HupfnQw6Y7R172ZpOEpIbmVkXOwsOf-HA,1592
|
|
465
464
|
meta_reports/__init__.py,sha256=huYR-GaImMWZqv6puEYfY7y_8m1OA_hRVXRYNBvNLkQ,80
|
|
466
465
|
meta_reports/admin/__init__.py,sha256=V-rlMJJZCgnDaMOwk5PgZNIclOp_FW2y9yc-iCLQFHA,910
|
|
@@ -722,7 +721,7 @@ meta_sites/models.py,sha256=DLA-hDdFszAVNCe1sZqVoLmIXifFW0HeZsipP9D1Ic4,46
|
|
|
722
721
|
meta_sites/sites.py,sha256=H26Erar3_fLVl5wf2ILDM5C6wGEoi0dQbiSPmzb9OGw,1625
|
|
723
722
|
meta_subject/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
724
723
|
meta_subject/action_items.py,sha256=l7Bw4m0Hu72bemH70UToI__VCERz8YKEKcsWCL6BJxk,6804
|
|
725
|
-
meta_subject/admin/__init__.py,sha256=
|
|
724
|
+
meta_subject/admin/__init__.py,sha256=04MeBKUNsTc1DKJDE7r9w-KfZWxBEB-QLBIiazhzzFs,2779
|
|
726
725
|
meta_subject/admin/autocomplete_admin.py,sha256=bVxma7KTHhKHWqLPxbP2GwiGcHeBUyMutTDXZ2RomEY,1158
|
|
727
726
|
meta_subject/admin/birth_outcome_admin.py,sha256=76hwS4wIbuFpxAvIoQwjVqyr4znVGhWOnuKBuk1FIZ8,3242
|
|
728
727
|
meta_subject/admin/blood_results/__init__.py,sha256=24WaqyGYCj3F-8amy7HFEwet1Z1ZHgsVvdSrWmmGvVs,546
|
|
@@ -762,7 +761,6 @@ meta_subject/admin/patient_history_admin.py,sha256=xeHhoeZS-F7nXAopZI8HxAjZUFLDY
|
|
|
762
761
|
meta_subject/admin/physical_exam_admin.py,sha256=NnYsclV3dAQZO9f9IUIj44d8ttbCFFmAPi-KXF8uVQg,1874
|
|
763
762
|
meta_subject/admin/pregnancy_update_admin.py,sha256=g-pXELecNtxePvDGlx7Iwx7w0GNUtPMEw0q5eVdMAg0,929
|
|
764
763
|
meta_subject/admin/sf12_admin.py,sha256=1PDNewdE_JDcjfyh0tb0MEWnBgpE3-7W0tkNfWkSX5U,742
|
|
765
|
-
meta_subject/admin/spfg_admin.py,sha256=xAKximXRHtUgpuqDK4dmXbpN7OodLRQcEBbRy4Nb-iE,3522
|
|
766
764
|
meta_subject/admin/study_medication_admin.py,sha256=E1xZDDEMDoCSfgYhJ7E815ClSrh-A4HTY7iOy52auF4,6146
|
|
767
765
|
meta_subject/admin/subject_requisition_admin.py,sha256=CJxO4Qvphxm8RfjS0IFef9smMFVmVzI2KbSmdhpocXU,1864
|
|
768
766
|
meta_subject/admin/subject_visit_admin.py,sha256=FMJ6-aB_3JLrYnCAKM8vvYyWqN9P58RwR25JB1Po6bc,1405
|
|
@@ -772,8 +770,8 @@ meta_subject/admin/urine_pregnancy_admin.py,sha256=o90kDiRm28SqgSR8pwj4MVSICkzt_
|
|
|
772
770
|
meta_subject/admin_site.py,sha256=fxUn5QKgo6wYUG18HW11kVrPqWvmWV2_PzKbgZQM4pU,169
|
|
773
771
|
meta_subject/apps.py,sha256=iAQ8lizUpKa4gJnCGkTsuRQPtGWmSjnshZn8rZUguO8,289
|
|
774
772
|
meta_subject/baker_recipes.py,sha256=KEJQTjNH47KcGCR_2OxDwmSKhAWhmjiD3YsnqeqkzFU,2816
|
|
775
|
-
meta_subject/choices.py,sha256=
|
|
776
|
-
meta_subject/constants.py,sha256=
|
|
773
|
+
meta_subject/choices.py,sha256=lFseBsxliIRshCmqsIwdPnYXs1p_WT5D_Dfn2PcWONs,6754
|
|
774
|
+
meta_subject/constants.py,sha256=6rpHsHj3CPV7ntdWxYScRhPVoj4YIxX2lUZdZ9lrFN0,704
|
|
777
775
|
meta_subject/form_validators/__init__.py,sha256=2g1unLOkE4Wj1ZrWkXSdnZzYnV0kggn_SCpMrhnc_Rg,840
|
|
778
776
|
meta_subject/form_validators/birth_outcomes_form_validator.py,sha256=vujgXKIW4z8bJ536_9uBhETlbChhUvA3Rj5H8zR3UfI,349
|
|
779
777
|
meta_subject/form_validators/delivery_form_validator.py,sha256=mmi6mnr-DLa93uGMoqud_J1LuM1nPyu-VcNyIwEOXk8,3205
|
|
@@ -783,7 +781,7 @@ meta_subject/form_validators/egfr_drop_notification_form_validator.py,sha256=y5M
|
|
|
783
781
|
meta_subject/form_validators/followup_examination_form_validator.py,sha256=NS3Sa-bwC_HEe-CmezkFrbbjPanLe9p1v5ZOFspqgxg,4241
|
|
784
782
|
meta_subject/form_validators/glucose_form_validator.py,sha256=azIttaercmdE2-KM8hrlAzBmH3LHknrIxQ-o_s1kYcE,3979
|
|
785
783
|
meta_subject/form_validators/health_economics_form_validator.py,sha256=kp-LQU4ydBXlnYFt-0xKuVSb8Y4irlhz9d_X8ppvWgE,250
|
|
786
|
-
meta_subject/forms/__init__.py,sha256=
|
|
784
|
+
meta_subject/forms/__init__.py,sha256=LaxPRgHKMfmEWYnxHFbPkVFGSSNVrelG8dL2x49M5oU,2776
|
|
787
785
|
meta_subject/forms/birth_outcomes_form.py,sha256=qqhZNQKiYk8C8CFebZTQB0hOm4ONrgkTG7hfuK7kW-o,374
|
|
788
786
|
meta_subject/forms/blood_results/__init__.py,sha256=DYs2J30cgTPxvY9qDuKfr_kF_muoZ1iVmpu_I3wLpdM,528
|
|
789
787
|
meta_subject/forms/blood_results/blood_results_fbc_form.py,sha256=g6m0HE9I3DIxDPgk6TZUPVU-vliOb3Fiqe3kDyN7h38,714
|
|
@@ -820,7 +818,6 @@ meta_subject/forms/physical_exam_form.py,sha256=QgH1zAmYgp8Hi1tU-e68HaRRkZxf-6xG
|
|
|
820
818
|
meta_subject/forms/pregnancy_update_form.py,sha256=BTiWPoQ-HYbZhW0Go2DSqYU_e51pmJ_UIxEdSNlzTwE,559
|
|
821
819
|
meta_subject/forms/sf12_form.py,sha256=VDV4hyU9UckPX70isylfHWggcWZwiQfCWrpk9kGvxis,397
|
|
822
820
|
meta_subject/forms/slider_widget.py,sha256=aHUszQ1Xxjyf9Ph0echFMX1VuWl4mmabvWN2ixpRy-I,837
|
|
823
|
-
meta_subject/forms/spfq_form.py,sha256=WNMawCxrKCKq3gV1GOoZpxAeF5oAh4QBt6TMu1xGRv0,2123
|
|
824
821
|
meta_subject/forms/study_medication_form.py,sha256=zLPxVmxE3czWIRrSTnnD5-BRvIj5YDfOxhCNQELA9q4,3218
|
|
825
822
|
meta_subject/forms/subject_requisition_form.py,sha256=wf_IVqrwrgaZrPxwyS7Ku-NfWR9eWGW4N9VexANcnHA,950
|
|
826
823
|
meta_subject/forms/subject_visit_form.py,sha256=Zxyjb5-7wUmcLHD-M76ofuM8Vr92yzjvXqQ7GsB3U6o,1374
|
|
@@ -1071,6 +1068,7 @@ meta_subject/migrations/0230_alter_historicaldelivery_action_identifier_and_more
|
|
|
1071
1068
|
meta_subject/migrations/0231_alter_historicalmedicationadherence_consent_model_and_more.py,sha256=LMY0vJ4utO36Zpk0uugU_KlXkv9bCG9-nf8oFsUuWII,78654
|
|
1072
1069
|
meta_subject/migrations/0232_alter_patienthistory_concomitant_conditions_and_more.py,sha256=vX0wJmbLQSg7JYnvzAt3zA20bfPz1AnxNpodKAxdYhM,43686
|
|
1073
1070
|
meta_subject/migrations/0233_historicalspfq_spfq.py,sha256=U8imocD_gtCGTC0zUNt6UZlqZYBUtUNB7cEdFxBbnjA,46072
|
|
1071
|
+
meta_subject/migrations/0234_remove_spfq_site_remove_spfq_subject_visit_and_more.py,sha256=s_1aOSihYNqca-oVYWxiC19joGtOgvB4nz0qtEqmdwQ,584
|
|
1074
1072
|
meta_subject/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1075
1073
|
meta_subject/model_mixins/__init__.py,sha256=fWZpFJ_Ex-TOJFjgSGjcrquKSCenCh_K9Hiy8QUg36o,439
|
|
1076
1074
|
meta_subject/model_mixins/arv_history_model_mixin.py,sha256=6ILacF2koyYmwZIFHmmQO1uIT1eWzrahXxhAlxpQiX0,2898
|
|
@@ -1078,7 +1076,7 @@ meta_subject/model_mixins/crf_model_mixin.py,sha256=UK1ycbYwaZ8LSNTJm74QJ5c-01HD
|
|
|
1078
1076
|
meta_subject/model_mixins/crf_with_action_model_mixin.py,sha256=q1Q16YyPjQlpDtCPOXRkO5C7Vr7JO_QL8xWC48Uz33M,298
|
|
1079
1077
|
meta_subject/model_mixins/search_slug_model_mixin.py,sha256=mEN2gDycLKoZiExM2_H3Dxz8AMAwRSrCq4vu3afr5hA,275
|
|
1080
1078
|
meta_subject/model_mixins/vitals_fields_model_mixin.py,sha256=Uimo-sQS-l4I3KyHej8t0_49mT2UakMKCbO8giYUMQw,2205
|
|
1081
|
-
meta_subject/models/__init__.py,sha256=
|
|
1079
|
+
meta_subject/models/__init__.py,sha256=NXw6Ba2QlYL7ZjZoWeoS1A5g6R3ONnOKtFEH8ltDTvg,2974
|
|
1082
1080
|
meta_subject/models/birth_outcomes.py,sha256=DQp-8Cv5ZWBuaGdiYlL1V3uJaL6H2tf9gYPfYcMTCs8,3142
|
|
1083
1081
|
meta_subject/models/blood_results/__init__.py,sha256=F2jncEUtvrb4G9v5V6p3gSi4dI721CFVCImdJ9qFHmQ,530
|
|
1084
1082
|
meta_subject/models/blood_results/blood_results_fbc.py,sha256=kkOqCsqeIvCf2rw7vHGWMCEgo1_yiMDtTOi44aKtBro,1324
|
|
@@ -1105,7 +1103,7 @@ meta_subject/models/glucose_fbg.py,sha256=MzTPX1sVlp_ypqLmhsurVUV-Ks8XTIMHJy5MBj
|
|
|
1105
1103
|
meta_subject/models/glucose_review.py,sha256=bCnSBe_C3LeBy1XrZpV9rv-hOk8onZ_Tl37t7dqm-sw,450
|
|
1106
1104
|
meta_subject/models/health_economics/__init__.py,sha256=J557vTjzK1EvUAM4mx9zDVQ7Zr0W25stnWXz_zE2a-c,245
|
|
1107
1105
|
meta_subject/models/health_economics/health_economics.py,sha256=pjEbz3d6s-Cy2DEPZnGcd8KjFc27pVed9D6vr3eYLVg,9709
|
|
1108
|
-
meta_subject/models/health_economics/health_economics_simple.py,sha256=
|
|
1106
|
+
meta_subject/models/health_economics/health_economics_simple.py,sha256=w46TrjNvfk736IjtZ8lrN0H3is_ddGRUq8v6MgSqoBY,711
|
|
1109
1107
|
meta_subject/models/health_economics/health_economics_update.py,sha256=gzbu2lpVr9txwYUVfYKADgE0Om1YkNfrVPcwLczbNYc,3334
|
|
1110
1108
|
meta_subject/models/hepatitis_test.py,sha256=_jfDlR_spt7h4KGsMDxmobgAaToKiAZdLGIXCqfH60o,1852
|
|
1111
1109
|
meta_subject/models/malaria_test.py,sha256=4gQNBnvLDv70rjRcFBOpLPmYL8eeuqs0lRsJ7LrFqHM,343
|
|
@@ -1120,7 +1118,6 @@ meta_subject/models/physical_exam.py,sha256=0QH10ZutmowM6_uLyHaMsO0UiH3RrVWhfZD_
|
|
|
1120
1118
|
meta_subject/models/pregnancy_update.py,sha256=yeoMeDkMQxUBjKYjFvqkQCwByTH50jU0QiNXchqJMZo,950
|
|
1121
1119
|
meta_subject/models/sf12.py,sha256=1f6cAMtBUXy7jMaacAU8RJFFv73r9c3rJjBbNl-bSM4,283
|
|
1122
1120
|
meta_subject/models/signals.py,sha256=Z5qoVkSmls9bVm2HwdbaBAPuI6X9Y8v-7PP5F-GQbiU,4568
|
|
1123
|
-
meta_subject/models/spfq.py,sha256=kJjwPsG9YNU8P1XHOmmFvuKX1C36Agm4Np2reWliYcc,6239
|
|
1124
1121
|
meta_subject/models/study_medication.py,sha256=1kA_w4pYT1gcunfiQ46KdM01pd1jrQqLt4JEPLvfTTo,461
|
|
1125
1122
|
meta_subject/models/subject_requisition.py,sha256=bSDwD-hpXeioH3xA7E6eGMu4hxWLDDSxhznfjrpXTjw,341
|
|
1126
1123
|
meta_subject/models/subject_visit.py,sha256=UQQ31lsJS0znw-8d2ft7VOPamn1o-cixHQ9L8rV1vWA,2153
|
|
@@ -1147,7 +1144,7 @@ meta_visit_schedule/visit_schedules/phase_three/schedule.py,sha256=LU1HRaV6o1UeK
|
|
|
1147
1144
|
meta_visit_schedule/visit_schedules/phase_three/schedule_dm_referral.py,sha256=q12p5wXc2D7lSiJVBnoSQw8Q3vL6uDx1t3PuDJO-Z-U,1735
|
|
1148
1145
|
meta_visit_schedule/visit_schedules/phase_three/schedule_pregnancy.py,sha256=bEpbpCX3vfZmnsqudr0z8PU5kiaX4ws1sO5Im98Mo28,1106
|
|
1149
1146
|
meta_visit_schedule/visit_schedules/phase_three/visit_schedule.py,sha256=ak4qazeKlpIlvpqrK9hDDO0fwWuWyvb4Ec-JU31IJxc,654
|
|
1150
|
-
meta_edc-1.
|
|
1151
|
-
meta_edc-1.
|
|
1152
|
-
meta_edc-1.
|
|
1153
|
-
meta_edc-1.
|
|
1147
|
+
meta_edc-1.2.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
1148
|
+
meta_edc-1.2.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
|
|
1149
|
+
meta_edc-1.2.0.dist-info/METADATA,sha256=DiyZTaq7ut9pqEqAuJEpkcWT5wPdZDm5Ug_uyZokP9E,5166
|
|
1150
|
+
meta_edc-1.2.0.dist-info/RECORD,,
|
meta_prn/baker_recipes.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from dateutil.relativedelta import relativedelta
|
|
2
2
|
from django.utils import timezone
|
|
3
|
-
from edc_constants.constants import YES
|
|
3
|
+
from edc_constants.constants import NULL_STRING, YES
|
|
4
4
|
from faker import Faker
|
|
5
5
|
from model_bakery.recipe import Recipe
|
|
6
6
|
|
|
@@ -12,17 +12,17 @@ fake = Faker()
|
|
|
12
12
|
pregnancynotification = Recipe(
|
|
13
13
|
PregnancyNotification,
|
|
14
14
|
# site=None,
|
|
15
|
-
action_identifier=
|
|
16
|
-
subject_identifier=
|
|
15
|
+
action_identifier=NULL_STRING,
|
|
16
|
+
subject_identifier=NULL_STRING,
|
|
17
17
|
report_datetime=timezone.now(),
|
|
18
18
|
bhcg_confirmed=YES,
|
|
19
|
-
unconfirmed_details=
|
|
19
|
+
unconfirmed_details=NULL_STRING,
|
|
20
20
|
edd=timezone.now() + relativedelta(months=6),
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
dmreferral = Recipe(
|
|
24
24
|
DmReferral,
|
|
25
|
-
action_identifier=
|
|
26
|
-
subject_identifier=
|
|
25
|
+
action_identifier=NULL_STRING,
|
|
26
|
+
subject_identifier=NULL_STRING,
|
|
27
27
|
report_datetime=timezone.now(),
|
|
28
28
|
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Generated by Django 5.2.7 on 2025-10-01 14:33
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("meta_prn", "0068_alter_dmreferral_referral_note_and_more"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name="historicaloffstudymedication",
|
|
15
|
+
name="singleton_field",
|
|
16
|
+
field=models.CharField(
|
|
17
|
+
db_index=True,
|
|
18
|
+
default="",
|
|
19
|
+
editable=False,
|
|
20
|
+
help_text="auto updated for unique constraint",
|
|
21
|
+
max_length=50,
|
|
22
|
+
verbose_name="subject identifier",
|
|
23
|
+
),
|
|
24
|
+
),
|
|
25
|
+
migrations.AlterField(
|
|
26
|
+
model_name="offstudymedication",
|
|
27
|
+
name="singleton_field",
|
|
28
|
+
field=models.CharField(
|
|
29
|
+
default="",
|
|
30
|
+
editable=False,
|
|
31
|
+
help_text="auto updated for unique constraint",
|
|
32
|
+
max_length=50,
|
|
33
|
+
unique=True,
|
|
34
|
+
verbose_name="subject identifier",
|
|
35
|
+
),
|
|
36
|
+
),
|
|
37
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-30 22:50
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("meta_rando", "0007_spfqlist"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.DeleteModel(
|
|
14
|
+
name="SpfqList",
|
|
15
|
+
),
|
|
16
|
+
]
|
meta_rando/models/__init__.py
CHANGED
meta_subject/admin/__init__.py
CHANGED
|
@@ -28,7 +28,6 @@ from .patient_history_admin import PatientHistoryAdmin
|
|
|
28
28
|
from .physical_exam_admin import PhysicalExamAdmin
|
|
29
29
|
from .pregnancy_update_admin import PregnancyUpdateAdmin
|
|
30
30
|
from .sf12_admin import Sf12Admin
|
|
31
|
-
from .spfg_admin import SpfqAdmin
|
|
32
31
|
from .study_medication_admin import StudyMedicationAdmin
|
|
33
32
|
from .subject_requisition_admin import SubjectRequisitionAdmin
|
|
34
33
|
from .subject_visit_admin import SubjectVisitAdmin
|
|
@@ -67,7 +66,6 @@ __all__ = [
|
|
|
67
66
|
"PhysicalExamAdmin",
|
|
68
67
|
"PregnancyUpdateAdmin",
|
|
69
68
|
"Sf12Admin",
|
|
70
|
-
"SpfqAdmin",
|
|
71
69
|
"StudyMedicationAdmin",
|
|
72
70
|
"SubjectRequisitionAdmin",
|
|
73
71
|
"SubjectVisitAdmin",
|
meta_subject/choices.py
CHANGED
|
@@ -26,28 +26,14 @@ from .constants import (
|
|
|
26
26
|
ALL_OF_THE_TIME,
|
|
27
27
|
APPT,
|
|
28
28
|
APPT_OTHER,
|
|
29
|
-
EXTREME,
|
|
30
29
|
GOOD_BIT_OF_THE_TIME,
|
|
31
|
-
HIGHLY,
|
|
32
30
|
LITTLE_OF_THE_TIME,
|
|
33
31
|
LIVE_AT_TERM,
|
|
34
32
|
LIVE_PRETERM,
|
|
35
|
-
MODERATE,
|
|
36
|
-
MODERATELY,
|
|
37
33
|
MOST_OF_THE_TIME,
|
|
38
|
-
MUCH_LESS_EXPECTED,
|
|
39
|
-
MUCH_MORE_EXPECTED,
|
|
40
34
|
NO_COMPLICATIONS,
|
|
41
35
|
NONE_OF_THE_TIME,
|
|
42
|
-
NOT_AT_ALL,
|
|
43
|
-
SAME_AS_EXPECTED,
|
|
44
|
-
SEVERE,
|
|
45
|
-
SLIGHT,
|
|
46
|
-
SLIGHTLY,
|
|
47
36
|
SOME_OF_THE_TIME,
|
|
48
|
-
SOMEWHAT_LESS_EXPECTED,
|
|
49
|
-
SOMEWHAT_MORE_EXPECTED,
|
|
50
|
-
VERY_HIGHLY,
|
|
51
37
|
)
|
|
52
38
|
|
|
53
39
|
ACTIVITY_CHOICES = (
|
|
@@ -256,26 +242,3 @@ YES_NO_NO_EXAM = (
|
|
|
256
242
|
(NO, _(NO)),
|
|
257
243
|
(NO_EXAM, _("Exam not performed")),
|
|
258
244
|
)
|
|
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,29 +6,15 @@ 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"
|
|
10
9
|
FOLLOWUP_EXAMINATION_ACTION = "followup-examination-ae"
|
|
11
10
|
GOOD_BIT_OF_THE_TIME = "good_bit_of_the_time"
|
|
12
|
-
HIGHLY = "highly"
|
|
13
11
|
LITTLE_OF_THE_TIME = "little_of_the_time"
|
|
14
12
|
LIVE_AT_TERM = "live_at_term"
|
|
15
13
|
LIVE_PRETERM = "live_preterm"
|
|
16
14
|
LOW_EGFR_ACTION = "low-egfr"
|
|
17
15
|
MISSED_VISIT_ACTION = "missed_visit_action"
|
|
18
|
-
MODERATE = "moderate"
|
|
19
|
-
MODERATELY = "moderately"
|
|
20
16
|
MOST_OF_THE_TIME = "most_of_the_time"
|
|
21
|
-
MUCH_LESS_EXPECTED = "much_less_expected"
|
|
22
|
-
MUCH_MORE_EXPECTED = "much_more_expected"
|
|
23
17
|
NONE_OF_THE_TIME = "none_of_the_time"
|
|
24
|
-
NOT_AT_ALL = "not_at_all"
|
|
25
18
|
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"
|
|
32
19
|
SOME_OF_THE_TIME = "some_of_the_time"
|
|
33
20
|
URINE_PREGNANCY_ACTION = "urine_pregnancy_action"
|
|
34
|
-
VERY_HIGHLY = "very_highly"
|
meta_subject/forms/__init__.py
CHANGED
|
@@ -29,7 +29,6 @@ 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
|
|
33
32
|
from .study_medication_form import StudyMedicationForm
|
|
34
33
|
from .subject_requisition_form import SubjectRequisitionForm
|
|
35
34
|
from .subject_visit_form import SubjectVisitForm
|
|
@@ -70,7 +69,6 @@ __all__ = [
|
|
|
70
69
|
"PhysicalExamForm",
|
|
71
70
|
"PregnancyUpdateForm",
|
|
72
71
|
"Sf12Form",
|
|
73
|
-
"SpfqForm",
|
|
74
72
|
"StudyMedicationForm",
|
|
75
73
|
"SubjectRequisitionForm",
|
|
76
74
|
"SubjectVisitForm",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-30 22:50
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("meta_subject", "0233_historicalspfq_spfq"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.RemoveField(
|
|
14
|
+
model_name="spfq",
|
|
15
|
+
name="site",
|
|
16
|
+
),
|
|
17
|
+
migrations.RemoveField(
|
|
18
|
+
model_name="spfq",
|
|
19
|
+
name="subject_visit",
|
|
20
|
+
),
|
|
21
|
+
migrations.DeleteModel(
|
|
22
|
+
name="HistoricalSpfq",
|
|
23
|
+
),
|
|
24
|
+
migrations.DeleteModel(
|
|
25
|
+
name="Spfq",
|
|
26
|
+
),
|
|
27
|
+
]
|
meta_subject/models/__init__.py
CHANGED
|
@@ -42,7 +42,6 @@ from .signals import (
|
|
|
42
42
|
update_pregnancy_notification_on_delivery_post_save,
|
|
43
43
|
update_schedule_on_delivery_post_save,
|
|
44
44
|
)
|
|
45
|
-
from .spfq import Spfq
|
|
46
45
|
from .study_medication import StudyMedication
|
|
47
46
|
from .subject_requisition import SubjectRequisition
|
|
48
47
|
from .subject_visit import SubjectVisit
|
|
@@ -86,7 +85,6 @@ __all__ = [
|
|
|
86
85
|
"PhysicalExam",
|
|
87
86
|
"PregnancyUpdate",
|
|
88
87
|
"Sf12",
|
|
89
|
-
"Spfq",
|
|
90
88
|
"StudyMedication",
|
|
91
89
|
"SubjectRequisition",
|
|
92
90
|
"SubjectVisit",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
from edc_constants.choices import MARITAL_STATUS
|
|
3
|
-
from edc_he.model_mixins import
|
|
3
|
+
from edc_he.model_mixins import EducationModelMixin
|
|
4
4
|
from edc_model.models import BaseUuidModel
|
|
5
5
|
|
|
6
6
|
from ...model_mixins import CrfModelMixin
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class HealthEconomicsSimple(
|
|
9
|
+
class HealthEconomicsSimple(EducationModelMixin, CrfModelMixin, BaseUuidModel):
|
|
10
10
|
occupation = models.CharField(
|
|
11
11
|
verbose_name="What is your occupation/profession?", max_length=50
|
|
12
12
|
)
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
from django.contrib import admin
|
|
2
|
-
from django.utils.translation import gettext as _
|
|
3
|
-
from django_audit_fields import audit_fieldset_tuple
|
|
4
|
-
from edc_model_admin.dashboard import ModelAdminSubjectDashboardMixin
|
|
5
|
-
from edc_model_admin.history import SimpleHistoryAdmin
|
|
6
|
-
|
|
7
|
-
from ..admin_site import meta_consent_admin
|
|
8
|
-
from ..forms import SubjectConsentSpfqForm
|
|
9
|
-
from ..models import SubjectConsentSpfq
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@admin.register(SubjectConsentSpfq, site=meta_consent_admin)
|
|
13
|
-
class SubjectConsentSpfqAdmin(
|
|
14
|
-
ModelAdminSubjectDashboardMixin,
|
|
15
|
-
SimpleHistoryAdmin,
|
|
16
|
-
):
|
|
17
|
-
form = SubjectConsentSpfqForm
|
|
18
|
-
|
|
19
|
-
fieldsets = (
|
|
20
|
-
(
|
|
21
|
-
None,
|
|
22
|
-
{
|
|
23
|
-
"fields": (
|
|
24
|
-
"subject_identifier",
|
|
25
|
-
"initials",
|
|
26
|
-
"gender",
|
|
27
|
-
"language",
|
|
28
|
-
"consent_datetime",
|
|
29
|
-
)
|
|
30
|
-
},
|
|
31
|
-
),
|
|
32
|
-
(
|
|
33
|
-
"Review Questions",
|
|
34
|
-
{
|
|
35
|
-
"fields": (
|
|
36
|
-
"consent_reviewed",
|
|
37
|
-
"study_questions",
|
|
38
|
-
"assessment_score",
|
|
39
|
-
"consent_signature",
|
|
40
|
-
"consent_copy",
|
|
41
|
-
),
|
|
42
|
-
"description": _("The following questions are directed to the interviewer."),
|
|
43
|
-
},
|
|
44
|
-
),
|
|
45
|
-
audit_fieldset_tuple,
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
search_fields = ("subject_identifier",)
|
|
49
|
-
|
|
50
|
-
radio_fields = { # noqa: RUF012
|
|
51
|
-
"gender": admin.VERTICAL,
|
|
52
|
-
"assessment_score": admin.VERTICAL,
|
|
53
|
-
"consent_copy": admin.VERTICAL,
|
|
54
|
-
"consent_reviewed": admin.VERTICAL,
|
|
55
|
-
"consent_signature": admin.VERTICAL,
|
|
56
|
-
"language": admin.VERTICAL,
|
|
57
|
-
"study_questions": admin.VERTICAL,
|
|
58
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
from django import forms
|
|
2
|
-
from django.core.exceptions import ObjectDoesNotExist
|
|
3
|
-
from edc_action_item.forms import ActionItemFormMixin
|
|
4
|
-
from edc_form_validators import FormValidatorMixin
|
|
5
|
-
from edc_registration.models import RegisteredSubject
|
|
6
|
-
from edc_sites.modelform_mixins import SiteModelFormMixin
|
|
7
|
-
|
|
8
|
-
from meta_consent.models import SubjectConsentSpfq
|
|
9
|
-
from meta_rando.models import SpfqList
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class SubjectConsentSpfqForm(
|
|
13
|
-
SiteModelFormMixin, ActionItemFormMixin, FormValidatorMixin, forms.ModelForm
|
|
14
|
-
):
|
|
15
|
-
def clean(self):
|
|
16
|
-
cleaned_data = super().clean()
|
|
17
|
-
|
|
18
|
-
try:
|
|
19
|
-
RegisteredSubject.objects.get(
|
|
20
|
-
subject_identifier=cleaned_data.get("subject_identifier"),
|
|
21
|
-
initials=cleaned_data.get("initials"),
|
|
22
|
-
gender=cleaned_data.get("gender"),
|
|
23
|
-
)
|
|
24
|
-
except ObjectDoesNotExist as e:
|
|
25
|
-
raise forms.ValidationError(
|
|
26
|
-
{
|
|
27
|
-
"__all__": (
|
|
28
|
-
"Subject not known to the META trial. "
|
|
29
|
-
"Check that the identifier, initials and gender match the patient "
|
|
30
|
-
"register from the main META trial."
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
) from e
|
|
34
|
-
try:
|
|
35
|
-
SpfqList.objects.get(
|
|
36
|
-
subject_identifier=cleaned_data.get("subject_identifier"),
|
|
37
|
-
)
|
|
38
|
-
except ObjectDoesNotExist as e:
|
|
39
|
-
raise forms.ValidationError(
|
|
40
|
-
{
|
|
41
|
-
"__all__": (
|
|
42
|
-
"Subject not found .A subject with this identifier "
|
|
43
|
-
"has not been selected for the sub-study."
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
) from e
|
|
47
|
-
return cleaned_data
|
|
48
|
-
|
|
49
|
-
class Meta:
|
|
50
|
-
model = SubjectConsentSpfq
|
|
51
|
-
fields = "__all__"
|
|
52
|
-
widgets = { # noqa: RUF012
|
|
53
|
-
"action_identifier": forms.TextInput(attrs={"readonly": "readonly"}),
|
|
54
|
-
"subject_identifier": forms.TextInput(attrs={"readonly": "readonly"}),
|
|
55
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
from django.conf import settings
|
|
2
|
-
from django.contrib.sites.managers import CurrentSiteManager
|
|
3
|
-
from django.core.validators import RegexValidator
|
|
4
|
-
from django.db import models
|
|
5
|
-
from django.utils import timezone
|
|
6
|
-
from django.utils.translation import gettext_lazy as _
|
|
7
|
-
from django_crypto_fields.fields import EncryptedCharField
|
|
8
|
-
from edc_consent.field_mixins import (
|
|
9
|
-
ReviewFieldsMixin,
|
|
10
|
-
)
|
|
11
|
-
from edc_consent.managers import ConsentObjectsManager
|
|
12
|
-
from edc_constants.choices import GENDER
|
|
13
|
-
from edc_constants.constants import NULL_STRING
|
|
14
|
-
from edc_model.models import BaseUuidModel, HistoricalRecords
|
|
15
|
-
from edc_sites.model_mixins import SiteModelMixin
|
|
16
|
-
|
|
17
|
-
from .model_mixins import SearchSlugModelMixin
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class SubjectConsentSpfq(
|
|
21
|
-
SiteModelMixin,
|
|
22
|
-
ReviewFieldsMixin,
|
|
23
|
-
SearchSlugModelMixin,
|
|
24
|
-
BaseUuidModel,
|
|
25
|
-
):
|
|
26
|
-
"""A model completed by the user that captures the ICF for SPFQ."""
|
|
27
|
-
|
|
28
|
-
subject_identifier = models.CharField(
|
|
29
|
-
verbose_name=_("Subject identifier"), max_length=50, unique=True
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
initials = EncryptedCharField(
|
|
33
|
-
validators=[
|
|
34
|
-
RegexValidator(
|
|
35
|
-
regex=r"^[A-Z]{2,3}$",
|
|
36
|
-
message="Ensure initials consist of letters only in upper case, no spaces.",
|
|
37
|
-
)
|
|
38
|
-
],
|
|
39
|
-
default=NULL_STRING,
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
gender = models.CharField(
|
|
43
|
-
verbose_name="Gender",
|
|
44
|
-
choices=GENDER,
|
|
45
|
-
max_length=1,
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
consent_datetime = models.DateTimeField(
|
|
49
|
-
verbose_name=_("Consent datetime"), default=timezone.now
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
report_datetime = models.DateTimeField(null=True, editable=False)
|
|
53
|
-
|
|
54
|
-
language = models.CharField(
|
|
55
|
-
verbose_name=_("Language of consent"),
|
|
56
|
-
max_length=25,
|
|
57
|
-
choices=settings.LANGUAGES,
|
|
58
|
-
help_text=_(
|
|
59
|
-
"The language used for the consent process will "
|
|
60
|
-
"also be used during data collection."
|
|
61
|
-
),
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
model_name = models.CharField(
|
|
65
|
-
verbose_name="model",
|
|
66
|
-
max_length=50,
|
|
67
|
-
help_text=(
|
|
68
|
-
"label_lower of this model class. Will be different if "
|
|
69
|
-
"instance has been added/edited via a proxy model"
|
|
70
|
-
),
|
|
71
|
-
default=NULL_STRING,
|
|
72
|
-
editable=False,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
version = models.CharField(
|
|
76
|
-
verbose_name="Consent version",
|
|
77
|
-
max_length=10,
|
|
78
|
-
default="1.0",
|
|
79
|
-
help_text="See 'consent definition' for consent versions by period.",
|
|
80
|
-
editable=False,
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
on_site = CurrentSiteManager()
|
|
84
|
-
|
|
85
|
-
objects = ConsentObjectsManager()
|
|
86
|
-
|
|
87
|
-
history = HistoricalRecords()
|
|
88
|
-
|
|
89
|
-
def __str__(self):
|
|
90
|
-
return f"{self.subject_identifier} V{self.version}"
|
|
91
|
-
|
|
92
|
-
def save(self, *args, **kwargs):
|
|
93
|
-
if not self.id:
|
|
94
|
-
self.model_name = self._meta.label_lower
|
|
95
|
-
self.report_datetime = self.consent_datetime
|
|
96
|
-
super().save(*args, **kwargs)
|
|
97
|
-
|
|
98
|
-
def natural_key(self):
|
|
99
|
-
return self.subject_identifier, self.version
|
|
100
|
-
|
|
101
|
-
class Meta(BaseUuidModel.Meta):
|
|
102
|
-
verbose_name = "Subject Consent for SPFQ"
|
|
103
|
-
verbose_name_plural = "Subject Consents for SPFQ"
|
meta_rando/models/spfq_list.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
from edc_constants.choices import GENDER
|
|
3
|
-
from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
|
|
4
|
-
from edc_model.models import BaseUuidModel
|
|
5
|
-
from edc_sites.model_mixins import SiteModelMixin
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class SpfqList(SiteModelMixin, UniqueSubjectIdentifierFieldMixin, BaseUuidModel):
|
|
9
|
-
sid = models.IntegerField(unique=True)
|
|
10
|
-
|
|
11
|
-
last_visit_code = models.CharField(max_length=25)
|
|
12
|
-
|
|
13
|
-
last_appt_datetime = models.DateTimeField()
|
|
14
|
-
|
|
15
|
-
gender = models.CharField(max_length=10, choices=GENDER)
|
|
16
|
-
|
|
17
|
-
weight_bin = models.CharField(
|
|
18
|
-
max_length=25,
|
|
19
|
-
choices=(("lt_35", "<35"), ("gte_35__lte_49", "35-49"), ("gte_50", ">=50")),
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
date_generated = models.DateTimeField()
|
|
23
|
-
|
|
24
|
-
class Meta(BaseUuidModel.Meta):
|
|
25
|
-
verbose_name = "SPFQ List"
|
|
26
|
-
verbose_name_plural = "SPFQ List"
|
meta_subject/admin/spfg_admin.py
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
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/forms/spfq_form.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
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__"
|
meta_subject/models/spfq.py
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
from edc_constants.choices import DIFFICULT_TO_EASY_CHOICE, DISAGREE_TO_AGREE_CHOICE, YES_NO
|
|
3
|
-
from edc_model.models import BaseUuidModel
|
|
4
|
-
|
|
5
|
-
from ..choices import (
|
|
6
|
-
LESS_EXPECTED_TO_MORE_EXPECTED_CHOICE,
|
|
7
|
-
NOT_AT_ALL_TO_HIGHLY_CHOICE,
|
|
8
|
-
NOT_AT_ALL_TO_SEVERE_CHOICE,
|
|
9
|
-
)
|
|
10
|
-
from ..model_mixins import CrfModelMixin
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Spfq(CrfModelMixin, BaseUuidModel):
|
|
14
|
-
a01 = models.CharField(
|
|
15
|
-
verbose_name="I understood the treatment process in this trial",
|
|
16
|
-
max_length=25,
|
|
17
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
18
|
-
help_text="for example: when and how to take or use a treatment",
|
|
19
|
-
)
|
|
20
|
-
a02 = models.CharField(
|
|
21
|
-
verbose_name=(
|
|
22
|
-
"The information given to me before "
|
|
23
|
-
"I joined the trial was everything I wanted to know"
|
|
24
|
-
),
|
|
25
|
-
max_length=25,
|
|
26
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
27
|
-
help_text=(
|
|
28
|
-
"for example: visits and procedures, "
|
|
29
|
-
"time commitment, who to contact with questions"
|
|
30
|
-
),
|
|
31
|
-
)
|
|
32
|
-
a03 = models.CharField(
|
|
33
|
-
verbose_name=(
|
|
34
|
-
"The information given to me before I "
|
|
35
|
-
"joined the trial was easy for me to understand"
|
|
36
|
-
),
|
|
37
|
-
max_length=25,
|
|
38
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
39
|
-
help_text=(
|
|
40
|
-
"for example: visits and procedures, "
|
|
41
|
-
"time commitment, who to contact with questions"
|
|
42
|
-
),
|
|
43
|
-
)
|
|
44
|
-
a04 = models.CharField(
|
|
45
|
-
verbose_name=(
|
|
46
|
-
"I felt comfortable that I could ask any questions before I joined the trial"
|
|
47
|
-
),
|
|
48
|
-
max_length=25,
|
|
49
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
50
|
-
)
|
|
51
|
-
b01 = models.CharField(
|
|
52
|
-
verbose_name="Overall I was satisfied with the trial site",
|
|
53
|
-
max_length=25,
|
|
54
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
55
|
-
help_text=(
|
|
56
|
-
"for example: comfort and privacy of treatment area, "
|
|
57
|
-
"waiting area, parking, ease of access to the site"
|
|
58
|
-
),
|
|
59
|
-
)
|
|
60
|
-
b02 = models.CharField(
|
|
61
|
-
verbose_name="My trial visits were well organized",
|
|
62
|
-
max_length=25,
|
|
63
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
64
|
-
)
|
|
65
|
-
b03 = models.CharField(
|
|
66
|
-
verbose_name="My trial visits were scheduled at a convenient time for me",
|
|
67
|
-
max_length=25,
|
|
68
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
69
|
-
)
|
|
70
|
-
b04 = models.CharField(
|
|
71
|
-
verbose_name="The staff treated me with respect",
|
|
72
|
-
max_length=25,
|
|
73
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
74
|
-
)
|
|
75
|
-
b05 = models.CharField(
|
|
76
|
-
verbose_name="I felt comfortable that I could ask questions during the trial",
|
|
77
|
-
max_length=25,
|
|
78
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
79
|
-
)
|
|
80
|
-
b06 = models.CharField(
|
|
81
|
-
verbose_name=(
|
|
82
|
-
"I was satisfied with the answers I have received to my questions during the trial"
|
|
83
|
-
),
|
|
84
|
-
max_length=25,
|
|
85
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
86
|
-
)
|
|
87
|
-
b07 = models.CharField(
|
|
88
|
-
verbose_name="The time taken to collect data was acceptable to me",
|
|
89
|
-
max_length=25,
|
|
90
|
-
choices=YES_NO,
|
|
91
|
-
help_text="for example: in person visits, questionnaires, forms",
|
|
92
|
-
)
|
|
93
|
-
b08 = models.CharField(
|
|
94
|
-
verbose_name="The impact the trial has had on my daily activities is acceptable",
|
|
95
|
-
max_length=25,
|
|
96
|
-
choices=YES_NO,
|
|
97
|
-
help_text="for example: household chores, work commitments, eating",
|
|
98
|
-
)
|
|
99
|
-
b09 = models.CharField(
|
|
100
|
-
verbose_name="The way in which trial data is being collected is acceptable to me",
|
|
101
|
-
max_length=25,
|
|
102
|
-
choices=YES_NO,
|
|
103
|
-
help_text=(
|
|
104
|
-
"for example: in person, online questionnaire, "
|
|
105
|
-
"diary, wearable sensors, monitoring machines, technology"
|
|
106
|
-
),
|
|
107
|
-
)
|
|
108
|
-
b10 = models.CharField(
|
|
109
|
-
verbose_name=(
|
|
110
|
-
"Optional: I am being kept informed of the results of "
|
|
111
|
-
"my medical tests done during the trial, including during screening"
|
|
112
|
-
),
|
|
113
|
-
max_length=25,
|
|
114
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
115
|
-
help_text="for example: blood tests, scans etc.",
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
c01 = models.CharField(
|
|
119
|
-
verbose_name="I was informed when I had completed the trial",
|
|
120
|
-
max_length=25,
|
|
121
|
-
choices=YES_NO,
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
c02 = models.CharField(
|
|
125
|
-
verbose_name=(
|
|
126
|
-
"I was informed of any future opportunities to "
|
|
127
|
-
"access the overall trial results if I wanted to"
|
|
128
|
-
),
|
|
129
|
-
max_length=25,
|
|
130
|
-
choices=YES_NO,
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
c03 = models.CharField(
|
|
134
|
-
verbose_name="How easy was it to take the medication?",
|
|
135
|
-
max_length=25,
|
|
136
|
-
choices=DIFFICULT_TO_EASY_CHOICE,
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
c04 = models.CharField(
|
|
140
|
-
verbose_name="Did you experience any burden or side effects?",
|
|
141
|
-
max_length=25,
|
|
142
|
-
choices=NOT_AT_ALL_TO_SEVERE_CHOICE,
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
c05 = models.CharField(
|
|
146
|
-
verbose_name="How acceptable was it to take the drug?",
|
|
147
|
-
max_length=25,
|
|
148
|
-
choices=NOT_AT_ALL_TO_HIGHLY_CHOICE,
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
c06 = models.CharField(
|
|
152
|
-
verbose_name="How easy was it to fit the medication into your routine?",
|
|
153
|
-
max_length=25,
|
|
154
|
-
choices=DIFFICULT_TO_EASY_CHOICE,
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
c07 = models.CharField(
|
|
158
|
-
verbose_name="How burdensome was taking part in the trial?",
|
|
159
|
-
max_length=25,
|
|
160
|
-
choices=NOT_AT_ALL_TO_SEVERE_CHOICE,
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
c08 = models.CharField(
|
|
164
|
-
verbose_name=(
|
|
165
|
-
"Overall, I was satisfied with the information "
|
|
166
|
-
"I received about future support after the trial"
|
|
167
|
-
),
|
|
168
|
-
max_length=25,
|
|
169
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
170
|
-
help_text="for example: future treatment, follow-up contact details",
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
c09 = models.CharField(
|
|
174
|
-
verbose_name="Overall, I was satisfied with my trial experience",
|
|
175
|
-
max_length=25,
|
|
176
|
-
choices=DISAGREE_TO_AGREE_CHOICE,
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
c10 = models.CharField(
|
|
180
|
-
verbose_name=(
|
|
181
|
-
"Compared to when the trial started, the overall "
|
|
182
|
-
"commitment required was similar to what I expected"
|
|
183
|
-
),
|
|
184
|
-
max_length=25,
|
|
185
|
-
choices=LESS_EXPECTED_TO_MORE_EXPECTED_CHOICE,
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
class Meta(CrfModelMixin.Meta, BaseUuidModel.Meta):
|
|
189
|
-
verbose_name = "Feedback Questionnaire (SPFQ)"
|
|
190
|
-
verbose_name_plural = "Feedback Questionnaires (SPFQ)"
|
|
File without changes
|
|
File without changes
|