meta-edc 1.0.3__py3-none-any.whl → 1.0.4__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.
Files changed (31) hide show
  1. meta_analytics/dataframes/get_eos_df.py +1 -1
  2. meta_analytics/dataframes/get_last_imp_visits_df.py +5 -2
  3. meta_analytics/dataframes/screening/get_screening_df.py +2 -1
  4. meta_edc/settings/debug.py +2 -2
  5. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/METADATA +3 -3
  6. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/RECORD +31 -20
  7. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/WHEEL +1 -1
  8. meta_lists/list_data.py +4 -0
  9. meta_lists/migrations/0019_auto_20250128_0143.py +48 -0
  10. meta_subject/action_items.py +8 -1
  11. meta_subject/admin/__init__.py +1 -0
  12. meta_subject/admin/next_appointment_admin.py +20 -0
  13. meta_subject/forms/__init__.py +1 -0
  14. meta_subject/forms/next_appointment_form.py +37 -0
  15. meta_subject/metadata_rules/metadata_rules.py +14 -0
  16. meta_subject/metadata_rules/predicates.py +29 -3
  17. meta_subject/migrations/0216_historicalnextappointment_nextappointment.py +554 -0
  18. meta_subject/migrations/0217_alter_historicalnextappointment_appt_datetime_and_more.py +42 -0
  19. meta_subject/migrations/0218_alter_historicalnextappointment_appt_date_and_more.py +53 -0
  20. meta_subject/migrations/0219_remove_historicalnextappointment_allow_create_interim_and_more.py +92 -0
  21. meta_subject/migrations/0220_historicalbloodresultsgludummy_bloodresultsgludummy.py +834 -0
  22. meta_subject/models/__init__.py +2 -0
  23. meta_subject/models/blood_results/__init__.py +1 -0
  24. meta_subject/models/blood_results/blood_results_glu.py +29 -0
  25. meta_subject/models/next_appointment.py +16 -0
  26. meta_subject/tests/tests/test_next_appointment.py +231 -0
  27. meta_visit_schedule/visit_schedules/phase_three/crfs.py +20 -1
  28. meta_visit_schedule/visit_schedules/phase_three/schedule_pregnancy.py +1 -1
  29. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/AUTHORS +0 -0
  30. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/LICENSE +0 -0
  31. {meta_edc-1.0.3.dist-info → meta_edc-1.0.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,554 @@
1
+ # Generated by Django 6.0 on 2025-01-28 13:32
2
+
3
+ import _socket
4
+ import django.db.models.deletion
5
+ import django_audit_fields.fields.hostname_modification_field
6
+ import django_audit_fields.fields.userfield
7
+ import django_audit_fields.fields.uuid_auto_field
8
+ import django_audit_fields.models.audit_model_mixin
9
+ import django_revision.revision_field
10
+ import edc_crf.model_mixins.crf_status_model_mixin
11
+ import edc_model.validators.date
12
+ import edc_protocol.validators
13
+ import edc_utils.date
14
+ import edc_visit_tracking.managers
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
+ ("edc_appointment", "0048_alter_appointment_site_and_more"),
25
+ ("edc_facility", "0014_healthfacility_title_historicalhealthfacility_title"),
26
+ ("edc_visit_schedule", "0017_alter_onschedule_managers"),
27
+ ("meta_subject", "0215_alter_historicalstudymedication_stock_codes_and_more"),
28
+ ("sites", "0002_alter_domain_unique"),
29
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
30
+ ]
31
+
32
+ operations = [
33
+ migrations.CreateModel(
34
+ name="HistoricalNextAppointment",
35
+ fields=[
36
+ (
37
+ "revision",
38
+ django_revision.revision_field.RevisionField(
39
+ blank=True,
40
+ editable=False,
41
+ help_text="System field. Git repository tag:branch:commit.",
42
+ max_length=75,
43
+ null=True,
44
+ verbose_name="Revision",
45
+ ),
46
+ ),
47
+ (
48
+ "created",
49
+ models.DateTimeField(
50
+ blank=True,
51
+ default=django_audit_fields.models.audit_model_mixin.utcnow,
52
+ ),
53
+ ),
54
+ (
55
+ "modified",
56
+ models.DateTimeField(
57
+ blank=True,
58
+ default=django_audit_fields.models.audit_model_mixin.utcnow,
59
+ ),
60
+ ),
61
+ (
62
+ "user_created",
63
+ django_audit_fields.fields.userfield.UserField(
64
+ blank=True,
65
+ help_text="Updated by admin.save_model",
66
+ max_length=50,
67
+ verbose_name="user created",
68
+ ),
69
+ ),
70
+ (
71
+ "user_modified",
72
+ django_audit_fields.fields.userfield.UserField(
73
+ blank=True,
74
+ help_text="Updated by admin.save_model",
75
+ max_length=50,
76
+ verbose_name="user modified",
77
+ ),
78
+ ),
79
+ (
80
+ "hostname_created",
81
+ models.CharField(
82
+ blank=True,
83
+ default=_socket.gethostname,
84
+ help_text="System field. (modified on create only)",
85
+ max_length=60,
86
+ verbose_name="Hostname created",
87
+ ),
88
+ ),
89
+ (
90
+ "hostname_modified",
91
+ django_audit_fields.fields.hostname_modification_field.HostnameModificationField(
92
+ blank=True,
93
+ help_text="System field. (modified on every save)",
94
+ max_length=50,
95
+ verbose_name="Hostname modified",
96
+ ),
97
+ ),
98
+ (
99
+ "device_created",
100
+ models.CharField(blank=True, max_length=10, verbose_name="Device created"),
101
+ ),
102
+ (
103
+ "device_modified",
104
+ models.CharField(
105
+ blank=True, max_length=10, verbose_name="Device modified"
106
+ ),
107
+ ),
108
+ (
109
+ "locale_created",
110
+ models.CharField(
111
+ blank=True,
112
+ help_text="Auto-updated by Modeladmin",
113
+ max_length=10,
114
+ null=True,
115
+ verbose_name="Locale created",
116
+ ),
117
+ ),
118
+ (
119
+ "locale_modified",
120
+ models.CharField(
121
+ blank=True,
122
+ help_text="Auto-updated by Modeladmin",
123
+ max_length=10,
124
+ null=True,
125
+ verbose_name="Locale modified",
126
+ ),
127
+ ),
128
+ (
129
+ "id",
130
+ django_audit_fields.fields.uuid_auto_field.UUIDAutoField(
131
+ blank=True,
132
+ db_index=True,
133
+ editable=False,
134
+ help_text="System auto field. UUID primary key.",
135
+ ),
136
+ ),
137
+ (
138
+ "consent_model",
139
+ models.CharField(blank=True, max_length=50, null=True),
140
+ ),
141
+ (
142
+ "consent_version",
143
+ models.CharField(blank=True, max_length=10, null=True),
144
+ ),
145
+ (
146
+ "report_datetime",
147
+ models.DateTimeField(
148
+ default=edc_utils.date.get_utcnow,
149
+ help_text="If reporting today, use today's date/time, otherwise use the date/time this information was reported.",
150
+ validators=[
151
+ edc_protocol.validators.datetime_not_before_study_start,
152
+ edc_model.validators.date.datetime_not_future,
153
+ ],
154
+ verbose_name="Report Date",
155
+ ),
156
+ ),
157
+ (
158
+ "appt_date",
159
+ models.DateField(
160
+ help_text="Should fall on an valid clinic day for this facility",
161
+ null=True,
162
+ verbose_name="Next scheduled routine/facility appointment",
163
+ ),
164
+ ),
165
+ (
166
+ "appt_datetime",
167
+ models.DateField(
168
+ help_text="Should fall on an valid clinic day for this facility",
169
+ null=True,
170
+ verbose_name="Next scheduled routine/facility appointment date and time",
171
+ ),
172
+ ),
173
+ (
174
+ "allow_create_interim",
175
+ models.BooleanField(
176
+ default=False,
177
+ help_text="Override date check to allow the EDC to create an interim appointment if the date is within window period of the current appointment.",
178
+ verbose_name="Override date check?",
179
+ ),
180
+ ),
181
+ (
182
+ "crf_status",
183
+ models.CharField(
184
+ choices=[
185
+ ("INCOMPLETE", "Incomplete (some data pending)"),
186
+ ("COMPLETE", "Complete"),
187
+ ],
188
+ default=edc_crf.model_mixins.crf_status_model_mixin.get_crf_status_default,
189
+ help_text="If some data is still pending, flag this CRF as incomplete",
190
+ max_length=25,
191
+ verbose_name="CRF status",
192
+ ),
193
+ ),
194
+ (
195
+ "crf_status_comments",
196
+ models.TextField(
197
+ blank=True,
198
+ help_text="for example, why some data is still pending",
199
+ null=True,
200
+ verbose_name="Any comments related to status of this CRF",
201
+ ),
202
+ ),
203
+ (
204
+ "history_id",
205
+ models.UUIDField(
206
+ default=uuid.uuid4,
207
+ editable=False,
208
+ primary_key=True,
209
+ serialize=False,
210
+ ),
211
+ ),
212
+ ("history_date", models.DateTimeField(db_index=True)),
213
+ ("history_change_reason", models.CharField(max_length=100, null=True)),
214
+ (
215
+ "history_type",
216
+ models.CharField(
217
+ choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")],
218
+ max_length=1,
219
+ ),
220
+ ),
221
+ (
222
+ "health_facility",
223
+ models.ForeignKey(
224
+ blank=True,
225
+ db_constraint=False,
226
+ null=True,
227
+ on_delete=django.db.models.deletion.DO_NOTHING,
228
+ related_name="+",
229
+ to="edc_facility.healthfacility",
230
+ ),
231
+ ),
232
+ (
233
+ "history_user",
234
+ models.ForeignKey(
235
+ null=True,
236
+ on_delete=django.db.models.deletion.SET_NULL,
237
+ related_name="+",
238
+ to=settings.AUTH_USER_MODEL,
239
+ ),
240
+ ),
241
+ (
242
+ "info_source",
243
+ models.ForeignKey(
244
+ blank=True,
245
+ db_constraint=False,
246
+ max_length=15,
247
+ null=True,
248
+ on_delete=django.db.models.deletion.DO_NOTHING,
249
+ related_name="+",
250
+ to="edc_appointment.infosources",
251
+ verbose_name="What is the source of this appointment date",
252
+ ),
253
+ ),
254
+ (
255
+ "site",
256
+ models.ForeignKey(
257
+ blank=True,
258
+ db_constraint=False,
259
+ null=True,
260
+ on_delete=django.db.models.deletion.DO_NOTHING,
261
+ related_name="+",
262
+ to="sites.site",
263
+ ),
264
+ ),
265
+ (
266
+ "subject_visit",
267
+ models.ForeignKey(
268
+ blank=True,
269
+ db_constraint=False,
270
+ null=True,
271
+ on_delete=django.db.models.deletion.DO_NOTHING,
272
+ related_name="+",
273
+ to="meta_subject.subjectvisit",
274
+ ),
275
+ ),
276
+ (
277
+ "visitschedule",
278
+ models.ForeignKey(
279
+ blank=True,
280
+ db_constraint=False,
281
+ help_text="Click SAVE to let the EDC suggest. Once selected, interim appointments will be flagged as not required/missed.",
282
+ max_length=15,
283
+ null=True,
284
+ on_delete=django.db.models.deletion.DO_NOTHING,
285
+ related_name="+",
286
+ to="edc_visit_schedule.visitschedule",
287
+ verbose_name="Which study visit code is closest to this appointment date",
288
+ ),
289
+ ),
290
+ ],
291
+ options={
292
+ "verbose_name": "historical Next Appointment",
293
+ "verbose_name_plural": "historical Next Appointments",
294
+ "ordering": ("-history_date", "-history_id"),
295
+ "get_latest_by": ("history_date", "history_id"),
296
+ },
297
+ bases=(simple_history.models.HistoricalChanges, models.Model),
298
+ ),
299
+ migrations.CreateModel(
300
+ name="NextAppointment",
301
+ fields=[
302
+ (
303
+ "revision",
304
+ django_revision.revision_field.RevisionField(
305
+ blank=True,
306
+ editable=False,
307
+ help_text="System field. Git repository tag:branch:commit.",
308
+ max_length=75,
309
+ null=True,
310
+ verbose_name="Revision",
311
+ ),
312
+ ),
313
+ (
314
+ "created",
315
+ models.DateTimeField(
316
+ blank=True,
317
+ default=django_audit_fields.models.audit_model_mixin.utcnow,
318
+ ),
319
+ ),
320
+ (
321
+ "modified",
322
+ models.DateTimeField(
323
+ blank=True,
324
+ default=django_audit_fields.models.audit_model_mixin.utcnow,
325
+ ),
326
+ ),
327
+ (
328
+ "user_created",
329
+ django_audit_fields.fields.userfield.UserField(
330
+ blank=True,
331
+ help_text="Updated by admin.save_model",
332
+ max_length=50,
333
+ verbose_name="user created",
334
+ ),
335
+ ),
336
+ (
337
+ "user_modified",
338
+ django_audit_fields.fields.userfield.UserField(
339
+ blank=True,
340
+ help_text="Updated by admin.save_model",
341
+ max_length=50,
342
+ verbose_name="user modified",
343
+ ),
344
+ ),
345
+ (
346
+ "hostname_created",
347
+ models.CharField(
348
+ blank=True,
349
+ default=_socket.gethostname,
350
+ help_text="System field. (modified on create only)",
351
+ max_length=60,
352
+ verbose_name="Hostname created",
353
+ ),
354
+ ),
355
+ (
356
+ "hostname_modified",
357
+ django_audit_fields.fields.hostname_modification_field.HostnameModificationField(
358
+ blank=True,
359
+ help_text="System field. (modified on every save)",
360
+ max_length=50,
361
+ verbose_name="Hostname modified",
362
+ ),
363
+ ),
364
+ (
365
+ "device_created",
366
+ models.CharField(blank=True, max_length=10, verbose_name="Device created"),
367
+ ),
368
+ (
369
+ "device_modified",
370
+ models.CharField(
371
+ blank=True, max_length=10, verbose_name="Device modified"
372
+ ),
373
+ ),
374
+ (
375
+ "locale_created",
376
+ models.CharField(
377
+ blank=True,
378
+ help_text="Auto-updated by Modeladmin",
379
+ max_length=10,
380
+ null=True,
381
+ verbose_name="Locale created",
382
+ ),
383
+ ),
384
+ (
385
+ "locale_modified",
386
+ models.CharField(
387
+ blank=True,
388
+ help_text="Auto-updated by Modeladmin",
389
+ max_length=10,
390
+ null=True,
391
+ verbose_name="Locale modified",
392
+ ),
393
+ ),
394
+ (
395
+ "id",
396
+ django_audit_fields.fields.uuid_auto_field.UUIDAutoField(
397
+ blank=True,
398
+ editable=False,
399
+ help_text="System auto field. UUID primary key.",
400
+ primary_key=True,
401
+ serialize=False,
402
+ ),
403
+ ),
404
+ (
405
+ "consent_model",
406
+ models.CharField(blank=True, max_length=50, null=True),
407
+ ),
408
+ (
409
+ "consent_version",
410
+ models.CharField(blank=True, max_length=10, null=True),
411
+ ),
412
+ (
413
+ "report_datetime",
414
+ models.DateTimeField(
415
+ default=edc_utils.date.get_utcnow,
416
+ help_text="If reporting today, use today's date/time, otherwise use the date/time this information was reported.",
417
+ validators=[
418
+ edc_protocol.validators.datetime_not_before_study_start,
419
+ edc_model.validators.date.datetime_not_future,
420
+ ],
421
+ verbose_name="Report Date",
422
+ ),
423
+ ),
424
+ (
425
+ "appt_date",
426
+ models.DateField(
427
+ help_text="Should fall on an valid clinic day for this facility",
428
+ null=True,
429
+ verbose_name="Next scheduled routine/facility appointment",
430
+ ),
431
+ ),
432
+ (
433
+ "appt_datetime",
434
+ models.DateField(
435
+ help_text="Should fall on an valid clinic day for this facility",
436
+ null=True,
437
+ verbose_name="Next scheduled routine/facility appointment date and time",
438
+ ),
439
+ ),
440
+ (
441
+ "allow_create_interim",
442
+ models.BooleanField(
443
+ default=False,
444
+ help_text="Override date check to allow the EDC to create an interim appointment if the date is within window period of the current appointment.",
445
+ verbose_name="Override date check?",
446
+ ),
447
+ ),
448
+ (
449
+ "crf_status",
450
+ models.CharField(
451
+ choices=[
452
+ ("INCOMPLETE", "Incomplete (some data pending)"),
453
+ ("COMPLETE", "Complete"),
454
+ ],
455
+ default=edc_crf.model_mixins.crf_status_model_mixin.get_crf_status_default,
456
+ help_text="If some data is still pending, flag this CRF as incomplete",
457
+ max_length=25,
458
+ verbose_name="CRF status",
459
+ ),
460
+ ),
461
+ (
462
+ "crf_status_comments",
463
+ models.TextField(
464
+ blank=True,
465
+ help_text="for example, why some data is still pending",
466
+ null=True,
467
+ verbose_name="Any comments related to status of this CRF",
468
+ ),
469
+ ),
470
+ (
471
+ "health_facility",
472
+ models.ForeignKey(
473
+ blank=True,
474
+ null=True,
475
+ on_delete=django.db.models.deletion.PROTECT,
476
+ to="edc_facility.healthfacility",
477
+ ),
478
+ ),
479
+ (
480
+ "info_source",
481
+ models.ForeignKey(
482
+ max_length=15,
483
+ null=True,
484
+ on_delete=django.db.models.deletion.PROTECT,
485
+ to="edc_appointment.infosources",
486
+ verbose_name="What is the source of this appointment date",
487
+ ),
488
+ ),
489
+ (
490
+ "site",
491
+ models.ForeignKey(
492
+ null=True,
493
+ on_delete=django.db.models.deletion.PROTECT,
494
+ related_name="+",
495
+ to="sites.site",
496
+ ),
497
+ ),
498
+ (
499
+ "subject_visit",
500
+ models.OneToOneField(
501
+ on_delete=django.db.models.deletion.PROTECT,
502
+ to="meta_subject.subjectvisit",
503
+ ),
504
+ ),
505
+ (
506
+ "visitschedule",
507
+ models.ForeignKey(
508
+ help_text="Click SAVE to let the EDC suggest. Once selected, interim appointments will be flagged as not required/missed.",
509
+ max_length=15,
510
+ null=True,
511
+ on_delete=django.db.models.deletion.PROTECT,
512
+ to="edc_visit_schedule.visitschedule",
513
+ verbose_name="Which study visit code is closest to this appointment date",
514
+ ),
515
+ ),
516
+ ],
517
+ options={
518
+ "verbose_name": "Next Appointment",
519
+ "verbose_name_plural": "Next Appointments",
520
+ "abstract": False,
521
+ "default_permissions": (
522
+ "add",
523
+ "change",
524
+ "delete",
525
+ "view",
526
+ "export",
527
+ "import",
528
+ ),
529
+ "default_manager_name": "objects",
530
+ "indexes": [
531
+ models.Index(
532
+ fields=["subject_visit", "site"],
533
+ name="meta_subjec_subject_0d7238_idx",
534
+ ),
535
+ models.Index(
536
+ fields=["subject_visit", "report_datetime"],
537
+ name="meta_subjec_subject_208c45_idx",
538
+ ),
539
+ models.Index(
540
+ fields=["modified", "created"],
541
+ name="meta_subjec_modifie_0f17e9_idx",
542
+ ),
543
+ models.Index(
544
+ fields=["user_modified", "user_created"],
545
+ name="meta_subjec_user_mo_c4e256_idx",
546
+ ),
547
+ ],
548
+ },
549
+ managers=[
550
+ ("objects", edc_visit_tracking.managers.CrfModelManager()),
551
+ ("on_site", edc_visit_tracking.managers.CrfCurrentSiteManager()),
552
+ ],
553
+ ),
554
+ ]
@@ -0,0 +1,42 @@
1
+ # Generated by Django 6.0 on 2025-01-28 23:32
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ("edc_facility", "0014_healthfacility_title_historicalhealthfacility_title"),
11
+ ("meta_subject", "0216_historicalnextappointment_nextappointment"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.AlterField(
16
+ model_name="historicalnextappointment",
17
+ name="appt_datetime",
18
+ field=models.DateTimeField(
19
+ help_text="Should fall on an valid clinic day for this facility",
20
+ null=True,
21
+ verbose_name="Next scheduled routine/facility appointment date and time",
22
+ ),
23
+ ),
24
+ migrations.AlterField(
25
+ model_name="nextappointment",
26
+ name="appt_datetime",
27
+ field=models.DateTimeField(
28
+ help_text="Should fall on an valid clinic day for this facility",
29
+ null=True,
30
+ verbose_name="Next scheduled routine/facility appointment date and time",
31
+ ),
32
+ ),
33
+ migrations.AlterField(
34
+ model_name="nextappointment",
35
+ name="health_facility",
36
+ field=models.ForeignKey(
37
+ null=True,
38
+ on_delete=django.db.models.deletion.PROTECT,
39
+ to="edc_facility.healthfacility",
40
+ ),
41
+ ),
42
+ ]
@@ -0,0 +1,53 @@
1
+ # Generated by Django 6.0 on 2025-02-01 03:06
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("meta_subject", "0217_alter_historicalnextappointment_appt_datetime_and_more"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="historicalnextappointment",
15
+ name="appt_date",
16
+ field=models.DateField(
17
+ blank=True,
18
+ help_text="Should fall on an valid clinic day for this facility",
19
+ null=True,
20
+ verbose_name="Next scheduled routine/facility appointment",
21
+ ),
22
+ ),
23
+ migrations.AlterField(
24
+ model_name="historicalnextappointment",
25
+ name="appt_datetime",
26
+ field=models.DateTimeField(
27
+ blank=True,
28
+ help_text="Should fall on an valid clinic day for this facility",
29
+ null=True,
30
+ verbose_name="Next scheduled routine/facility appointment date and time",
31
+ ),
32
+ ),
33
+ migrations.AlterField(
34
+ model_name="nextappointment",
35
+ name="appt_date",
36
+ field=models.DateField(
37
+ blank=True,
38
+ help_text="Should fall on an valid clinic day for this facility",
39
+ null=True,
40
+ verbose_name="Next scheduled routine/facility appointment",
41
+ ),
42
+ ),
43
+ migrations.AlterField(
44
+ model_name="nextappointment",
45
+ name="appt_datetime",
46
+ field=models.DateTimeField(
47
+ blank=True,
48
+ help_text="Should fall on an valid clinic day for this facility",
49
+ null=True,
50
+ verbose_name="Next scheduled routine/facility appointment date and time",
51
+ ),
52
+ ),
53
+ ]