meta-edc 1.1.18__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/migrations/0033_historicalsubjectconsentspfq_subjectconsentspfq.py +615 -0
- meta_consent/migrations/0034_remove_subjectconsentspfq_site_and_more.py +23 -0
- meta_consent/models/signals.py +13 -16
- meta_edc/settings/defaults.py +14 -10
- meta_edc/urls.py +1 -0
- {meta_edc-1.1.18.dist-info → meta_edc-1.2.0.dist-info}/METADATA +6 -5
- {meta_edc-1.1.18.dist-info → meta_edc-1.2.0.dist-info}/RECORD +24 -12
- meta_labs/list_data.py +2 -2
- meta_prn/baker_recipes.py +6 -6
- meta_prn/migrations/0069_alter_historicaloffstudymedication_singleton_field_and_more.py +37 -0
- meta_rando/migrations/0007_spfqlist.py +197 -0
- meta_rando/migrations/0008_delete_spfqlist.py +16 -0
- meta_rando/models/__init__.py +1 -0
- meta_rando/{models.py → models/randomization_list.py} +3 -3
- 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/migrations/0234_remove_spfq_site_remove_spfq_subject_visit_and_more.py +27 -0
- meta_subject/models/health_economics/health_economics_simple.py +2 -2
- {meta_edc-1.1.18.dist-info → meta_edc-1.2.0.dist-info}/WHEEL +0 -0
- {meta_edc-1.1.18.dist-info → meta_edc-1.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-30 01:40
|
|
2
|
+
|
|
3
|
+
import _socket
|
|
4
|
+
import django.contrib.sites.managers
|
|
5
|
+
import django.core.validators
|
|
6
|
+
import django.db.models.deletion
|
|
7
|
+
import django.utils.timezone
|
|
8
|
+
import django_audit_fields.fields.hostname_modification_field
|
|
9
|
+
import django_audit_fields.fields.userfield
|
|
10
|
+
import django_audit_fields.fields.uuid_auto_field
|
|
11
|
+
import django_crypto_fields.fields.encrypted_char_field
|
|
12
|
+
import django_revision.revision_field
|
|
13
|
+
import edc_consent.managers
|
|
14
|
+
import edc_consent.validators
|
|
15
|
+
import simple_history.models
|
|
16
|
+
import uuid
|
|
17
|
+
from django.conf import settings
|
|
18
|
+
from django.db import migrations, models
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Migration(migrations.Migration):
|
|
22
|
+
|
|
23
|
+
dependencies = [
|
|
24
|
+
("meta_consent", "0032_alter_historicalsubjectconsent_device_created_and_more"),
|
|
25
|
+
("sites", "0002_alter_domain_unique"),
|
|
26
|
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
operations = [
|
|
30
|
+
migrations.CreateModel(
|
|
31
|
+
name="HistoricalSubjectConsentSpfq",
|
|
32
|
+
fields=[
|
|
33
|
+
(
|
|
34
|
+
"revision",
|
|
35
|
+
django_revision.revision_field.RevisionField(
|
|
36
|
+
blank=True,
|
|
37
|
+
default="",
|
|
38
|
+
editable=False,
|
|
39
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
40
|
+
max_length=75,
|
|
41
|
+
verbose_name="Revision",
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
(
|
|
45
|
+
"created",
|
|
46
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
47
|
+
),
|
|
48
|
+
(
|
|
49
|
+
"modified",
|
|
50
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
51
|
+
),
|
|
52
|
+
(
|
|
53
|
+
"user_created",
|
|
54
|
+
django_audit_fields.fields.userfield.UserField(
|
|
55
|
+
blank=True,
|
|
56
|
+
default="",
|
|
57
|
+
help_text="Updated by admin.save_model",
|
|
58
|
+
max_length=50,
|
|
59
|
+
verbose_name="user created",
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
(
|
|
63
|
+
"user_modified",
|
|
64
|
+
django_audit_fields.fields.userfield.UserField(
|
|
65
|
+
blank=True,
|
|
66
|
+
default="",
|
|
67
|
+
help_text="Updated by admin.save_model",
|
|
68
|
+
max_length=50,
|
|
69
|
+
verbose_name="user modified",
|
|
70
|
+
),
|
|
71
|
+
),
|
|
72
|
+
(
|
|
73
|
+
"hostname_created",
|
|
74
|
+
models.CharField(
|
|
75
|
+
blank=True,
|
|
76
|
+
default=_socket.gethostname,
|
|
77
|
+
help_text="System field. (modified on create only)",
|
|
78
|
+
max_length=60,
|
|
79
|
+
verbose_name="Hostname created",
|
|
80
|
+
),
|
|
81
|
+
),
|
|
82
|
+
(
|
|
83
|
+
"hostname_modified",
|
|
84
|
+
django_audit_fields.fields.hostname_modification_field.HostnameModificationField(
|
|
85
|
+
blank=True,
|
|
86
|
+
default="",
|
|
87
|
+
help_text="System field. (modified on every save)",
|
|
88
|
+
max_length=50,
|
|
89
|
+
verbose_name="Hostname modified",
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
(
|
|
93
|
+
"device_created",
|
|
94
|
+
models.CharField(
|
|
95
|
+
blank=True,
|
|
96
|
+
default="",
|
|
97
|
+
max_length=10,
|
|
98
|
+
verbose_name="Device created",
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
(
|
|
102
|
+
"device_modified",
|
|
103
|
+
models.CharField(
|
|
104
|
+
blank=True,
|
|
105
|
+
default="",
|
|
106
|
+
max_length=10,
|
|
107
|
+
verbose_name="Device modified",
|
|
108
|
+
),
|
|
109
|
+
),
|
|
110
|
+
(
|
|
111
|
+
"locale_created",
|
|
112
|
+
models.CharField(
|
|
113
|
+
blank=True,
|
|
114
|
+
default="",
|
|
115
|
+
help_text="Auto-updated by Modeladmin",
|
|
116
|
+
max_length=10,
|
|
117
|
+
verbose_name="Locale created",
|
|
118
|
+
),
|
|
119
|
+
),
|
|
120
|
+
(
|
|
121
|
+
"locale_modified",
|
|
122
|
+
models.CharField(
|
|
123
|
+
blank=True,
|
|
124
|
+
default="",
|
|
125
|
+
help_text="Auto-updated by Modeladmin",
|
|
126
|
+
max_length=10,
|
|
127
|
+
verbose_name="Locale modified",
|
|
128
|
+
),
|
|
129
|
+
),
|
|
130
|
+
(
|
|
131
|
+
"id",
|
|
132
|
+
django_audit_fields.fields.uuid_auto_field.UUIDAutoField(
|
|
133
|
+
blank=True,
|
|
134
|
+
db_index=True,
|
|
135
|
+
editable=False,
|
|
136
|
+
help_text="System auto field. UUID primary key.",
|
|
137
|
+
),
|
|
138
|
+
),
|
|
139
|
+
(
|
|
140
|
+
"consent_reviewed",
|
|
141
|
+
models.CharField(
|
|
142
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
143
|
+
help_text="If no, participant is not eligible.",
|
|
144
|
+
max_length=3,
|
|
145
|
+
null=True,
|
|
146
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
147
|
+
verbose_name="I have reviewed the consent with the participant",
|
|
148
|
+
),
|
|
149
|
+
),
|
|
150
|
+
(
|
|
151
|
+
"study_questions",
|
|
152
|
+
models.CharField(
|
|
153
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
154
|
+
help_text="If no, participant is not eligible.",
|
|
155
|
+
max_length=3,
|
|
156
|
+
null=True,
|
|
157
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
158
|
+
verbose_name="I have answered all questions the participant had about the study",
|
|
159
|
+
),
|
|
160
|
+
),
|
|
161
|
+
(
|
|
162
|
+
"assessment_score",
|
|
163
|
+
models.CharField(
|
|
164
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
165
|
+
help_text="If no, participant is not eligible.",
|
|
166
|
+
max_length=3,
|
|
167
|
+
null=True,
|
|
168
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
169
|
+
verbose_name="I have asked the participant questions about this study and the participant has demonstrated understanding",
|
|
170
|
+
),
|
|
171
|
+
),
|
|
172
|
+
(
|
|
173
|
+
"consent_signature",
|
|
174
|
+
models.CharField(
|
|
175
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
176
|
+
help_text="If no, participant is not eligible.",
|
|
177
|
+
max_length=3,
|
|
178
|
+
null=True,
|
|
179
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
180
|
+
verbose_name="I have verified that the participant has signed the consent form",
|
|
181
|
+
),
|
|
182
|
+
),
|
|
183
|
+
(
|
|
184
|
+
"consent_copy",
|
|
185
|
+
models.CharField(
|
|
186
|
+
choices=[
|
|
187
|
+
("Yes", "Yes"),
|
|
188
|
+
("No", "No"),
|
|
189
|
+
("Declined", "Yes, but subject declined copy"),
|
|
190
|
+
],
|
|
191
|
+
help_text="If declined, return copy with the consent",
|
|
192
|
+
max_length=20,
|
|
193
|
+
null=True,
|
|
194
|
+
validators=[edc_consent.validators.eligible_if_yes_or_declined],
|
|
195
|
+
verbose_name="I have provided the participant with a copy of their signed informed consent",
|
|
196
|
+
),
|
|
197
|
+
),
|
|
198
|
+
(
|
|
199
|
+
"slug",
|
|
200
|
+
models.CharField(
|
|
201
|
+
db_index=True,
|
|
202
|
+
default="",
|
|
203
|
+
editable=False,
|
|
204
|
+
help_text="Hold slug field values for quick search. Excludes encrypted fields",
|
|
205
|
+
max_length=250,
|
|
206
|
+
),
|
|
207
|
+
),
|
|
208
|
+
(
|
|
209
|
+
"subject_identifier",
|
|
210
|
+
models.CharField(
|
|
211
|
+
db_index=True, max_length=50, verbose_name="Subject identifier"
|
|
212
|
+
),
|
|
213
|
+
),
|
|
214
|
+
(
|
|
215
|
+
"initials",
|
|
216
|
+
django_crypto_fields.fields.encrypted_char_field.EncryptedCharField(
|
|
217
|
+
blank=True,
|
|
218
|
+
default="",
|
|
219
|
+
help_text=" (Encryption: RSA local)",
|
|
220
|
+
max_length=71,
|
|
221
|
+
validators=[
|
|
222
|
+
django.core.validators.RegexValidator(
|
|
223
|
+
message="Ensure initials consist of letters only in upper case, no spaces.",
|
|
224
|
+
regex="^[A-Z]{2,3}$",
|
|
225
|
+
)
|
|
226
|
+
],
|
|
227
|
+
),
|
|
228
|
+
),
|
|
229
|
+
(
|
|
230
|
+
"gender",
|
|
231
|
+
models.CharField(
|
|
232
|
+
choices=[("M", "Male"), ("F", "Female")],
|
|
233
|
+
max_length=1,
|
|
234
|
+
verbose_name="Gender",
|
|
235
|
+
),
|
|
236
|
+
),
|
|
237
|
+
(
|
|
238
|
+
"consent_datetime",
|
|
239
|
+
models.DateTimeField(
|
|
240
|
+
default=django.utils.timezone.now,
|
|
241
|
+
verbose_name="Consent datetime",
|
|
242
|
+
),
|
|
243
|
+
),
|
|
244
|
+
("report_datetime", models.DateTimeField(editable=False, null=True)),
|
|
245
|
+
(
|
|
246
|
+
"language",
|
|
247
|
+
models.CharField(
|
|
248
|
+
choices=[
|
|
249
|
+
("sw", "Swahili"),
|
|
250
|
+
("en-gb", "British English"),
|
|
251
|
+
("en", "English"),
|
|
252
|
+
("mas", "Maasai"),
|
|
253
|
+
],
|
|
254
|
+
help_text="The language used for the consent process will also be used during data collection.",
|
|
255
|
+
max_length=25,
|
|
256
|
+
verbose_name="Language of consent",
|
|
257
|
+
),
|
|
258
|
+
),
|
|
259
|
+
(
|
|
260
|
+
"model_name",
|
|
261
|
+
models.CharField(
|
|
262
|
+
default="",
|
|
263
|
+
editable=False,
|
|
264
|
+
help_text="label_lower of this model class. Will be different if instance has been added/edited via a proxy model",
|
|
265
|
+
max_length=50,
|
|
266
|
+
verbose_name="model",
|
|
267
|
+
),
|
|
268
|
+
),
|
|
269
|
+
(
|
|
270
|
+
"version",
|
|
271
|
+
models.CharField(
|
|
272
|
+
default="1.0",
|
|
273
|
+
editable=False,
|
|
274
|
+
help_text="See 'consent definition' for consent versions by period.",
|
|
275
|
+
max_length=10,
|
|
276
|
+
verbose_name="Consent version",
|
|
277
|
+
),
|
|
278
|
+
),
|
|
279
|
+
(
|
|
280
|
+
"history_id",
|
|
281
|
+
models.UUIDField(
|
|
282
|
+
default=uuid.uuid4,
|
|
283
|
+
editable=False,
|
|
284
|
+
primary_key=True,
|
|
285
|
+
serialize=False,
|
|
286
|
+
),
|
|
287
|
+
),
|
|
288
|
+
("history_date", models.DateTimeField(db_index=True)),
|
|
289
|
+
("history_change_reason", models.CharField(max_length=100, null=True)),
|
|
290
|
+
(
|
|
291
|
+
"history_type",
|
|
292
|
+
models.CharField(
|
|
293
|
+
choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")],
|
|
294
|
+
max_length=1,
|
|
295
|
+
),
|
|
296
|
+
),
|
|
297
|
+
(
|
|
298
|
+
"history_user",
|
|
299
|
+
models.ForeignKey(
|
|
300
|
+
null=True,
|
|
301
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
302
|
+
related_name="+",
|
|
303
|
+
to=settings.AUTH_USER_MODEL,
|
|
304
|
+
),
|
|
305
|
+
),
|
|
306
|
+
(
|
|
307
|
+
"site",
|
|
308
|
+
models.ForeignKey(
|
|
309
|
+
blank=True,
|
|
310
|
+
db_constraint=False,
|
|
311
|
+
null=True,
|
|
312
|
+
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
313
|
+
related_name="+",
|
|
314
|
+
to="sites.site",
|
|
315
|
+
),
|
|
316
|
+
),
|
|
317
|
+
],
|
|
318
|
+
options={
|
|
319
|
+
"verbose_name": "historical Subject Consent for SPFQ",
|
|
320
|
+
"verbose_name_plural": "historical Subject Consents for SPFQ",
|
|
321
|
+
"ordering": ("-history_date", "-history_id"),
|
|
322
|
+
"get_latest_by": ("history_date", "history_id"),
|
|
323
|
+
},
|
|
324
|
+
bases=(simple_history.models.HistoricalChanges, models.Model),
|
|
325
|
+
),
|
|
326
|
+
migrations.CreateModel(
|
|
327
|
+
name="SubjectConsentSpfq",
|
|
328
|
+
fields=[
|
|
329
|
+
(
|
|
330
|
+
"revision",
|
|
331
|
+
django_revision.revision_field.RevisionField(
|
|
332
|
+
blank=True,
|
|
333
|
+
default="",
|
|
334
|
+
editable=False,
|
|
335
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
336
|
+
max_length=75,
|
|
337
|
+
verbose_name="Revision",
|
|
338
|
+
),
|
|
339
|
+
),
|
|
340
|
+
(
|
|
341
|
+
"created",
|
|
342
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
343
|
+
),
|
|
344
|
+
(
|
|
345
|
+
"modified",
|
|
346
|
+
models.DateTimeField(blank=True, default=django.utils.timezone.now),
|
|
347
|
+
),
|
|
348
|
+
(
|
|
349
|
+
"user_created",
|
|
350
|
+
django_audit_fields.fields.userfield.UserField(
|
|
351
|
+
blank=True,
|
|
352
|
+
default="",
|
|
353
|
+
help_text="Updated by admin.save_model",
|
|
354
|
+
max_length=50,
|
|
355
|
+
verbose_name="user created",
|
|
356
|
+
),
|
|
357
|
+
),
|
|
358
|
+
(
|
|
359
|
+
"user_modified",
|
|
360
|
+
django_audit_fields.fields.userfield.UserField(
|
|
361
|
+
blank=True,
|
|
362
|
+
default="",
|
|
363
|
+
help_text="Updated by admin.save_model",
|
|
364
|
+
max_length=50,
|
|
365
|
+
verbose_name="user modified",
|
|
366
|
+
),
|
|
367
|
+
),
|
|
368
|
+
(
|
|
369
|
+
"hostname_created",
|
|
370
|
+
models.CharField(
|
|
371
|
+
blank=True,
|
|
372
|
+
default=_socket.gethostname,
|
|
373
|
+
help_text="System field. (modified on create only)",
|
|
374
|
+
max_length=60,
|
|
375
|
+
verbose_name="Hostname created",
|
|
376
|
+
),
|
|
377
|
+
),
|
|
378
|
+
(
|
|
379
|
+
"hostname_modified",
|
|
380
|
+
django_audit_fields.fields.hostname_modification_field.HostnameModificationField(
|
|
381
|
+
blank=True,
|
|
382
|
+
default="",
|
|
383
|
+
help_text="System field. (modified on every save)",
|
|
384
|
+
max_length=50,
|
|
385
|
+
verbose_name="Hostname modified",
|
|
386
|
+
),
|
|
387
|
+
),
|
|
388
|
+
(
|
|
389
|
+
"device_created",
|
|
390
|
+
models.CharField(
|
|
391
|
+
blank=True,
|
|
392
|
+
default="",
|
|
393
|
+
max_length=10,
|
|
394
|
+
verbose_name="Device created",
|
|
395
|
+
),
|
|
396
|
+
),
|
|
397
|
+
(
|
|
398
|
+
"device_modified",
|
|
399
|
+
models.CharField(
|
|
400
|
+
blank=True,
|
|
401
|
+
default="",
|
|
402
|
+
max_length=10,
|
|
403
|
+
verbose_name="Device modified",
|
|
404
|
+
),
|
|
405
|
+
),
|
|
406
|
+
(
|
|
407
|
+
"locale_created",
|
|
408
|
+
models.CharField(
|
|
409
|
+
blank=True,
|
|
410
|
+
default="",
|
|
411
|
+
help_text="Auto-updated by Modeladmin",
|
|
412
|
+
max_length=10,
|
|
413
|
+
verbose_name="Locale created",
|
|
414
|
+
),
|
|
415
|
+
),
|
|
416
|
+
(
|
|
417
|
+
"locale_modified",
|
|
418
|
+
models.CharField(
|
|
419
|
+
blank=True,
|
|
420
|
+
default="",
|
|
421
|
+
help_text="Auto-updated by Modeladmin",
|
|
422
|
+
max_length=10,
|
|
423
|
+
verbose_name="Locale modified",
|
|
424
|
+
),
|
|
425
|
+
),
|
|
426
|
+
(
|
|
427
|
+
"id",
|
|
428
|
+
django_audit_fields.fields.uuid_auto_field.UUIDAutoField(
|
|
429
|
+
blank=True,
|
|
430
|
+
editable=False,
|
|
431
|
+
help_text="System auto field. UUID primary key.",
|
|
432
|
+
primary_key=True,
|
|
433
|
+
serialize=False,
|
|
434
|
+
),
|
|
435
|
+
),
|
|
436
|
+
(
|
|
437
|
+
"consent_reviewed",
|
|
438
|
+
models.CharField(
|
|
439
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
440
|
+
help_text="If no, participant is not eligible.",
|
|
441
|
+
max_length=3,
|
|
442
|
+
null=True,
|
|
443
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
444
|
+
verbose_name="I have reviewed the consent with the participant",
|
|
445
|
+
),
|
|
446
|
+
),
|
|
447
|
+
(
|
|
448
|
+
"study_questions",
|
|
449
|
+
models.CharField(
|
|
450
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
451
|
+
help_text="If no, participant is not eligible.",
|
|
452
|
+
max_length=3,
|
|
453
|
+
null=True,
|
|
454
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
455
|
+
verbose_name="I have answered all questions the participant had about the study",
|
|
456
|
+
),
|
|
457
|
+
),
|
|
458
|
+
(
|
|
459
|
+
"assessment_score",
|
|
460
|
+
models.CharField(
|
|
461
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
462
|
+
help_text="If no, participant is not eligible.",
|
|
463
|
+
max_length=3,
|
|
464
|
+
null=True,
|
|
465
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
466
|
+
verbose_name="I have asked the participant questions about this study and the participant has demonstrated understanding",
|
|
467
|
+
),
|
|
468
|
+
),
|
|
469
|
+
(
|
|
470
|
+
"consent_signature",
|
|
471
|
+
models.CharField(
|
|
472
|
+
choices=[("Yes", "Yes"), ("No", "No")],
|
|
473
|
+
help_text="If no, participant is not eligible.",
|
|
474
|
+
max_length=3,
|
|
475
|
+
null=True,
|
|
476
|
+
validators=[edc_consent.validators.eligible_if_yes],
|
|
477
|
+
verbose_name="I have verified that the participant has signed the consent form",
|
|
478
|
+
),
|
|
479
|
+
),
|
|
480
|
+
(
|
|
481
|
+
"consent_copy",
|
|
482
|
+
models.CharField(
|
|
483
|
+
choices=[
|
|
484
|
+
("Yes", "Yes"),
|
|
485
|
+
("No", "No"),
|
|
486
|
+
("Declined", "Yes, but subject declined copy"),
|
|
487
|
+
],
|
|
488
|
+
help_text="If declined, return copy with the consent",
|
|
489
|
+
max_length=20,
|
|
490
|
+
null=True,
|
|
491
|
+
validators=[edc_consent.validators.eligible_if_yes_or_declined],
|
|
492
|
+
verbose_name="I have provided the participant with a copy of their signed informed consent",
|
|
493
|
+
),
|
|
494
|
+
),
|
|
495
|
+
(
|
|
496
|
+
"slug",
|
|
497
|
+
models.CharField(
|
|
498
|
+
db_index=True,
|
|
499
|
+
default="",
|
|
500
|
+
editable=False,
|
|
501
|
+
help_text="Hold slug field values for quick search. Excludes encrypted fields",
|
|
502
|
+
max_length=250,
|
|
503
|
+
),
|
|
504
|
+
),
|
|
505
|
+
(
|
|
506
|
+
"subject_identifier",
|
|
507
|
+
models.CharField(
|
|
508
|
+
max_length=50, unique=True, verbose_name="Subject identifier"
|
|
509
|
+
),
|
|
510
|
+
),
|
|
511
|
+
(
|
|
512
|
+
"initials",
|
|
513
|
+
django_crypto_fields.fields.encrypted_char_field.EncryptedCharField(
|
|
514
|
+
blank=True,
|
|
515
|
+
default="",
|
|
516
|
+
help_text=" (Encryption: RSA local)",
|
|
517
|
+
max_length=71,
|
|
518
|
+
validators=[
|
|
519
|
+
django.core.validators.RegexValidator(
|
|
520
|
+
message="Ensure initials consist of letters only in upper case, no spaces.",
|
|
521
|
+
regex="^[A-Z]{2,3}$",
|
|
522
|
+
)
|
|
523
|
+
],
|
|
524
|
+
),
|
|
525
|
+
),
|
|
526
|
+
(
|
|
527
|
+
"gender",
|
|
528
|
+
models.CharField(
|
|
529
|
+
choices=[("M", "Male"), ("F", "Female")],
|
|
530
|
+
max_length=1,
|
|
531
|
+
verbose_name="Gender",
|
|
532
|
+
),
|
|
533
|
+
),
|
|
534
|
+
(
|
|
535
|
+
"consent_datetime",
|
|
536
|
+
models.DateTimeField(
|
|
537
|
+
default=django.utils.timezone.now,
|
|
538
|
+
verbose_name="Consent datetime",
|
|
539
|
+
),
|
|
540
|
+
),
|
|
541
|
+
("report_datetime", models.DateTimeField(editable=False, null=True)),
|
|
542
|
+
(
|
|
543
|
+
"language",
|
|
544
|
+
models.CharField(
|
|
545
|
+
choices=[
|
|
546
|
+
("sw", "Swahili"),
|
|
547
|
+
("en-gb", "British English"),
|
|
548
|
+
("en", "English"),
|
|
549
|
+
("mas", "Maasai"),
|
|
550
|
+
],
|
|
551
|
+
help_text="The language used for the consent process will also be used during data collection.",
|
|
552
|
+
max_length=25,
|
|
553
|
+
verbose_name="Language of consent",
|
|
554
|
+
),
|
|
555
|
+
),
|
|
556
|
+
(
|
|
557
|
+
"model_name",
|
|
558
|
+
models.CharField(
|
|
559
|
+
default="",
|
|
560
|
+
editable=False,
|
|
561
|
+
help_text="label_lower of this model class. Will be different if instance has been added/edited via a proxy model",
|
|
562
|
+
max_length=50,
|
|
563
|
+
verbose_name="model",
|
|
564
|
+
),
|
|
565
|
+
),
|
|
566
|
+
(
|
|
567
|
+
"version",
|
|
568
|
+
models.CharField(
|
|
569
|
+
default="1.0",
|
|
570
|
+
editable=False,
|
|
571
|
+
help_text="See 'consent definition' for consent versions by period.",
|
|
572
|
+
max_length=10,
|
|
573
|
+
verbose_name="Consent version",
|
|
574
|
+
),
|
|
575
|
+
),
|
|
576
|
+
(
|
|
577
|
+
"site",
|
|
578
|
+
models.ForeignKey(
|
|
579
|
+
null=True,
|
|
580
|
+
on_delete=django.db.models.deletion.PROTECT,
|
|
581
|
+
related_name="+",
|
|
582
|
+
to="sites.site",
|
|
583
|
+
),
|
|
584
|
+
),
|
|
585
|
+
],
|
|
586
|
+
options={
|
|
587
|
+
"verbose_name": "Subject Consent for SPFQ",
|
|
588
|
+
"verbose_name_plural": "Subject Consents for SPFQ",
|
|
589
|
+
"abstract": False,
|
|
590
|
+
"default_permissions": (
|
|
591
|
+
"add",
|
|
592
|
+
"change",
|
|
593
|
+
"delete",
|
|
594
|
+
"view",
|
|
595
|
+
"export",
|
|
596
|
+
"import",
|
|
597
|
+
),
|
|
598
|
+
"default_manager_name": "objects",
|
|
599
|
+
"indexes": [
|
|
600
|
+
models.Index(
|
|
601
|
+
fields=["modified", "created"],
|
|
602
|
+
name="meta_consen_modifie_561720_idx",
|
|
603
|
+
),
|
|
604
|
+
models.Index(
|
|
605
|
+
fields=["user_modified", "user_created"],
|
|
606
|
+
name="meta_consen_user_mo_163676_idx",
|
|
607
|
+
),
|
|
608
|
+
],
|
|
609
|
+
},
|
|
610
|
+
managers=[
|
|
611
|
+
("on_site", django.contrib.sites.managers.CurrentSiteManager()),
|
|
612
|
+
("objects", edc_consent.managers.ConsentObjectsManager()),
|
|
613
|
+
],
|
|
614
|
+
),
|
|
615
|
+
]
|
|
@@ -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/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(
|