meta-edc 1.0.6__py3-none-any.whl → 1.1.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.
Files changed (79) hide show
  1. meta_ae/action_items.py +10 -2
  2. meta_ae/baker_recipes.py +1 -2
  3. meta_ae/tests/tests/test_actions.py +1 -2
  4. meta_analytics/dataframes/__init__.py +3 -0
  5. meta_analytics/dataframes/constants.py +1 -1
  6. meta_analytics/dataframes/get_eos_df.py +15 -2
  7. meta_analytics/dataframes/get_glucose_df.py +149 -0
  8. meta_analytics/dataframes/get_glucose_fbg_df.py +27 -0
  9. meta_analytics/dataframes/get_glucose_fbg_ogtt_df.py +22 -0
  10. meta_analytics/dataframes/glucose_endpoints/endpoint_by_date.py +106 -120
  11. meta_analytics/dataframes/glucose_endpoints/glucose_endpoints_by_date.py +36 -227
  12. meta_analytics/dataframes/utils.py +18 -4
  13. meta_analytics/notebooks/anu.ipynb +95 -0
  14. meta_analytics/notebooks/appointment_planning.ipynb +329 -0
  15. meta_analytics/notebooks/arvs.ipynb +103 -0
  16. meta_analytics/notebooks/cleaning/consent_v1_ext.ipynb +227 -0
  17. meta_analytics/notebooks/cleaning/offschedule_eos.ipynb +353 -0
  18. meta_analytics/notebooks/dsmc/renal_dysfunction.ipynb +435 -0
  19. meta_analytics/notebooks/endpoints/meta_endpoints_by_date.ipynb +664 -0
  20. meta_analytics/notebooks/followup_examination.ipynb +141 -0
  21. meta_analytics/notebooks/hba1c.ipynb +136 -0
  22. meta_analytics/notebooks/hiv_regimens.ipynb +429 -0
  23. meta_analytics/notebooks/incidence.ipynb +232 -0
  24. meta_analytics/notebooks/liver.ipynb +389 -0
  25. meta_analytics/notebooks/magreth.ipynb +645 -0
  26. meta_analytics/notebooks/monitoring_report.ipynb +1751 -0
  27. meta_analytics/notebooks/pharmacy.ipynb +1070 -0
  28. meta_analytics/notebooks/pharmacy_stock_202410.ipynb +306 -0
  29. meta_analytics/notebooks/steering.ipynb +61 -0
  30. meta_analytics/notebooks/undiagnosed/meta3_screening_consort_chart.ipynb +1176 -0
  31. meta_analytics/notebooks/undiagnosed/meta3_screening_undiagnosed.ipynb +519 -0
  32. meta_analytics/notebooks/undiagnosed/meta_screening_table2.ipynb +964 -0
  33. meta_analytics/notebooks/undiagnosed/screen_undiagnosed_or.ipynb +296 -0
  34. meta_analytics/notebooks/undiagnosed/screening.ipynb +273 -0
  35. meta_analytics/notebooks/undiagnosed/screening2.ipynb +958 -0
  36. meta_analytics/notebooks/undiagnosed/screening_undiagnosed_20241002.ipynb +958 -0
  37. meta_analytics/notebooks/ven.ipynb +191 -0
  38. meta_analytics/notebooks/vitals.ipynb +263 -0
  39. meta_analytics/utils.py +81 -0
  40. meta_edc/settings/debug.py +3 -2
  41. meta_edc/urls.py +1 -0
  42. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/METADATA +6 -5
  43. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/RECORD +77 -36
  44. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/WHEEL +1 -1
  45. meta_edc-1.1.0.dist-info/licenses/AUTHORS.rst +8 -0
  46. meta_labs/reportables.py +14 -11
  47. meta_labs/tests/test_reportables.py +33 -12
  48. meta_pharmacy/notebooks/pharmacy.ipynb +41 -0
  49. meta_prn/migrations/0063_historicaloffstudymedication_singleton_field_and_more.py +37 -0
  50. meta_prn/migrations/0064_auto_20250602_2143.py +18 -0
  51. meta_prn/models/end_of_study.py +2 -0
  52. meta_prn/models/off_study_medication.py +2 -0
  53. meta_reports/migrations/0054_auto_20250422_2003.py +81 -0
  54. meta_reports/migrations/0055_alter_glucosesummary_table.py +17 -0
  55. meta_reports/migrations/0056_auto_20250422_2214.py +54 -0
  56. meta_reports/migrations/0057_auto_20250422_2224.py +54 -0
  57. meta_reports/migrations/0058_auto_20250422_2232.py +54 -0
  58. meta_reports/models/dbviews/glucose_summary/unmanaged_model.py +13 -1
  59. meta_reports/models/dbviews/glucose_summary/view_definition.py +8 -5
  60. meta_screening/eligibility/eligibility_part_three/base_eligibility_part_three.py +59 -47
  61. meta_screening/form_validators/screening_part_three.py +6 -1
  62. meta_screening/tests/meta_test_case_mixin.py +3 -0
  63. meta_screening/tests/tests/test_forms.py +9 -2
  64. meta_screening/tests/tests/test_screening_part_three.py +11 -14
  65. meta_subject/action_items.py +1 -2
  66. meta_subject/choices.py +2 -1
  67. meta_subject/form_validators/glucose_form_validator.py +16 -1
  68. meta_subject/forms/blood_results/blood_results_rft_form.py +60 -3
  69. meta_subject/forms/study_medication_form.py +5 -3
  70. meta_subject/migrations/0221_auto_20250402_1913.py +42 -0
  71. meta_subject/migrations/0222_alter_historicalstudymedication_stock_codes_and_more.py +46 -0
  72. meta_subject/migrations/0223_bloodresultsfbc_errors_bloodresultsgludummy_errors_and_more.py +83 -0
  73. meta_subject/migrations/0224_bloodresultsfbc_abnormal_summary_and_more.py +153 -0
  74. meta_subject/tests/tests/test_egfr.py +5 -5
  75. meta_analytics/dataframes/enrolled/__init__.py +0 -1
  76. meta_analytics/dataframes/enrolled/get_glucose_df.py +0 -122
  77. /meta_edc-1.0.6.dist-info/AUTHORS → /meta_analytics/dataframes/glucose_endpoints/utils.py +0 -0
  78. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info/licenses}/LICENSE +0 -0
  79. {meta_edc-1.0.6.dist-info → meta_edc-1.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,54 @@
1
+ # Generated by Django 6.0 on 2025-04-22 19:14
2
+
3
+ import django_db_views.migration_functions
4
+ import django_db_views.operations
5
+ from django.db import migrations
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ("meta_reports", "0055_alter_glucosesummary_table"),
12
+ ]
13
+
14
+ operations = [
15
+ django_db_views.operations.ViewRunPython(
16
+ code=django_db_views.migration_functions.ForwardViewMigration(
17
+ "select *, uuid() as id, now() as `created`, 'meta_reports.glucosesummaryview' as `report_model` from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS `ogtt_value`, NULL AS `ogtt_datetime`, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
18
+ "meta_reports_glucosesummaryview",
19
+ engine="django.db.backends.mysql",
20
+ ),
21
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
22
+ "select *, uuid() as id, now() as `created`, 'meta_reports.glucosesummaryview' as `report_model` from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS `ogtt_value`, NULL AS `ogtt_datetime`, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
23
+ "meta_reports_glucosesummaryview",
24
+ engine="django.db.backends.mysql",
25
+ ),
26
+ atomic=False,
27
+ ),
28
+ django_db_views.operations.ViewRunPython(
29
+ code=django_db_views.migration_functions.ForwardViewMigration(
30
+ "select *, get_random_uuid() as id, now() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
31
+ "meta_reports_glucosesummaryview",
32
+ engine="django.db.backends.postgresql",
33
+ ),
34
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
35
+ "select *, get_random_uuid() as id, now() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
36
+ "meta_reports_glucosesummaryview",
37
+ engine="django.db.backends.postgresql",
38
+ ),
39
+ atomic=False,
40
+ ),
41
+ django_db_views.operations.ViewRunPython(
42
+ code=django_db_views.migration_functions.ForwardViewMigration(
43
+ "select *, uuid() as id, datetime() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
44
+ "meta_reports_glucosesummaryview",
45
+ engine="django.db.backends.sqlite3",
46
+ ),
47
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
48
+ "select *, uuid() as id, datetime() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
49
+ "meta_reports_glucosesummaryview",
50
+ engine="django.db.backends.sqlite3",
51
+ ),
52
+ atomic=False,
53
+ ),
54
+ ]
@@ -0,0 +1,54 @@
1
+ # Generated by Django 6.0 on 2025-04-22 19:24
2
+
3
+ import django_db_views.migration_functions
4
+ import django_db_views.operations
5
+ from django.db import migrations
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ("meta_reports", "0056_auto_20250422_2214"),
12
+ ]
13
+
14
+ operations = [
15
+ django_db_views.operations.ViewRunPython(
16
+ code=django_db_views.migration_functions.ForwardViewMigration(
17
+ "select *, uuid() as id, now() as `created`, 'meta_reports.glucosesummaryview' as `report_model` from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS `ogtt_value`, NULL AS `ogtt_datetime`, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
18
+ "meta_reports_glucosesummaryview",
19
+ engine="django.db.backends.mysql",
20
+ ),
21
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
22
+ "select *, uuid() as id, now() as `created`, 'meta_reports.glucosesummaryview' as `report_model` from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS `ogtt_value`, NULL AS `ogtt_datetime`, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
23
+ "meta_reports_glucosesummaryview",
24
+ engine="django.db.backends.mysql",
25
+ ),
26
+ atomic=False,
27
+ ),
28
+ django_db_views.operations.ViewRunPython(
29
+ code=django_db_views.migration_functions.ForwardViewMigration(
30
+ "select *, get_random_uuid() as id, now() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
31
+ "meta_reports_glucosesummaryview",
32
+ engine="django.db.backends.postgresql",
33
+ ),
34
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
35
+ "select *, get_random_uuid() as id, now() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
36
+ "meta_reports_glucosesummaryview",
37
+ engine="django.db.backends.postgresql",
38
+ ),
39
+ atomic=False,
40
+ ),
41
+ django_db_views.operations.ViewRunPython(
42
+ code=django_db_views.migration_functions.ForwardViewMigration(
43
+ "select *, uuid() as id, datetime() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
44
+ "meta_reports_glucosesummaryview",
45
+ engine="django.db.backends.sqlite3",
46
+ ),
47
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
48
+ "select *, uuid() as id, datetime() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
49
+ "meta_reports_glucosesummaryview",
50
+ engine="django.db.backends.sqlite3",
51
+ ),
52
+ atomic=False,
53
+ ),
54
+ ]
@@ -0,0 +1,54 @@
1
+ # Generated by Django 6.0 on 2025-04-22 19:32
2
+
3
+ import django_db_views.migration_functions
4
+ import django_db_views.operations
5
+ from django.db import migrations
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ("meta_reports", "0057_auto_20250422_2224"),
12
+ ]
13
+
14
+ operations = [
15
+ django_db_views.operations.ViewRunPython(
16
+ code=django_db_views.migration_functions.ForwardViewMigration(
17
+ "select *, uuid() as id, now() as `created`, 'meta_reports.glucosesummaryview' as `report_model` from (SELECT v.subject_identifier, fbg_value, fbg_units, fbg_datetime, NULL AS `ogtt_value`, NULL AS `ogtt_units`, NULL AS `ogtt_datetime`, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_units, fbg_datetime, ogtt_value, ogtt_units, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
18
+ "meta_reports_glucosesummaryview",
19
+ engine="django.db.backends.mysql",
20
+ ),
21
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
22
+ "select *, uuid() as id, now() as `created`, 'meta_reports.glucosesummaryview' as `report_model` from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS `ogtt_value`, NULL AS `ogtt_datetime`, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS `fasted`, fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
23
+ "meta_reports_glucosesummaryview",
24
+ engine="django.db.backends.mysql",
25
+ ),
26
+ atomic=False,
27
+ ),
28
+ django_db_views.operations.ViewRunPython(
29
+ code=django_db_views.migration_functions.ForwardViewMigration(
30
+ "select *, get_random_uuid() as id, now() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_units, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_units\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_units, fbg_datetime, ogtt_value, ogtt_units, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
31
+ "meta_reports_glucosesummaryview",
32
+ engine="django.db.backends.postgresql",
33
+ ),
34
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
35
+ "select *, get_random_uuid() as id, now() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
36
+ "meta_reports_glucosesummaryview",
37
+ engine="django.db.backends.postgresql",
38
+ ),
39
+ atomic=False,
40
+ ),
41
+ django_db_views.operations.ViewRunPython(
42
+ code=django_db_views.migration_functions.ForwardViewMigration(
43
+ "select *, uuid() as id, datetime() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_units, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_units\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_units, fbg_datetime, ogtt_value, ogtt_units, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
44
+ "meta_reports_glucosesummaryview",
45
+ engine="django.db.backends.sqlite3",
46
+ ),
47
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration(
48
+ "select *, uuid() as id, datetime() as created, 'meta_reports.glucosesummaryview' as report_model from (SELECT v.subject_identifier, fbg_value, fbg_datetime, NULL AS \"ogtt_value\", NULL AS \"ogtt_datetime\", CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucosefbg' AS source FROM meta_subject_glucosefbg AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier UNION SELECT v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime, CASE WHEN fasting = 'fasting' THEN 'Yes' WHEN fasting = 'non_fasting' THEN 'No' ELSE fasting END AS \"fasted\", fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime, fasting_duration_delta, 'meta_subject.glucose' AS source FROM meta_subject_glucose AS fbg LEFT JOIN meta_subject_subjectvisit AS v ON v.id = fbg.subject_visit_id LEFT JOIN meta_prn_endofstudy AS eos ON v.subject_identifier = eos.subject_identifier) as A ORDER BY subject_identifier, site_id",
49
+ "meta_reports_glucosesummaryview",
50
+ engine="django.db.backends.sqlite3",
51
+ ),
52
+ atomic=False,
53
+ ),
54
+ ]
@@ -9,14 +9,24 @@ class GlucoseSummary(QaReportModelMixin, DBView):
9
9
 
10
10
  fbg_value = models.DecimalField(max_digits=8, decimal_places=2, null=True)
11
11
 
12
+ fbg_units = models.CharField(max_length=15, null=True)
13
+
12
14
  fbg_datetime = models.DateTimeField(null=True)
13
15
 
14
16
  ogtt_value = models.DecimalField(max_digits=8, decimal_places=2, null=True)
15
17
 
18
+ ogtt_units = models.CharField(max_length=15, null=True)
19
+
16
20
  ogtt_datetime = models.DateTimeField(null=True)
17
21
 
18
22
  fasted = models.CharField(max_length=15, null=True)
19
23
 
24
+ fasting_duration_delta = models.DurationField(
25
+ verbose_name="Fasting duration (hrs)", null=True
26
+ )
27
+
28
+ report_datetime = models.DateTimeField(null=True)
29
+
20
30
  visit_code = models.CharField(max_length=25)
21
31
 
22
32
  visit_code_sequence = models.IntegerField()
@@ -25,11 +35,13 @@ class GlucoseSummary(QaReportModelMixin, DBView):
25
35
 
26
36
  offstudy_datetime = models.DateTimeField(null=True)
27
37
 
38
+ source = models.CharField(max_length=35, null=True)
39
+
28
40
  view_definition = get_view_definition()
29
41
 
30
42
  class Meta:
31
43
  managed = False
32
- db_table = "glucose_summary_view"
44
+ db_table = "meta_reports_glucosesummaryview"
33
45
  verbose_name = "Glucose Summary"
34
46
  verbose_name_plural = "Glucose Summary"
35
47
  default_permissions = qa_reports_permissions
@@ -3,22 +3,25 @@ from edc_qareports.sql_generator import SqlViewGenerator
3
3
 
4
4
  def get_view_definition() -> dict:
5
5
  subquery = """
6
- select v.subject_identifier, fbg_value, fbg_datetime, null as `ogtt_value`, null as `ogtt_datetime`,
6
+ select v.subject_identifier, fbg_value, fbg_units, fbg_datetime, null as `ogtt_value`, null as `ogtt_units`,
7
+ null as `ogtt_datetime`,
7
8
  case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as `fasted`,
8
- fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
9
+ fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime,
10
+ fasting_duration_delta, "meta_subject.glucosefbg" as source
9
11
  from meta_subject_glucosefbg as fbg
10
12
  left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
11
13
  left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
12
14
  UNION
13
- select v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime,
15
+ select v.subject_identifier, fbg_value, fbg_units, fbg_datetime, ogtt_value, ogtt_units, ogtt_datetime,
14
16
  case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as `fasted`,
15
- fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
17
+ fbg.site_id, v.visit_code, v.visit_code_sequence, v.report_datetime, v.appointment_id, eos.offstudy_datetime,
18
+ fasting_duration_delta, "meta_subject.glucose" as source
16
19
  from meta_subject_glucose as fbg
17
20
  left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
18
21
  left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
19
22
  """ # noqa
20
23
  sql_view = SqlViewGenerator(
21
- report_model="meta_reports.glucose_summary_view",
24
+ report_model="meta_reports.glucosesummaryview",
22
25
  ordering=["subject_identifier", "site_id"],
23
26
  )
24
27
  return {
@@ -1,15 +1,12 @@
1
1
  from edc_constants.constants import NEG, NO, NOT_APPLICABLE
2
2
  from edc_egfr import EgfrCkdEpi
3
3
  from edc_egfr.calculators import EgfrCalculatorError
4
- from edc_reportable import (
5
- MICROMOLES_PER_LITER,
6
- MILLIMOLES_PER_LITER,
7
- ConversionNotHandled,
8
- calculate_bmi,
9
- convert_units,
10
- )
4
+ from edc_reportable.exceptions import ConversionNotHandled
5
+ from edc_reportable.units import MICROMOLES_PER_LITER, MILLIMOLES_PER_LITER
6
+ from edc_reportable.utils import convert_units
11
7
  from edc_screening.fc import FC
12
8
  from edc_screening.screening_eligibility import ScreeningEligibility
9
+ from edc_vitals.calculators import calculate_bmi
13
10
 
14
11
 
15
12
  class BaseEligibilityPartThree(ScreeningEligibility):
@@ -82,64 +79,79 @@ class BaseEligibilityPartThree(ScreeningEligibility):
82
79
 
83
80
  @property
84
81
  def converted_creatinine_value(self):
85
- try:
86
- value = convert_units(
87
- self.creatinine_value,
88
- units_from=self.creatinine_units,
89
- units_to=MICROMOLES_PER_LITER,
90
- )
91
- except ConversionNotHandled as e:
92
- raise ConversionNotHandled(f"Creatinine. {e}")
82
+ value = None
83
+ if self.creatinine_value and self.creatinine_units:
84
+ try:
85
+ value = convert_units(
86
+ label="creatinine",
87
+ value=self.creatinine_value,
88
+ units_from=self.creatinine_units,
89
+ units_to=MICROMOLES_PER_LITER,
90
+ )
91
+ except ConversionNotHandled as e:
92
+ raise ConversionNotHandled(f"Creatinine. {e}")
93
93
  if value and float(value) > 999999.9999:
94
94
  raise ConversionNotHandled("Creatinine value is absurd.")
95
95
  return value
96
96
 
97
97
  @property
98
98
  def converted_fbg_value(self):
99
- try:
100
- value = convert_units(
101
- self.fbg_value,
102
- units_from=self.fbg_units,
103
- units_to=MILLIMOLES_PER_LITER,
104
- )
105
- except ConversionNotHandled as e:
106
- raise ConversionNotHandled(f"FBG. {e}")
99
+ value = None
100
+ if self.fbg_value and self.fbg_units:
101
+ try:
102
+ value = convert_units(
103
+ label="glucose",
104
+ value=self.fbg_value,
105
+ units_from=self.fbg_units,
106
+ units_to=MILLIMOLES_PER_LITER,
107
+ )
108
+ except ConversionNotHandled as e:
109
+ raise ConversionNotHandled(f"FBG. {e}")
107
110
  return value
108
111
 
109
112
  @property
110
113
  def converted_fbg2_value(self):
111
- try:
112
- value = convert_units(
113
- self.fbg2_value,
114
- units_from=self.fbg2_units,
115
- units_to=MILLIMOLES_PER_LITER,
116
- )
117
- except ConversionNotHandled as e:
118
- raise ConversionNotHandled(f"FBG2. {e}")
114
+ value = None
115
+ if self.fbg2_value and self.fbg2_units:
116
+ try:
117
+ value = convert_units(
118
+ label="glucose",
119
+ value=self.fbg2_value,
120
+ units_from=self.fbg2_units,
121
+ units_to=MILLIMOLES_PER_LITER,
122
+ )
123
+ except ConversionNotHandled as e:
124
+ raise ConversionNotHandled(f"FBG2. {e}")
119
125
  return value
120
126
 
121
127
  @property
122
128
  def converted_ogtt_value(self):
123
- try:
124
- value = convert_units(
125
- self.ogtt_value,
126
- units_from=self.ogtt_units,
127
- units_to=MILLIMOLES_PER_LITER,
128
- )
129
- except ConversionNotHandled as e:
130
- raise ConversionNotHandled(f"OGTT. {e}")
129
+ value = None
130
+ if self.ogtt_value and self.ogtt_units:
131
+ try:
132
+ value = convert_units(
133
+ label="glucose",
134
+ value=self.ogtt_value,
135
+ units_from=self.ogtt_units,
136
+ units_to=MILLIMOLES_PER_LITER,
137
+ )
138
+ except ConversionNotHandled as e:
139
+ raise ConversionNotHandled(f"OGTT. {e}")
131
140
  return value
132
141
 
133
142
  @property
134
143
  def converted_ogtt2_value(self):
135
- try:
136
- value = convert_units(
137
- self.ogtt2_value,
138
- units_from=self.ogtt2_units,
139
- units_to=MILLIMOLES_PER_LITER,
140
- )
141
- except ConversionNotHandled as e:
142
- raise ConversionNotHandled(f"OGTT2. {e}")
144
+ value = None
145
+ if self.ogtt2_value and self.ogtt2_units:
146
+ try:
147
+ value = convert_units(
148
+ label="glucose",
149
+ value=self.ogtt2_value,
150
+ units_from=self.ogtt2_units,
151
+ units_to=MILLIMOLES_PER_LITER,
152
+ )
153
+ except ConversionNotHandled as e:
154
+ raise ConversionNotHandled(f"OGTT2. {e}")
143
155
  return value
144
156
 
145
157
  def set_eligible_model_field(self):
@@ -74,7 +74,12 @@ class ScreeningPartThreeFormValidator(
74
74
  self.validate_creatinine_required_fields()
75
75
  self.required_if(YES, field="hba1c_performed", field_required="hba1c_datetime")
76
76
  self.required_if(YES, field="hba1c_performed", field_required="hba1c_value")
77
- self.validate_egfr()
77
+ self.validate_egfr(
78
+ gender=self.instance.gender,
79
+ age_in_years=self.instance.age_in_years,
80
+ weight_in_kgs=self.cleaned_data.get("weight"),
81
+ ethnicity=self.instance.ethnicity,
82
+ )
78
83
  self.validate_suitability_for_study()
79
84
 
80
85
  @property
@@ -14,6 +14,7 @@ from edc_list_data.site_list_data import site_list_data
14
14
  from edc_metadata import REQUIRED
15
15
  from edc_metadata.models import CrfMetadata
16
16
  from edc_randomization.site_randomizers import site_randomizers
17
+ from edc_reportable.utils import load_reference_ranges
17
18
  from edc_sites.site import sites
18
19
  from edc_sites.utils import add_or_update_django_sites
19
20
  from edc_visit_tracking.constants import SCHEDULED
@@ -21,6 +22,7 @@ from model_bakery import baker
21
22
 
22
23
  from meta_consent.models import SubjectConsent, SubjectConsentV1Ext
23
24
  from meta_edc.meta_version import PHASE_THREE
25
+ from meta_labs.reportables import reference_range_options
24
26
  from meta_pharmacy.prepare_meta_pharmacy import prepare_meta_pharmacy
25
27
  from meta_sites.sites import domain_suffix
26
28
  from meta_subject.models import SubjectVisit
@@ -53,6 +55,7 @@ class MetaTestCaseMixin(AppointmentTestCaseMixin):
53
55
 
54
56
  @classmethod
55
57
  def setUpTestData(cls):
58
+ load_reference_ranges(**reference_range_options)
56
59
  import_holidays(test=True)
57
60
  add_or_update_django_sites(single_sites=sites.get_by_country("tanzania", aslist=True))
58
61
  if cls.import_randomization_list:
@@ -3,7 +3,8 @@ from random import choices
3
3
 
4
4
  from dateutil.relativedelta import relativedelta
5
5
  from django.test import TestCase
6
- from edc_constants.constants import FEMALE, MALE, NO, NOT_APPLICABLE, POS, YES
6
+ from edc_constants.constants import BLACK, FEMALE, MALE, NO, NOT_APPLICABLE, POS, YES
7
+ from edc_reportable import MILLIGRAMS_PER_DECILITER
7
8
  from edc_utils.date import get_utcnow
8
9
 
9
10
  from meta_screening.forms import (
@@ -394,4 +395,10 @@ class TestForms(ScreeningTestMixin, TestCase):
394
395
  def test_screening_creatinine(self):
395
396
  instance = self.complete_part_one(hospital_identifier="9678281237")
396
397
  _, instance = self.complete_part_two(instance=instance)
397
- self.complete_part_three(instance=instance, verbose=True, creatinine=9000.0)
398
+ self.complete_part_three(
399
+ instance=instance,
400
+ verbose=True,
401
+ ethnicity=BLACK,
402
+ creatinine_value=1.5,
403
+ creatinine_units=MILLIGRAMS_PER_DECILITER,
404
+ )
@@ -4,11 +4,8 @@ from decimal import Decimal
4
4
  from dateutil.relativedelta import relativedelta
5
5
  from django.test import TestCase
6
6
  from edc_constants.constants import FEMALE, NO, NOT_APPLICABLE, POS, TBD, YES
7
- from edc_reportable import (
8
- MICROMOLES_PER_LITER,
9
- MILLIMOLES_PER_LITER,
10
- ConversionNotHandled,
11
- )
7
+ from edc_reportable import MICROMOLES_PER_LITER, MILLIMOLES_PER_LITER
8
+ from edc_reportable.utils import convert_units
12
9
  from edc_utils.date import get_utcnow
13
10
 
14
11
  from meta_screening.constants import (
@@ -292,20 +289,20 @@ class TestScreeningPartThree(TestCase):
292
289
  obj.ogtt_value = 3.0
293
290
  obj.ogtt_units = MICROMOLES_PER_LITER
294
291
  obj.ogtt_datetime = get_utcnow()
295
- try:
296
- obj.save()
297
- except ConversionNotHandled:
298
- pass
299
- else:
300
- self.fail("ConversionNotHandled unexpectedly not raised.")
292
+ obj.save()
301
293
 
302
294
  obj.refresh_from_db()
295
+ obj.ogtt_value = convert_units(
296
+ label="glucose",
297
+ value=3.0,
298
+ units_from=MICROMOLES_PER_LITER,
299
+ units_to=MILLIMOLES_PER_LITER,
300
+ )
303
301
  obj.ogtt_units = MILLIMOLES_PER_LITER
304
302
  obj.save()
305
303
 
306
- self.assertIn(ineligible_reason, obj.reasons_ineligible_part_three)
307
- self.assertEqual(obj.eligible_part_three, TBD)
308
- self.assertFalse(obj.eligible)
304
+ self.assertEqual(obj.eligible_part_three, YES)
305
+ self.assertTrue(obj.eligible)
309
306
  self.assertFalse(obj.consented)
310
307
 
311
308
  obj.ogtt_base_datetime = get_utcnow()
@@ -2,7 +2,7 @@ from django.apps import apps as django_apps
2
2
  from edc_action_item import Action, ActionWithNotification, site_action_items
3
3
  from edc_action_item.site_action_items import AlreadyRegistered
4
4
  from edc_adverse_event.constants import AE_INITIAL_ACTION
5
- from edc_constants.constants import HIGH_PRIORITY, NEW, NONE, POS, YES
5
+ from edc_constants.constants import GRADE3, GRADE4, HIGH_PRIORITY, NEW, NONE, POS, YES
6
6
  from edc_egfr.constants import EGFR_DROP_NOTIFICATION_ACTION
7
7
  from edc_lab_results.action_items import BloodResultsFbcAction
8
8
  from edc_lab_results.action_items import (
@@ -17,7 +17,6 @@ from edc_lab_results.action_items import (
17
17
  BloodResultsRftAction as BaseBloodResultsRftAction,
18
18
  )
19
19
  from edc_ltfu.constants import LTFU_ACTION
20
- from edc_reportable import GRADE3, GRADE4
21
20
  from edc_visit_schedule.constants import OFFSCHEDULE_ACTION
22
21
  from edc_visit_schedule.utils import is_baseline
23
22
  from edc_visit_tracking.constants import MISSED_VISIT
meta_subject/choices.py CHANGED
@@ -3,6 +3,8 @@ from edc_constants.constants import (
3
3
  ABSENT,
4
4
  CLOSED,
5
5
  DEAD,
6
+ GRADE3,
7
+ GRADE4,
6
8
  NEW,
7
9
  NO,
8
10
  NO_EXAM,
@@ -15,7 +17,6 @@ from edc_constants.constants import (
15
17
  PRESENT_WITH_REINFORCEMENT,
16
18
  YES,
17
19
  )
18
- from edc_reportable.constants import GRADE3, GRADE4
19
20
  from edc_visit_tracking.constants import MISSED_VISIT, SCHEDULED, UNSCHEDULED
20
21
 
21
22
  from meta_ae.choices import INFORMANT_RELATIONSHIP
@@ -5,6 +5,8 @@ from edc_crf.crf_form_validator import CrfFormValidator
5
5
  from edc_form_validators import INVALID_ERROR
6
6
  from edc_glucose.form_validators import FbgOgttFormValidatorMixin
7
7
 
8
+ from meta_reports.models import GlucoseSummary
9
+
8
10
  from ..constants import AMENDMENT_DATE
9
11
 
10
12
 
@@ -79,5 +81,18 @@ class GlucoseFormValidator(FbgOgttFormValidatorMixin, CrfFormValidator):
79
81
  elif self.cleaned_data.get("fbg_value") >= Decimal("7.0") and self.cleaned_data.get(
80
82
  "ogtt_value"
81
83
  ) < Decimal("11.1"):
82
- value = PENDING
84
+ # is there a previous FBG>=7.0 in sequence or do you need to repeat?
85
+ previous_obj = (
86
+ GlucoseSummary.objects.filter(
87
+ subject_identifier=self.subject_identifier,
88
+ fbg_datetime__lt=self.cleaned_data.get("fbg_datetime"),
89
+ )
90
+ .order_by("fbg_datetime")
91
+ .last()
92
+ )
93
+ if previous_obj and previous_obj.fbg_value >= Decimal("7.0"):
94
+ value = YES
95
+ else:
96
+ # you need to schedule a repeat
97
+ value = PENDING
83
98
  return value