meta-edc 0.3.38__py3-none-any.whl → 0.3.40__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.
- meta_analytics/__init__.py +0 -2
- meta_analytics/dataframes/__init__.py +1 -0
- meta_analytics/dataframes/get_last_imp_visits_df.py +101 -0
- meta_auth/auth_objects.py +1 -0
- meta_consent/consents.py +6 -0
- meta_consent/locale/lg/LC_MESSAGES/django.po +69 -0
- meta_consent/locale/sw/LC_MESSAGES/django.po +12 -12
- meta_dashboard/locale/lg/LC_MESSAGES/django.po +30 -0
- meta_dashboard/locale/sw/LC_MESSAGES/django.po +11 -2
- meta_dashboard/navbars.py +2 -0
- meta_dashboard/templatetags/meta_dashboard_extras.py +1 -1
- meta_dashboard/tests/urls.py +0 -1
- meta_dashboard/view_utils/__init__.py +6 -0
- meta_dashboard/view_utils/subject_screening_button.py +2 -2
- meta_edc/__init__.py +3 -10
- meta_edc/{celery/debug.py → celery.py} +2 -2
- meta_edc/navbars.py +2 -0
- meta_edc/settings/debug.py +8 -0
- meta_edc/settings/defaults.py +29 -16
- meta_edc/templates/meta_edc/bootstrap3/home.html +2 -2
- meta_edc/tests/tests/test_endpoints.py +1 -0
- meta_edc/urls.py +1 -0
- {meta_edc-0.3.38.dist-info → meta_edc-0.3.40.dist-info}/METADATA +6 -6
- {meta_edc-0.3.38.dist-info → meta_edc-0.3.40.dist-info}/RECORD +74 -64
- {meta_edc-0.3.38.dist-info → meta_edc-0.3.40.dist-info}/WHEEL +1 -1
- meta_pharmacy/admin/__init__.py +0 -1
- meta_pharmacy/admin_site.py +5 -1
- meta_pharmacy/apps.py +2 -0
- meta_pharmacy/forms/__init__.py +2 -0
- meta_pharmacy/forms/rx_form.py +16 -0
- meta_pharmacy/{forms.py → forms/substitutions_form.py} +1 -14
- meta_pharmacy/label_configs.py +30 -0
- meta_pharmacy/labels/__init__.py +5 -2
- meta_pharmacy/labels/draw_label_for_subject_with_barcode.py +58 -0
- meta_pharmacy/labels/draw_label_for_subject_with_code128.py +14 -0
- meta_pharmacy/labels/draw_label_with_test_data.py +26 -0
- meta_pharmacy/labels/label_data.py +14 -0
- meta_pharmacy/labels/print_sheets.py +22 -11
- meta_pharmacy/list_data.py +8 -0
- meta_pharmacy/management/commands/__init__.py +0 -0
- meta_pharmacy/management/commands/update_initial_pharmacy_data.py +10 -0
- meta_pharmacy/migrations/0002_initial.py +7 -5
- meta_pharmacy/migrations/0008_remove_lotnumber_medication_and_more.py +390 -0
- meta_pharmacy/migrations/0009_remove_historicalrx_slug.py +17 -0
- meta_pharmacy/models/__init__.py +1 -2
- meta_pharmacy/models/label_data.py +38 -0
- meta_pharmacy/models/{label.py → rx_label.py} +8 -19
- meta_pharmacy/utils/__init__.py +1 -0
- meta_pharmacy/utils/update_initial_pharmacy_data.py +146 -0
- meta_prn/admin/pregnancy_notification_admin.py +6 -2
- meta_reports/admin/__init__.py +1 -0
- meta_reports/admin/dbviews/glucose_summary_admin.py +1 -1
- meta_reports/admin/last_imp_refill_admin.py +181 -0
- meta_reports/migrations/0052_lastimpvisit.py +57 -0
- meta_reports/migrations/0053_rename_lastimpvisit_lastimprefill_and_more.py +31 -0
- meta_reports/models/__init__.py +1 -0
- meta_reports/models/last_imp_refill.py +34 -0
- meta_subject/admin/study_medication_admin.py +10 -0
- meta_subject/forms/study_medication_form.py +35 -0
- meta_subject/locale/lg/LC_MESSAGES/django.po +470 -0
- meta_subject/locale/sw/LC_MESSAGES/django.po +191 -89
- meta_subject/metadata_rules/predicates.py +34 -7
- meta_subject/migrations/0214_historicalstudymedication_stock_codes_and_more.py +44 -0
- meta_subject/migrations/0215_alter_historicalstudymedication_stock_codes_and_more.py +46 -0
- meta_subject/tests/tests/test_metadata_rules.py +2 -2
- meta_subject/tests/tests/test_mnsi.py +180 -113
- meta_subject/tests/tests/test_sf12.py +0 -12
- meta_visit_schedule/visit_schedules/phase_three/crfs.py +18 -6
- tests/test_settings.py +4 -1
- meta_edc/celery/__init__.py +0 -2
- meta_edc/celery/live.py +0 -17
- meta_edc/celery/uat.py +0 -17
- meta_pharmacy/admin/lot_number_admin.py +0 -43
- meta_pharmacy/labels/get_label_data.py +0 -30
- meta_pharmacy/models/lot_number.py +0 -25
- meta_reports/models/unmanaged/README +0 -14
- meta_reports/models/unmanaged/patient_history_missing_baseline_cd4.py +0 -26
- meta_reports/models/unmanaged/patient_history_missing_baseline_cd4.sql +0 -10
- meta_reports/models/unmanaged/unattended_three_in_row.py +0 -24
- meta_reports/models/unmanaged/unattended_three_in_row.sql +0 -19
- meta_reports/models/unmanaged/unattended_three_in_row2.py +0 -24
- meta_reports/models/unmanaged/unattended_three_in_row2.sql +0 -39
- meta_reports/models/unmanaged/unattended_two_in_row.py +0 -22
- meta_reports/models/unmanaged/unattended_two_in_row.sql +0 -19
- {meta_reports/models/unmanaged → meta_edc/migrations}/__init__.py +0 -0
- {meta_edc-0.3.38.dist-info → meta_edc-0.3.40.dist-info}/AUTHORS +0 -0
- {meta_edc-0.3.38.dist-info → meta_edc-0.3.40.dist-info}/LICENSE +0 -0
- {meta_edc-0.3.38.dist-info → meta_edc-0.3.40.dist-info}/top_level.txt +0 -0
- /meta_pharmacy/{admin/label_admin.py → management/__init__.py} +0 -0
meta_analytics/__init__.py
CHANGED
@@ -8,6 +8,7 @@ from .constants import (
|
|
8
8
|
endpoint_columns,
|
9
9
|
)
|
10
10
|
from .get_eos_df import get_eos_df
|
11
|
+
from .get_last_imp_visits_df import get_last_imp_visits_df
|
11
12
|
from .glucose_endpoints import EndpointByDate, GlucoseEndpointsByDate
|
12
13
|
from .screening import get_glucose_tested_only_df, get_screening_df
|
13
14
|
from .utils import (
|
@@ -0,0 +1,101 @@
|
|
1
|
+
import pandas as pd
|
2
|
+
from django.apps import apps as django_apps
|
3
|
+
from django.core.exceptions import ObjectDoesNotExist
|
4
|
+
from django_pandas.io import read_frame
|
5
|
+
from edc_pdutils.dataframes import get_appointments, get_crf
|
6
|
+
|
7
|
+
|
8
|
+
class InvalidLotNumber(Exception):
|
9
|
+
pass
|
10
|
+
|
11
|
+
|
12
|
+
def site_cond(df, site_id):
|
13
|
+
return (0 == 0) if not site_id else df.site_id == site_id
|
14
|
+
|
15
|
+
|
16
|
+
def get_last_imp_visits_df(
|
17
|
+
lot_no: str | None = None,
|
18
|
+
site_id: int | None = None,
|
19
|
+
) -> pd.DataFrame:
|
20
|
+
"""Returns a dataframe of the last IMP visits based on the last
|
21
|
+
StudyMedication refill report.
|
22
|
+
|
23
|
+
`assignment` col defaults to "*****" unless a valid `lot_no` is
|
24
|
+
provided.
|
25
|
+
"""
|
26
|
+
lot_obj = None
|
27
|
+
if lot_no:
|
28
|
+
lot_number_model_cls = django_apps.get_model("meta_pharmacy.lotnumber")
|
29
|
+
try:
|
30
|
+
lot_obj = lot_number_model_cls.objects.get(lot_no=lot_no)
|
31
|
+
except ObjectDoesNotExist:
|
32
|
+
raise ObjectDoesNotExist("The lot number given is invalid")
|
33
|
+
|
34
|
+
df_meds = get_crf(
|
35
|
+
"meta_subject.studymedication", subject_visit_model="meta_subject.subjectvisit"
|
36
|
+
)
|
37
|
+
df_meds = (
|
38
|
+
df_meds[(df_meds.refill == "Yes") & (site_cond(df_meds, site_id))]
|
39
|
+
.groupby(by=["subject_identifier", "site_id"])
|
40
|
+
.agg({"last_visit_code": "max", "last_visit_datetime": "max"})
|
41
|
+
.reset_index()
|
42
|
+
)
|
43
|
+
df_meds = df_meds.rename(
|
44
|
+
columns={"last_visit_code": "imp_visit_code", "last_visit_datetime": "imp_visit_date"}
|
45
|
+
)
|
46
|
+
df_meds.reset_index()
|
47
|
+
|
48
|
+
# merge with OffSchedule
|
49
|
+
opts = {} if not site_id else dict(site_id=site_id)
|
50
|
+
offschedule_model_cls = django_apps.get_model("meta_prn.offschedule")
|
51
|
+
df_off = read_frame(
|
52
|
+
offschedule_model_cls.objects.values(
|
53
|
+
"subject_identifier", "offschedule_datetime"
|
54
|
+
).filter(**opts),
|
55
|
+
verbose=False,
|
56
|
+
)
|
57
|
+
df_off["offschedule_datetime"] = df_off["offschedule_datetime"].dt.tz_localize(None)
|
58
|
+
df_off["offschedule_datetime"] = df_off["offschedule_datetime"].dt.normalize()
|
59
|
+
df_off = df_off.set_index("subject_identifier")
|
60
|
+
|
61
|
+
df_meds = df_meds.set_index("subject_identifier")
|
62
|
+
df_final = pd.merge(
|
63
|
+
df_meds, df_off, left_index=True, right_index=True, how="outer"
|
64
|
+
).reset_index()
|
65
|
+
|
66
|
+
# merge with RandomizationList if lot_obj
|
67
|
+
# note: slow to decrypt assignment
|
68
|
+
if lot_obj:
|
69
|
+
rando_model_cls = django_apps.get_model("meta_rando.randomizationlist")
|
70
|
+
qs = rando_model_cls.objects.values("subject_identifier", "assignment").filter(
|
71
|
+
assignment=lot_obj.assignment
|
72
|
+
)
|
73
|
+
df_rando = read_frame(qs, verbose=False)
|
74
|
+
df_final = df_final.merge(df_rando, on="subject_identifier", how="left")
|
75
|
+
else:
|
76
|
+
df_final["assignment"] = "*****"
|
77
|
+
|
78
|
+
# merge in appts
|
79
|
+
df_appt = (
|
80
|
+
get_appointments()
|
81
|
+
.groupby(by=["subject_identifier"])
|
82
|
+
.agg({"next_visit_code": "max", "next_appt_datetime": "max"})
|
83
|
+
.reset_index()
|
84
|
+
)
|
85
|
+
df_final = df_final.merge(
|
86
|
+
df_appt[["subject_identifier", "next_visit_code", "next_appt_datetime"]],
|
87
|
+
on="subject_identifier",
|
88
|
+
how="left",
|
89
|
+
)
|
90
|
+
df_final = df_final[(df_final.offschedule_datetime.isna()) & (df_final.assignment.notna())]
|
91
|
+
|
92
|
+
# Filter out subjects off_schedule.
|
93
|
+
# If lot_obj, filter out those with alternative assignment.
|
94
|
+
df_final = df_final[(df_final.offschedule_datetime.isna()) & (df_final.assignment.notna())]
|
95
|
+
df_final = df_final.drop(columns=["offschedule_datetime"])
|
96
|
+
|
97
|
+
# calculate days since the IMP visit
|
98
|
+
df_final["days_since"] = pd.to_datetime("today").normalize() - df_final.imp_visit_date
|
99
|
+
df_final["days_until"] = df_final.next_appt_datetime - pd.to_datetime("today").normalize()
|
100
|
+
df_final = df_final.reset_index()
|
101
|
+
return df_final
|
meta_auth/auth_objects.py
CHANGED
@@ -14,6 +14,7 @@ reports_codenames = get_app_codenames("meta_reports")
|
|
14
14
|
reports_codenames.remove("meta_reports.view_impsubstitutions")
|
15
15
|
|
16
16
|
meta_pharmacy_codenames = get_app_codenames("meta_pharmacy")
|
17
|
+
meta_pharmacy_codenames.extend(get_app_codenames("django_pylabels"))
|
17
18
|
meta_pharmacy_codenames.append("meta_reports.view_impsubstitutions")
|
18
19
|
meta_pharmacy_codenames.append("meta_reports.viewallsites_impsubstitutions")
|
19
20
|
excluded_meta_pharmacy_codenames = [
|
meta_consent/consents.py
CHANGED
@@ -12,6 +12,12 @@ consent_v1 = ConsentDefinition(
|
|
12
12
|
age_is_adult=18,
|
13
13
|
age_max=110,
|
14
14
|
gender=[MALE, FEMALE],
|
15
|
+
screening_model=[
|
16
|
+
"meta_screening.subjectscreening",
|
17
|
+
"meta_screening.screeningpartone",
|
18
|
+
"meta_screening.screeningparttwo",
|
19
|
+
"meta_screening.screeningpartthree",
|
20
|
+
],
|
15
21
|
)
|
16
22
|
|
17
23
|
site_consents.register(consent_v1)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
5
|
+
#
|
6
|
+
#, fuzzy
|
7
|
+
msgid ""
|
8
|
+
msgstr ""
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
11
|
+
"POT-Creation-Date: 2024-11-19 23:35+0300\n"
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15
|
+
"Language: \n"
|
16
|
+
"MIME-Version: 1.0\n"
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
19
|
+
|
20
|
+
#: meta_consent/admin/modeladmin_mixins.py:68
|
21
|
+
msgid "The following questions are directed to the interviewer."
|
22
|
+
msgstr ""
|
23
|
+
|
24
|
+
#: meta_consent/admin/modeladmin_mixins.py:118
|
25
|
+
msgid "Create missing METFORMIN prescription"
|
26
|
+
msgstr ""
|
27
|
+
|
28
|
+
#: meta_consent/admin/modeladmin_mixins.py:140
|
29
|
+
#, python-format
|
30
|
+
msgid ""
|
31
|
+
"Created %(created)s/%(total)s missing %(display_name)s prescriptions. Got "
|
32
|
+
"%(exist)s/%(total)s prescriptions already exist"
|
33
|
+
msgstr ""
|
34
|
+
|
35
|
+
#: meta_consent/form_validators/subject_consent_form_validator.py:14
|
36
|
+
msgid "Expected 'hospital number'."
|
37
|
+
msgstr ""
|
38
|
+
|
39
|
+
#: meta_consent/form_validators/subject_consent_form_validator.py:22
|
40
|
+
msgid "The hospital identifier does not match that reported at screening."
|
41
|
+
msgstr ""
|
42
|
+
|
43
|
+
#: meta_consent/forms/subject_consent_form.py:13
|
44
|
+
msgid ""
|
45
|
+
"Use Country ID Number, Passport number, driver's license number or Country "
|
46
|
+
"ID receipt number"
|
47
|
+
msgstr ""
|
48
|
+
|
49
|
+
#: meta_consent/forms/subject_consent_form.py:19
|
50
|
+
msgid ""
|
51
|
+
"Required only if participant is illiterate. Format is 'LASTNAME, FIRSTNAME'. "
|
52
|
+
"All uppercase separated by a comma."
|
53
|
+
msgstr ""
|
54
|
+
|
55
|
+
#: meta_consent/forms/subject_consent_form.py:24
|
56
|
+
msgid "(read-only)"
|
57
|
+
msgstr ""
|
58
|
+
|
59
|
+
#: meta_consent/models/subject_consent.py:54
|
60
|
+
msgid "Screening identifier"
|
61
|
+
msgstr ""
|
62
|
+
|
63
|
+
#: meta_consent/models/subject_consent.py:58
|
64
|
+
msgid "Screening datetime"
|
65
|
+
msgstr ""
|
66
|
+
|
67
|
+
#: meta_consent/models/subject_consent.py:63
|
68
|
+
msgid "from screening"
|
69
|
+
msgstr ""
|
@@ -8,7 +8,7 @@ msgid ""
|
|
8
8
|
msgstr ""
|
9
9
|
"Project-Id-Version: PACKAGE VERSION\n"
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
11
|
-
"POT-Creation-Date:
|
11
|
+
"POT-Creation-Date: 2024-11-19 23:35+0300\n"
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
@@ -18,53 +18,53 @@ msgstr ""
|
|
18
18
|
"Content-Transfer-Encoding: 8bit\n"
|
19
19
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
20
20
|
|
21
|
-
#: admin/
|
21
|
+
#: meta_consent/admin/modeladmin_mixins.py:68
|
22
22
|
msgid "The following questions are directed to the interviewer."
|
23
23
|
msgstr ""
|
24
24
|
|
25
|
-
#: admin/
|
25
|
+
#: meta_consent/admin/modeladmin_mixins.py:118
|
26
26
|
msgid "Create missing METFORMIN prescription"
|
27
27
|
msgstr ""
|
28
28
|
|
29
|
-
#: admin/
|
29
|
+
#: meta_consent/admin/modeladmin_mixins.py:140
|
30
30
|
#, python-format
|
31
31
|
msgid ""
|
32
32
|
"Created %(created)s/%(total)s missing %(display_name)s prescriptions. Got "
|
33
33
|
"%(exist)s/%(total)s prescriptions already exist"
|
34
34
|
msgstr ""
|
35
35
|
|
36
|
-
#:
|
36
|
+
#: meta_consent/form_validators/subject_consent_form_validator.py:14
|
37
37
|
msgid "Expected 'hospital number'."
|
38
38
|
msgstr ""
|
39
39
|
|
40
|
-
#:
|
40
|
+
#: meta_consent/form_validators/subject_consent_form_validator.py:22
|
41
41
|
msgid "The hospital identifier does not match that reported at screening."
|
42
42
|
msgstr ""
|
43
43
|
|
44
|
-
#: forms/subject_consent_form.py:
|
44
|
+
#: meta_consent/forms/subject_consent_form.py:13
|
45
45
|
msgid ""
|
46
46
|
"Use Country ID Number, Passport number, driver's license number or Country "
|
47
47
|
"ID receipt number"
|
48
48
|
msgstr ""
|
49
49
|
|
50
|
-
#: forms/subject_consent_form.py:
|
50
|
+
#: meta_consent/forms/subject_consent_form.py:19
|
51
51
|
msgid ""
|
52
52
|
"Required only if participant is illiterate. Format is 'LASTNAME, FIRSTNAME'. "
|
53
53
|
"All uppercase separated by a comma."
|
54
54
|
msgstr ""
|
55
55
|
|
56
|
-
#: forms/subject_consent_form.py:
|
56
|
+
#: meta_consent/forms/subject_consent_form.py:24
|
57
57
|
msgid "(read-only)"
|
58
58
|
msgstr ""
|
59
59
|
|
60
|
-
#: models/subject_consent.py:
|
60
|
+
#: meta_consent/models/subject_consent.py:54
|
61
61
|
msgid "Screening identifier"
|
62
62
|
msgstr ""
|
63
63
|
|
64
|
-
#: models/subject_consent.py:
|
64
|
+
#: meta_consent/models/subject_consent.py:58
|
65
65
|
msgid "Screening datetime"
|
66
66
|
msgstr ""
|
67
67
|
|
68
|
-
#: models/subject_consent.py:
|
68
|
+
#: meta_consent/models/subject_consent.py:63
|
69
69
|
msgid "from screening"
|
70
70
|
msgstr ""
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
5
|
+
#
|
6
|
+
#, fuzzy
|
7
|
+
msgid ""
|
8
|
+
msgstr ""
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
11
|
+
"POT-Creation-Date: 2024-11-19 23:35+0300\n"
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
15
|
+
"Language: \n"
|
16
|
+
"MIME-Version: 1.0\n"
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
19
|
+
|
20
|
+
#: meta_dashboard/view_utils/subject_screening_button.py:42
|
21
|
+
msgid "View"
|
22
|
+
msgstr ""
|
23
|
+
|
24
|
+
#: meta_dashboard/view_utils/subject_screening_button.py:44
|
25
|
+
msgid "Edit"
|
26
|
+
msgstr ""
|
27
|
+
|
28
|
+
#: meta_dashboard/views/subject/dashboard/dashboard_view.py:17
|
29
|
+
msgid "Audit"
|
30
|
+
msgstr ""
|
@@ -8,7 +8,7 @@ msgid ""
|
|
8
8
|
msgstr ""
|
9
9
|
"Project-Id-Version: PACKAGE VERSION\n"
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
11
|
-
"POT-Creation-Date:
|
11
|
+
"POT-Creation-Date: 2024-11-19 23:35+0300\n"
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
@@ -17,6 +17,15 @@ msgstr ""
|
|
17
17
|
"Content-Type: text/plain; charset=UTF-8\n"
|
18
18
|
"Content-Transfer-Encoding: 8bit\n"
|
19
19
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
20
|
-
|
20
|
+
|
21
|
+
#: meta_dashboard/view_utils/subject_screening_button.py:42
|
22
|
+
msgid "View"
|
23
|
+
msgstr ""
|
24
|
+
|
25
|
+
#: meta_dashboard/view_utils/subject_screening_button.py:44
|
26
|
+
msgid "Edit"
|
27
|
+
msgstr ""
|
28
|
+
|
29
|
+
#: meta_dashboard/views/subject/dashboard/dashboard_view.py:17
|
21
30
|
msgid "Audit"
|
22
31
|
msgstr ""
|
meta_dashboard/navbars.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from edc_adverse_event.navbars import ae_navbar_item, tmg_navbar_item
|
2
2
|
from edc_data_manager.navbar_item import dm_navbar_item
|
3
3
|
from edc_navbar import Navbar, NavbarItem, site_navbars
|
4
|
+
from edc_pharmacy.navbars import pharmacy_navbar_item
|
4
5
|
from edc_review_dashboard.navbars import navbar_item as review_navbar_item
|
5
6
|
|
6
7
|
no_url_namespace = False # True if settings.APP_NAME == "meta_dashboard" else False
|
@@ -33,6 +34,7 @@ navbar.register(
|
|
33
34
|
)
|
34
35
|
|
35
36
|
|
37
|
+
navbar.register(pharmacy_navbar_item)
|
36
38
|
navbar.register(review_navbar_item)
|
37
39
|
navbar.register(tmg_navbar_item)
|
38
40
|
navbar.register(ae_navbar_item)
|
@@ -9,7 +9,7 @@ from edc_dashboard.url_names import url_names
|
|
9
9
|
from edc_dashboard.utils import get_bootstrap_version
|
10
10
|
|
11
11
|
from meta_consent.models import SubjectConsent
|
12
|
-
from meta_dashboard.view_utils
|
12
|
+
from meta_dashboard.view_utils import (
|
13
13
|
SubjectScreeningPartOneButton,
|
14
14
|
SubjectScreeningPartThreeButton,
|
15
15
|
SubjectScreeningPartTwoButton,
|
meta_dashboard/tests/urls.py
CHANGED
@@ -47,7 +47,6 @@ urlpatterns = [
|
|
47
47
|
path("edc_export/", include("edc_export.urls")),
|
48
48
|
path("edc_lab_dashboard/", include("edc_lab_dashboard.urls")),
|
49
49
|
path("edc_locator/", include("edc_locator.urls")),
|
50
|
-
path("edc_pharmacy_dashboard/", include("edc_pharmacy_dashboard.urls")),
|
51
50
|
path("edc_protocol/", include("edc_protocol.urls")),
|
52
51
|
path("edc_subject_dashboard/", include("edc_subject_dashboard.urls")),
|
53
52
|
path("edc_visit_schedule/", include("edc_visit_schedule.urls")),
|
@@ -5,10 +5,10 @@ from typing import Type
|
|
5
5
|
|
6
6
|
from django.utils.translation import gettext as _
|
7
7
|
from edc_constants.constants import TBD, YES
|
8
|
-
from edc_subject_dashboard.view_utils import
|
9
|
-
from edc_subject_dashboard.view_utils.subject_screening_button import (
|
8
|
+
from edc_subject_dashboard.view_utils import (
|
10
9
|
SubjectScreeningButton as BaseSubjectScreeningButton,
|
11
10
|
)
|
11
|
+
from edc_view_utils import ADD, CHANGE, VIEW
|
12
12
|
|
13
13
|
from meta_screening.models import ScreeningPartOne, ScreeningPartThree, ScreeningPartTwo
|
14
14
|
|
meta_edc/__init__.py
CHANGED
@@ -1,16 +1,7 @@
|
|
1
1
|
import os
|
2
|
-
import sys
|
3
2
|
from importlib.metadata import PackageNotFoundError, version
|
4
3
|
|
5
|
-
|
6
|
-
# it will load the correct settings module coming from
|
7
|
-
# systemd service
|
8
|
-
if "meta_edc.celery.live:app" in sys.argv:
|
9
|
-
from .celery.live import app as celery_app
|
10
|
-
elif "meta_edc.celery.uat:app" in sys.argv:
|
11
|
-
from .celery.uat import app as celery_app
|
12
|
-
else:
|
13
|
-
from .celery.debug import app as celery_app
|
4
|
+
from .celery import app as celery_app
|
14
5
|
|
15
6
|
try:
|
16
7
|
__version__ = version(os.getcwd().split(os.sep)[-1])
|
@@ -19,3 +10,5 @@ except PackageNotFoundError:
|
|
19
10
|
|
20
11
|
|
21
12
|
__all__ = ["celery_app", "__version__"]
|
13
|
+
|
14
|
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "meta_edc.settings.debug")
|
@@ -6,8 +6,8 @@ from celery import Celery
|
|
6
6
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "meta_edc.settings.debug")
|
7
7
|
|
8
8
|
# config celery
|
9
|
-
#
|
10
|
-
app = Celery("meta_edc"
|
9
|
+
# app = Celery("meta_edc", include=["meta_reports", "edc_pharmacy"])
|
10
|
+
app = Celery("meta_edc")
|
11
11
|
app.config_from_object("django.conf:settings", namespace="CELERY")
|
12
12
|
app.autodiscover_tasks()
|
13
13
|
|
meta_edc/navbars.py
CHANGED
@@ -5,6 +5,7 @@ from edc_adverse_event.navbars import ae_navbar_item, tmg_navbar_item
|
|
5
5
|
from edc_data_manager.navbar_item import dm_navbar_item
|
6
6
|
from edc_lab_dashboard.navbars import navbar as lab_navbar
|
7
7
|
from edc_navbar import Navbar, site_navbars
|
8
|
+
from edc_pharmacy.navbars import pharmacy_navbar_item
|
8
9
|
from edc_review_dashboard.navbars import navbar as review_navbar
|
9
10
|
|
10
11
|
from meta_dashboard.navbars import navbar as meta_dashboard_navbar
|
@@ -29,6 +30,7 @@ navbar.register(
|
|
29
30
|
for navbar_item in review_navbar.navbar_items:
|
30
31
|
navbar.register(navbar_item)
|
31
32
|
|
33
|
+
navbar.register(pharmacy_navbar_item)
|
32
34
|
navbar.register(tmg_navbar_item)
|
33
35
|
navbar.register(ae_navbar_item)
|
34
36
|
navbar.register(dm_navbar_item)
|
meta_edc/settings/debug.py
CHANGED
@@ -32,3 +32,11 @@ EDC_MODEL_ADMIN_CSS_THEME = "edc_purple"
|
|
32
32
|
if os.path.exists(BASE_DIR) and not os.path.exists(KEY_PATH): # noqa
|
33
33
|
os.makedirs(KEY_PATH) # noqa
|
34
34
|
AUTO_CREATE_KEYS = True
|
35
|
+
|
36
|
+
# if debugging, run `export DJANGO_DEBUG=True` before running runserver
|
37
|
+
# CELERY_TASK_ALWAYS_EAGER = os.getenv("DJANGO_DEBUG", "False") == "True"
|
38
|
+
# CELERY_TASK_EAGER_PROPAGATES = CELERY_TASK_ALWAYS_EAGER
|
39
|
+
|
40
|
+
EDC_PDF_REPORTS_WATERMARK_WORD = "SAMPLE"
|
41
|
+
EDC_PDF_REPORTS_WATERMARK_FONT = ("Helvetica", 100)
|
42
|
+
EDC_PHARMACY_LABEL_WATERMARK_WORD = "DO NOT USE"
|
meta_edc/settings/defaults.py
CHANGED
@@ -34,19 +34,17 @@ env = environ.Env(
|
|
34
34
|
EDC_SITES_DOMAIN_SUFFIX="meta4.clinicedc.org",
|
35
35
|
)
|
36
36
|
|
37
|
-
BASE_DIR =
|
38
|
-
ENV_DIR =
|
37
|
+
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
38
|
+
ENV_DIR = Path(__file__).resolve().parent.parent.parent
|
39
39
|
|
40
40
|
# copy your .env file from .envs/ to BASE_DIR
|
41
41
|
if "test" in sys.argv:
|
42
|
-
env.read_env(
|
43
|
-
print(f"Reading env from {
|
42
|
+
env.read_env(ENV_DIR / ".env-tests")
|
43
|
+
print(f"Reading env from {(BASE_DIR /'.env-tests')}") # noqa
|
44
44
|
else:
|
45
|
-
if not
|
46
|
-
raise FileExistsError(
|
47
|
-
|
48
|
-
)
|
49
|
-
env.read_env(os.path.join(ENV_DIR, ".env"))
|
45
|
+
if not (ENV_DIR / ".env").exists():
|
46
|
+
raise FileExistsError(f"Environment file does not exist. Got `{(ENV_DIR / '.env')}`")
|
47
|
+
env.read_env(ENV_DIR / ".env")
|
50
48
|
|
51
49
|
|
52
50
|
LOGGING_ENABLED = env("DJANGO_LOGGING_ENABLED")
|
@@ -67,7 +65,7 @@ LIVE_SYSTEM = env.str("DJANGO_LIVE_SYSTEM")
|
|
67
65
|
|
68
66
|
ETC_DIR = env.str("DJANGO_ETC_FOLDER")
|
69
67
|
|
70
|
-
TEST_DIR =
|
68
|
+
TEST_DIR = BASE_DIR / APP_NAME / "tests"
|
71
69
|
|
72
70
|
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS")
|
73
71
|
|
@@ -92,6 +90,7 @@ INSTALLED_APPS = [
|
|
92
90
|
"django.contrib.sites",
|
93
91
|
"multisite.apps.AppConfig",
|
94
92
|
"defender",
|
93
|
+
"sequences.apps.SequencesConfig",
|
95
94
|
# "django_celery_beat",
|
96
95
|
# "django_celery_results",
|
97
96
|
"django_db_views",
|
@@ -102,6 +101,8 @@ INSTALLED_APPS = [
|
|
102
101
|
"logentry_admin",
|
103
102
|
"simple_history",
|
104
103
|
"storages",
|
104
|
+
"django_pylabels.apps.AppConfig",
|
105
|
+
"edc_pylabels.apps.AppConfig",
|
105
106
|
"edc_sites.apps.AppConfig",
|
106
107
|
"edc_action_item.apps.AppConfig",
|
107
108
|
"edc_appointment.apps.AppConfig",
|
@@ -235,7 +236,7 @@ if env("DATABASE_SQLITE_ENABLED"):
|
|
235
236
|
DATABASES = {
|
236
237
|
"default": {
|
237
238
|
"ENGINE": "django.db.backends.sqlite3",
|
238
|
-
"NAME":
|
239
|
+
"NAME": BASE_DIR / "db.sqlite3",
|
239
240
|
}
|
240
241
|
}
|
241
242
|
|
@@ -307,6 +308,11 @@ LANGUAGE_CODE = "en-gb"
|
|
307
308
|
LANGUAGE_LIST = ["sw", "en-gb", "en", "mas"]
|
308
309
|
LANGUAGES = [(code, LANG_INFO[code]["name"]) for code in LANGUAGE_LIST]
|
309
310
|
|
311
|
+
# LOCALE_PATHS = [
|
312
|
+
# base_dir / "locale",
|
313
|
+
# base_dir.parent / "edc-pharmacy" / "edc_pharmacy" / "locale",
|
314
|
+
# ]
|
315
|
+
|
310
316
|
TIME_ZONE = env.str("DJANGO_TIME_ZONE")
|
311
317
|
DATE_INPUT_FORMATS = ["%Y-%m-%d", "%d/%m/%Y"]
|
312
318
|
DATETIME_INPUT_FORMATS = [
|
@@ -349,8 +355,8 @@ if not DEBUG:
|
|
349
355
|
SECURE_BROWSER_XSS_FILTER = True
|
350
356
|
|
351
357
|
# edc_lab and label
|
352
|
-
LABEL_TEMPLATE_FOLDER = env.str("DJANGO_LABEL_TEMPLATE_FOLDER") or
|
353
|
-
BASE_DIR
|
358
|
+
LABEL_TEMPLATE_FOLDER = env.str("DJANGO_LABEL_TEMPLATE_FOLDER") or (
|
359
|
+
BASE_DIR / "label_templates" / "2.25x1.25in"
|
354
360
|
)
|
355
361
|
CUPS_SERVERS = env.dict("DJANGO_CUPS_SERVERS")
|
356
362
|
|
@@ -458,7 +464,7 @@ GIT_DIR = BASE_DIR
|
|
458
464
|
KEY_PATH = env.str("DJANGO_KEY_FOLDER")
|
459
465
|
AUTO_CREATE_KEYS = env("DJANGO_AUTO_CREATE_KEYS")
|
460
466
|
|
461
|
-
EXPORT_FOLDER = env.str("DJANGO_EXPORT_FOLDER") or
|
467
|
+
EXPORT_FOLDER = env.str("DJANGO_EXPORT_FOLDER") or Path("~/").expanduser()
|
462
468
|
|
463
469
|
# django_simple_history
|
464
470
|
SIMPLE_HISTORY_ENFORCE_HISTORY_MODEL_PERMISSIONS = True
|
@@ -520,7 +526,7 @@ if env("AWS_ENABLED"):
|
|
520
526
|
STATIC_ROOT = ""
|
521
527
|
elif DEBUG:
|
522
528
|
STATIC_URL = env.str("DJANGO_STATIC_URL")
|
523
|
-
STATIC_ROOT =
|
529
|
+
STATIC_ROOT = Path("~/source/edc_source/meta-edc/static/").expanduser()
|
524
530
|
else:
|
525
531
|
# run collectstatic, check nginx LOCATION
|
526
532
|
STATIC_URL = env.str("DJANGO_STATIC_URL")
|
@@ -534,10 +540,17 @@ if CELERY_ENABLED:
|
|
534
540
|
CELERY_BROKER_URL = (
|
535
541
|
f"redis://:{quote(env.str('DJANGO_REDIS_PASSWORD'), safe='')}@127.0.0.1:6379/0"
|
536
542
|
)
|
543
|
+
CELERY_RESULT_BACKEND = (
|
544
|
+
f"redis://:{quote(env.str('DJANGO_REDIS_PASSWORD'), safe='')}@127.0.0.1:6379/0"
|
545
|
+
)
|
537
546
|
else:
|
538
547
|
CELERY_BROKER_URL = "redis://127.0.0.1:6379/0"
|
548
|
+
CELERY_RESULT_BACKEND = "redis://localhost:6379/0"
|
539
549
|
# CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers.DatabaseScheduler"
|
540
|
-
|
550
|
+
CELERY_ACCEPT_CONTENT = ["json"]
|
551
|
+
CELERY_TASK_SERIALIZER = "json"
|
552
|
+
CELERY_RESULT_SERIALIZER = "json"
|
553
|
+
CELERY_TIMEZONE = "UTC"
|
541
554
|
|
542
555
|
if "test" in sys.argv:
|
543
556
|
|
@@ -59,8 +59,8 @@ a { cursor: pointer; }
|
|
59
59
|
{% if perms.meta_reports %}
|
60
60
|
<a href="{% url 'meta_reports:home_url' %}" class="list-group-item"><i class="fa-solid fa-stroopwafel fa-lg fa-fw"></i></i> QA Reports</a>
|
61
61
|
{% endif %}
|
62
|
-
{% if perms.
|
63
|
-
<a href="{% url
|
62
|
+
{% if perms.edc_pharmacy.nav_pharmacy_section %}
|
63
|
+
<a href="{% url 'edc_pharmacy:home_url' %}" class="list-group-item"><i class="fas fa-prescription fa-lg fa-fw"></i> Pharmacy</a>
|
64
64
|
{% endif %}
|
65
65
|
{% if perms.edc_export %}
|
66
66
|
<a href="{% url 'edc_export:home_url' %}" class="list-group-item"><i class="fas fa-file-export fa-lg fa-fw"></i> Export data</a>
|
@@ -85,6 +85,7 @@ class AdminSiteTest(MetaTestCaseMixin, WebTest):
|
|
85
85
|
import_module("edc_adverse_event.auths")
|
86
86
|
import_module("edc_appointment.auths")
|
87
87
|
import_module("edc_consent.auths")
|
88
|
+
import_module("edc_pylabels.auths")
|
88
89
|
import_module("edc_dashboard.auths")
|
89
90
|
import_module("edc_data_manager.auths")
|
90
91
|
import_module("edc_qareports.auths")
|
meta_edc/urls.py
CHANGED
@@ -22,6 +22,7 @@ urlpatterns = [
|
|
22
22
|
path("accounts/", include("edc_auth.urls_for_accounts", namespace="auth")),
|
23
23
|
path("administration/", AdministrationView.as_view(), name="administration_url"),
|
24
24
|
path("subject/", include("meta_dashboard.urls")),
|
25
|
+
*paths_for_urlpatterns("edc_pylabels"),
|
25
26
|
*paths_for_urlpatterns("edc_auth"),
|
26
27
|
*paths_for_urlpatterns("edc_action_item"),
|
27
28
|
*paths_for_urlpatterns("edc_adverse_event"),
|
@@ -1,11 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: meta-edc
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.40
|
4
4
|
Summary: META Trial EDC (http://www.isrctn.com/ISRCTN76157257)
|
5
5
|
Home-page: https://github.com/meta-trial/meta-edc
|
6
|
-
Author:
|
7
|
-
Author-email: ew2789@gmail.com
|
8
|
-
License:
|
6
|
+
Author: Erik van Widenfelt
|
7
|
+
Author-email: Erik van Widenfelt <ew2789@gmail.com>, Jonathan Willitts <j.willitts@ucl.ac.uk>
|
8
|
+
License: GNU GENERAL PUBLIC LICENSE
|
9
9
|
Version 3, 29 June 2007
|
10
10
|
|
11
11
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
@@ -693,11 +693,11 @@ Requires-Python: >=3.12
|
|
693
693
|
Description-Content-Type: text/x-rst
|
694
694
|
License-File: LICENSE
|
695
695
|
License-File: AUTHORS
|
696
|
-
Requires-Dist: edc
|
696
|
+
Requires-Dist: edc==0.6.15
|
697
697
|
Requires-Dist: edc-microscopy
|
698
698
|
Requires-Dist: beautifulsoup4
|
699
699
|
Requires-Dist: celery[redis]
|
700
|
-
Requires-Dist:
|
700
|
+
Requires-Dist: django-pylabels
|
701
701
|
|
702
702
|
|pypi| |actions| |codecov| |downloads|
|
703
703
|
|