diff --git a/CHANGES b/CHANGES index 2c109f16..f6dbf215 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,7 @@ Changes unreleased ------ - add QA reports for Missing Lab Values +- add Sodium field to Blood Result: Chemistry form (#521) - bump to edc 0.6.12 0.1.55 diff --git a/effect_labs/panels.py b/effect_labs/panels.py index 12ec4538..e85affaf 100644 --- a/effect_labs/panels.py +++ b/effect_labs/panels.py @@ -26,6 +26,7 @@ "egfr", "magnesium", "potassium", + "sodium", "ggt", "urea", ("tbil", "Total Bilirubin"), diff --git a/effect_reports/migrations/0006_auto_20240913_1115.py b/effect_reports/migrations/0006_auto_20240913_1115.py new file mode 100644 index 00000000..fb554314 --- /dev/null +++ b/effect_reports/migrations/0006_auto_20240913_1115.py @@ -0,0 +1,55 @@ +# Generated by Django 5.1.1 on 2024-09-13 09:15 + +import django_db_views.migration_functions +import django_db_views.operations +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("effect_reports", "0005_auto_20240912_1156"), + ("effect_subject", "0117_bloodresultschem_sodium_abnormal_and_more"), + ] + + operations = [ + django_db_views.operations.ViewRunPython( + code=django_db_views.migration_functions.ForwardViewMigration( + "select *, uuid() as id, now() as `created`, 'onstudy_missing_lab_values_view' as `report_model` from (SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultschem AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'chemistry' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.lpcsf' AS label_lower, 'CSFC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_lpcsf AS crf ON req.id = crf.csf_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'csf_culture' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultsfbc AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'fbc' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.tbdiagnostics' AS label_lower, 'SPM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_tbdiagnostics AS crf ON req.id = crf.sputum_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'sputum' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alt_value IS NULL OR crf.alt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing creatinine value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.creatinine_value IS NULL OR crf.creatinine_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing albumin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.albumin_value IS NULL OR crf.albumin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alp_value IS NULL OR crf.alp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ast value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ast_value IS NULL OR crf.ast_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing crp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.crp_value IS NULL OR crf.crp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing egfr value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.egfr_value IS NULL OR crf.egfr_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing magnesium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.magnesium_value IS NULL OR crf.magnesium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing potassium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.potassium_value IS NULL OR crf.potassium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing sodium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.sodium_value IS NULL OR crf.sodium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ggt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ggt_value IS NULL OR crf.ggt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing urea value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.urea_value IS NULL OR crf.urea_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing tbil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.tbil_value IS NULL OR crf.tbil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing haemoglobin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.haemoglobin_value IS NULL OR crf.haemoglobin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing wbc value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.wbc_value IS NULL OR crf.wbc_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing platelets value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.platelets_value IS NULL OR crf.platelets_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_value IS NULL OR crf.neutrophil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_diff_value IS NULL OR crf.neutrophil_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_value IS NULL OR crf.lymphocyte_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_diff_value IS NULL OR crf.lymphocyte_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified) as A ORDER BY subject_identifier, site_id", + "onstudy_missing_lab_values_view", + engine="django.db.backends.mysql", + ), + reverse_code=django_db_views.migration_functions.BackwardViewMigration( + "select *, uuid() as id, now() as `created`, 'onstudy_missing_lab_values_view' as `report_model` from (SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultschem AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'chemistry' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.lpcsf' AS label_lower, 'CSFC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_lpcsf AS crf ON req.id = crf.csf_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'csf_culture' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultsfbc AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'fbc' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.tbdiagnostics' AS label_lower, 'SPM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_tbdiagnostics AS crf ON req.id = crf.sputum_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'sputum' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alt_value IS NULL OR crf.alt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing creatinine value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.creatinine_value IS NULL OR crf.creatinine_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing albumin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.albumin_value IS NULL OR crf.albumin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alp_value IS NULL OR crf.alp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ast value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ast_value IS NULL OR crf.ast_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing crp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.crp_value IS NULL OR crf.crp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing egfr value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.egfr_value IS NULL OR crf.egfr_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing magnesium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.magnesium_value IS NULL OR crf.magnesium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing potassium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.potassium_value IS NULL OR crf.potassium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ggt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ggt_value IS NULL OR crf.ggt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing urea value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.urea_value IS NULL OR crf.urea_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing tbil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.tbil_value IS NULL OR crf.tbil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing haemoglobin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.haemoglobin_value IS NULL OR crf.haemoglobin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing wbc value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.wbc_value IS NULL OR crf.wbc_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing platelets value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.platelets_value IS NULL OR crf.platelets_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_value IS NULL OR crf.neutrophil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_diff_value IS NULL OR crf.neutrophil_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_value IS NULL OR crf.lymphocyte_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_diff_value IS NULL OR crf.lymphocyte_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified) as A ORDER BY subject_identifier, site_id", + "onstudy_missing_lab_values_view", + engine="django.db.backends.mysql", + ), + atomic=False, + ), + django_db_views.operations.ViewRunPython( + code=django_db_views.migration_functions.ForwardViewMigration( + "select *, get_random_uuid() as id, now() as created, 'onstudy_missing_lab_values_view' as report_model from (SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultschem AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'chemistry' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.lpcsf' AS label_lower, 'CSFC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_lpcsf AS crf ON req.id = crf.csf_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'csf_culture' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultsfbc AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'fbc' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.tbdiagnostics' AS label_lower, 'SPM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_tbdiagnostics AS crf ON req.id = crf.sputum_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'sputum' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alt_value IS NULL OR crf.alt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing creatinine value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.creatinine_value IS NULL OR crf.creatinine_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing albumin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.albumin_value IS NULL OR crf.albumin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alp_value IS NULL OR crf.alp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ast value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ast_value IS NULL OR crf.ast_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing crp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.crp_value IS NULL OR crf.crp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing egfr value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.egfr_value IS NULL OR crf.egfr_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing magnesium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.magnesium_value IS NULL OR crf.magnesium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing potassium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.potassium_value IS NULL OR crf.potassium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing sodium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.sodium_value IS NULL OR crf.sodium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ggt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ggt_value IS NULL OR crf.ggt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing urea value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.urea_value IS NULL OR crf.urea_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing tbil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.tbil_value IS NULL OR crf.tbil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing haemoglobin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.haemoglobin_value IS NULL OR crf.haemoglobin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing wbc value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.wbc_value IS NULL OR crf.wbc_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing platelets value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.platelets_value IS NULL OR crf.platelets_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_value IS NULL OR crf.neutrophil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_diff_value IS NULL OR crf.neutrophil_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_value IS NULL OR crf.lymphocyte_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_diff_value IS NULL OR crf.lymphocyte_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified) as A ORDER BY subject_identifier, site_id", + "onstudy_missing_lab_values_view", + engine="django.db.backends.postgresql", + ), + reverse_code=django_db_views.migration_functions.BackwardViewMigration( + "select *, get_random_uuid() as id, now() as created, 'onstudy_missing_lab_values_view' as report_model from (SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultschem AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'chemistry' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.lpcsf' AS label_lower, 'CSFC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_lpcsf AS crf ON req.id = crf.csf_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'csf_culture' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultsfbc AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'fbc' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.tbdiagnostics' AS label_lower, 'SPM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_tbdiagnostics AS crf ON req.id = crf.sputum_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'sputum' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alt_value IS NULL OR crf.alt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing creatinine value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.creatinine_value IS NULL OR crf.creatinine_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing albumin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.albumin_value IS NULL OR crf.albumin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alp_value IS NULL OR crf.alp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ast value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ast_value IS NULL OR crf.ast_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing crp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.crp_value IS NULL OR crf.crp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing egfr value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.egfr_value IS NULL OR crf.egfr_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing magnesium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.magnesium_value IS NULL OR crf.magnesium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing potassium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.potassium_value IS NULL OR crf.potassium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ggt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ggt_value IS NULL OR crf.ggt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing urea value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.urea_value IS NULL OR crf.urea_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing tbil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.tbil_value IS NULL OR crf.tbil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing haemoglobin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.haemoglobin_value IS NULL OR crf.haemoglobin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing wbc value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.wbc_value IS NULL OR crf.wbc_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing platelets value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.platelets_value IS NULL OR crf.platelets_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_value IS NULL OR crf.neutrophil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_diff_value IS NULL OR crf.neutrophil_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_value IS NULL OR crf.lymphocyte_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_diff_value IS NULL OR crf.lymphocyte_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified) as A ORDER BY subject_identifier, site_id", + "onstudy_missing_lab_values_view", + engine="django.db.backends.postgresql", + ), + atomic=False, + ), + django_db_views.operations.ViewRunPython( + code=django_db_views.migration_functions.ForwardViewMigration( + "select *, uuid() as id, datetime() as created, 'onstudy_missing_lab_values_view' as report_model from (SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultschem AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'chemistry' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.lpcsf' AS label_lower, 'CSFC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_lpcsf AS crf ON req.id = crf.csf_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'csf_culture' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultsfbc AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'fbc' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.tbdiagnostics' AS label_lower, 'SPM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_tbdiagnostics AS crf ON req.id = crf.sputum_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'sputum' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alt_value IS NULL OR crf.alt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing creatinine value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.creatinine_value IS NULL OR crf.creatinine_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing albumin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.albumin_value IS NULL OR crf.albumin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alp_value IS NULL OR crf.alp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ast value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ast_value IS NULL OR crf.ast_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing crp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.crp_value IS NULL OR crf.crp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing egfr value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.egfr_value IS NULL OR crf.egfr_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing magnesium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.magnesium_value IS NULL OR crf.magnesium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing potassium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.potassium_value IS NULL OR crf.potassium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing sodium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.sodium_value IS NULL OR crf.sodium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ggt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ggt_value IS NULL OR crf.ggt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing urea value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.urea_value IS NULL OR crf.urea_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing tbil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.tbil_value IS NULL OR crf.tbil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing haemoglobin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.haemoglobin_value IS NULL OR crf.haemoglobin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing wbc value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.wbc_value IS NULL OR crf.wbc_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing platelets value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.platelets_value IS NULL OR crf.platelets_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_value IS NULL OR crf.neutrophil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_diff_value IS NULL OR crf.neutrophil_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_value IS NULL OR crf.lymphocyte_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_diff_value IS NULL OR crf.lymphocyte_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified) as A ORDER BY subject_identifier, site_id", + "onstudy_missing_lab_values_view", + engine="django.db.backends.sqlite3", + ), + reverse_code=django_db_views.migration_functions.BackwardViewMigration( + "select *, uuid() as id, datetime() as created, 'onstudy_missing_lab_values_view' as report_model from (SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultschem AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'chemistry' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.lpcsf' AS label_lower, 'CSFC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_lpcsf AS crf ON req.id = crf.csf_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'csf_culture' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_bloodresultsfbc AS crf ON req.id = crf.requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'fbc' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT req.subject_identifier, req.id AS original_id, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified, 'effect_subject.tbdiagnostics' AS label_lower, 'SPM requisitioned but not entered' AS label, COUNT(*) AS records FROM effect_subject_subjectrequisition AS req LEFT JOIN effect_subject_tbdiagnostics AS crf ON req.id = crf.sputum_requisition_id LEFT JOIN effect_subject_subjectvisit AS v ON v.id = req.subject_visit_id LEFT JOIN edc_lab_panel AS panel ON req.panel_id = panel.id WHERE panel.name = 'sputum' AND req.is_drawn = 'Yes' AND crf.id IS NULL GROUP BY req.id, req.subject_identifier, req.subject_visit_id, req.report_datetime, req.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, req.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alt_value IS NULL OR crf.alt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing creatinine value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.creatinine_value IS NULL OR crf.creatinine_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing albumin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.albumin_value IS NULL OR crf.albumin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing alp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.alp_value IS NULL OR crf.alp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ast value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ast_value IS NULL OR crf.ast_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing crp value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.crp_value IS NULL OR crf.crp_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing egfr value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.egfr_value IS NULL OR crf.egfr_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing magnesium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.magnesium_value IS NULL OR crf.magnesium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing potassium value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.potassium_value IS NULL OR crf.potassium_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing ggt value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.ggt_value IS NULL OR crf.ggt_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing urea value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.urea_value IS NULL OR crf.urea_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultschem' AS label_lower, 'CHEM: missing tbil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultschem AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.tbil_value IS NULL OR crf.tbil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing haemoglobin value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.haemoglobin_value IS NULL OR crf.haemoglobin_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing wbc value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.wbc_value IS NULL OR crf.wbc_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing platelets value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.platelets_value IS NULL OR crf.platelets_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_value IS NULL OR crf.neutrophil_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing neutrophil_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.neutrophil_diff_value IS NULL OR crf.neutrophil_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_value IS NULL OR crf.lymphocyte_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified UNION SELECT v.subject_identifier, crf.id AS original_id, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified, 'effect_subject.bloodresultsfbc' AS label_lower, 'FBC: missing lymphocyte_diff value/units' AS label, COUNT(*) AS records FROM effect_subject_bloodresultsfbc AS crf LEFT JOIN effect_subject_subjectvisit AS v ON v.id = crf.subject_visit_id WHERE crf.lymphocyte_diff_value IS NULL OR crf.lymphocyte_diff_units IS NULL GROUP BY v.subject_identifier, crf.subject_visit_id, crf.report_datetime, crf.site_id, v.visit_code, v.visit_code_sequence, v.schedule_name, crf.modified) as A ORDER BY subject_identifier, site_id", + "onstudy_missing_lab_values_view", + engine="django.db.backends.sqlite3", + ), + atomic=False, + ), + ] diff --git a/effect_subject/migrations/0117_bloodresultschem_sodium_abnormal_and_more.py b/effect_subject/migrations/0117_bloodresultschem_sodium_abnormal_and_more.py new file mode 100644 index 00000000..e0bb1156 --- /dev/null +++ b/effect_subject/migrations/0117_bloodresultschem_sodium_abnormal_and_more.py @@ -0,0 +1,190 @@ +# Generated by Django 5.1.1 on 2024-09-12 14:55 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("effect_subject", "0116_alter_bloodculture_options_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="bloodresultschem", + name="sodium_abnormal", + field=models.CharField( + blank=True, + choices=[("Yes", "Yes"), ("No", "No")], + max_length=25, + null=True, + verbose_name="abnormal", + ), + ), + migrations.AddField( + model_name="bloodresultschem", + name="sodium_grade", + field=models.IntegerField( + blank=True, + choices=[ + (0, "Not graded"), + (1, "Grade 1"), + (2, "Grade 2"), + (3, "Grade 3"), + (4, "Grade 4"), + (5, "Grade 5"), + ], + null=True, + verbose_name="Grade", + ), + ), + migrations.AddField( + model_name="bloodresultschem", + name="sodium_grade_description", + field=models.CharField( + blank=True, max_length=250, null=True, verbose_name="Grade description" + ), + ), + migrations.AddField( + model_name="bloodresultschem", + name="sodium_quantifier", + field=models.CharField( + blank=True, + choices=[("=", "="), (">", ">"), (">=", ">="), ("<", "<"), ("<=", "<=")], + default="=", + max_length=10, + null=True, + verbose_name="Quantifier", + ), + ), + migrations.AddField( + model_name="bloodresultschem", + name="sodium_reportable", + field=models.CharField( + blank=True, + choices=[ + ("N/A", "Not applicable"), + ("3", "Yes, grade 3"), + ("4", "Yes, grade 4"), + ("No", "Not reportable"), + ("Already reported", "Already reported"), + ("present_at_baseline", "Present at baseline"), + ], + max_length=25, + null=True, + verbose_name="reportable", + ), + ), + migrations.AddField( + model_name="bloodresultschem", + name="sodium_units", + field=models.CharField( + blank=True, + choices=[("mmol/L", "mmol/L (millimoles/L)")], + max_length=15, + null=True, + verbose_name="units", + ), + ), + migrations.AddField( + model_name="bloodresultschem", + name="sodium_value", + field=models.DecimalField( + blank=True, + decimal_places=0, + max_digits=8, + null=True, + validators=[django.core.validators.MinValueValidator(0.0)], + verbose_name="Sodium (Na)", + ), + ), + migrations.AddField( + model_name="historicalbloodresultschem", + name="sodium_abnormal", + field=models.CharField( + blank=True, + choices=[("Yes", "Yes"), ("No", "No")], + max_length=25, + null=True, + verbose_name="abnormal", + ), + ), + migrations.AddField( + model_name="historicalbloodresultschem", + name="sodium_grade", + field=models.IntegerField( + blank=True, + choices=[ + (0, "Not graded"), + (1, "Grade 1"), + (2, "Grade 2"), + (3, "Grade 3"), + (4, "Grade 4"), + (5, "Grade 5"), + ], + null=True, + verbose_name="Grade", + ), + ), + migrations.AddField( + model_name="historicalbloodresultschem", + name="sodium_grade_description", + field=models.CharField( + blank=True, max_length=250, null=True, verbose_name="Grade description" + ), + ), + migrations.AddField( + model_name="historicalbloodresultschem", + name="sodium_quantifier", + field=models.CharField( + blank=True, + choices=[("=", "="), (">", ">"), (">=", ">="), ("<", "<"), ("<=", "<=")], + default="=", + max_length=10, + null=True, + verbose_name="Quantifier", + ), + ), + migrations.AddField( + model_name="historicalbloodresultschem", + name="sodium_reportable", + field=models.CharField( + blank=True, + choices=[ + ("N/A", "Not applicable"), + ("3", "Yes, grade 3"), + ("4", "Yes, grade 4"), + ("No", "Not reportable"), + ("Already reported", "Already reported"), + ("present_at_baseline", "Present at baseline"), + ], + max_length=25, + null=True, + verbose_name="reportable", + ), + ), + migrations.AddField( + model_name="historicalbloodresultschem", + name="sodium_units", + field=models.CharField( + blank=True, + choices=[("mmol/L", "mmol/L (millimoles/L)")], + max_length=15, + null=True, + verbose_name="units", + ), + ), + migrations.AddField( + model_name="historicalbloodresultschem", + name="sodium_value", + field=models.DecimalField( + blank=True, + decimal_places=0, + max_digits=8, + null=True, + validators=[django.core.validators.MinValueValidator(0.0)], + verbose_name="Sodium (Na)", + ), + ), + ] diff --git a/effect_subject/models/lab_results/blood_results_chem.py b/effect_subject/models/lab_results/blood_results_chem.py index 5d6296e1..ab080daf 100644 --- a/effect_subject/models/lab_results/blood_results_chem.py +++ b/effect_subject/models/lab_results/blood_results_chem.py @@ -19,6 +19,7 @@ GgtModelMixin, MagnesiumModelMixin, PotassiumModelMixin, + SodiumModelMixin, TotalBilirubinModelMixin, UreaModelMixin, UricAcidModelMixin, @@ -51,6 +52,7 @@ class BloodResultsChem( EgfrModelMixin, MagnesiumModelMixin, PotassiumModelMixin, + SodiumModelMixin, TotalBilirubinModelMixin, UreaModelMixin, UricAcidModelMixin, diff --git a/effect_subject/tests/tests/test_lab_results.py b/effect_subject/tests/tests/test_lab_results.py index 1c436373..091b6ecb 100644 --- a/effect_subject/tests/tests/test_lab_results.py +++ b/effect_subject/tests/tests/test_lab_results.py @@ -8,10 +8,18 @@ from django import forms from django.conf import settings from django.contrib.sites.models import Site -from django.test import TestCase +from django.test import TestCase, tag from edc_constants.constants import NO, NOT_APPLICABLE, YES from edc_lab.models import Panel -from edc_reportable import GRADE4, PERCENT, TEN_X_9_PER_LITER +from edc_reportable import ( + ALREADY_REPORTED, + GRADE3, + GRADE4, + MILLIMOLES_PER_LITER, + PERCENT, + PRESENT_AT_BASELINE, + TEN_X_9_PER_LITER, +) from edc_utils import convert_php_dateformat, get_utcnow from edc_visit_schedule.constants import DAY01, DAY03, DAY09 @@ -43,6 +51,7 @@ def __repr__(self): @time_machine.travel(datetime(2023, 1, 10, 8, 00, tzinfo=ZoneInfo("UTC"))) +@tag("lab") class TestLabResults(EffectTestCaseMixin, TestCase): def setUp(self) -> None: screening_datetime = get_utcnow() - relativedelta(years=1) @@ -499,3 +508,577 @@ def test_negative_values_lt_0_for_neutrophil_lymphocyte_raises(self): ["Ensure this value is greater than or equal to 0.0."], form.errors.get(f"{result_type}_value"), ) + + def test_sodium_in_normal_range_ok(self): + subject_visit = self.get_subject_visit( + subject_screening=self.subject_screening, + subject_consent=self.subject_consent, + visit_code=DAY01, + appt_datetime=self.subject_consent.consent_datetime, + ) + panel_results_data = self.get_panel_results_data(subject_visit, "chemistry") + for normal_value in [136, 140, 144, 145]: + with self.subTest(normal_value=normal_value): + panel_results_data.update( + { + "sodium_value": normal_value, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": NO, + "sodium_reportable": NOT_APPLICABLE, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form = BloodResultsChemForm(panel_results_data) + self.assertTrue( + form.is_valid(), + f"Expected form to be valid. Got: {form.errors.as_data()}", + ) + + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + try: + form_validator.validate() + except forms.ValidationError as e: + self.fail(f"ValidationError unexpectedly raised. Got {e}") + + def test_sodium_135_treated_as_normal(self): + """... "for the EDC we should allow 135-145 inclusive to be + normal". + """ + subject_visit = self.get_subject_visit( + subject_screening=self.subject_screening, + subject_consent=self.subject_consent, + visit_code=DAY01, + appt_datetime=self.subject_consent.consent_datetime, + ) + panel_results_data = self.get_panel_results_data(subject_visit, "chemistry") + panel_results_data.update( + { + "sodium_value": 135, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": YES, + "sodium_reportable": NOT_APPLICABLE, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_abnormal", cm.exception.error_dict) + self.assertIn( + "Invalid. Result is not abnormal", + str(cm.exception.error_dict.get("sodium_abnormal")), + ) + + for reportable_response in [GRADE3, GRADE4, ALREADY_REPORTED, PRESENT_AT_BASELINE]: + with self.subTest(reportable_response=reportable_response): + panel_results_data.update( + { + "sodium_abnormal": NO, + "sodium_reportable": reportable_response, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_reportable", cm.exception.error_dict) + self.assertIn( + "Invalid. Expected 'No' or 'Not applicable'.", + str(cm.exception.error_dict.get("sodium_reportable")), + ) + + panel_results_data.update( + { + "sodium_abnormal": NO, + "sodium_reportable": NO, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_reportable", cm.exception.error_dict) + self.assertIn( + "This field is not applicable", + str(cm.exception.error_dict.get("sodium_reportable")), + ) + + panel_results_data.update( + { + "sodium_value": 135, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": NO, + "sodium_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + try: + form_validator.validate() + except forms.ValidationError as e: + self.fail(f"ValidationError unexpectedly raised. Got {e}") + + def test_sodium_abnormal_raises_if_not_acknowledged(self): + subject_visit = self.get_subject_visit( + subject_screening=self.subject_screening, + subject_consent=self.subject_consent, + visit_code=DAY01, + appt_datetime=self.subject_consent.consent_datetime, + ) + panel_results_data = self.get_panel_results_data(subject_visit, "chemistry") + for abnormal_value in [ + # abnormal (G1/G2 low sodium) + 134, + 133, + 131, + 130, + 129, + 126, + 125, + # abnormal (G1/G2 high sodium) + 146, + 149, + 150, + 151, + 153, + ]: + with self.subTest(abnormal_value=abnormal_value): + panel_results_data.update( + { + "sodium_value": abnormal_value, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": NO, + "sodium_reportable": NOT_APPLICABLE, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_value", cm.exception.error_dict) + self.assertIn( + "SODIUM is abnormal.", + str(cm.exception.error_dict.get("sodium_value")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": NO, + "results_abnormal": YES, + "results_reportable": NO, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + try: + form_validator.validate() + except forms.ValidationError as e: + self.fail(f"ValidationError unexpectedly raised. Got {e}") + + def test_sodium_reportable_applicable_if_sodium_abnormal(self): + subject_visit = self.get_subject_visit( + subject_screening=self.subject_screening, + subject_consent=self.subject_consent, + visit_code=DAY01, + appt_datetime=self.subject_consent.consent_datetime, + ) + panel_results_data = self.get_panel_results_data(subject_visit, "chemistry") + for abnormal_value in [ + # abnormal (G1/G2 low sodium) + 134, + 125, + # abnormal (G1/G2 high sodium) + 146, + 153, + ]: + with self.subTest(abnormal_value=abnormal_value): + panel_results_data.update( + { + "sodium_value": abnormal_value, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": YES, + "sodium_reportable": NOT_APPLICABLE, + "results_abnormal": YES, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_reportable", cm.exception.error_dict) + self.assertIn( + "This field is applicable if result is abnormal", + str(cm.exception.error_dict.get("sodium_reportable")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": NO, + "results_abnormal": YES, + "results_reportable": NO, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + try: + form_validator.validate() + except forms.ValidationError as e: + self.fail(f"ValidationError unexpectedly raised. Got {e}") + + def test_sodium_reportable_raises_if_abnormal_lt_g3_and_reported_reportable(self): + subject_visit = self.get_subject_visit( + subject_screening=self.subject_screening, + subject_consent=self.subject_consent, + visit_code=DAY01, + appt_datetime=self.subject_consent.consent_datetime, + ) + panel_results_data = self.get_panel_results_data(subject_visit, "chemistry") + for abnormal_value in [ + # abnormal (G1/G2 low sodium) + 134, + 125, + # abnormal (G1/G2 high sodium) + 146, + 153, + ]: + for reportable_response in [ + GRADE3, + GRADE4, + ALREADY_REPORTED, + PRESENT_AT_BASELINE, + ]: + with self.subTest( + abnormal_value=abnormal_value, reportable_response=reportable_response + ): + panel_results_data.update( + { + "sodium_value": abnormal_value, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": YES, + "sodium_reportable": reportable_response, + "results_abnormal": YES, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_reportable", cm.exception.error_dict) + self.assertIn( + "Invalid. Expected 'No' or 'Not applicable'.", + str(cm.exception.error_dict.get("sodium_reportable")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": NO, + "results_abnormal": YES, + "results_reportable": NO, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + try: + form_validator.validate() + except forms.ValidationError as e: + self.fail(f"ValidationError unexpectedly raised. Got {e}") + + def test_sodium_g3_raises_if_not_acknowledged(self): + subject_visit = self.get_subject_visit( + subject_screening=self.subject_screening, + subject_consent=self.subject_consent, + visit_code=DAY01, + appt_datetime=self.subject_consent.consent_datetime, + ) + panel_results_data = self.get_panel_results_data(subject_visit, "chemistry") + for g3_value in [ + # G3 (low sodium) + 121, + 122, + 123, + 124, + # G3 (high sodium) + 154, + 155, + 158, + 159, + ]: + for reportable_response in [NOT_APPLICABLE, NO, GRADE4]: + with self.subTest(g3_value=g3_value, reportable_response=reportable_response): + panel_results_data.update( + { + "sodium_value": g3_value, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": NO, + "sodium_reportable": reportable_response, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_value", cm.exception.error_dict) + self.assertIn( + "SODIUM is reportable.", + str(cm.exception.error_dict.get("sodium_value")), + ) + self.assertIn( + "GRADE 3.", + str(cm.exception.error_dict.get("sodium_value")), + ) + + panel_results_data.update( + { + "sodium_abnormal": NO, + "sodium_reportable": GRADE3, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_value", cm.exception.error_dict) + self.assertIn( + "SODIUM is abnormal.", + str(cm.exception.error_dict.get("sodium_value")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE3, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("results_abnormal", cm.exception.error_dict) + self.assertIn( + "1 of the above results is abnormal", + str(cm.exception.error_dict.get("results_abnormal")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE3, + "results_abnormal": YES, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("results_reportable", cm.exception.error_dict) + self.assertIn( + "This field is applicable.", + str(cm.exception.error_dict.get("results_reportable")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE3, + "results_abnormal": YES, + "results_reportable": NO, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("results_reportable", cm.exception.error_dict) + self.assertIn( + "1 of the above results is reportable", + str(cm.exception.error_dict.get("results_reportable")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE3, + "results_abnormal": YES, + "results_reportable": YES, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + try: + form_validator.validate() + except forms.ValidationError as e: + self.fail(f"ValidationError unexpectedly raised. Got {e}") + + def test_sodium_g4_raises_if_not_acknowledged(self): + subject_visit = self.get_subject_visit( + subject_screening=self.subject_screening, + subject_consent=self.subject_consent, + visit_code=DAY01, + appt_datetime=self.subject_consent.consent_datetime, + ) + panel_results_data = self.get_panel_results_data(subject_visit, "chemistry") + for g4_value in [ + # G4 (low sodium) + 120, + 119, + 110, + 100, + # G4 (high sodium) + 160, + 161, + 170, + 200, + ]: + for reportable_response in [NOT_APPLICABLE, NO, GRADE3]: + with self.subTest(g4_value=g4_value, reportable_response=reportable_response): + panel_results_data.update( + { + "sodium_value": g4_value, + "sodium_units": MILLIMOLES_PER_LITER, + "sodium_abnormal": NO, + "sodium_reportable": reportable_response, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_value", cm.exception.error_dict) + self.assertIn( + "SODIUM is reportable.", + str(cm.exception.error_dict.get("sodium_value")), + ) + self.assertIn( + "GRADE 4.", + str(cm.exception.error_dict.get("sodium_value")), + ) + + panel_results_data.update( + { + "sodium_abnormal": NO, + "sodium_reportable": GRADE4, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("sodium_value", cm.exception.error_dict) + self.assertIn( + "SODIUM is abnormal.", + str(cm.exception.error_dict.get("sodium_value")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE4, + "results_abnormal": NO, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("results_abnormal", cm.exception.error_dict) + self.assertIn( + "1 of the above results is abnormal", + str(cm.exception.error_dict.get("results_abnormal")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE4, + "results_abnormal": YES, + "results_reportable": NOT_APPLICABLE, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("results_reportable", cm.exception.error_dict) + self.assertIn( + "This field is applicable.", + str(cm.exception.error_dict.get("results_reportable")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE4, + "results_abnormal": YES, + "results_reportable": NO, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + with self.assertRaises(forms.ValidationError) as cm: + form_validator.validate() + self.assertIn("results_reportable", cm.exception.error_dict) + self.assertIn( + "1 of the above results is reportable", + str(cm.exception.error_dict.get("results_reportable")), + ) + + panel_results_data.update( + { + "sodium_abnormal": YES, + "sodium_reportable": GRADE4, + "results_abnormal": YES, + "results_reportable": YES, + } + ) + form_validator = BloodResultsChemFormValidator( + cleaned_data=panel_results_data, model=BloodResultsChem + ) + try: + form_validator.validate() + except forms.ValidationError as e: + self.fail(f"ValidationError unexpectedly raised. Got {e}")