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,3 +1,8 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
4
+ from typing import TYPE_CHECKING
5
+
1
6
  import arrow
2
7
  from django.conf import settings
3
8
  from django.core.exceptions import ObjectDoesNotExist
@@ -15,6 +20,12 @@ from edc_visit_tracking.utils import (
15
20
  from ..constants import AUTO_RESOLVED
16
21
  from ..models import DataQuery
17
22
 
23
+ if TYPE_CHECKING:
24
+ from edc_registration.models import RegisteredSubject
25
+ from edc_visit_schedule.visit_schedule import VisitSchedule
26
+
27
+ from ..models import QueryRule
28
+
18
29
 
19
30
  class QueryRuleHandlerError(Exception):
20
31
  pass
@@ -57,11 +68,12 @@ class QueryRuleHandler:
57
68
 
58
69
  def __init__(
59
70
  self,
60
- query_rule_obj=None,
61
- registered_subject=None,
62
- visit_schedule_obj=None,
63
- visit_code_sequence=None,
64
- now=None,
71
+ *,
72
+ query_rule_obj: QueryRule,
73
+ registered_subject: RegisteredSubject,
74
+ visit_schedule_obj: VisitSchedule,
75
+ now: datetime,
76
+ visit_code_sequence: int | None = None,
65
77
  ):
66
78
  self._field_values = {}
67
79
  self._model_obj = None
@@ -7,7 +7,7 @@ from django.db import models
7
7
  from django.db.models.deletion import PROTECT
8
8
  from django.template.loader import render_to_string
9
9
 
10
- from edc_constants.constants import NORMAL
10
+ from edc_constants.constants import NORMAL, NULL_STRING
11
11
  from edc_model.models import BaseUuidModel, HistoricalRecords
12
12
  from edc_visit_schedule.constants import DAYS, HOURS, MONTHS, WEEKS
13
13
 
@@ -31,7 +31,7 @@ class QueryRuleManager(models.Manager):
31
31
  def get_rule_handler_choices(model_name=None):
32
32
  choices = []
33
33
  for rule_handler in site_data_manager.get_rule_handlers(model_name=model_name):
34
- choices.append((rule_handler.name, rule_handler.display_name))
34
+ choices.append((rule_handler.name, rule_handler.display_name)) # noqa: PERF401
35
35
  return tuple(choices) or (
36
36
  (DEFAULT_RULE_HANDLER, DEFAULT_RULE_HANDLER.replace("_", " ").title()),
37
37
  )
@@ -105,7 +105,7 @@ class QueryRule(BaseUuidModel):
105
105
 
106
106
  title = models.CharField(max_length=150, unique=True)
107
107
 
108
- reference_model = models.CharField(max_length=150, null=True, editable=False)
108
+ reference_model = models.CharField(max_length=150, default=NULL_STRING, editable=False)
109
109
 
110
110
  sender = models.ForeignKey(
111
111
  DataManagerUser,
@@ -152,7 +152,7 @@ class QueryRule(BaseUuidModel):
152
152
 
153
153
  query_text = models.TextField(
154
154
  help_text="Generic query text for auto-generated queries.",
155
- null=True,
155
+ default=NULL_STRING,
156
156
  blank=True,
157
157
  )
158
158
 
@@ -192,7 +192,7 @@ class QueryRule(BaseUuidModel):
192
192
 
193
193
  reference = models.CharField(max_length=36, default=uuid4, unique=True)
194
194
 
195
- comment = models.TextField(null=True, blank=True)
195
+ comment = models.TextField(default=NULL_STRING, blank=True)
196
196
 
197
197
  objects = QueryRuleManager()
198
198
 
@@ -209,13 +209,13 @@ class QueryRule(BaseUuidModel):
209
209
  def natural_key(self):
210
210
  return (self.title,)
211
211
 
212
- natural_key.dependencies = [
212
+ natural_key.dependencies = (
213
213
  "edc_data_manager.CrfDataDictionary",
214
214
  "edc_data_manager.DataManagerUser",
215
215
  "edc_data_manager.QueryUser",
216
216
  "edc_data_manager.queryvisitschedule",
217
217
  "edc_data_manager.RequisitionPanel",
218
- ]
218
+ )
219
219
 
220
220
  @property
221
221
  def rendered_query_text(self) -> str:
@@ -5,5 +5,5 @@ dm_navbar_item = NavbarItem(
5
5
  title="Data Management",
6
6
  label="DM",
7
7
  codename="edc_data_manager.nav_data_manager_section",
8
- url_name="edc_data_manager:home_url",
8
+ url_with_namespace="edc_data_manager:home_url",
9
9
  )
@@ -87,7 +87,7 @@ class QueryRuleWrapper:
87
87
  return getattr(
88
88
  self.subject_identifiers,
89
89
  "all",
90
- lambda: [{"subject_identifier": s for s in self.subject_identifiers}],
90
+ lambda: [{"subject_identifier": s} for s in self.subject_identifiers],
91
91
  )
92
92
 
93
93
  @staticmethod
@@ -21,7 +21,7 @@ class RuleRunner:
21
21
  def __init__(
22
22
  self,
23
23
  query_rule_obj: QueryRule = None,
24
- now: datetime = None,
24
+ now: datetime | None = None,
25
25
  verbose: bool | None = None,
26
26
  ):
27
27
  self.query_rule_obj = query_rule_obj # query rule model instance
@@ -55,11 +55,11 @@ class RuleRunner:
55
55
 
56
56
  def run_one(
57
57
  self,
58
- subject_identifier: str = None,
59
- visit_schedule_name: str = None,
60
- schedule_name: str = None,
61
- visit_code: str = None,
62
- timepoint: Decimal = None,
58
+ subject_identifier: str,
59
+ visit_schedule_name: str,
60
+ schedule_name: str,
61
+ visit_code: str,
62
+ timepoint: Decimal,
63
63
  ):
64
64
  visit_schedule_obj = QueryVisitSchedule.objects.get(
65
65
  visit_schedule_name=visit_schedule_name,
edc_device/navbars.py CHANGED
@@ -8,7 +8,7 @@ device.register(
8
8
  label="device",
9
9
  fa_icon="fa-calculator",
10
10
  codename="edc_navbar.nav_edc_device",
11
- url_name="edc_device:home_url",
11
+ url_with_namespace="edc_device:home_url",
12
12
  )
13
13
  )
14
14
 
edc_export/navbars.py CHANGED
@@ -7,7 +7,7 @@ navbar.register(
7
7
  name="export",
8
8
  label="Export",
9
9
  fa_icon="fa-file-export",
10
- url_name="edc_export:home_url",
10
+ url_with_namespace="edc_export:home_url",
11
11
  codename="edc_navbar.nav_export",
12
12
  )
13
13
  )
@@ -16,7 +16,7 @@ navbar.register(
16
16
  NavbarItem(
17
17
  name="data_request",
18
18
  label="Export Admin",
19
- url_name="edc_export:admin:index",
19
+ url_with_namespace="edc_export:admin:index",
20
20
  codename="edc_navbar.nav_export",
21
21
  )
22
22
  )
@@ -7,7 +7,7 @@ from edc_model.validators import hm_validator
7
7
 
8
8
 
9
9
  def fasting_model_mixin_factory(
10
- prefix: str = None, verbose_names: dict | None = None, **kwargs
10
+ prefix: str | None = None, verbose_names: dict | None = None, **kwargs
11
11
  ):
12
12
  prefix = "" if prefix is None else f"{prefix}_"
13
13
  verbose_names = verbose_names or {}
@@ -96,16 +96,13 @@ class Identifier:
96
96
  @property
97
97
  def last_identifier(self):
98
98
  """Returns the last identifier in the identifier model."""
99
- try:
100
- instance = (
101
- self.identifier_model_cls.objects.filter(identifier_type=self.name)
102
- .order_by("-sequence_number")
103
- .first()
104
- )
105
- except AttributeError:
106
- return None
107
- else:
99
+ if instance := (
100
+ self.identifier_model_cls.objects.filter(identifier_type=self.name)
101
+ .order_by("-sequence_number")
102
+ .first()
103
+ ):
108
104
  return instance.identifier
105
+ return None
109
106
 
110
107
  def remove_separator(self, identifier):
111
108
  """Returns the identifier after removing the separator.
@@ -1,14 +1,18 @@
1
1
  """To customize any of the values below,
2
2
  use settings.LAB_DASHBOARD_URL_NAMES.
3
+
4
+ These have nothing to do with url_names dictionary
3
5
  """
4
6
 
7
+ import contextlib
8
+
5
9
  from django.conf import settings
6
10
 
7
11
  dashboard_urls = dict(
8
12
  aliquot_listboard_url="edc_lab_dashboard:aliquot_listboard_url",
9
- dashboard_url="edc_lab_dashboard:home_url",
13
+ lab_dashboard_home_url="edc_lab_dashboard:home_url",
10
14
  # home_url="edc_lab_dashboard:home_url",
11
- listboard_url="edc_lab_dashboard:requisition_listboard_url",
15
+ # listboard_url="edc_lab_dashboard:requisition_listboard_url",
12
16
  manage_box_listboard_url="edc_lab_dashboard:manage_box_listboard_url",
13
17
  manage_manifest_listboard_url="edc_lab_dashboard:manage_manifest_listboard_url",
14
18
  manifest_listboard_url="edc_lab_dashboard:manifest_listboard_url",
@@ -32,7 +36,5 @@ dashboard_urls = dict(
32
36
  verify_box_item_form_action_url="edc_lab_dashboard:verify_box_item_form_action_url",
33
37
  )
34
38
 
35
- try:
39
+ with contextlib.suppress(AttributeError):
36
40
  dashboard_urls.update(**settings.LAB_DASHBOARD_URL_NAMES)
37
- except AttributeError:
38
- pass
@@ -1,38 +1,31 @@
1
1
  from django.conf import settings
2
-
2
+ from edc_dashboard.middleware_mixins import EdcTemplateMiddlewareMixin
3
3
  from edc_lab.constants import SHIPPED
4
4
 
5
5
  from .dashboard_templates import dashboard_templates
6
6
  from .dashboard_urls import dashboard_urls
7
7
 
8
8
 
9
- class DashboardMiddleware:
9
+ class DashboardMiddleware(EdcTemplateMiddlewareMixin):
10
10
  def __init__(self, get_response):
11
11
  self.get_response = get_response
12
12
 
13
13
  def __call__(self, request):
14
- response = self.get_response(request)
15
- return response
14
+ self.check_for_required_request_attrs(request)
15
+ return self.get_response(request)
16
16
 
17
17
  def process_view(self, request, *args):
18
+ lab_dashboard_urls = getattr(settings, "LAB_DASHBOARD_URL_NAMES", {})
19
+ dashboard_urls.update(**lab_dashboard_urls)
18
20
  request.url_name_data.update(**dashboard_urls)
19
- try:
20
- url_name_data = settings.LAB_DASHBOARD_URL_NAMES
21
- except AttributeError:
22
- pass
23
- else:
24
- request.url_name_data.update(**url_name_data)
25
21
 
26
- template_data = dashboard_templates
27
- try:
28
- template_data.update(settings.LAB_DASHBOARD_BASE_TEMPLATES)
29
- except AttributeError:
30
- pass
22
+ template_data = getattr(settings, "LAB_DASHBOARD_BASE_TEMPLATES", {})
23
+ template_data.update(**dashboard_templates)
31
24
  request.template_data.update(**template_data)
32
25
 
33
26
  def process_template_response(self, request, response):
34
- if response.context_data:
27
+ if getattr(response, "context_data", None):
28
+ response.context_data.update(SHIPPED=SHIPPED)
35
29
  response.context_data.update(**request.url_name_data)
36
30
  response.context_data.update(**request.template_data)
37
- response.context_data.update(SHIPPED=SHIPPED)
38
31
  return response
@@ -8,7 +8,7 @@ specimens_navbar = NavbarItem(
8
8
  title="Specimens",
9
9
  fa_icon="fa-flask",
10
10
  codename="edc_lab_dashboard.nav_lab_section",
11
- url_name="requisition_listboard_url",
11
+ url_names_key="requisition_listboard_url",
12
12
  )
13
13
 
14
14
  _specimens_navbar = copy(specimens_navbar)
@@ -22,7 +22,7 @@ navbar.register(
22
22
  name="requisition",
23
23
  label="Requisition",
24
24
  codename="edc_lab_dashboard.nav_lab_requisition",
25
- url_name="requisition_listboard_url",
25
+ url_names_key="requisition_listboard_url",
26
26
  )
27
27
  )
28
28
 
@@ -31,7 +31,7 @@ navbar.register(
31
31
  name="receive",
32
32
  label="Receive",
33
33
  codename="edc_lab_dashboard.nav_lab_receive",
34
- url_name="receive_listboard_url",
34
+ url_names_key="receive_listboard_url",
35
35
  )
36
36
  )
37
37
 
@@ -40,7 +40,7 @@ navbar.register(
40
40
  name="process",
41
41
  label="Process",
42
42
  codename="edc_lab_dashboard.nav_lab_process",
43
- url_name="process_listboard_url",
43
+ url_names_key="process_listboard_url",
44
44
  )
45
45
  )
46
46
 
@@ -49,7 +49,7 @@ navbar.register(
49
49
  name="pack",
50
50
  label="Pack",
51
51
  codename="edc_lab_dashboard.nav_lab_pack",
52
- url_name="pack_listboard_url",
52
+ url_names_key="pack_listboard_url",
53
53
  )
54
54
  )
55
55
 
@@ -58,7 +58,7 @@ navbar.register(
58
58
  name="manifest",
59
59
  label="Manifest",
60
60
  codename="edc_lab_dashboard.nav_lab_manifest",
61
- url_name="manifest_listboard_url",
61
+ url_names_key="manifest_listboard_url",
62
62
  )
63
63
  )
64
64
 
@@ -67,7 +67,7 @@ navbar.register(
67
67
  name="aliquot",
68
68
  label="Aliquot",
69
69
  codename="edc_lab_dashboard.nav_lab_aliquot",
70
- url_name="aliquot_listboard_url",
70
+ url_names_key="aliquot_listboard_url",
71
71
  )
72
72
  )
73
73
 
@@ -76,7 +76,7 @@ navbar.register(
76
76
  name="result",
77
77
  label="Result",
78
78
  codename="edc_lab_dashboard.nav_lab_result",
79
- url_name="result_listboard_url",
79
+ url_names_key="result_listboard_url",
80
80
  )
81
81
  )
82
82
 
@@ -86,7 +86,7 @@ navbar.register(
86
86
  title="Specimens",
87
87
  fa_icon="fa-flask",
88
88
  codename="edc_lab_dashboard.nav_lab_section",
89
- url_name="requisition_listboard_url",
89
+ url_names_key="requisition_listboard_url",
90
90
  active=True,
91
91
  )
92
92
  )
@@ -0,0 +1,7 @@
1
+ {% for label, status in options.items %}
2
+ {% if status %}
3
+ <span class="text text-success"><i class="fas fa-check-circle fa-lg" title="{{ label|title }}"></i></span>
4
+ {% else %}
5
+ <span class="text text-danger"><i class="fas fa-times-circle fa-lg" title="Not {{ label }}"></i></span>
6
+ {% endif %}
7
+ {% endfor %}
edc_lab_dashboard/urls.py CHANGED
@@ -1,5 +1,4 @@
1
1
  from django.urls.conf import path, re_path
2
-
3
2
  from edc_dashboard.url_names import url_names
4
3
 
5
4
  from .dashboard_urls import dashboard_urls
@@ -97,7 +96,7 @@ urlpatterns = [
97
96
  name="verify_box_listboard_url",
98
97
  ),
99
98
  re_path(
100
- "listboard/box/(?P<action_name>verify)/" "(?P<position>[0-9]+)/$",
99
+ "listboard/box/(?P<action_name>verify)/(?P<position>[0-9]+)/$",
101
100
  VerifyBoxListboardView.as_view(),
102
101
  name="verify_box_listboard_url",
103
102
  ),
@@ -158,9 +157,7 @@ urlpatterns = [
158
157
  name="manage_box_item_form_action_url",
159
158
  ),
160
159
  re_path(
161
- "box/(?P<box_identifier>[A-Z0-9]+)/"
162
- "(?P<action_name>verify)/"
163
- "(?P<position>[0-9]+)/$",
160
+ "box/(?P<box_identifier>[A-Z0-9]+)/(?P<action_name>verify)/(?P<position>[0-9]+)/$",
164
161
  VerifyBoxItemView.as_view(),
165
162
  name="verify_box_item_form_action_url",
166
163
  ),
@@ -2,7 +2,6 @@ from typing import Any
2
2
 
3
3
  from django.urls.base import reverse
4
4
  from django.views.generic.base import ContextMixin
5
-
6
5
  from edc_dashboard.url_names import url_names
7
6
 
8
7
 
@@ -14,7 +13,7 @@ class FormActionViewMixin(ContextMixin):
14
13
  action_name = None
15
14
  form_action_name = "form_action"
16
15
  form_action_selected_items_name = "selected_items"
17
- form_action_url = None
16
+ form_action_url = None # url name
18
17
 
19
18
  def get_context_data(self, **kwargs) -> dict[str, Any]:
20
19
  kwargs.update(
@@ -23,13 +23,13 @@ class ActionView(TemplateView):
23
23
  aliquot, etc.
24
24
  """
25
25
 
26
- form_action_selected_items_name = "selected_items"
27
- post_action_url = None # key exists in url_names
28
- redirect_querystring = {}
29
- template_name = dashboard_templates.get("home_template")
30
- valid_form_actions = []
26
+ form_action_selected_items_name: str = "selected_items"
27
+ post_action_url: str = None # key exists in url_names
28
+ redirect_querystring: dict = {} # noqa: RUF012
29
+ template_name: str = dashboard_templates.get("home_template")
30
+ valid_form_actions: tuple[str, ...] = ()
31
31
 
32
- navbar_name = "specimens"
32
+ navbar_name: str = "specimens"
33
33
 
34
34
  def __init__(self, **kwargs):
35
35
  super().__init__(**kwargs)
@@ -9,7 +9,7 @@ from .action_view import ActionView
9
9
 
10
10
  class AliquotView(EdcViewMixin, LabPrintersMixin, ActionView):
11
11
  post_action_url = "aliquot_listboard_url"
12
- valid_form_actions = ["print_labels"]
12
+ valid_form_actions = ("print_labels",)
13
13
  action_name = "aliquot"
14
14
  label_cls = AliquotLabel
15
15
 
@@ -2,7 +2,6 @@ from django.contrib import messages
2
2
  from django.core.exceptions import ObjectDoesNotExist
3
3
  from django.urls import reverse
4
4
  from django.utils.html import format_html
5
-
6
5
  from edc_dashboard.url_names import url_names
7
6
  from edc_dashboard.view_mixins import EdcViewMixin
8
7
  from edc_lab import SHIPPED
@@ -13,8 +12,8 @@ from .action_view import ActionView
13
12
 
14
13
 
15
14
  class ManageBoxItemView(EdcViewMixin, BoxViewMixin, ActionView):
16
- post_action_url = "manage_box_listboard_url"
17
- valid_form_actions = ["add_item", "renumber_items", "remove_selected_items"]
15
+ post_action_url = "manage_box_listboard_url" # url_name
16
+ valid_form_actions = ("add_item", "renumber_items", "remove_selected_items")
18
17
 
19
18
  @property
20
19
  def url_kwargs(self):
@@ -16,7 +16,7 @@ class ManageManifestViewError(Exception):
16
16
 
17
17
  class ManageManifestView(EdcViewMixin, ManifestViewMixin, ActionView):
18
18
  post_action_url = "manage_manifest_listboard_url"
19
- valid_form_actions = ["add_item", "remove_selected_items"]
19
+ valid_form_actions = ("add_item", "remove_selected_items")
20
20
 
21
21
  @property
22
22
  def url_kwargs(self):
@@ -13,11 +13,11 @@ from .action_view import ActionView
13
13
 
14
14
  class ManifestView(EdcViewMixin, ManifestViewMixin, LabPrintersMixin, ActionView):
15
15
  post_action_url = "manifest_listboard_url"
16
- valid_form_actions = [
16
+ valid_form_actions = (
17
17
  "remove_selected_items",
18
18
  "print_labels",
19
19
  "ship_selected_items",
20
- ]
20
+ )
21
21
  label_cls = ManifestLabel
22
22
 
23
23
  def process_form_action(self, request=None):
@@ -14,11 +14,11 @@ from .action_view import ActionView
14
14
 
15
15
  class PackView(EdcViewMixin, LabPrintersMixin, ActionView):
16
16
  post_action_url = "pack_listboard_url"
17
- valid_form_actions = [
17
+ valid_form_actions = (
18
18
  "add_selected_to_manifest",
19
19
  "remove_selected_items",
20
20
  "print_labels",
21
- ]
21
+ )
22
22
  label_cls = BoxLabel
23
23
 
24
24
  def __init__(self, **kwargs):
@@ -9,7 +9,7 @@ from .action_view import ActionView
9
9
 
10
10
  class ProcessView(EdcViewMixin, ProcessRequisitionViewMixin, ActionView):
11
11
  post_action_url = "process_listboard_url"
12
- valid_form_actions = ["process"]
12
+ valid_form_actions = ("process",)
13
13
  action_name = "process"
14
14
  label_cls = AliquotLabel
15
15
 
@@ -14,7 +14,7 @@ from .action_view import ActionView
14
14
 
15
15
  class ReceiveView(EdcViewMixin, ProcessRequisitionViewMixin, ActionView):
16
16
  post_action_url = "receive_listboard_url"
17
- valid_form_actions = ["receive", "receive_and_process"]
17
+ valid_form_actions = ("receive", "receive_and_process")
18
18
  label_cls = AliquotLabel
19
19
  specimen_cls = Specimen
20
20
 
@@ -11,7 +11,7 @@ from .action_view import ActionView
11
11
 
12
12
  class RequisitionView(EdcViewMixin, ProcessRequisitionViewMixin, ActionView):
13
13
  post_action_url = "requisition_listboard_url"
14
- valid_form_actions = ["print_labels", "print_aliquot_labels"]
14
+ valid_form_actions = ("print_labels", "print_aliquot_labels")
15
15
  action_name = "requisition"
16
16
  label_cls = RequisitionLabel
17
17
 
@@ -11,7 +11,7 @@ from .action_view import ActionView
11
11
  class VerifyBoxItemView(EdcViewMixin, BoxViewMixin, ActionView):
12
12
  post_action_url = "verify_box_listboard_url"
13
13
  box_item_failed = False
14
- valid_form_actions = ["verify_item", "reset_box", "verify_box"]
14
+ valid_form_actions = ("verify_item", "reset_box", "verify_box")
15
15
 
16
16
  @property
17
17
  def url_kwargs(self):
@@ -2,7 +2,6 @@ from copy import copy
2
2
  from typing import Any
3
3
 
4
4
  from django.urls.base import reverse
5
-
6
5
  from edc_dashboard.url_names import url_names
7
6
 
8
7
  from .base_box_item_listboard_view import BaseBoxItemListboardView
@@ -10,13 +9,13 @@ from .base_box_item_listboard_view import BaseBoxItemListboardView
10
9
 
11
10
  class ManageBoxListboardView(BaseBoxItemListboardView):
12
11
  action_name = "manage"
13
- form_action_url = "manage_box_item_form_action_url"
14
- listboard_url = "manage_box_listboard_url"
12
+ form_action_url = "manage_box_item_form_action_url" # url_name
13
+ listboard_url = "manage_box_listboard_url" # url_name
15
14
  listboard_template = "manage_box_listboard_template"
16
- verify_box_listboard_url = "verify_box_listboard_url"
15
+ verify_box_listboard_url = "verify_box_listboard_url" # url_name
17
16
  listboard_model = "edc_lab.boxitem"
18
17
  navbar_selected_item = "pack"
19
- search_form_url = "manage_box_listboard_url"
18
+ search_form_url = "manage_box_listboard_url" # url_name
20
19
 
21
20
  @property
22
21
  def url_kwargs(self):
@@ -11,15 +11,15 @@ from .base_listboard_view import BaseListboardView
11
11
  class ManifestListboardView(BaseListboardView):
12
12
  navbar_selected_item = "manifest"
13
13
 
14
- form_action_url = "manifest_form_action_url"
15
- listboard_url = "manifest_listboard_url"
14
+ form_action_url = "manifest_form_action_url" # url_name
15
+ listboard_url = "manifest_listboard_url" # url_name
16
16
  listboard_template = "manifest_listboard_template"
17
17
  listboard_model = "edc_lab.manifest"
18
18
  listboard_view_permission_codename = "edc_lab_dashboard.view_lab_manifest_listboard"
19
19
  listboard_view_only_my_permission_codename = None
20
20
  listboard_view_filters = ManifestListboardViewFilters()
21
- search_form_url = "manifest_listboard_url"
22
- print_manifest_url = "print_manifest_url"
21
+ search_form_url = "manifest_listboard_url" # url_name
22
+ print_manifest_url = "print_manifest_url" # url_name
23
23
 
24
24
  def get_context_data(self, **kwargs) -> dict[str, Any]:
25
25
  kwargs.update(
@@ -31,8 +31,7 @@ class ManifestListboardView(BaseListboardView):
31
31
 
32
32
  def get(self, request, *args, **kwargs):
33
33
  if request.GET.get("pdf"):
34
- response = self.print_manifest()
35
- return response
34
+ return self.print_manifest()
36
35
  return super().get(request, *args, **kwargs)
37
36
 
38
37
  @property
@@ -6,7 +6,6 @@ from django.apps import apps as django_apps
6
6
  from django.urls import reverse
7
7
  from django.utils.html import format_html
8
8
  from django.utils.safestring import mark_safe
9
-
10
9
  from edc_constants.constants import YES
11
10
  from edc_dashboard.url_names import url_names
12
11
 
@@ -20,13 +19,13 @@ app_config = django_apps.get_app_config("edc_lab_dashboard")
20
19
 
21
20
  class ProcessListboardView(RequisitionListboardView):
22
21
  action_name = "process"
23
- form_action_url = "process_form_action_url"
22
+ form_action_url = "process_form_action_url" # url_name
24
23
  listboard_template = "process_listboard_template"
25
- listboard_url = "process_listboard_url"
24
+ listboard_url = "process_listboard_url" # url_name
26
25
  listboard_view_permission_codename = "edc_lab_dashboard.view_lab_process_listboard"
27
26
  listboard_view_only_my_permission_codename = None
28
27
  navbar_selected_item = "process"
29
- search_form_url = "process_listboard_url"
28
+ search_form_url = "process_listboard_url" # url_name
30
29
 
31
30
  def get_queryset_filter_options(self, request, *args, **kwargs) -> tuple[Q, dict]:
32
31
  q_object, options = super().get_queryset_filter_options(request, *args, **kwargs)
@@ -34,7 +33,7 @@ class ProcessListboardView(RequisitionListboardView):
34
33
  return q_object, options
35
34
 
36
35
  def get_empty_queryset_message(self):
37
- href = reverse(url_names.get("pack_listboard_url"))
36
+ href = reverse(url_names.get(self.listboard_url))
38
37
  return format_html(
39
38
  "All specimens have been processed. Continue to "
40
39
  '<a href="{}" class="alert-link">packing</a>',