clinicedc 2.0.38__py3-none-any.whl → 2.0.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.

Potentially problematic release.


This version of clinicedc might be problematic. Click here for more details.

Files changed (157) hide show
  1. {clinicedc-2.0.38.dist-info → clinicedc-2.0.40.dist-info}/METADATA +3 -12
  2. {clinicedc-2.0.38.dist-info → clinicedc-2.0.40.dist-info}/RECORD +146 -153
  3. {clinicedc-2.0.38.dist-info → clinicedc-2.0.40.dist-info}/WHEEL +1 -1
  4. edc_adverse_event/dashboard_urls.py +2 -0
  5. edc_adverse_event/middleware.py +7 -6
  6. edc_adverse_event/navbars.py +4 -8
  7. edc_adverse_event/templates/edc_adverse_event/tmg/tmg_ae_listboard_result.html +27 -23
  8. edc_adverse_event/templatetags/edc_adverse_event_extras.py +21 -34
  9. edc_adverse_event/urls.py +14 -6
  10. edc_adverse_event/view_mixins/ae/ae_listboard_view_mixin.py +6 -8
  11. edc_adverse_event/view_mixins/ae/death_report_listboard_view_mixin.py +2 -4
  12. edc_adverse_event/view_mixins/tmg/tmg_ae_listboard_view_mixin.py +9 -7
  13. edc_adverse_event/views/home_view.py +1 -2
  14. edc_adverse_event/views/tmg/death_listboard_view.py +8 -6
  15. edc_adverse_event/views/tmg/home_view.py +4 -3
  16. edc_adverse_event/views/tmg/summary_listboard_view.py +4 -4
  17. edc_appointment/utils.py +3 -6
  18. edc_appointment/views/unscheduled_appointment_view.py +1 -1
  19. edc_consent/form_validators/consent_definition_form_validator_mixin.py +5 -2
  20. edc_consent/model_mixins/consent_version_model_mixin.py +1 -1
  21. edc_consent/navbars.py +2 -1
  22. edc_crf/model_mixins/crf_model_mixin.py +5 -1
  23. edc_crf/model_mixins/crf_no_manager_model_mixin.py +2 -2
  24. edc_crf/model_mixins/singleton_crf_model_mixin.py +1 -1
  25. edc_dashboard/middleware.py +10 -16
  26. edc_dashboard/middleware_mixins.py +10 -0
  27. edc_dashboard/navbars.py +1 -1
  28. edc_dashboard/url_config.py +50 -31
  29. edc_dashboard/url_names.py +23 -17
  30. edc_dashboard/utils.py +4 -4
  31. edc_dashboard/view_mixins/template_request_context_mixin.py +5 -8
  32. edc_dashboard/view_mixins/url_request_context_mixin.py +38 -26
  33. edc_dashboard/views/administration_view.py +2 -2
  34. edc_dashboard/views/dashboard_view.py +5 -10
  35. edc_data_manager/handlers/handlers.py +17 -5
  36. edc_data_manager/models/query_rule.py +7 -7
  37. edc_data_manager/navbar_item.py +1 -1
  38. edc_data_manager/rule/query_rule_wrapper.py +1 -1
  39. edc_data_manager/rule/rule_runner.py +6 -6
  40. edc_device/navbars.py +1 -1
  41. edc_export/navbars.py +2 -2
  42. edc_glucose/model_mixin_factories/fasting_model_mixin_factory.py +1 -1
  43. edc_identifier/identifier.py +6 -9
  44. edc_lab_dashboard/dashboard_urls.py +7 -5
  45. edc_lab_dashboard/middleware.py +10 -17
  46. edc_lab_dashboard/navbars.py +9 -9
  47. edc_lab_dashboard/templates/edc_lab_dashboard/listboard/tags/status_column.html +7 -0
  48. edc_lab_dashboard/urls.py +2 -5
  49. edc_lab_dashboard/view_mixins/form_action_view_mixin.py +1 -2
  50. edc_lab_dashboard/views/action_views/action_view.py +6 -6
  51. edc_lab_dashboard/views/action_views/aliquot_view.py +1 -1
  52. edc_lab_dashboard/views/action_views/manage_box_item_view.py +2 -3
  53. edc_lab_dashboard/views/action_views/manage_manifest_view.py +1 -1
  54. edc_lab_dashboard/views/action_views/manifest_view.py +2 -2
  55. edc_lab_dashboard/views/action_views/pack_view.py +2 -2
  56. edc_lab_dashboard/views/action_views/process_view.py +1 -1
  57. edc_lab_dashboard/views/action_views/receive_view.py +1 -1
  58. edc_lab_dashboard/views/action_views/requisition_view.py +1 -1
  59. edc_lab_dashboard/views/action_views/verify_box_item_view.py +1 -1
  60. edc_lab_dashboard/views/listboard_views/manage_box_listboard_view.py +4 -5
  61. edc_lab_dashboard/views/listboard_views/manifest_listboard_view.py +5 -6
  62. edc_lab_dashboard/views/listboard_views/process_listboard_view.py +4 -5
  63. edc_lab_dashboard/views/listboard_views/receive_listboard_view.py +5 -6
  64. edc_lab_dashboard/views/listboard_views/verify_box_listboard_view.py +5 -6
  65. edc_label/navbars.py +1 -1
  66. edc_list_data/admin.py +3 -3
  67. edc_list_data/load_model_data.py +1 -1
  68. edc_list_data/management/commands/load_list_data.py +2 -2
  69. edc_list_data/site_list_data.py +4 -4
  70. edc_listboard/middleware.py +9 -8
  71. edc_listboard/templates/edc_listboard/listboard.html +1 -1
  72. edc_listboard/view_mixins/listboard_filter_view_mixin.py +1 -1
  73. edc_listboard/view_mixins/search_form_view_mixin.py +1 -1
  74. edc_listboard/views/listboard_view.py +16 -25
  75. edc_listboard/views/screen/screening_listboard_view.py +2 -2
  76. edc_listboard/views/subject/subject_listboard_view.py +2 -2
  77. edc_locator/forms/subject_locator_form_validator.py +2 -2
  78. edc_ltfu/action_items.py +1 -2
  79. edc_ltfu/forms/ltfu_form_validator_mixin.py +3 -3
  80. edc_ltfu/modeladmin_mixin.py +1 -1
  81. edc_ltfu/modelform_mixins.py +2 -2
  82. edc_metadata/admin/modeladmin_mixins.py +11 -9
  83. edc_metadata/management/commands/update_metadata.py +1 -1
  84. edc_metadata/management/commands/update_metadata_schedule_names.py +7 -7
  85. edc_metadata/management/commands/validate_entry_status.py +1 -1
  86. edc_metadata/management/commands/validate_rule_groups.py +1 -1
  87. edc_metadata/metadata/metadata_getter.py +3 -5
  88. edc_metadata/metadata_handler.py +5 -5
  89. edc_metadata/metadata_mixins/source_model_metadata_mixin.py +1 -1
  90. edc_metadata/metadata_refresher.py +1 -1
  91. edc_metadata/metadata_rules/crf/crf_rule.py +1 -1
  92. edc_metadata/metadata_rules/logic.py +3 -3
  93. edc_metadata/metadata_rules/persistant_singleton_mixin.py +2 -4
  94. edc_metadata/metadata_rules/requisition/requisition_rule_group.py +1 -1
  95. edc_metadata/metadata_rules/rule.py +4 -3
  96. edc_metadata/metadata_rules/rule_group.py +2 -2
  97. edc_metadata/metadata_rules/rule_group_meta_options.py +2 -2
  98. edc_metadata/metadata_rules/rule_group_metaclass.py +21 -22
  99. edc_metadata/metadata_rules/site.py +1 -1
  100. edc_metadata/metadata_updater.py +4 -3
  101. edc_metadata/model_mixins/creates/creates_metadata_model_mixin.py +3 -5
  102. edc_metadata/model_mixins/updates/updates_metadata_model_mixin.py +1 -1
  103. edc_metadata/next_form_getter.py +15 -19
  104. edc_metadata/offline_models.py +1 -1
  105. edc_metadata/requisition/requisition_metadata_handler.py +5 -5
  106. edc_metadata/update_metadata_on_schedule_change.py +2 -4
  107. edc_metadata/utils.py +1 -1
  108. edc_model/models/signals.py +7 -2
  109. edc_model_admin/mixins/model_admin_redirect_on_delete_mixin.py +4 -3
  110. edc_navbar/apps.py +0 -2
  111. edc_navbar/navbar.py +1 -1
  112. edc_navbar/navbar_item.py +29 -16
  113. edc_navbar/navbars.py +6 -19
  114. edc_navbar/site_navbars.py +6 -7
  115. edc_navbar/system_checks.py +3 -10
  116. edc_navbar/utils.py +14 -0
  117. edc_navbar/view_mixin.py +6 -9
  118. edc_pharmacy/navbars.py +1 -1
  119. edc_pharmacy/views/confirm_stock_from_queryset_view.py +3 -3
  120. edc_protocol/middleware.py +9 -13
  121. edc_protocol/navbars.py +1 -1
  122. edc_refusal/forms.py +1 -3
  123. edc_reportable/utils/convert_units.py +1 -1
  124. edc_review_dashboard/middleware.py +6 -3
  125. edc_review_dashboard/navbars.py +1 -2
  126. edc_review_dashboard/urls.py +3 -2
  127. edc_review_dashboard/views/subject_review_listboard_view.py +4 -2
  128. edc_subject_dashboard/dashboard_templates.py +1 -3
  129. edc_subject_dashboard/dashboard_urls.py +8 -0
  130. edc_subject_dashboard/middleware.py +10 -7
  131. edc_subject_dashboard/templates/edc_subject_dashboard/buttons/refresh_appointments_button.html +1 -1
  132. edc_subject_dashboard/templates/edc_subject_dashboard/dashboard.html +1 -1
  133. edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +3 -1
  134. edc_subject_dashboard/urls.py +13 -4
  135. edc_subject_dashboard/views/base_requisition_view.py +2 -1
  136. edc_subject_dashboard/views/subject_dashboard_view.py +1 -2
  137. edc_timepoint/__init__.py +0 -2
  138. edc_timepoint/model_mixins.py +1 -2
  139. edc_timepoint/utils.py +1 -1
  140. edc_timepoint/visit_timepoint_lookup.py +6 -0
  141. edc_visit_schedule/admin/subject_schedule_history_admin.py +1 -2
  142. edc_visit_schedule/navbars.py +3 -4
  143. edc_visit_schedule/visit/visit.py +15 -0
  144. edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_mixin.py +5 -0
  145. edc_visit_tracking/models/subject_visit.py +5 -0
  146. edc_lab_dashboard/model_wrappers/__init__.py +0 -8
  147. edc_lab_dashboard/model_wrappers/aliquot_model_wrapper.py +0 -31
  148. edc_lab_dashboard/model_wrappers/base_box_item_model_wrapper.py +0 -21
  149. edc_lab_dashboard/model_wrappers/box_model_wrapper.py +0 -12
  150. edc_lab_dashboard/model_wrappers/manage_box_item_model_wrapper.py +0 -6
  151. edc_lab_dashboard/model_wrappers/manifest_item_model_wrapper.py +0 -21
  152. edc_lab_dashboard/model_wrappers/manifest_model_wrapper.py +0 -11
  153. edc_lab_dashboard/model_wrappers/requisition_model_wrapper.py +0 -25
  154. edc_lab_dashboard/model_wrappers/result_model_wrapper.py +0 -8
  155. edc_lab_dashboard/model_wrappers/verify_box_model_wrapper.py +0 -10
  156. edc_navbar/get_default_navbar.py +0 -9
  157. {clinicedc-2.0.38.dist-info → clinicedc-2.0.40.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.23
2
+ Generator: uv 0.9.5
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,3 +1,5 @@
1
+ """These have nothing to do with url_names dictionary"""
2
+
1
3
  dashboard_urls = dict(
2
4
  ae_home_url="edc_adverse_event:ae_home_url",
3
5
  tmg_home_url="edc_adverse_event:tmg_home_url",
@@ -1,22 +1,23 @@
1
+ from edc_dashboard.middleware_mixins import EdcTemplateMiddlewareMixin
2
+
1
3
  from .dashboard_templates import dashboard_templates
2
4
  from .dashboard_urls import dashboard_urls
3
5
 
4
6
 
5
- class DashboardMiddleware:
7
+ class DashboardMiddleware(EdcTemplateMiddlewareMixin):
6
8
  def __init__(self, get_response):
7
9
  self.get_response = get_response
8
10
 
9
11
  def __call__(self, request):
10
- response = self.get_response(request)
11
- return response
12
+ self.check_for_required_request_attrs(request)
13
+ return self.get_response(request)
12
14
 
13
15
  def process_view(self, request, *args):
14
16
  request.url_name_data.update(**dashboard_urls)
15
- template_data = dashboard_templates
16
- request.template_data.update(**template_data)
17
+ request.template_data.update(**dashboard_templates)
17
18
 
18
19
  def process_template_response(self, request, response):
19
- if response.context_data:
20
+ if getattr(response, "context_data", None):
20
21
  response.context_data.update(**request.url_name_data)
21
22
  response.context_data.update(**request.template_data)
22
23
  return response
@@ -1,24 +1,20 @@
1
- from django.conf import settings
2
-
3
1
  from edc_navbar import Navbar, NavbarItem, site_navbars
4
2
 
5
- no_url_namespace = True if settings.APP_NAME == "edc_adverse_event" else False
6
-
7
3
  ae_navbar_item = NavbarItem(
8
4
  name="ae_home",
9
5
  title="Adverse Events",
10
6
  label="AE",
11
7
  codename="edc_adverse_event.nav_ae_section",
12
- url_name="edc_adverse_event:ae_home_url",
13
- no_url_namespace=no_url_namespace,
8
+ url_names_key="ae_home_url",
9
+ url_with_namespace="edc_adverse_event:ae_home_url",
14
10
  )
15
11
 
16
12
  tmg_navbar_item = NavbarItem(
17
13
  name="tmg_home",
18
14
  label="TMG",
19
15
  codename="edc_adverse_event.nav_tmg_section",
20
- url_name="edc_adverse_event:tmg_home_url",
21
- no_url_namespace=no_url_namespace,
16
+ url_names_key="tmg_home_url",
17
+ url_with_namespace="edc_adverse_event:tmg_home_url",
22
18
  )
23
19
 
24
20
  ae_navbar = Navbar(name="edc_adverse_event")
@@ -13,12 +13,15 @@
13
13
  {% has_perms_for_tmg_role as may_access_page %}
14
14
  {% if may_access_page %}
15
15
  {% for result in results %}
16
+ {% with results_loop=forloop %}
16
17
  <div class="panel panel-default">
17
18
  <div class="panel-heading clearfix">
18
- <span class="badge">{{ forloop.counter }}</span> <span class="text text-uppercase">{{ result.subject_identifier }}</span> {% copy_string_to_clipboard_button result.subject_identifier %} <span class="text text-muted small">{{ utc_date|timeuntil:result.report_datetime.date }} ago</span>
19
+ <span class="badge">{{ results_loop.counter }}</span> <span class="text text-uppercase">{{ result.subject_identifier }}</span> {% copy_string_to_clipboard_button result.subject_identifier %} <span class="text text-muted small">{{ utc_date|timeuntil:result.report_datetime.date }} ago</span>
19
20
  <span class="pull-right">
20
21
  <div class="btn-group">
21
- <a class="btn btn-sm btn-default" role="button" title="Go to action item" href="{{ result.get_absolute_url }}?next={{ listboard_filter_url }},subject_identifier&subject_identifier={{ result.subject_identifier }}">{{ result.identifier }}</a>
22
+ {% if result.identifier %}
23
+ <a class="btn btn-sm btn-default" role="button" title="Go to action item" href="{{ result.get_absolute_url }}?next={{ listboard_filter_url }},subject_identifier&subject_identifier={{ result.subject_identifier }}">{{ result.identifier }}</a>
24
+ {% endif %}
22
25
  <a class="btn btn-sm btn-primary" role="button" title="go to list of reported visits for this subject" href="{% url subject_review_listboard_url|default:"subject_review_listboard_url_cannot_be_none" subject_identifier=result.subject_identifier %}?q={{ result.subject_identifier }}">Subject Review <i class="fas fa-share fa-fw"></i></a>
23
26
  </div>
24
27
  </span>
@@ -30,19 +33,18 @@
30
33
  <div class="list-group">
31
34
  <div class="list-group-item list-group-item-default"><i class="fa-solid fa-folder-tree fa-fw"></i> TMG documents in workflow </div>
32
35
 
33
- {# {% render_tmg_panel action_item=result by_user_created_only=True counter=forloop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %} #}
36
+ {# {% render_tmg_panel action_item=result by_user_created_only=True counter=results_loop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %} #}
34
37
 
35
38
  {# AE TMG #}
36
- {% ae_tmg_queryset subject_identifier=result.subject_identifier as qs %}
37
- {% if qs.count == 0 %}
38
- {% ae_tmg_action_item subject_identifier=result.subject_identifier as tmg_action_item %}
39
- {% if tmg_action_item %}
40
- {% render_tmg_panel action_item=tmg_action_item by_user_created_only=True counter=forloop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %}
41
- {% endif %}
42
- {% else %}
43
- {% for ae_tmg in qs %}
44
- {% render_tmg_panel reference_obj=ae_tmg by_user_created_only=True counter=forloop.counter next_url_name=listboard_filter_url %}
45
- {% endfor %}
39
+ {% ae_tmg_action_item_queryset result.subject_identifier status as ae_tmg_action_item_qs %}
40
+ {% for ae_tmg_action_item in ae_tmg_action_item_qs %}
41
+ {% render_tmg_panel action_item=ae_tmg_action_item by_user_created_only=True counter=results_loop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %}
42
+ {% endfor %}
43
+ {% if status != NEW %}
44
+ {% ae_tmg_queryset subject_identifier=result.subject_identifier as ae_tmg_qs %}
45
+ {% for ae_tmg in ae_tmg_qs %}
46
+ {% render_tmg_panel reference_obj=ae_tmg by_user_created_only=True counter=results_loop.counter next_url_name=listboard_filter_url %}
47
+ {% endfor %}
46
48
  {% endif %}
47
49
 
48
50
  {# DEATH REPORT TMG #}
@@ -50,11 +52,11 @@
50
52
  {% if qs.count == 0 %}
51
53
  {% death_report_tmg_action_item subject_identifier=result.subject_identifier as tmg_action_item %}
52
54
  {% if tmg_action_item %}
53
- {% render_tmg_panel action_item=tmg_action_item by_user_created_only=True counter=forloop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %}
55
+ {% render_tmg_panel action_item=tmg_action_item by_user_created_only=True counter=results_loop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %}
54
56
  {% endif %}
55
57
  {% else %}
56
58
  {% for death_report_tmg in qs %}
57
- {% render_tmg_panel reference_obj=death_report_tmg by_user_created_only=True counter=forloop.counter next_url_name=listboard_filter_url %}
59
+ {% render_tmg_panel reference_obj=death_report_tmg by_user_created_only=True counter=results_loop.counter next_url_name=listboard_filter_url %}
58
60
  {% endfor %}
59
61
  {% endif %}
60
62
 
@@ -63,11 +65,11 @@
63
65
  {% if qs.count == 0 %}
64
66
  {% death_report_tmg_second_action_item subject_identifier=result.subject_identifier as tmg_action_item %}
65
67
  {% if tmg_action_item %}
66
- {% render_tmg_panel action_item=tmg_action_item by_user_created_only=True counter=forloop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %}
68
+ {% render_tmg_panel action_item=tmg_action_item by_user_created_only=True counter=results_loop.counter report_status=result.reference_obj.report_status next_url_name=listboard_filter_url %}
67
69
  {% endif %}
68
70
  {% else %}
69
71
  {% for death_report_tmg in qs %}
70
- {% render_tmg_panel reference_obj=death_report_tmg by_user_created_only=True counter=forloop.counter next_url_name=listboard_filter_url %}
72
+ {% render_tmg_panel reference_obj=death_report_tmg by_user_created_only=True counter=results_loop.counter next_url_name=listboard_filter_url %}
71
73
  {% endfor %}
72
74
  {% endif %}
73
75
 
@@ -80,12 +82,13 @@
80
82
  <div class="list-group">
81
83
  {# AE INTIAL #}
82
84
  <div class="list-group-item"><i class="fa-regular fa-file fa-fw"></i> First document in workflow</div>
83
- {% if result.parent_action_item %}
84
- {% render_tmg_panel action_item=result.parent_action_item counter=forloop.counter next_url_name=listboard_filter_url %}
85
+ {% ae_tmg_action_item_queryset result.subject_identifier status as ae_tmg_action_item_qs %}
86
+ {% for ae_tmg_action_item in ae_tmg_action_item_qs %}
87
+ {% render_tmg_panel action_item=ae_tmg_action_item.parent_action_item counter=results_loop.counter next_url_name=listboard_filter_url %}
88
+ {% endfor %}
85
89
  {% if result.related_action_item and result.parent_action_item.reference_obj.action_identifier != result.related_action_item.reference_obj.action_identifier %}
86
- {% render_tmg_panel action_item=result.related_action_item counter=forloop.counter next_url_name=listboard_filter_url %}
90
+ {% render_tmg_panel action_item=result.related_action_item counter=results_loop.counter next_url_name=listboard_filter_url %}
87
91
  {% endif %}
88
- {% endif %}
89
92
  </div>
90
93
  </div>
91
94
 
@@ -97,12 +100,12 @@
97
100
  {% ae_followup_queryset ae_initial=result.parent_action_item.reference_obj as qs %}
98
101
  {% if qs.count == 0 %}<div class="list-group-item">There are no follow-ups to this AE</div>{% endif %}
99
102
  {% for ae_followup in qs %}
100
- {% render_tmg_panel reference_obj=ae_followup counter=forloop.counter next_url_name=listboard_filter_url %}
103
+ {% render_tmg_panel reference_obj=ae_followup counter=results_loop.counter next_url_name=listboard_filter_url %}
101
104
  {% endfor %}
102
105
 
103
106
  {% death_report_queryset subject_identifier=result.subject_identifier as qs %}
104
107
  {% for death_report in qs %}
105
- {% render_tmg_panel reference_obj=death_report counter=forloop.counter next_url_name=listboard_filter_url %}
108
+ {% render_tmg_panel reference_obj=death_report counter=results_loop.counter next_url_name=listboard_filter_url %}
106
109
  {% endfor %}
107
110
  </div>
108
111
 
@@ -110,6 +113,7 @@
110
113
  </div>
111
114
  </div>
112
115
  </div>
116
+ {% endwith %}
113
117
  {% endfor %}
114
118
  {% else %}
115
119
  <div class="alert alert-danger">
@@ -88,15 +88,13 @@ def format_ae_description(context, ae_initial, wrap_length):
88
88
  context["YES"] = YES
89
89
  context["ae_initial"] = ae_initial
90
90
  try:
91
- context["sae_reason"] = format_html(
92
- "{}",
93
- mark_safe(wrapx(escape_braces(ae_initial.sae_reason.name), wrap_length)), # nosec B703, B308
91
+ context["sae_reason"] = mark_safe( # noqa: S308
92
+ wrapx(escape_braces(ae_initial.sae_reason.name), wrap_length)
94
93
  )
95
94
  except AttributeError:
96
95
  context["sae_reason"] = ""
97
- context["ae_description"] = format_html(
98
- "{}",
99
- mark_safe(wrapx(escape_braces(ae_initial.ae_description), wrap_length)), # nosec B703, B308
96
+ context["ae_description"] = mark_safe(
97
+ wrapx(escape_braces(ae_initial.ae_description), wrap_length)
100
98
  )
101
99
  return context
102
100
 
@@ -111,11 +109,8 @@ def format_ae_followup_description(context, ae_followup, wrap_length):
111
109
  context["ae_followup"] = ae_followup
112
110
  context["ae_initial"] = ae_followup.ae_initial
113
111
  try:
114
- context["sae_reason"] = format_html(
115
- "{}",
116
- mark_safe(
117
- wrapx(escape_braces(ae_followup.ae_initial.sae_reason.name), wrap_length)
118
- ), # nosec B703, B308
112
+ context["sae_reason"] = mark_safe( # noqa: S308
113
+ wrapx(escape_braces(ae_followup.ae_initial.sae_reason.name), wrap_length)
119
114
  )
120
115
  except AttributeError:
121
116
  context["sae_reason"] = ""
@@ -177,55 +172,47 @@ def render_death_report_tmg_panel(context, action_item: ActionItem = None):
177
172
 
178
173
 
179
174
  @register.simple_tag
180
- def ae_tmg_queryset(subject_identifier: str = None) -> QuerySet[DeathReportTmgModel]:
175
+ def ae_tmg_queryset(subject_identifier) -> QuerySet[DeathReportTmgModel]:
181
176
  return get_ae_model("aetmg").objects.filter(subject_identifier=subject_identifier)
182
177
 
183
178
 
184
179
  @register.simple_tag
185
- def death_report_tmg_queryset(
186
- subject_identifier: str = None,
187
- ) -> QuerySet[DeathReportTmgModel]:
180
+ def death_report_tmg_queryset(subject_identifier: str) -> QuerySet[DeathReportTmgModel]:
188
181
  return get_ae_model("deathreporttmg").objects.filter(subject_identifier=subject_identifier)
189
182
 
190
183
 
191
184
  @register.simple_tag
192
- def death_report_tmg2_queryset(
193
- subject_identifier: str = None,
194
- ) -> QuerySet[DeathReportTmgSecondModel]:
185
+ def death_report_tmg2_queryset(subject_identifier: str) -> QuerySet[DeathReportTmgSecondModel]:
195
186
  return get_ae_model("deathreporttmgsecond").objects.filter(
196
187
  subject_identifier=subject_identifier
197
188
  )
198
189
 
199
190
 
200
191
  @register.simple_tag
201
- def death_report_queryset(
202
- subject_identifier: str = None,
203
- ) -> QuerySet[DeathReportTmgSecondModel]:
192
+ def death_report_queryset(subject_identifier: str) -> QuerySet[DeathReportTmgSecondModel]:
204
193
  return get_ae_model("deathreport").objects.filter(subject_identifier=subject_identifier)
205
194
 
206
195
 
207
196
  @register.simple_tag
208
197
  def ae_followup_queryset(
209
198
  ae_initial: AeInitialModel = None,
210
- ) -> QuerySet[AeFollowupModel] | None:
199
+ ) -> QuerySet[AeFollowupModel]:
211
200
  if ae_initial:
212
201
  return get_ae_model("aefollowup").objects.filter(ae_initial_id=ae_initial.id)
213
- return None
202
+ return get_ae_model("aefollowup").objects.none()
214
203
 
215
204
 
216
205
  @register.simple_tag
217
- def ae_tmg_action_item(subject_identifier: str = None) -> ActionItem:
218
- try:
219
- obj = django_apps.get_model("edc_action_item.actionitem").objects.get(
220
- subject_identifier=subject_identifier, action_type__name=AE_TMG_ACTION
221
- )
222
- except ObjectDoesNotExist:
223
- obj = None
224
- return obj
206
+ def ae_tmg_action_item_queryset(subject_identifier: str, *status) -> QuerySet[ActionItem]:
207
+ return django_apps.get_model("edc_action_item.actionitem").objects.filter(
208
+ subject_identifier=subject_identifier,
209
+ action_type__name=AE_TMG_ACTION,
210
+ status__in=status,
211
+ )
225
212
 
226
213
 
227
214
  @register.simple_tag
228
- def death_report_tmg_action_item(subject_identifier: str = None) -> ActionItem:
215
+ def death_report_tmg_action_item(subject_identifier: str) -> ActionItem:
229
216
  try:
230
217
  obj = django_apps.get_model("edc_action_item.actionitem").objects.get(
231
218
  subject_identifier=subject_identifier,
@@ -237,7 +224,7 @@ def death_report_tmg_action_item(subject_identifier: str = None) -> ActionItem:
237
224
 
238
225
 
239
226
  @register.simple_tag
240
- def death_report_tmg_second_action_item(subject_identifier: str = None) -> ActionItem:
227
+ def death_report_tmg_second_action_item(subject_identifier: str) -> ActionItem:
241
228
  try:
242
229
  obj = django_apps.get_model("edc_action_item.actionitem").objects.get(
243
230
  subject_identifier=subject_identifier,
@@ -265,7 +252,7 @@ def render_tmg_panel(
265
252
  reference_obj = reference_obj or get_reference_obj(action_item)
266
253
  if not action_item and reference_obj:
267
254
  action_item = reference_obj.action_item
268
- disable_all = True if not has_valid_tmg_perms(request=context["request"]) else False
255
+ disable_all = bool(not has_valid_tmg_perms(request=context["request"]))
269
256
  if action_item:
270
257
  params = dict(
271
258
  user=context["request"].user,
edc_adverse_event/urls.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from django.urls.conf import path
2
-
2
+ from edc_dashboard.url_names import url_names
3
3
  from edc_protocol.research_protocol_config import ResearchProtocolConfig
4
4
 
5
5
  from .admin_site import edc_adverse_event_admin
@@ -18,27 +18,32 @@ app_name = "edc_adverse_event"
18
18
 
19
19
  urlpatterns = NewTmgAeListboardView.urls(
20
20
  namespace=app_name,
21
- label="new_tmg_ae_listboard",
21
+ url_names_key="new_tmg_ae_listboard_url",
22
+ identifier_label="subject_identifier",
22
23
  identifier_pattern=ResearchProtocolConfig().subject_identifier_pattern,
23
24
  )
24
25
  urlpatterns += OpenTmgAeListboardView.urls(
25
26
  namespace=app_name,
26
- label="open_tmg_ae_listboard",
27
+ url_names_key="open_tmg_ae_listboard_url",
28
+ identifier_label="subject_identifier",
27
29
  identifier_pattern=ResearchProtocolConfig().subject_identifier_pattern,
28
30
  )
29
31
  urlpatterns += ClosedTmgAeListboardView.urls(
30
32
  namespace=app_name,
31
- label="closed_tmg_ae_listboard",
33
+ url_names_key="closed_tmg_ae_listboard_url",
34
+ identifier_label="subject_identifier",
32
35
  identifier_pattern=ResearchProtocolConfig().subject_identifier_pattern,
33
36
  )
34
37
  urlpatterns += TmgDeathListboardView.urls(
35
38
  namespace=app_name,
36
- label="tmg_death_listboard",
39
+ url_names_key="tmg_death_listboard_url",
40
+ identifier_label="subject_identifier",
37
41
  identifier_pattern=ResearchProtocolConfig().subject_identifier_pattern,
38
42
  )
39
43
  urlpatterns += TmgSummaryListboardView.urls(
40
44
  namespace=app_name,
41
- label="tmg_summary_listboard",
45
+ url_names_key="tmg_summary_listboard_url",
46
+ identifier_label="subject_identifier",
42
47
  identifier_pattern=ResearchProtocolConfig().subject_identifier_pattern,
43
48
  )
44
49
  urlpatterns += [
@@ -47,3 +52,6 @@ urlpatterns += [
47
52
  path("admin/", edc_adverse_event_admin.urls),
48
53
  path("", AeHomeView.as_view(), name="home_url"),
49
54
  ]
55
+
56
+ url_names.register(key="tmg_home_url", url_with_namespace=f"{app_name}:tmg_home_url")
57
+ url_names.register(key="ae_home_url", url_with_namespace=f"{app_name}:ae_home_url")
@@ -9,6 +9,7 @@ from django.utils.html import format_html
9
9
  from django.utils.safestring import mark_safe
10
10
 
11
11
  from edc_constants.constants import CLOSED, NEW, OPEN
12
+ from edc_dashboard.url_names import url_names
12
13
  from edc_dashboard.view_mixins import EdcViewMixin
13
14
  from edc_listboard.view_mixins import ListboardFilterViewMixin, SearchFormViewMixin
14
15
  from edc_listboard.views import ListboardView as BaseListboardView
@@ -49,16 +50,16 @@ class AeListboardViewMixin(
49
50
  ordering = "-report_datetime"
50
51
  paginate_by = 25
51
52
  search_form_url = "ae_listboard_url"
52
- action_type_names = [AE_INITIAL_ACTION]
53
+ action_type_names = (AE_INITIAL_ACTION, )
53
54
 
54
- search_fields = [
55
+ search_fields = (
55
56
  "subject_identifier",
56
57
  "action_identifier",
57
58
  "parent_action_item__action_identifier",
58
59
  "related_action_item__action_identifier",
59
60
  "user_created",
60
61
  "user_modified",
61
- ]
62
+ )
62
63
 
63
64
  @property
64
65
  def ae_initial_model_cls(self):
@@ -77,10 +78,7 @@ class AeListboardViewMixin(
77
78
  kwargs.update(
78
79
  AE_INITIAL_ACTION=AE_INITIAL_ACTION,
79
80
  utc_date=timezone.now().date(),
80
- **self.add_url_to_context(
81
- new_key="ae_home_url",
82
- existing_key=self.home_url,
83
- ),
81
+ **{"ae_home_url": url_names.get(self.home_url)},
84
82
  )
85
83
  return super().get_context_data(**kwargs)
86
84
 
@@ -98,7 +96,7 @@ class AeListboardViewMixin(
98
96
  pks = []
99
97
  for obj in queryset:
100
98
  try:
101
- obj.reference_obj
99
+ obj.reference_obj # noqa: B018
102
100
  except ObjectDoesNotExist:
103
101
  pks.append(obj.pk)
104
102
  return queryset.exclude(pk__in=pks)
@@ -8,6 +8,7 @@ from django.utils.html import format_html
8
8
  from django.utils.safestring import mark_safe
9
9
 
10
10
  from edc_constants.constants import CLOSED, NEW, OPEN
11
+ from edc_dashboard.url_names import url_names
11
12
  from edc_dashboard.view_mixins import EdcViewMixin
12
13
  from edc_listboard.view_mixins import ListboardFilterViewMixin, SearchFormViewMixin
13
14
  from edc_listboard.views import ListboardView as BaseListboardView
@@ -70,10 +71,7 @@ class DeathReportListboardViewMixin(
70
71
  kwargs.update(
71
72
  DEATH_REPORT_ACTION=DEATH_REPORT_ACTION,
72
73
  utc_date=timezone.now().date(),
73
- **self.add_url_to_context(
74
- new_key="ae_home_url",
75
- existing_key=self.home_url,
76
- ),
74
+ **{"ae_home_url": url_names.get(self.home_url)},
77
75
  )
78
76
  return super().get_context_data(**kwargs)
79
77
 
@@ -4,13 +4,13 @@ from typing import TYPE_CHECKING, Any
4
4
 
5
5
  from django.db.models import Min
6
6
  from django.utils import timezone
7
-
8
7
  from edc_constants.constants import CLOSED, NEW, OPEN
9
8
  from edc_dashboard.view_mixins import EdcViewMixin
9
+ from edc_export.constants import CANCELLED
10
10
  from edc_listboard.view_mixins import ListboardFilterViewMixin, SearchFormViewMixin
11
11
  from edc_listboard.views import ListboardView as BaseListboardView
12
12
  from edc_navbar import NavbarViewMixin
13
- from edc_navbar.get_default_navbar import get_default_navbar
13
+ from edc_navbar.utils import get_default_navbar_name
14
14
 
15
15
  from ...constants import (
16
16
  AE_TMG_ACTION,
@@ -46,29 +46,31 @@ class TmgAeListboardViewMixin(
46
46
  listboard_panel_title = "TMG: AE Reports"
47
47
  listboard_view_permission_codename = "edc_adverse_event.view_tmg_listboard"
48
48
 
49
- navbar_name = get_default_navbar()
49
+ navbar_name = get_default_navbar_name()
50
50
  navbar_selected_item = "tmg_home"
51
51
  ordering = "-report_datetime"
52
52
  paginate_by = 10
53
53
  search_form_url = "tmg_ae_listboard_url"
54
- action_type_names = [
54
+ action_type_names = (
55
55
  AE_TMG_ACTION,
56
56
  DEATH_REPORT_TMG_ACTION,
57
57
  DEATH_REPORT_TMG_SECOND_ACTION,
58
- ]
58
+ )
59
59
 
60
- search_fields = [
60
+ search_fields = (
61
61
  "subject_identifier",
62
62
  "action_identifier",
63
63
  "parent_action_item__action_identifier",
64
64
  "related_action_item__action_identifier",
65
65
  "user_created",
66
66
  "user_modified",
67
- ]
67
+ )
68
68
 
69
69
  def get_context_data(self, **kwargs) -> dict[str, Any]:
70
70
  kwargs.update(
71
71
  AE_TMG_ACTION=AE_TMG_ACTION,
72
+ NEW=NEW,
73
+ CANCELLED=CANCELLED,
72
74
  utc_date=timezone.now().date(),
73
75
  subject_identifier=self.kwargs.get("subject_identifier"),
74
76
  )
@@ -2,7 +2,6 @@ from typing import Any
2
2
 
3
3
  from django.urls import reverse
4
4
  from django.views.generic import TemplateView
5
-
6
5
  from edc_dashboard.url_names import url_names
7
6
  from edc_dashboard.view_mixins import EdcViewMixin, UrlRequestContextMixin
8
7
  from edc_navbar import NavbarViewMixin
@@ -37,6 +36,6 @@ class AeHomeView(UrlRequestContextMixin, EdcViewMixin, NavbarViewMixin, Template
37
36
  ae_initial_changelist_url=ae_initial_changelist_url,
38
37
  death_report_changelist_url=death_report_changelist_url,
39
38
  death_report_listboard_url=death_report_listboard_url,
40
- **self.add_url_to_context(new_key="ae_home_url", existing_key=self.url_name),
39
+ **{self.url_name: url_names.get(self.url_name)},
41
40
  )
42
41
  return super().get_context_data(**kwargs)
@@ -5,7 +5,6 @@ from typing import Any
5
5
 
6
6
  from django.db.models import Q
7
7
 
8
- from edc_dashboard.url_names import url_names
9
8
  from edc_dashboard.view_mixins import EdcViewMixin
10
9
  from edc_listboard.view_mixins import ListboardFilterViewMixin, SearchFormViewMixin
11
10
  from edc_listboard.views import ListboardView as BaseListboardView
@@ -21,10 +20,11 @@ class DeathListboardView(
21
20
  SearchFormViewMixin,
22
21
  BaseListboardView,
23
22
  ):
23
+ subject_dashboard_url_name = "subject_dashboard_url" # see url_names
24
24
  listboard_back_url = "tmg_home_url"
25
25
 
26
26
  listboard_template = "tmg_death_listboard_template"
27
- listboard_url = "tmg_death_listboard_url"
27
+ listboard_url = "tmg_death_listboard_url" # url_name
28
28
  listboard_panel_style = "warning"
29
29
  listboard_model = f"{get_adverse_event_app_label()}.deathreport"
30
30
  listboard_model_manager_name = "objects"
@@ -33,18 +33,20 @@ class DeathListboardView(
33
33
  navbar_selected_item = "tmg_home"
34
34
  ordering = "-created"
35
35
  paginate_by = 25
36
- search_form_url = "tmg_death_listboard_url"
37
- search_fields = [
36
+ search_form_url = "tmg_death_listboard_url" # url_name
37
+ search_fields = (
38
38
  "subject_identifier",
39
39
  "action_identifier",
40
40
  "parent_action_item__action_identifier",
41
41
  "related_action_item__action_identifier",
42
42
  "user_created",
43
43
  "user_modified",
44
- ]
44
+ )
45
45
 
46
46
  def get_context_data(self, **kwargs) -> dict[str, Any]:
47
- kwargs.update({"subject_dashboard_url": url_names.get("subject_dashboard_url")})
47
+ # kwargs.update(
48
+ # {"subject_dashboard_url": url_names.get(self.subject_dashboard_url_name)}
49
+ # )
48
50
  if self.kwargs.get("subject_identifier"):
49
51
  kwargs.update({"q": self.kwargs.get("subject_identifier")})
50
52
  return super().get_context_data(**kwargs)
@@ -38,9 +38,10 @@ class TmgHomeView(EdcViewMixin, NavbarViewMixin, TemplateView):
38
38
  .values("status", "site__name")
39
39
  .annotate(items=Count("status"))
40
40
  )
41
- notices = []
42
- for item in qs.order_by("status", "site__name"):
43
- notices.append([item.get("site__name"), item.get("status"), item.get("items")])
41
+ notices = [
42
+ (item.get("site__name"), item.get("status"), item.get("items"))
43
+ for item in qs.order_by("status", "site__name")
44
+ ]
44
45
  new_count = ActionItem.objects.filter(
45
46
  action_type__name=AE_TMG_ACTION,
46
47
  site__name=get_current_site(request=self.request).name,
@@ -42,20 +42,20 @@ class SummaryListboardView(
42
42
  ordering = "-report_datetime"
43
43
  paginate_by = 25
44
44
  search_form_url = "tmg_summary_listboard_url"
45
- action_type_names = [
45
+ action_type_names = (
46
46
  AE_TMG_ACTION,
47
47
  DEATH_REPORT_TMG_ACTION,
48
48
  DEATH_REPORT_ACTION,
49
49
  AE_FOLLOWUP_ACTION,
50
- ]
51
- search_fields = [
50
+ )
51
+ search_fields = (
52
52
  "subject_identifier",
53
53
  "action_identifier",
54
54
  "parent_action_item__action_identifier",
55
55
  "related_action_item__action_identifier",
56
56
  "user_created",
57
57
  "user_modified",
58
- ]
58
+ )
59
59
 
60
60
  def get_context_data(self, **kwargs) -> dict[str, Any]:
61
61
  kwargs.update(AE_TMG_ACTION=AE_TMG_ACTION, utc_date=timezone.now().date())
edc_appointment/utils.py CHANGED
@@ -23,7 +23,6 @@ from django.db import transaction
23
23
  from django.db.models import Count, ProtectedError
24
24
  from django.urls import reverse
25
25
  from django.utils.translation import gettext as _
26
-
27
26
  from edc_constants.constants import CLINIC, NOT_APPLICABLE, OK
28
27
  from edc_constants.constants import ERROR as ERROR_CODE
29
28
  from edc_dashboard.url_names import url_names
@@ -67,7 +66,6 @@ if TYPE_CHECKING:
67
66
  from decimal import Decimal
68
67
 
69
68
  from django.db.models import QuerySet
70
-
71
69
  from edc_crf.model_mixins import CrfModelMixin as Base
72
70
  from edc_metadata.model_mixins.creates import CreatesMetadataModelMixin
73
71
 
@@ -709,9 +707,8 @@ def skip_appointment(appointment: Appointment, comment: str | None = None):
709
707
 
710
708
  def get_unscheduled_appointment_url(appointment: Appointment = None) -> str:
711
709
  """Returns a url for the unscheduled appointment."""
712
- dashboard_url_name = "subject_dashboard_url"
713
- dashboard_url = url_names.get(dashboard_url_name)
714
- unscheduled_appointment_url_name = "edc_appointment:unscheduled_appointment_url"
710
+ dashboard_url = url_names.get("subject_dashboard_url")
711
+ unscheduled_appointment_url = "edc_appointment:unscheduled_appointment_url"
715
712
  kwargs = dict(
716
713
  subject_identifier=appointment.subject_identifier,
717
714
  visit_schedule_name=appointment.visit_schedule_name,
@@ -722,7 +719,7 @@ def get_unscheduled_appointment_url(appointment: Appointment = None) -> str:
722
719
  )
723
720
  kwargs.update(visit_code_sequence=str(appointment.visit_code_sequence + 1))
724
721
  kwargs.update(redirect_url=dashboard_url)
725
- return reverse(unscheduled_appointment_url_name, kwargs=kwargs)
722
+ return reverse(unscheduled_appointment_url, kwargs=kwargs)
726
723
 
727
724
 
728
725
  def update_appt_status_for_timepoint(related_visit: RelatedVisitModel) -> None:
@@ -27,7 +27,7 @@ class UnscheduledAppointmentView(View):
27
27
  """
28
28
 
29
29
  unscheduled_appointment_cls = UnscheduledAppointmentCreator
30
- dashboard_template = "subject_dashboard_template"
30
+ dashboard_template_name = "subject_dashboard_template"
31
31
 
32
32
  def get(self, request, *args, **kwargs): # noqa: ARG002
33
33
  kwargs["suggested_visit_code_sequence"] = int(kwargs["visit_code_sequence"])