meta-edc 0.3.38__py3-none-any.whl → 0.3.39__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 (85) hide show
  1. meta_analytics/__init__.py +0 -2
  2. meta_analytics/dataframes/__init__.py +1 -0
  3. meta_analytics/dataframes/get_last_imp_visits_df.py +101 -0
  4. meta_auth/auth_objects.py +1 -0
  5. meta_consent/consents.py +6 -0
  6. meta_consent/locale/lg/LC_MESSAGES/django.po +69 -0
  7. meta_consent/locale/sw/LC_MESSAGES/django.po +12 -12
  8. meta_dashboard/locale/lg/LC_MESSAGES/django.po +30 -0
  9. meta_dashboard/locale/sw/LC_MESSAGES/django.po +11 -2
  10. meta_dashboard/navbars.py +2 -0
  11. meta_dashboard/tests/urls.py +0 -1
  12. meta_dashboard/view_utils/subject_screening_button.py +2 -2
  13. meta_edc/__init__.py +3 -10
  14. meta_edc/{celery/debug.py → celery.py} +2 -2
  15. meta_edc/navbars.py +2 -0
  16. meta_edc/settings/debug.py +4 -0
  17. meta_edc/settings/defaults.py +29 -16
  18. meta_edc/templates/meta_edc/bootstrap3/home.html +1 -1
  19. meta_edc/urls.py +1 -0
  20. {meta_edc-0.3.38.dist-info → meta_edc-0.3.39.dist-info}/METADATA +6 -6
  21. {meta_edc-0.3.38.dist-info → meta_edc-0.3.39.dist-info}/RECORD +70 -59
  22. {meta_edc-0.3.38.dist-info → meta_edc-0.3.39.dist-info}/WHEEL +1 -1
  23. meta_pharmacy/admin/__init__.py +0 -1
  24. meta_pharmacy/admin/actions.py +38 -0
  25. meta_pharmacy/admin_site.py +5 -1
  26. meta_pharmacy/apps.py +2 -0
  27. meta_pharmacy/forms/__init__.py +2 -0
  28. meta_pharmacy/forms/rx_form.py +16 -0
  29. meta_pharmacy/{forms.py → forms/substitutions_form.py} +1 -14
  30. meta_pharmacy/label_configs.py +30 -0
  31. meta_pharmacy/labels/__init__.py +3 -1
  32. meta_pharmacy/labels/draw_label_for_subject_with_barcode.py +58 -0
  33. meta_pharmacy/labels/draw_label_for_subject_with_code128.py +14 -0
  34. meta_pharmacy/labels/draw_label_with_test_data.py +26 -0
  35. meta_pharmacy/labels/label_data.py +14 -0
  36. meta_pharmacy/labels/print_sheets.py +22 -11
  37. meta_pharmacy/list_data.py +8 -0
  38. meta_pharmacy/management/commands/__init__.py +0 -0
  39. meta_pharmacy/management/commands/update_initial_pharmacy_data.py +10 -0
  40. meta_pharmacy/migrations/0002_initial.py +7 -5
  41. meta_pharmacy/migrations/0008_remove_lotnumber_medication_and_more.py +390 -0
  42. meta_pharmacy/migrations/0009_remove_historicalrx_slug.py +17 -0
  43. meta_pharmacy/models/__init__.py +1 -2
  44. meta_pharmacy/models/label_data.py +38 -0
  45. meta_pharmacy/models/{label.py → rx_label.py} +8 -19
  46. meta_pharmacy/utils/__init__.py +1 -0
  47. meta_pharmacy/utils/update_initial_pharmacy_data.py +146 -0
  48. meta_prn/admin/pregnancy_notification_admin.py +6 -2
  49. meta_reports/admin/__init__.py +1 -0
  50. meta_reports/admin/dbviews/glucose_summary_admin.py +1 -1
  51. meta_reports/admin/last_imp_refill_admin.py +181 -0
  52. meta_reports/migrations/0052_lastimpvisit.py +57 -0
  53. meta_reports/migrations/0053_rename_lastimpvisit_lastimprefill_and_more.py +31 -0
  54. meta_reports/models/__init__.py +1 -0
  55. meta_reports/models/last_imp_refill.py +34 -0
  56. meta_subject/admin/study_medication_admin.py +10 -0
  57. meta_subject/forms/study_medication_form.py +35 -0
  58. meta_subject/locale/lg/LC_MESSAGES/django.po +470 -0
  59. meta_subject/locale/sw/LC_MESSAGES/django.po +191 -89
  60. meta_subject/metadata_rules/predicates.py +34 -7
  61. meta_subject/migrations/0214_historicalstudymedication_stock_codes_and_more.py +44 -0
  62. meta_subject/migrations/0215_alter_historicalstudymedication_stock_codes_and_more.py +46 -0
  63. meta_subject/tests/tests/test_mnsi.py +180 -113
  64. meta_visit_schedule/visit_schedules/phase_three/crfs.py +18 -6
  65. tests/test_settings.py +4 -1
  66. meta_edc/celery/__init__.py +0 -2
  67. meta_edc/celery/live.py +0 -17
  68. meta_edc/celery/uat.py +0 -17
  69. meta_pharmacy/admin/lot_number_admin.py +0 -43
  70. meta_pharmacy/labels/get_label_data.py +0 -30
  71. meta_pharmacy/models/lot_number.py +0 -25
  72. meta_reports/models/unmanaged/README +0 -14
  73. meta_reports/models/unmanaged/patient_history_missing_baseline_cd4.py +0 -26
  74. meta_reports/models/unmanaged/patient_history_missing_baseline_cd4.sql +0 -10
  75. meta_reports/models/unmanaged/unattended_three_in_row.py +0 -24
  76. meta_reports/models/unmanaged/unattended_three_in_row.sql +0 -19
  77. meta_reports/models/unmanaged/unattended_three_in_row2.py +0 -24
  78. meta_reports/models/unmanaged/unattended_three_in_row2.sql +0 -39
  79. meta_reports/models/unmanaged/unattended_two_in_row.py +0 -22
  80. meta_reports/models/unmanaged/unattended_two_in_row.sql +0 -19
  81. {meta_reports/models/unmanaged → meta_edc/migrations}/__init__.py +0 -0
  82. {meta_edc-0.3.38.dist-info → meta_edc-0.3.39.dist-info}/AUTHORS +0 -0
  83. {meta_edc-0.3.38.dist-info → meta_edc-0.3.39.dist-info}/LICENSE +0 -0
  84. {meta_edc-0.3.38.dist-info → meta_edc-0.3.39.dist-info}/top_level.txt +0 -0
  85. /meta_pharmacy/{admin/label_admin.py → management/__init__.py} +0 -0
@@ -1,2 +0,0 @@
1
- from .dataframes import get_eos_df, get_glucose_tested_only_df, get_screening_df
2
- from .get_tables import get_tables
@@ -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: 2023-09-07 09:43-0500\n"
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/subject_consent_admin.py:74
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/subject_consent_admin.py:124
25
+ #: meta_consent/admin/modeladmin_mixins.py:118
26
26
  msgid "Create missing METFORMIN prescription"
27
27
  msgstr ""
28
28
 
29
- #: admin/subject_consent_admin.py:146
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
- #: forms/subject_consent_form.py:18
36
+ #: meta_consent/form_validators/subject_consent_form_validator.py:14
37
37
  msgid "Expected 'hospital number'."
38
38
  msgstr ""
39
39
 
40
- #: forms/subject_consent_form.py:26
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:54
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:60
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:65
56
+ #: meta_consent/forms/subject_consent_form.py:24
57
57
  msgid "(read-only)"
58
58
  msgstr ""
59
59
 
60
- #: models/subject_consent.py:63
60
+ #: meta_consent/models/subject_consent.py:54
61
61
  msgid "Screening identifier"
62
62
  msgstr ""
63
63
 
64
- #: models/subject_consent.py:67
64
+ #: meta_consent/models/subject_consent.py:58
65
65
  msgid "Screening datetime"
66
66
  msgstr ""
67
67
 
68
- #: models/subject_consent.py:72
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: 2023-09-07 09:35-0500\n"
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
- #: views/subject/dashboard/dashboard_view.py:9
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)
@@ -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 ADD, CHANGE, VIEW
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
- # celery_app loads settings before Django, so ensure
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
- # remember to include additional apps with tasks
10
- app = Celery("meta_edc", include=["meta_reports"])
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)
@@ -32,3 +32,7 @@ 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
@@ -34,19 +34,17 @@ env = environ.Env(
34
34
  EDC_SITES_DOMAIN_SUFFIX="meta4.clinicedc.org",
35
35
  )
36
36
 
37
- BASE_DIR = str(Path(os.path.dirname(os.path.abspath(__file__))).parent.parent)
38
- ENV_DIR = str(Path(os.path.dirname(os.path.abspath(__file__))).parent.parent)
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(os.path.join(ENV_DIR, ".env-tests"))
43
- print(f"Reading env from {os.path.join(BASE_DIR, '.env-tests')}")
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 os.path.exists(os.path.join(ENV_DIR, ".env")):
46
- raise FileExistsError(
47
- f"Environment file does not exist. Got `{os.path.join(ENV_DIR, '.env')}`"
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 = os.path.join(BASE_DIR, APP_NAME, "tests")
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": os.path.join(BASE_DIR, "db.sqlite3"),
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 os.path.join(
353
- BASE_DIR, "label_templates", "2.25x1.25in"
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 os.path.expanduser("~/")
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 = os.path.expanduser("~/source/edc_source/meta-edc/static/")
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
 
@@ -60,7 +60,7 @@ a { cursor: pointer; }
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>&nbsp;&nbsp;&nbsp;QA Reports</a>
61
61
  {% endif %}
62
62
  {% if perms.edc_navbar.nav_pharmacy_section %}
63
- <a href="{% url edc_randomization_url_name %}" class="list-group-item"><i class="fas fa-medkit fa-lg fa-fw"></i>&nbsp;&nbsp;&nbsp;Pharmacy</a>
63
+ <a href="{% url 'edc_pharmacy:home_url' %}" class="list-group-item"><i class="fas fa-prescription fa-lg fa-fw"></i>&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;Export data</a>
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.38
3
+ Version: 0.3.39
4
4
  Summary: META Trial EDC (http://www.isrctn.com/ISRCTN76157257)
5
5
  Home-page: https://github.com/meta-trial/meta-edc
6
- Author: Blair Bonnett
7
- Author-email: ew2789@gmail.com
8
- License: GNU GENERAL PUBLIC 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 ==0.6.14
696
+ Requires-Dist: edc==0.6.14
697
697
  Requires-Dist: edc-microscopy
698
698
  Requires-Dist: beautifulsoup4
699
699
  Requires-Dist: celery[redis]
700
- Requires-Dist: pylabels2
700
+ Requires-Dist: django-pylabels
701
701
 
702
702
  |pypi| |actions| |codecov| |downloads|
703
703