meta-edc 1.1.13__py3-none-any.whl → 1.1.15__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.

Potentially problematic release.


This version of meta-edc might be problematic. Click here for more details.

Files changed (72) hide show
  1. meta_ae/action_items.py +15 -18
  2. meta_ae/templatetags/meta_ae_extras.py +2 -2
  3. meta_analytics/dataframes/get_last_imp_visits_df.py +2 -2
  4. meta_analytics/tables/enrolled/glucose.py +1 -2
  5. meta_consent/models/subject_consent_v1.py +0 -1
  6. meta_dashboard/view_utils/subject_screening_button.py +3 -3
  7. meta_edc/admin.py +1 -1
  8. meta_edc/celery.py +2 -1
  9. meta_edc/celery_live.py +2 -1
  10. meta_edc/celery_uat.py +2 -1
  11. meta_edc/meta_version.py +2 -2
  12. meta_edc/navbars.py +7 -5
  13. meta_edc/settings/defaults.py +3 -3
  14. meta_edc/urls.py +1 -1
  15. meta_edc/utils.py +3 -1
  16. {meta_edc-1.1.13.dist-info → meta_edc-1.1.15.dist-info}/METADATA +10 -11
  17. {meta_edc-1.1.13.dist-info → meta_edc-1.1.15.dist-info}/RECORD +72 -70
  18. meta_pharmacy/admin/substitutions_admin.py +1 -1
  19. meta_pharmacy/forms/rx_form.py +0 -1
  20. meta_pharmacy/management/commands/update_initial_pharmacy_data.py +4 -3
  21. meta_pharmacy/models/rx_label.py +0 -1
  22. meta_prn/action_items.py +23 -31
  23. meta_prn/admin/end_of_study_admin.py +2 -2
  24. meta_prn/admin/offschedule_dm_referral_admin.py +0 -1
  25. meta_prn/admin/offschedule_postnatal_admin.py +0 -1
  26. meta_prn/admin/offschedule_pregnancy_admin.py +0 -1
  27. meta_prn/choices.py +6 -6
  28. meta_prn/form_validators/end_of_study.py +9 -8
  29. meta_prn/forms/dm_referral_form.py +2 -8
  30. meta_prn/forms/end_of_study_form.py +1 -1
  31. meta_prn/forms/off_study_medication_form.py +2 -2
  32. meta_prn/forms/pregnancy_notification_form.py +14 -16
  33. meta_prn/list_data.py +2 -2
  34. meta_prn/migrations/0068_alter_dmreferral_referral_note_and_more.py +235 -0
  35. meta_prn/models/dm_referral.py +2 -2
  36. meta_prn/models/end_of_study.py +7 -7
  37. meta_prn/models/loss_to_followup.py +6 -6
  38. meta_prn/models/off_study_medication.py +3 -2
  39. meta_prn/models/pregnancy_notification.py +3 -3
  40. meta_prn/models/protocol_incident.py +4 -1
  41. meta_prn/models/signals.py +15 -13
  42. meta_prn/models/subject_transfer.py +0 -1
  43. meta_rando/randomizers.py +1 -1
  44. meta_reports/admin/dbviews/imp_substitutions_admin.py +1 -1
  45. meta_reports/admin/dbviews/on_study_missing_values_admin/unmanaged_model_admin.py +0 -1
  46. meta_reports/admin/endpoints_all_admin.py +0 -1
  47. meta_reports/admin/modeladmin_mixins.py +1 -1
  48. meta_reports/migrations/0060_auto_20250926_0242.py +366 -0
  49. meta_reports/models/dbviews/imp_substitutions/unmanaged_model.py +0 -1
  50. meta_reports/models/dbviews/on_study_missing_lab_values/unmanged_model.py +0 -1
  51. meta_reports/models/dbviews/on_study_missing_values/unmanged_model.py +0 -1
  52. meta_reports/models/dbviews/patient_history_missing_baseline_cd4/unmanaged_model.py +0 -1
  53. meta_reports/models/dbviews/unattended_three_in_row/unmanaged_model.py +0 -1
  54. meta_reports/models/dbviews/unattended_three_in_row2/unmanaged_model.py +0 -1
  55. meta_reports/models/dbviews/unattended_two_in_row/unmanaged_model.py +0 -1
  56. meta_screening/admin/fieldsets.py +0 -1
  57. meta_screening/admin/screening_part_one_admin.py +0 -1
  58. meta_screening/forms/field_lists.py +0 -1
  59. meta_subject/admin/birth_outcome_admin.py +4 -2
  60. meta_subject/admin/fields.py +5 -5
  61. meta_subject/admin/fieldsets.py +5 -5
  62. meta_subject/admin/glucose_admin.py +2 -4
  63. meta_subject/admin/glucose_fbg_admin.py +5 -7
  64. meta_subject/admin/list_filters.py +3 -3
  65. meta_subject/admin/next_appointment_admin.py +0 -1
  66. meta_subject/form_validators/glucose_form_validator.py +7 -5
  67. meta_subject/forms/blood_results/blood_results_hba1c_form.py +1 -1
  68. meta_subject/forms/subject_requisition_form.py +1 -1
  69. meta_subject/models/blood_results/__init__.py +0 -1
  70. meta_subject/models/next_appointment.py +0 -1
  71. {meta_edc-1.1.13.dist-info → meta_edc-1.1.15.dist-info}/WHEEL +0 -0
  72. {meta_edc-1.1.13.dist-info → meta_edc-1.1.15.dist-info}/licenses/LICENSE +0 -0
meta_ae/action_items.py CHANGED
@@ -43,7 +43,7 @@ class AeFollowupAction(ActionWithNotification):
43
43
  name = AE_FOLLOWUP_ACTION
44
44
  display_name = "Submit AE Followup Report"
45
45
  notification_display_name = "AE Followup Report"
46
- parent_action_names = [AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION]
46
+ parent_action_names = (AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION)
47
47
  reference_model = "meta_ae.aefollowup"
48
48
  related_reference_model = "meta_ae.aeinitial"
49
49
  related_reference_fk_attr = "ae_initial"
@@ -61,7 +61,7 @@ class AeFollowupAction(ActionWithNotification):
61
61
  priority = HIGH_PRIORITY
62
62
 
63
63
  def get_next_actions(self):
64
- next_actions = []
64
+ next_actions = ()
65
65
 
66
66
  # add AE followup to next_actions if followup.
67
67
  next_actions = self.append_to_next_if_required(
@@ -98,14 +98,14 @@ class AeInitialAction(ActionWithNotification):
98
98
  name = AE_INITIAL_ACTION
99
99
  display_name = "Submit AE Initial Report"
100
100
  notification_display_name = "AE Initial Report"
101
- parent_action_names = [
101
+ parent_action_names = (
102
102
  BLOOD_RESULTS_LIPIDS_ACTION,
103
103
  BLOOD_RESULTS_GLU_ACTION,
104
104
  BLOOD_RESULTS_LFT_ACTION,
105
105
  BLOOD_RESULTS_RFT_ACTION,
106
106
  BLOOD_RESULTS_FBC_ACTION,
107
107
  FOLLOWUP_EXAMINATION_ACTION,
108
- ]
108
+ )
109
109
  reference_model = "meta_ae.aeinitial"
110
110
  show_link_to_changelist = True
111
111
  show_link_to_add = True
@@ -118,7 +118,7 @@ class AeInitialAction(ActionWithNotification):
118
118
 
119
119
  1. Add death report action if death
120
120
  """
121
- next_actions = []
121
+ next_actions = ()
122
122
  deceased = (
123
123
  self.reference_obj.ae_grade == GRADE5 or self.reference_obj.sae_reason.name == DEAD
124
124
  )
@@ -156,20 +156,18 @@ class AeInitialAction(ActionWithNotification):
156
156
  required=self.reference_obj.ae_grade == GRADE4,
157
157
  )
158
158
  # add next AeTmgAction if G3 and is an SAE
159
- next_actions = self.append_to_next_if_required(
159
+ return self.append_to_next_if_required(
160
160
  next_actions=next_actions,
161
161
  action_name=AE_TMG_ACTION,
162
162
  required=(self.reference_obj.ae_grade == GRADE3 and self.reference_obj.sae == YES),
163
163
  )
164
164
 
165
- return next_actions
166
-
167
165
 
168
166
  class AeSusarAction(ActionWithNotification):
169
167
  name = AE_SUSAR_ACTION
170
168
  display_name = "Submit AE SUSAR Report"
171
169
  notification_display_name = "AE SUSAR Report"
172
- parent_action_names = [AE_INITIAL_ACTION]
170
+ parent_action_names = (AE_INITIAL_ACTION,)
173
171
  reference_model = "meta_ae.aesusar"
174
172
  related_reference_model = "meta_ae.aeinitial"
175
173
  related_reference_fk_attr = "ae_initial"
@@ -184,7 +182,7 @@ class AeTmgAction(ActionWithNotification):
184
182
  name = AE_TMG_ACTION
185
183
  display_name = "TMG AE Report pending"
186
184
  notification_display_name = "TMG AE Report"
187
- parent_action_names = [AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION, AE_TMG_ACTION]
185
+ parent_action_names = (AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION, AE_TMG_ACTION)
188
186
  reference_model = "meta_ae.aetmg"
189
187
  related_reference_model = "meta_ae.aeinitial"
190
188
  related_reference_fk_attr = "ae_initial"
@@ -204,13 +202,13 @@ class DeathReportAction(PregnancyActionItemMixin, ActionWithNotification):
204
202
  display_name = "Submit Death Report"
205
203
  notification_display_name = "Death Report"
206
204
  reference_model = "meta_ae.deathreport"
207
- parent_action_names = [AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION]
205
+ parent_action_names = (AE_INITIAL_ACTION, AE_FOLLOWUP_ACTION)
208
206
  show_link_to_changelist = True
209
207
  show_link_to_add = True
210
208
  admin_site_name = "meta_ae_admin"
211
209
  priority = HIGH_PRIORITY
212
210
  singleton = True
213
- dirty_fields = ["cause_of_death"]
211
+ dirty_fields = ("cause_of_death",)
214
212
 
215
213
  def get_next_actions(self):
216
214
  """Adds 1 DEATHReportTMG if not yet created and
@@ -242,7 +240,7 @@ class DeathReportTmgAction(ActionWithNotification):
242
240
  name = DEATH_REPORT_TMG_ACTION
243
241
  display_name = "TMG Death Report pending"
244
242
  notification_display_name = "TMG Death Report"
245
- parent_action_names = [DEATH_REPORT_ACTION, DEATH_REPORT_TMG_ACTION]
243
+ parent_action_names = (DEATH_REPORT_ACTION, DEATH_REPORT_TMG_ACTION)
246
244
  reference_model = "meta_ae.deathreporttmg"
247
245
  related_reference_model = "meta_ae.deathreport"
248
246
  related_reference_fk_attr = "death_report"
@@ -301,12 +299,11 @@ class DeathReportTmgAction(ActionWithNotification):
301
299
  )
302
300
  .count()
303
301
  < 2
302
+ ) and (
303
+ self.reference_obj.cause_of_death
304
+ != self.related_action_item.reference_obj.cause_of_death
304
305
  ):
305
- if (
306
- self.reference_obj.cause_of_death
307
- != self.related_action_item.reference_obj.cause_of_death
308
- ):
309
- next_actions = ["self"]
306
+ next_actions = ["self"]
310
307
  return next_actions
311
308
 
312
309
 
@@ -24,6 +24,6 @@ def format_ae_description(context, ae_initial, wrap_length):
24
24
  context["OTHER"] = OTHER
25
25
  context["YES"] = YES
26
26
  context["ae_initial"] = ae_initial
27
- context["sae_reason"] = mark_safe(formatted_sae_reason) # nosec B308, B703
28
- context["ae_description"] = mark_safe(formatted_ae_description) # nosec B308, B703
27
+ context["sae_reason"] = mark_safe(formatted_sae_reason) # nosec B308, B703 # noqa: S308
28
+ context["ae_description"] = mark_safe(formatted_ae_description) # nosec B308, B703 # noqa: S308
29
29
  return context
@@ -62,8 +62,8 @@ def get_last_imp_visits_df(
62
62
  df_off = df_off.set_index("subject_identifier")
63
63
 
64
64
  df_meds = df_meds.set_index("subject_identifier")
65
- df_final = pd.merge(
66
- df_meds, df_off, left_index=True, right_index=True, how="outer"
65
+ df_final = df_meds.merge(
66
+ df_off, left_index=True, right_index=True, how="outer"
67
67
  ).reset_index()
68
68
 
69
69
  # merge with RandomizationList if lot_obj
@@ -24,5 +24,4 @@ class GlucoseTable(Table):
24
24
  df_tmp = df_tmp.reset_index()
25
25
  gender_tbl = GenderTable(main_df=df_tmp).table_df
26
26
  age_tbl = AgeTable(main_df=df_tmp).table_df
27
- self.table_df = pd.concat([self.table_df, gender_tbl, age_tbl])
28
- self.table_df.reset_index(drop=True, inplace=True)
27
+ self.table_df = pd.concat([self.table_df, gender_tbl, age_tbl]).reset_index(drop=True)
@@ -5,7 +5,6 @@ from .subject_consent import SubjectConsent
5
5
 
6
6
 
7
7
  class SubjectConsentV1(SubjectConsent):
8
-
9
8
  objects = ConsentObjectsByCdefManager()
10
9
  on_site = CurrentSiteByCdefManager()
11
10
  history = HistoricalRecords()
@@ -42,7 +42,7 @@ class SubjectScreeningButton(BaseSubjectScreeningButton):
42
42
 
43
43
  @dataclass
44
44
  class SubjectScreeningPartOneButton(SubjectScreeningButton):
45
- model_obj: ScreeningPartOne = None
45
+ model_obj: ScreeningPartOne | None = None
46
46
  model_cls: type[ScreeningPartOne] = field(default=ScreeningPartOne)
47
47
 
48
48
  @property
@@ -52,7 +52,7 @@ class SubjectScreeningPartOneButton(SubjectScreeningButton):
52
52
 
53
53
  @dataclass
54
54
  class SubjectScreeningPartTwoButton(SubjectScreeningButton):
55
- model_obj: ScreeningPartTwo = None
55
+ model_obj: ScreeningPartTwo | None = None
56
56
  model_cls: type[ScreeningPartTwo] = field(default=ScreeningPartTwo)
57
57
 
58
58
  @property
@@ -84,7 +84,7 @@ class SubjectScreeningPartTwoButton(SubjectScreeningButton):
84
84
 
85
85
  @dataclass
86
86
  class SubjectScreeningPartThreeButton(SubjectScreeningButton):
87
- model_obj: ScreeningPartThree = None
87
+ model_obj: ScreeningPartThree | None = None
88
88
  model_cls: type[ScreeningPartThree] = field(default=ScreeningPartThree)
89
89
 
90
90
  @property
meta_edc/admin.py CHANGED
@@ -18,7 +18,7 @@ class AdminSite(DjangoAdminSite):
18
18
  index_title = "Site administration"
19
19
  site_url = "/administration/"
20
20
 
21
- def __init__(self, **kwargs):
21
+ def __init__(self, **kwargs): # noqa: ARG002
22
22
  super().__init__(name="meta_edc")
23
23
 
24
24
 
meta_edc/celery.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import sys
2
3
 
3
4
  from celery import Celery
4
5
 
@@ -13,4 +14,4 @@ app.autodiscover_tasks()
13
14
 
14
15
  @app.task(bind=True)
15
16
  def debug_task(self):
16
- print(f"Request: {self.request!r}")
17
+ sys.stdout.write(f"Request: {self.request!r}\n")
meta_edc/celery_live.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import sys
2
3
 
3
4
  from celery import Celery
4
5
 
@@ -15,4 +16,4 @@ app.autodiscover_tasks()
15
16
 
16
17
  @app.task(bind=True)
17
18
  def debug_task(self):
18
- print(f"Request: {self.request!r}")
19
+ sys.stdout.write(f"Request: {self.request!r}\n")
meta_edc/celery_uat.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import sys
2
3
 
3
4
  from celery import Celery
4
5
 
@@ -21,4 +22,4 @@ app.autodiscover_tasks()
21
22
 
22
23
  @app.task(bind=True)
23
24
  def debug_task(self):
24
- print(f"Request: {self.request!r}")
25
+ sys.stdout.write(f"Request: {self.request!r}\n")
meta_edc/meta_version.py CHANGED
@@ -3,11 +3,11 @@ PHASE_THREE = 3
3
3
  PHASE_THREE_ONLY = "PHASE_THREE_ONLY"
4
4
 
5
5
 
6
- class InvalidMetaVersion(Exception):
6
+ class InvalidMetaVersion(Exception): # noqa: N818
7
7
  pass
8
8
 
9
9
 
10
10
  def get_meta_version():
11
- from django.conf import settings
11
+ from django.conf import settings # noqa: PLC0415
12
12
 
13
13
  return settings.META_PHASE
meta_edc/navbars.py CHANGED
@@ -12,19 +12,21 @@ from meta_dashboard.navbars import navbar as meta_dashboard_navbar
12
12
 
13
13
  navbar = Navbar(name=settings.APP_NAME)
14
14
 
15
- navbar_item = copy([item for item in lab_navbar.navbar_items if item.name == "specimens"][0])
15
+ navbar_item = copy(next(item for item in lab_navbar.navbar_items if item.name == "specimens"))
16
16
  navbar_item.active = False
17
17
  navbar_item.label = "Specimens"
18
18
  navbar.register(navbar_item)
19
19
 
20
20
  navbar.register(
21
- [item for item in meta_dashboard_navbar.navbar_items if item.name == "screened_subject"][0]
21
+ next(
22
+ item for item in meta_dashboard_navbar.navbar_items if item.name == "screened_subject"
23
+ )
22
24
  )
23
25
 
24
26
  navbar.register(
25
- [item for item in meta_dashboard_navbar.navbar_items if item.name == "consented_subject"][
26
- 0
27
- ]
27
+ next(
28
+ item for item in meta_dashboard_navbar.navbar_items if item.name == "consented_subject"
29
+ )
28
30
  )
29
31
 
30
32
  for navbar_item in review_navbar.navbar_items:
@@ -2,7 +2,7 @@ import os
2
2
  import sys
3
3
  from importlib.metadata import version
4
4
  from pathlib import Path
5
- from urllib.parse import quote
5
+ from urllib.parse import quote, urljoin
6
6
 
7
7
  import django
8
8
  import environ
@@ -48,7 +48,7 @@ else:
48
48
  # copy your .env file from .envs/ to BASE_DIR
49
49
  if "test" in sys.argv:
50
50
  env.read_env(ENV_DIR / ".env-tests")
51
- print(f"Reading env from {(BASE_DIR /'.env-tests')}") # noqa
51
+ print(f"Reading env from {(BASE_DIR / '.env-tests')}") # noqa
52
52
  else:
53
53
  if not (ENV_DIR / ".env").exists():
54
54
  raise FileExistsError(f"Environment file does not exist. Got `{(ENV_DIR / '.env')}`")
@@ -550,7 +550,7 @@ if env("AWS_ENABLED"):
550
550
  AWS_LOCATION = env.str("AWS_LOCATION")
551
551
  AWS_IS_GZIPPED = True
552
552
  STORAGES = {"staticfiles": {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"}}
553
- STATIC_URL = f"{os.path.join(AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)}/"
553
+ STATIC_URL = urljoin(AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
554
554
  STATIC_ROOT = ""
555
555
  elif DEBUG:
556
556
  STATIC_URL = env.str("DJANGO_STATIC_URL")
meta_edc/urls.py CHANGED
@@ -10,7 +10,7 @@ from edc_utils.paths_for_urlpatterns import paths_for_urlpatterns
10
10
  from .views import HomeView
11
11
 
12
12
 
13
- def trigger_error(request):
13
+ def trigger_error(request): # noqa: ARG001
14
14
  division_by_zero = 1 / 0 # noqa
15
15
 
16
16
 
meta_edc/utils.py CHANGED
@@ -1,9 +1,11 @@
1
+ import sys
2
+
1
3
  from django.core.exceptions import ImproperlyConfigured
2
4
 
3
5
 
4
6
  def confirm_meta_version(phase):
5
7
  response = input(f"This is meta phase {phase}. Type 2 or 3 to continue: ")
6
8
  if response not in ["2", "3"]:
7
- print("settings load has been halted.")
9
+ sys.stdout.write("settings load has been halted.\n")
8
10
  raise ImproperlyConfigured("Check settings.META_PHASE")
9
11
  return int(response)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meta-edc
3
- Version: 1.1.13
3
+ Version: 1.1.15
4
4
  Summary: META Trial EDC (https://www.isrctn.com/ISRCTN76157257)
5
5
  Keywords: django,clinicedc,META EDC,EDC,clinical trials,META Trial,ISRCTN76157257
6
6
  Author: Erik van Widenfelt, Jonathan Willitts
@@ -15,13 +15,12 @@ Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Programming Language :: Python :: 3.13
18
- Requires-Dist: clinicedc>=2.0.13
19
- Requires-Dist: edc-he>=1.1.0
20
- Requires-Dist: edc-microscopy>=1.1.1
21
- Requires-Dist: edc-mnsi>=1.1.3
22
- Requires-Dist: edc-phq9>=1.0.1
23
- Requires-Dist: edc-qol>=1.1.2
24
- Requires-Dist: psycopg2>=2.9.10
18
+ Requires-Dist: clinicedc>=2.0.26
19
+ Requires-Dist: edc-he>=1.2.0
20
+ Requires-Dist: edc-microscopy>=1.2.0
21
+ Requires-Dist: edc-mnsi>=1.2.0
22
+ Requires-Dist: edc-phq9>=1.1.0
23
+ Requires-Dist: edc-qol>=1.2.0
25
24
  Requires-Python: >=3.12, <3.14
26
25
  Description-Content-Type: text/x-rst
27
26
 
@@ -89,8 +88,8 @@ Assuming you are logged into the account ``myaccount``:
89
88
  mkdir ~/edc && \
90
89
  cd ~/edc && \
91
90
  uv venv && \
92
- uv pip install -U meta-edc==1.1.12 && \
93
- wget https://raw.githubusercontent.com/meta-trial/meta-edc/1.1.12/manage.py && \
91
+ uv pip install -U meta-edc==1.1.14 && \
92
+ wget https://raw.githubusercontent.com/meta-trial/meta-edc/1.1.14/manage.py && \
94
93
  uv pip freeze | grep meta-edc
95
94
 
96
95
  Copy your ``.env`` file to ``~/.etc``.
@@ -140,7 +139,7 @@ From the above example:
140
139
 
141
140
  cd ~/edc && \
142
141
  uv venv --clear && \
143
- uv pip install -U meta-edc==1.1.12 && \
142
+ uv pip install -U meta-edc==1.1.14 && \
144
143
  wget -O manage.py https://raw.githubusercontent.com/meta-trial/meta-edc/1.1.10/manage.py && \
145
144
  uv pip freeze | grep meta-edc && \
146
145
  python manage.py check