meta-edc 0.3.27__py3-none-any.whl → 0.3.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {meta_edc-0.3.27.dist-info → meta_edc-0.3.29.dist-info}/METADATA +2 -2
  2. {meta_edc-0.3.27.dist-info → meta_edc-0.3.29.dist-info}/RECORD +26 -17
  3. meta_reports/admin/__init__.py +1 -0
  4. meta_reports/admin/unmanaged/__init__.py +1 -0
  5. meta_reports/admin/unmanaged/on_study_missing_values_admin/__init__.py +1 -0
  6. meta_reports/admin/unmanaged/on_study_missing_values_admin/unmanaged_model_admin.py +13 -0
  7. meta_reports/migrations/0039_onstudymissingvalues.py +44 -0
  8. meta_reports/migrations/0040_auto_20240824_0412.py +282 -0
  9. meta_reports/models/__init__.py +1 -0
  10. meta_reports/models/dbviews/__init__.py +1 -0
  11. meta_reports/models/dbviews/glucose_summary/view_definition.py +14 -59
  12. meta_reports/models/dbviews/missing_screening_ogtt/view_definition.py +14 -49
  13. meta_reports/models/dbviews/on_study_missing_values/__init__.py +1 -0
  14. meta_reports/models/dbviews/on_study_missing_values/qa_cases.py +53 -0
  15. meta_reports/models/dbviews/on_study_missing_values/unmanged_model.py +20 -0
  16. meta_reports/models/dbviews/on_study_missing_values/view_definition.py +20 -0
  17. meta_reports/models/dbviews/patient_history_missing_baseline_cd4/view_definition.py +13 -47
  18. meta_reports/models/dbviews/unattended_three_in_row/view_definition.py +20 -67
  19. meta_reports/models/dbviews/unattended_three_in_row2/view_definition.py +44 -128
  20. meta_reports/models/dbviews/unattended_two_in_row/view_definition.py +25 -72
  21. meta_reports/utils.py +0 -0
  22. meta_subject/model_mixins/arv_history_model_mixin.py +3 -3
  23. {meta_edc-0.3.27.dist-info → meta_edc-0.3.29.dist-info}/AUTHORS +0 -0
  24. {meta_edc-0.3.27.dist-info → meta_edc-0.3.29.dist-info}/LICENSE +0 -0
  25. {meta_edc-0.3.27.dist-info → meta_edc-0.3.29.dist-info}/WHEEL +0 -0
  26. {meta_edc-0.3.27.dist-info → meta_edc-0.3.29.dist-info}/top_level.txt +0 -0
@@ -1,73 +1,28 @@
1
- mysql_view: str = """ # noqa
2
- select *, uuid() as id, now() as created, 'meta_reports.glucose_summary_view' as report_model
3
- from (
4
- select v.subject_identifier, fbg_value, fbg_datetime, null as 'ogtt_value', null as 'ogtt_datetime',
5
- case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as 'fasted',
6
- fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
7
- from meta_subject_glucosefbg as fbg
8
- left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
9
- left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
10
- UNION
11
- select v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime,
12
- case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as 'fasted',
13
- fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
14
- from meta_subject_glucose as fbg
15
- left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
16
- left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
17
- ) as A
18
- order by subject_identifier, fbg_datetime;
19
- """
1
+ from edc_qareports.sql_generator import SqlViewGenerator
20
2
 
21
- pg_view: str = """ # noqa
22
- select *, get_random_uuid() as id, now() as created, 'meta_reports.glucose_summary_view' as report_model
23
- from (
24
- select v.subject_identifier, fbg_value, fbg_datetime, null as ogtt_value, null as ogtt_datetime,
25
- case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as fasted,
26
- fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
27
- from meta_subject_glucosefbg as fbg
28
- left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
29
- left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
30
- UNION
31
- select v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime,
32
- case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as fasted,
33
- fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
34
- from meta_subject_glucose as fbg
35
- left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
36
- left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
37
- ) as A
38
- order by subject_identifier, fbg_datetime;
39
- """
40
3
 
41
- sqlite3_view: str = """ # noqa
42
- SELECT *, lower(
43
- hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
44
- substr(hex( randomblob(2)), 2) || '-' ||
45
- substr('AB89', 1 + (abs(random()) % 4) , 1) ||
46
- substr(hex(randomblob(2)), 2) || '-' ||
47
- hex(randomblob(6))
48
- ) as id, datetime() as `created`, 'meta_reports.glucose_summary_view' as report_model
49
- from (
50
- select v.subject_identifier, fbg_value, fbg_datetime, null as ogtt_value, null as ogtt_datetime,
51
- case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as fasted,
4
+ def get_view_definition() -> dict:
5
+ subquery = """
6
+ select v.subject_identifier, fbg_value, fbg_datetime, null as `ogtt_value`, null as `ogtt_datetime`,
7
+ case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as `fasted`,
52
8
  fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
53
9
  from meta_subject_glucosefbg as fbg
54
10
  left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
55
11
  left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
56
12
  UNION
57
13
  select v.subject_identifier, fbg_value, fbg_datetime, ogtt_value, ogtt_datetime,
58
- case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as fasted,
14
+ case when fasting="fasting" then "Yes" when fasting="non_fasting" then "No" else fasting end as `fasted`,
59
15
  fbg.site_id, v.visit_code, v.visit_code_sequence, v.appointment_id, eos.offstudy_datetime
60
16
  from meta_subject_glucose as fbg
61
17
  left join meta_subject_subjectvisit as v on v.id=fbg.subject_visit_id
62
18
  left join meta_prn_endofstudy as eos on v.subject_identifier=eos.subject_identifier
63
- ) as A
64
- order by subject_identifier, fbg_datetime;
65
- """
66
-
67
-
68
- def get_view_definition() -> dict:
19
+ """ # noqa
20
+ sql_view = SqlViewGenerator(
21
+ report_model="meta_reports.glucose_summary_view",
22
+ ordering=["subject_identifier", "site_id"],
23
+ )
69
24
  return {
70
- "django.db.backends.mysql": mysql_view,
71
- "django.db.backends.postgresql": pg_view,
72
- "django.db.backends.sqlite3": sqlite3_view,
25
+ "django.db.backends.mysql": sql_view.as_mysql(subquery),
26
+ "django.db.backends.postgresql": sql_view.as_postgres(subquery),
27
+ "django.db.backends.sqlite3": sql_view.as_sqlite(subquery),
73
28
  }
@@ -1,55 +1,20 @@
1
- mysql_view: str = """ # noqa
2
- select *, uuid() as id, now() as created,
3
- 'meta_reports.missing_screening_ogtt_view' as report_model
4
- from (
5
- select screening_identifier, site_id, report_datetime as 'screening_datetime', fbg_datetime,
6
- converted_fbg_value as fbg_value, converted_ogtt_value as ogtt_value, repeat_glucose_performed as repeated,
7
- p3_ltfu, fbg2_value, ogtt2_value, fbg2_datetime, ogtt2_datetime, consented,
8
- screening_identifier as subject_identifier, id as original_id
9
- from meta_screening_subjectscreening
10
- where converted_fbg_value is not null and converted_ogtt_value is null and unsuitable_agreed != "Yes"
11
- ) as A
12
- order by screening_identifier
13
- """
1
+ from edc_qareports.sql_generator import SqlViewGenerator
14
2
 
15
- pg_view: str = """ # noqa
16
- select *, get_random_uuid() as id, now() as created,
17
- 'meta_reports.missing_screening_ogtt_view' as report_model
18
- from (
19
- select screening_identifier, site_id, report_datetime as 'screening_datetime', fbg_datetime,
20
- converted_fbg_value as fbg_value, converted_ogtt_value as ogtt_value, repeat_glucose_performed as repeated,
21
- p3_ltfu, fbg2_value, ogtt2_value, fbg2_datetime, ogtt2_datetime, consented,
22
- screening_identifier as subject_identifier, id as original_id
23
- from meta_screening_subjectscreening
24
- where converted_fbg_value is not null and converted_ogtt_value is null and unsuitable_agreed != "Yes"
25
- ) as A
26
- order by screening_identifier
27
- """
28
3
 
29
- sqlite3_view = """ # noqa
30
- SELECT *, lower(
31
- hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
32
- substr(hex( randomblob(2)), 2) || '-' ||
33
- substr('AB89', 1 + (abs(random()) % 4) , 1) ||
34
- substr(hex(randomblob(2)), 2) || '-' ||
35
- hex(randomblob(6))
36
- ) as id, datetime() as `created`,
37
- 'meta_reports.missing_screening_ogtt_view' as report_model
38
- from (
39
- select screening_identifier, site_id, report_datetime as 'screening_datetime', fbg_datetime,
40
- converted_fbg_value as fbg_value, converted_ogtt_value as ogtt_value, fbg2_value, ogtt2_value,
41
- repeat_glucose_performed as repeated, p3_ltfu, fbg2_datetime, ogtt2_datetime, consented,
42
- screening_identifier as subject_identifier, id as original_id
4
+ def get_view_definition() -> dict:
5
+ subquery = """select screening_identifier, site_id, report_datetime as `screening_datetime`, fbg_datetime,
6
+ converted_fbg_value as `fbg_value`, converted_ogtt_value as `ogtt_value`, fbg2_value, ogtt2_value,
7
+ repeat_glucose_performed as `repeated`, p3_ltfu, fbg2_datetime, ogtt2_datetime, consented,
8
+ screening_identifier as `subject_identifier`, id as `original_id`
43
9
  from meta_screening_subjectscreening
44
10
  where converted_fbg_value is not null and converted_ogtt_value is null and unsuitable_agreed != "Yes"
45
- ) as A
46
- order by screening_identifier
47
- """
48
-
49
-
50
- def get_view_definition() -> dict:
11
+ """ # noqa
12
+ sql_view = SqlViewGenerator(
13
+ report_model="meta_reports.missing_screening_ogtt_view",
14
+ ordering=["subject_identifier", "site_id"],
15
+ )
51
16
  return {
52
- "django.db.backends.mysql": mysql_view,
53
- "django.db.backends.postgresql": pg_view,
54
- "django.db.backends.sqlite3": sqlite3_view,
17
+ "django.db.backends.mysql": sql_view.as_mysql(subquery),
18
+ "django.db.backends.postgresql": sql_view.as_postgres(subquery),
19
+ "django.db.backends.sqlite3": sql_view.as_sqlite(subquery),
55
20
  }
@@ -0,0 +1 @@
1
+ from .unmanged_model import OnStudyMissingValues
@@ -0,0 +1,53 @@
1
+ qa_cases = [
2
+ dict(
3
+ label="No HIV Diagnosis date",
4
+ dbtable="meta_subject_patienthistory",
5
+ label_lower="meta_subject.patienthistory",
6
+ fld_name="hiv_diagnosis_date",
7
+ ),
8
+ dict(
9
+ label="No VL value",
10
+ dbtable="meta_subject_patienthistory",
11
+ label_lower="meta_subject.patienthistory",
12
+ fld_name="viral_load",
13
+ ),
14
+ dict(
15
+ label="No VL date",
16
+ dbtable="meta_subject_patienthistory",
17
+ label_lower="meta_subject.patienthistory",
18
+ fld_name="viral_load_date",
19
+ ),
20
+ dict(
21
+ label="No CD4 value",
22
+ dbtable="meta_subject_patienthistory",
23
+ label_lower="meta_subject.patienthistory",
24
+ fld_name="cd4",
25
+ ),
26
+ dict(
27
+ label="No CD4 date",
28
+ dbtable="meta_subject_patienthistory",
29
+ label_lower="meta_subject.patienthistory",
30
+ fld_name="cd4_date",
31
+ ),
32
+ dict(
33
+ label="No current ARV start date",
34
+ dbtable="meta_subject_patienthistory",
35
+ label_lower="meta_subject.patienthistory",
36
+ fld_name="current_arv_regimen_start_date",
37
+ ),
38
+ dict(
39
+ label="No current ARV start date but previous ARV is YES",
40
+ dbtable="meta_subject_patienthistory",
41
+ label_lower="meta_subject.patienthistory",
42
+ where=(
43
+ 'crf.has_previous_arv_regimen="YES" and crf.current_arv_regimen_start_date is null'
44
+ ),
45
+ ),
46
+ dict(
47
+ label="Other current ARV regimen missing",
48
+ dbtable="meta_subject_patienthistory",
49
+ label_lower="meta_subject.patienthistory",
50
+ where='crf.other_current_arv_regimen is null and arvregimen.name="OTHER"',
51
+ list_tables=[("current_arv_regimen_id", "meta_lists_arvregimens", "arvregimen")],
52
+ ),
53
+ ]
@@ -0,0 +1,20 @@
1
+ from django_db_views.db_view import DBView
2
+ from edc_qareports.model_mixins import (
3
+ OnStudyMissingValuesModelMixin,
4
+ QaReportModelMixin,
5
+ qa_reports_permissions,
6
+ )
7
+
8
+ from .view_definition import get_view_definition
9
+
10
+
11
+ class OnStudyMissingValues(OnStudyMissingValuesModelMixin, QaReportModelMixin, DBView):
12
+
13
+ view_definition = get_view_definition()
14
+
15
+ class Meta:
16
+ managed = False
17
+ db_table = "onstudy_missing_values_view"
18
+ verbose_name = "Missing values for on-study patient"
19
+ verbose_name_plural = "Missing values for on-study patients"
20
+ default_permissions = qa_reports_permissions
@@ -0,0 +1,20 @@
1
+ from edc_qareports.sql_generator import (
2
+ SqlViewGenerator,
3
+ generate_subquery_for_missing_values,
4
+ )
5
+
6
+ from .qa_cases import qa_cases
7
+
8
+
9
+ def get_view_definition() -> dict:
10
+ subquery = generate_subquery_for_missing_values(qa_cases)
11
+ sql_view = SqlViewGenerator(
12
+ report_model="onstudy_missing_values_view",
13
+ ordering=["subject_identifier", "site_id"],
14
+ )
15
+
16
+ return {
17
+ "django.db.backends.mysql": sql_view.as_mysql(subquery),
18
+ "django.db.backends.postgresql": sql_view.as_postgres(subquery),
19
+ "django.db.backends.sqlite3": sql_view.as_sqlite(subquery),
20
+ }
@@ -1,55 +1,21 @@
1
- mysql_view: str = """
2
- select *, uuid() as id, now() as created,
3
- 'meta_reports.patienthistorymissingbaselinecd4' as report_model
4
- from (
5
- select subject_identifier, v.visit_code, v.visit_code_sequence,cd4,
6
- cd4_date, crf.site_id, crf.user_created, crf.user_modified,
7
- crf.modified
8
- from meta_subject_patienthistory as crf
9
- left join meta_subject_subjectvisit as v on crf.subject_visit_id=v.id
10
- where cd4 is null or cd4_date is null
11
- ) as A
12
- order by subject_identifier
13
- """
1
+ from edc_qareports.sql_generator import SqlViewGenerator
14
2
 
15
- pg_view: str = """
16
- select *, get_random_uuid() as id, now() as created,
17
- 'meta_reports.patienthistorymissingbaselinecd4' as report_model
18
- from (
19
- select subject_identifier, v.visit_code, v.visit_code_sequence,cd4,
20
- cd4_date, crf.site_id, crf.user_created, crf.user_modified,
21
- crf.modified
22
- from meta_subject_patienthistory as crf
23
- left join meta_subject_subjectvisit as v on crf.subject_visit_id=v.id
24
- where cd4 is null or cd4_date is null
25
- ) as A
26
- order by subject_identifier
27
- """
28
3
 
29
- sqlite3_view = """
30
- SELECT *, lower(
31
- hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
32
- substr(hex( randomblob(2)), 2) || '-' ||
33
- substr('AB89', 1 + (abs(random()) % 4) , 1) ||
34
- substr(hex(randomblob(2)), 2) || '-' ||
35
- hex(randomblob(6))
36
- ) as id, datetime() as `created`,
37
- 'meta_reports.patienthistorymissingbaselinecd4' as report_model
38
- from (
4
+ def get_view_definition() -> dict:
5
+ subquery = """
39
6
  select subject_identifier, v.visit_code, v.visit_code_sequence,cd4,
40
- cd4_date, crf.site_id, crf.user_created, crf.user_modified,
41
- crf.modified
7
+ cd4_date, crf.site_id, crf.user_created, crf.user_modified,
8
+ crf.modified
42
9
  from meta_subject_patienthistory as crf
43
10
  left join meta_subject_subjectvisit as v on crf.subject_visit_id=v.id
44
11
  where cd4 is null or cd4_date is null
45
- ) as A
46
- order by subject_identifier
47
- """
48
-
49
-
50
- def get_view_definition() -> dict:
12
+ """
13
+ sql_view = SqlViewGenerator(
14
+ report_model="meta_reports.patienthistorymissingbaselinecd4",
15
+ ordering=["subject_identifier", "site_id"],
16
+ )
51
17
  return {
52
- "django.db.backends.mysql": mysql_view,
53
- "django.db.backends.postgresql": pg_view,
54
- "django.db.backends.sqlite3": sqlite3_view,
18
+ "django.db.backends.mysql": sql_view.as_mysql(subquery),
19
+ "django.db.backends.postgresql": sql_view.as_postgres(subquery),
20
+ "django.db.backends.sqlite3": sql_view.as_sqlite(subquery),
55
21
  }
@@ -1,8 +1,12 @@
1
- mysql_view = """ # noqa
2
- select *, uuid() as id, now() as created, 'meta_reports.unattendedthreeinrow' as `report_model` from (
3
- select subject_identifier, site_id, appt_datetime, `first_value`, `second_value`, `third_value`,
4
- datediff(third_date, first_date) as `interval_days`,
5
- datediff(now(), first_date) as `from_now_days`
1
+ from edc_qareports.sql_generator import SqlViewGenerator
2
+
3
+
4
+ def get_view_definition() -> dict:
5
+ subquery = """
6
+ select subject_identifier, site_id, appt_datetime, `first_value`,
7
+ `second_value`, `third_value`,
8
+ datediff(`third_date`, `first_date`) as `interval_days`,
9
+ datediff(now(), `first_date`) as `from_now_days`
6
10
  from (
7
11
  select subject_identifier, site_id, appt_datetime,
8
12
  FIRST_VALUE(visit_code) OVER w as `first_value`,
@@ -10,69 +14,18 @@ mysql_view = """ # noqa
10
14
  NTH_VALUE(visit_code, 3) OVER w as `third_value`,
11
15
  FIRST_VALUE(appt_datetime) OVER w as `first_date`,
12
16
  NTH_VALUE(appt_datetime, 3) OVER w as `third_date`
13
- from edc_appointment_appointment where visit_code_sequence=0 and appt_status='New'
17
+ from edc_appointment_appointment where visit_code_sequence=0 and appt_status="New"
14
18
  and appt_datetime <= now()
15
19
  WINDOW w as (PARTITION BY subject_identifier order by appt_datetime ROWS UNBOUNDED PRECEDING)
16
- ) as A
17
- where `second_value` is not null and `third_value` is not null
18
- ) as B
19
- order by site_id, from_now_days desc
20
- """
21
-
22
- pg_view = """ # noqa
23
- select *, gen_random_uuid() as id, now() as created,
24
- 'meta_reports.unattendedthreeinrow' as report_model
25
- from (
26
- select subject_identifier, site_id, appt_datetime, first_value, second_value, third_value,
27
- EXTRACT(DAY FROM third_date - first_date) as interval_days,
28
- EXTRACT(DAY FROM now() - first_date) as from_now_days
29
- from (
30
- select subject_identifier,site_id,appt_datetime,
31
- FIRST_VALUE(visit_code) OVER w as first_value,
32
- NTH_VALUE(visit_code, 2) OVER w as second_value,
33
- NTH_VALUE(visit_code, 3) OVER w as third_value,
34
- FIRST_VALUE(appt_datetime) OVER w as first_date,
35
- NTH_VALUE(appt_datetime, 3) OVER w as third_date
36
- from edc_appointment_appointment where visit_code_sequence=0 and appt_status='New'
37
- and appt_datetime <= now()
38
- WINDOW w as (PARTITION BY subject_identifier order by appt_datetime ROWS UNBOUNDED PRECEDING)
39
- ) as A
40
- where second_value is not null and third_value is not null
41
- ) as B
42
- order by site_id, from_now_days desc
43
- """
44
-
45
- sqlite3_view = """ # noqa
46
- SELECT *, lower(
47
- hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
48
- substr(hex( randomblob(2)), 2) || '-' ||
49
- substr('AB89', 1 + (abs(random()) % 4) , 1) ||
50
- substr(hex(randomblob(2)), 2) || '-' ||
51
- hex(randomblob(6))
52
- ) as id, datetime() as created,'meta_reports.unattendedthreeinrow' as report_model from (
53
- select subject_identifier, site_id, appt_datetime, first_value, second_value, third_value,
54
- CAST(JulianDay(third_date) - JulianDay(first_date) AS INTEGER) as interval_days,
55
- CAST(JulianDay(datetime()) - JulianDay(first_date) AS INTEGER) as from_now_days
56
- from (
57
- select subject_identifier, site_id, appt_datetime,
58
- FIRST_VALUE(visit_code) OVER w as first_value,
59
- NTH_VALUE(visit_code, 2) OVER w as second_value,
60
- NTH_VALUE(visit_code, 3) OVER w as third_value,
61
- FIRST_VALUE(appt_datetime) OVER w as first_date,
62
- NTH_VALUE(appt_datetime, 3) OVER w as third_date
63
- from edc_appointment_appointment where visit_code_sequence=0 and appt_status='New'
64
- and appt_datetime <= datetime()
65
- WINDOW w as (PARTITION BY subject_identifier order by appt_datetime ROWS UNBOUNDED PRECEDING)
66
- ) as A
67
- where second_value is not null and third_value is not null
68
- ) as B
69
- order by site_id, from_now_days desc
70
- """
71
-
72
-
73
- def get_view_definition() -> dict:
20
+ ) as B
21
+ where `second_value` is not null and `third_value` is not null
22
+ """ # noqa
23
+ sql_view = SqlViewGenerator(
24
+ report_model="meta_reports.unattendedthreeinrow",
25
+ ordering=["subject_identifier", "site_id"],
26
+ )
74
27
  return {
75
- "django.db.backends.mysql": mysql_view,
76
- "django.db.backends.postgresql": pg_view,
77
- "django.db.backends.sqlite3": sqlite3_view,
28
+ "django.db.backends.mysql": sql_view.as_mysql(subquery),
29
+ "django.db.backends.postgresql": sql_view.as_postgres(subquery),
30
+ "django.db.backends.sqlite3": sql_view.as_sqlite(subquery),
78
31
  }
@@ -1,134 +1,50 @@
1
- mysql_view = """ # noqa
2
- with appointments as (
3
- select subject_identifier, site_id, visit_code, visit_code_sequence, appt_datetime,
4
- case when appt_timing='missed' then 'New' else appt_status end as `appt_status`,
5
- case when appt_timing='missed' then 1 else 0 end as `missed`
6
- from edc_appointment_appointment
7
- where visit_code_sequence=0 and appt_datetime<=now()
8
- order by subject_identifier, appt_datetime
9
- )
10
- select *, uuid() as `id`, now() as `created`, 'meta_reports.unattendedthreeinrow2' as `report_model` from (
11
- select distinct subject_identifier, site_id, `first_value`, `second_value`, `third_value`,
12
- datediff(third_date, first_date) as `interval_days`,
13
- datediff(now(), first_date) as `from_now_days`,
14
- `first_status`, `second_status`, `third_status`, sum(missed) as `missed_count`
15
- from (
16
- select subject_identifier,site_id,appt_datetime, missed,
17
- FIRST_VALUE(appt_status) OVER w as `third_status`,
18
- NTH_VALUE(appt_status, 2) OVER w as `second_status`,
19
- NTH_VALUE(appt_status, 3) OVER w as `first_status`,
20
- FIRST_VALUE(visit_code) OVER w as `third_value`,
21
- NTH_VALUE(visit_code, 2) OVER w as `second_value`,
22
- NTH_VALUE(visit_code, 3) OVER w as `first_value`,
23
- FIRST_VALUE(appt_datetime) OVER w as `third_date`,
24
- NTH_VALUE(appt_datetime, 2) OVER w as `second_date`,
25
- NTH_VALUE(appt_datetime, 3) OVER w as `first_date`
26
- from appointments
27
- WINDOW w as (PARTITION BY subject_identifier order by appt_datetime desc ROWS UNBOUNDED PRECEDING)
28
- ) as A
29
- where `second_value` is not null and `third_value` is not null
30
- and `first_status`='New'
31
- and `second_status`='New'
32
- and `third_status`='New'
33
- group by subject_identifier, site_id, `first_value`, `second_value`, `third_value`,
34
- datediff(`third_date`, `first_date`),
35
- datediff(now(), `first_date`),
36
- `first_status`, `second_status`, `third_status`
37
- order by subject_identifier, site_id
38
- ) as B
39
- """
1
+ from edc_qareports.sql_generator import SqlViewGenerator
40
2
 
41
- pg_view = """ # noqa
42
- with appointments as (
43
- select subject_identifier, site_id, visit_code, visit_code_sequence, appt_datetime,
44
- case when appt_timing='missed' then 'New' else appt_status end as appt_status,
45
- case when appt_timing='missed' then 1 else 0 end as missed
46
- from edc_appointment_appointment
47
- where visit_code_sequence=0 and appt_datetime<=now()
48
- order by subject_identifier, appt_datetime
49
- )
50
- select *, gen_random_uuid() as id, now() as created, 'meta_reports.unattendedthreeinrow2' as report_model
51
- from (
52
- select distinct subject_identifier, site_id, first_value, second_value, third_value,
53
- EXTRACT(DAY FROM third_date - first_date) as interval_days,
54
- EXTRACT(DAY FROM now() - first_date) as from_now_days,
55
- first_status, second_status, third_status, sum(missed) as missed_count
56
- from (
57
- select subject_identifier,site_id,appt_datetime, missed,
58
- FIRST_VALUE(appt_status) OVER w as third_status,
59
- NTH_VALUE(appt_status, 2) OVER w as second_status,
60
- NTH_VALUE(appt_status, 3) OVER w as first_status,
61
- FIRST_VALUE(visit_code) OVER w as third_value,
62
- NTH_VALUE(visit_code, 2) OVER w as second_value,
63
- NTH_VALUE(visit_code, 3) OVER w as first_value,
64
- FIRST_VALUE(appt_datetime) OVER w as third_date,
65
- NTH_VALUE(appt_datetime, 2) OVER w as second_date,
66
- NTH_VALUE(appt_datetime, 3) OVER w as first_date
67
- from appointments
68
- WINDOW w as (PARTITION BY subject_identifier order by appt_datetime desc ROWS UNBOUNDED PRECEDING)
69
- ) as A
70
- where second_value is not null and third_value is not null
71
- and first_status='New'
72
- and second_status='New'
73
- and third_status='New'
74
- group by subject_identifier, site_id, first_value, second_value, third_value,
75
- EXTRACT(DAY FROM third_date - first_date),
76
- EXTRACT(DAY FROM now() - first_date),
77
- first_status, second_status, third_status
78
- order by subject_identifier, site_id
79
- ) as B
80
- """
81
3
 
82
- sqlite3_view = """ # noqa
83
- with appointments as (
84
- select subject_identifier, site_id, visit_code, visit_code_sequence, appt_datetime,
85
- case when appt_timing='missed' then 'New' else appt_status end as `appt_status`,
86
- case when appt_timing='missed' then 1 else 0 end as `missed`
87
- from edc_appointment_appointment
88
- where visit_code_sequence=0 and appt_datetime<=now()
89
- order by subject_identifier, appt_datetime
90
- )
91
- SELECT *, lower(
92
- hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' ||
93
- substr(hex( randomblob(2)), 2) || '-' ||
94
- substr('AB89', 1 + (abs(random()) % 4) , 1) ||
95
- substr(hex(randomblob(2)), 2) || '-' ||
96
- hex(randomblob(6))
97
- ) as id, datetime() as created, 'meta_reports.unattendedthreeinrow2' as report_model from (
98
- select distinct subject_identifier, site_id, first_value, second_value, third_value,
99
- CAST(JulianDay(third_date) - JulianDay(first_date) AS Integer) as interval_days,
100
- CAST(JulianDay(datetime()) - JulianDay(first_date) AS Integer) as from_now_days,
101
- first_status, second_status, third_status, sum(missed) as missed_count
102
- from (
103
- select subject_identifier,site_id,appt_datetime, missed,
104
- FIRST_VALUE(appt_status) OVER w as third_status,
105
- NTH_VALUE(appt_status, 2) OVER w as second_status,
106
- NTH_VALUE(appt_status, 3) OVER w as first_status,
107
- FIRST_VALUE(visit_code) OVER w as third_value,
108
- NTH_VALUE(visit_code, 2) OVER w as second_value,
109
- NTH_VALUE(visit_code, 3) OVER w as first_value,
110
- FIRST_VALUE(appt_datetime) OVER w as third_date,
111
- NTH_VALUE(appt_datetime, 2) OVER w as second_date,
112
- NTH_VALUE(appt_datetime, 3) OVER w as first_date
113
- from appointments
114
- WINDOW w as (PARTITION BY subject_identifier order by appt_datetime desc ROWS UNBOUNDED PRECEDING)
115
- ) as A
116
- where second_value is not null and third_value is not null
117
- and first_status='New'
118
- and second_status='New'
119
- and third_status='New'
120
- group by subject_identifier, site_id, first_value, second_value, third_value,
121
- CAST(JulianDay(third_date) - JulianDay(first_date) AS Integer),
122
- CAST(JulianDay(datetime()) - JulianDay(first_date) AS Integer),
123
- first_status, second_status, third_status
124
- order by subject_identifier, site_id
125
- ) as B
126
- """
4
+ def get_view_definition() -> dict:
5
+ subquery = """select distinct subject_identifier, site_id, `first_value`, `second_value`, `third_value`,
6
+ datediff(`third_date`, `first_date`) as interval_days,
7
+ datediff(now(), `first_date`) as from_now_days,
8
+ `first_status`, `second_status`, `third_status`, sum(missed) as missed_count
9
+ from (
10
+ select subject_identifier,site_id,appt_datetime, `missed`,
11
+ FIRST_VALUE(appt_status) OVER w as `third_status`,
12
+ NTH_VALUE(appt_status, 2) OVER w as `second_status`,
13
+ NTH_VALUE(appt_status, 3) OVER w as `first_status`,
14
+ FIRST_VALUE(visit_code) OVER w as `third_value`,
15
+ NTH_VALUE(visit_code, 2) OVER w as `second_value`,
16
+ NTH_VALUE(visit_code, 3) OVER w as `first_value`,
17
+ FIRST_VALUE(appt_datetime) OVER w as `third_date`,
18
+ NTH_VALUE(appt_datetime, 2) OVER w as `second_date`,
19
+ NTH_VALUE(appt_datetime, 3) OVER w as `first_date`
20
+ from appointments
21
+ WINDOW w as (PARTITION BY subject_identifier order by appt_datetime desc ROWS UNBOUNDED PRECEDING)
22
+ ) as B
23
+ where `second_value` is not null and `third_value` is not null
24
+ and `first_status`="New"
25
+ and `second_status`="New"
26
+ and `third_status` ="New"
27
+ group by subject_identifier, site_id, `first_value`, `second_value`, `third_value`,
28
+ datediff(`third_date`, `first_date`),
29
+ datediff(now(), `first_date`),
30
+ `first_status`, `second_status`, `third_status`
31
+ order by subject_identifier, site_id""" # noqa
127
32
 
33
+ with_stmt = """with appointments as (select subject_identifier, site_id, visit_code, visit_code_sequence,
34
+ appt_datetime, case when appt_timing="missed" then "New" else appt_status end as `appt_status`,
35
+ case when appt_timing="missed" then 1 else 0 end as `missed`
36
+ from edc_appointment_appointment
37
+ where visit_code_sequence=0 and appt_datetime<=now()
38
+ order by subject_identifier, appt_datetime)""" # noqa
39
+
40
+ sql_view = SqlViewGenerator(
41
+ with_stmt=with_stmt,
42
+ report_model="meta_reports.unattendedthreeinrow2",
43
+ ordering=["subject_identifier", "site_id"],
44
+ )
128
45
 
129
- def get_view_definition() -> dict:
130
46
  return {
131
- "django.db.backends.mysql": mysql_view,
132
- "django.db.backends.postgresql": pg_view,
133
- "django.db.backends.sqlite3": sqlite3_view,
47
+ "django.db.backends.mysql": sql_view.as_mysql(subquery),
48
+ "django.db.backends.postgresql": sql_view.as_postgres(subquery),
49
+ "django.db.backends.sqlite3": sql_view.as_sqlite(subquery),
134
50
  }