clinicedc 2.0.39__py3-none-any.whl → 2.0.41__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.
- {clinicedc-2.0.39.dist-info → clinicedc-2.0.41.dist-info}/METADATA +3 -12
- {clinicedc-2.0.39.dist-info → clinicedc-2.0.41.dist-info}/RECORD +145 -151
- {clinicedc-2.0.39.dist-info → clinicedc-2.0.41.dist-info}/WHEEL +1 -1
- edc_adverse_event/dashboard_urls.py +2 -0
- edc_adverse_event/middleware.py +7 -6
- edc_adverse_event/navbars.py +4 -8
- edc_adverse_event/urls.py +14 -6
- edc_adverse_event/view_mixins/ae/ae_listboard_view_mixin.py +6 -8
- edc_adverse_event/view_mixins/ae/death_report_listboard_view_mixin.py +2 -4
- edc_adverse_event/view_mixins/tmg/tmg_ae_listboard_view_mixin.py +2 -3
- edc_adverse_event/views/home_view.py +1 -2
- edc_adverse_event/views/tmg/death_listboard_view.py +8 -6
- edc_adverse_event/views/tmg/home_view.py +4 -3
- edc_adverse_event/views/tmg/summary_listboard_view.py +4 -4
- edc_appointment/utils.py +3 -6
- edc_appointment/views/unscheduled_appointment_view.py +1 -1
- edc_consent/form_validators/consent_definition_form_validator_mixin.py +5 -2
- edc_consent/model_mixins/consent_version_model_mixin.py +1 -1
- edc_consent/navbars.py +2 -1
- edc_crf/model_mixins/crf_model_mixin.py +5 -1
- edc_crf/model_mixins/crf_no_manager_model_mixin.py +2 -2
- edc_crf/model_mixins/singleton_crf_model_mixin.py +1 -1
- edc_dashboard/middleware.py +10 -16
- edc_dashboard/middleware_mixins.py +10 -0
- edc_dashboard/navbars.py +1 -1
- edc_dashboard/url_config.py +50 -31
- edc_dashboard/url_names.py +23 -17
- edc_dashboard/utils.py +4 -4
- edc_dashboard/view_mixins/template_request_context_mixin.py +5 -8
- edc_dashboard/view_mixins/url_request_context_mixin.py +38 -26
- edc_dashboard/views/administration_view.py +2 -2
- edc_dashboard/views/dashboard_view.py +5 -10
- edc_data_manager/handlers/handlers.py +17 -5
- edc_data_manager/migrations/0043_alter_historicalqueryrule_comment_and_more.py +51 -0
- edc_data_manager/models/query_rule.py +7 -7
- edc_data_manager/navbar_item.py +1 -1
- edc_data_manager/rule/query_rule_wrapper.py +1 -1
- edc_data_manager/rule/rule_runner.py +6 -6
- edc_device/navbars.py +1 -1
- edc_export/navbars.py +2 -2
- edc_glucose/model_mixin_factories/fasting_model_mixin_factory.py +1 -1
- edc_identifier/identifier.py +6 -9
- edc_lab_dashboard/dashboard_urls.py +7 -5
- edc_lab_dashboard/middleware.py +10 -17
- edc_lab_dashboard/navbars.py +9 -9
- edc_lab_dashboard/templates/edc_lab_dashboard/listboard/tags/status_column.html +7 -0
- edc_lab_dashboard/urls.py +2 -5
- edc_lab_dashboard/view_mixins/form_action_view_mixin.py +1 -2
- edc_lab_dashboard/views/action_views/action_view.py +6 -6
- edc_lab_dashboard/views/action_views/aliquot_view.py +1 -1
- edc_lab_dashboard/views/action_views/manage_box_item_view.py +2 -3
- edc_lab_dashboard/views/action_views/manage_manifest_view.py +1 -1
- edc_lab_dashboard/views/action_views/manifest_view.py +2 -2
- edc_lab_dashboard/views/action_views/pack_view.py +2 -2
- edc_lab_dashboard/views/action_views/process_view.py +1 -1
- edc_lab_dashboard/views/action_views/receive_view.py +1 -1
- edc_lab_dashboard/views/action_views/requisition_view.py +1 -1
- edc_lab_dashboard/views/action_views/verify_box_item_view.py +1 -1
- edc_lab_dashboard/views/listboard_views/manage_box_listboard_view.py +4 -5
- edc_lab_dashboard/views/listboard_views/manifest_listboard_view.py +5 -6
- edc_lab_dashboard/views/listboard_views/process_listboard_view.py +4 -5
- edc_lab_dashboard/views/listboard_views/receive_listboard_view.py +5 -6
- edc_lab_dashboard/views/listboard_views/verify_box_listboard_view.py +5 -6
- edc_label/navbars.py +1 -1
- edc_list_data/admin.py +3 -3
- edc_list_data/load_model_data.py +1 -1
- edc_list_data/management/commands/load_list_data.py +2 -2
- edc_list_data/site_list_data.py +4 -4
- edc_listboard/middleware.py +9 -8
- edc_listboard/templates/edc_listboard/listboard.html +1 -1
- edc_listboard/view_mixins/listboard_filter_view_mixin.py +1 -1
- edc_listboard/view_mixins/search_form_view_mixin.py +1 -1
- edc_listboard/views/listboard_view.py +16 -25
- edc_listboard/views/screen/screening_listboard_view.py +2 -2
- edc_listboard/views/subject/subject_listboard_view.py +2 -2
- edc_locator/forms/subject_locator_form_validator.py +2 -2
- edc_ltfu/action_items.py +1 -2
- edc_ltfu/forms/ltfu_form_validator_mixin.py +3 -3
- edc_ltfu/modeladmin_mixin.py +1 -1
- edc_ltfu/modelform_mixins.py +2 -2
- edc_metadata/admin/modeladmin_mixins.py +11 -9
- edc_metadata/management/commands/update_metadata.py +1 -1
- edc_metadata/management/commands/update_metadata_schedule_names.py +7 -7
- edc_metadata/management/commands/validate_entry_status.py +1 -1
- edc_metadata/management/commands/validate_rule_groups.py +1 -1
- edc_metadata/metadata/metadata_getter.py +3 -5
- edc_metadata/metadata_handler.py +5 -5
- edc_metadata/metadata_mixins/source_model_metadata_mixin.py +1 -1
- edc_metadata/metadata_refresher.py +1 -1
- edc_metadata/metadata_rules/crf/crf_rule.py +1 -1
- edc_metadata/metadata_rules/logic.py +3 -3
- edc_metadata/metadata_rules/persistant_singleton_mixin.py +2 -4
- edc_metadata/metadata_rules/requisition/requisition_rule_group.py +1 -1
- edc_metadata/metadata_rules/rule.py +4 -3
- edc_metadata/metadata_rules/rule_group.py +2 -2
- edc_metadata/metadata_rules/rule_group_meta_options.py +2 -2
- edc_metadata/metadata_rules/rule_group_metaclass.py +21 -22
- edc_metadata/metadata_rules/site.py +1 -1
- edc_metadata/metadata_updater.py +4 -3
- edc_metadata/model_mixins/creates/creates_metadata_model_mixin.py +3 -5
- edc_metadata/model_mixins/updates/updates_metadata_model_mixin.py +1 -1
- edc_metadata/next_form_getter.py +15 -19
- edc_metadata/offline_models.py +1 -1
- edc_metadata/requisition/requisition_metadata_handler.py +5 -5
- edc_metadata/update_metadata_on_schedule_change.py +2 -4
- edc_metadata/utils.py +1 -1
- edc_model/models/signals.py +7 -2
- edc_model_admin/mixins/model_admin_redirect_on_delete_mixin.py +4 -3
- edc_navbar/apps.py +0 -2
- edc_navbar/navbar.py +1 -1
- edc_navbar/navbar_item.py +29 -16
- edc_navbar/navbars.py +6 -19
- edc_navbar/site_navbars.py +6 -7
- edc_navbar/system_checks.py +3 -10
- edc_navbar/utils.py +14 -0
- edc_navbar/view_mixin.py +6 -9
- edc_pharmacy/navbars.py +1 -1
- edc_pharmacy/views/confirm_stock_from_queryset_view.py +3 -3
- edc_protocol/middleware.py +9 -13
- edc_protocol/navbars.py +1 -1
- edc_refusal/forms.py +1 -3
- edc_reportable/utils/convert_units.py +1 -1
- edc_review_dashboard/middleware.py +6 -3
- edc_review_dashboard/navbars.py +1 -2
- edc_review_dashboard/urls.py +3 -2
- edc_review_dashboard/views/subject_review_listboard_view.py +4 -2
- edc_subject_dashboard/dashboard_templates.py +1 -3
- edc_subject_dashboard/dashboard_urls.py +8 -0
- edc_subject_dashboard/middleware.py +10 -7
- edc_subject_dashboard/templates/edc_subject_dashboard/buttons/refresh_appointments_button.html +1 -1
- edc_subject_dashboard/templates/edc_subject_dashboard/dashboard.html +1 -1
- edc_subject_dashboard/templatetags/edc_subject_dashboard_extras.py +3 -1
- edc_subject_dashboard/urls.py +13 -4
- edc_subject_dashboard/views/base_requisition_view.py +2 -1
- edc_subject_dashboard/views/subject_dashboard_view.py +1 -2
- edc_timepoint/__init__.py +0 -2
- edc_timepoint/model_mixins.py +1 -2
- edc_timepoint/utils.py +1 -1
- edc_timepoint/visit_timepoint_lookup.py +6 -0
- edc_visit_schedule/admin/subject_schedule_history_admin.py +1 -2
- edc_visit_schedule/navbars.py +3 -4
- edc_visit_schedule/visit/visit.py +15 -0
- edc_visit_tracking/model_mixins/visit_model_mixin/visit_model_mixin.py +5 -0
- edc_visit_tracking/models/subject_visit.py +5 -0
- edc_lab_dashboard/model_wrappers/__init__.py +0 -8
- edc_lab_dashboard/model_wrappers/aliquot_model_wrapper.py +0 -31
- edc_lab_dashboard/model_wrappers/base_box_item_model_wrapper.py +0 -21
- edc_lab_dashboard/model_wrappers/box_model_wrapper.py +0 -12
- edc_lab_dashboard/model_wrappers/manage_box_item_model_wrapper.py +0 -6
- edc_lab_dashboard/model_wrappers/manifest_item_model_wrapper.py +0 -21
- edc_lab_dashboard/model_wrappers/manifest_model_wrapper.py +0 -11
- edc_lab_dashboard/model_wrappers/requisition_model_wrapper.py +0 -25
- edc_lab_dashboard/model_wrappers/result_model_wrapper.py +0 -8
- edc_lab_dashboard/model_wrappers/verify_box_model_wrapper.py +0 -10
- edc_navbar/get_default_navbar.py +0 -9
- {clinicedc-2.0.39.dist-info → clinicedc-2.0.41.dist-info}/licenses/LICENSE +0 -0
edc_adverse_event/middleware.py
CHANGED
|
@@ -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
|
-
|
|
11
|
-
return
|
|
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
|
|
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
|
|
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
|
edc_adverse_event/navbars.py
CHANGED
|
@@ -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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
21
|
-
|
|
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")
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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.
|
|
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.
|
|
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,14 +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
|
|
10
9
|
from edc_export.constants import CANCELLED
|
|
11
10
|
from edc_listboard.view_mixins import ListboardFilterViewMixin, SearchFormViewMixin
|
|
12
11
|
from edc_listboard.views import ListboardView as BaseListboardView
|
|
13
12
|
from edc_navbar import NavbarViewMixin
|
|
14
|
-
from edc_navbar.
|
|
13
|
+
from edc_navbar.utils import get_default_navbar_name
|
|
15
14
|
|
|
16
15
|
from ...constants import (
|
|
17
16
|
AE_TMG_ACTION,
|
|
@@ -47,7 +46,7 @@ class TmgAeListboardViewMixin(
|
|
|
47
46
|
listboard_panel_title = "TMG: AE Reports"
|
|
48
47
|
listboard_view_permission_codename = "edc_adverse_event.view_tmg_listboard"
|
|
49
48
|
|
|
50
|
-
navbar_name =
|
|
49
|
+
navbar_name = get_default_navbar_name()
|
|
51
50
|
navbar_selected_item = "tmg_home"
|
|
52
51
|
ordering = "-report_datetime"
|
|
53
52
|
paginate_by = 10
|
|
@@ -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.
|
|
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(
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
713
|
-
|
|
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(
|
|
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
|
-
|
|
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"])
|
|
@@ -23,7 +23,9 @@ if TYPE_CHECKING:
|
|
|
23
23
|
class ConsentDefinitionFormValidatorMixin:
|
|
24
24
|
@property
|
|
25
25
|
def subject_consent(self):
|
|
26
|
-
cdef = self.get_consent_definition(
|
|
26
|
+
cdef = self.get_consent_definition(
|
|
27
|
+
self.report_datetime, self.report_datetime_field_attr
|
|
28
|
+
)
|
|
27
29
|
return cdef.model_cls.objects.get(subject_identifier=self.subject_identifier)
|
|
28
30
|
|
|
29
31
|
def get_consent_datetime_or_raise(
|
|
@@ -71,8 +73,9 @@ class ConsentDefinitionFormValidatorMixin:
|
|
|
71
73
|
self,
|
|
72
74
|
report_datetime: datetime,
|
|
73
75
|
fldname: str = None,
|
|
74
|
-
error_code: str = None,
|
|
76
|
+
error_code: str | None = None,
|
|
75
77
|
) -> ConsentDefinition:
|
|
78
|
+
error_code = error_code or INVALID_ERROR
|
|
76
79
|
# get the consent definition (must be from this schedule)
|
|
77
80
|
schedule = getattr(self, "related_visit", self.instance).schedule
|
|
78
81
|
|
|
@@ -24,7 +24,7 @@ class ConsentVersionModelMixin(models.Model):
|
|
|
24
24
|
update_versions = models.BooleanField(default=False)
|
|
25
25
|
|
|
26
26
|
consent_definition_name = models.CharField(
|
|
27
|
-
verbose_name="Consent definition", max_length=50,
|
|
27
|
+
verbose_name="Consent definition", max_length=50, default="", editable=False
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
def __str__(self):
|
edc_consent/navbars.py
CHANGED
|
@@ -2,12 +2,16 @@ from django.contrib.sites.models import Site
|
|
|
2
2
|
|
|
3
3
|
from edc_model.models import HistoricalRecords
|
|
4
4
|
from edc_sites.model_mixins import SiteModelMixin
|
|
5
|
+
from edc_timepoint.model_mixins import TimepointLookupModelMixin
|
|
6
|
+
from edc_timepoint.timepoint_lookup import TimepointLookup
|
|
5
7
|
from edc_visit_tracking.managers import CrfCurrentSiteManager, CrfModelManager
|
|
6
8
|
|
|
7
9
|
from .crf_no_manager_model_mixin import CrfNoManagerModelMixin
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
class CrfModelMixin(SiteModelMixin, CrfNoManagerModelMixin):
|
|
12
|
+
class CrfModelMixin(SiteModelMixin, TimepointLookupModelMixin, CrfNoManagerModelMixin):
|
|
13
|
+
timepoint_lookup_cls = TimepointLookup
|
|
14
|
+
|
|
11
15
|
objects = CrfModelManager()
|
|
12
16
|
on_site = CrfCurrentSiteManager()
|
|
13
17
|
history = HistoricalRecords(inherit=True)
|
|
@@ -23,11 +23,11 @@ class CrfNoManagerModelMixin(
|
|
|
23
23
|
def natural_key(self) -> tuple:
|
|
24
24
|
return self.related_visit.natural_key()
|
|
25
25
|
|
|
26
|
-
natural_key.dependencies =
|
|
26
|
+
natural_key.dependencies = (
|
|
27
27
|
settings.SUBJECT_VISIT_MODEL,
|
|
28
28
|
"sites.Site",
|
|
29
29
|
"edc_appointment.appointment",
|
|
30
|
-
|
|
30
|
+
)
|
|
31
31
|
|
|
32
32
|
class Meta:
|
|
33
33
|
abstract = True
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
class SingletonCrfModelMixin(models.Model):
|
|
5
6
|
"""Enforces one record per subject.
|
|
6
7
|
|
|
@@ -12,7 +13,6 @@ class SingletonCrfModelMixin(models.Model):
|
|
|
12
13
|
max_length=50,
|
|
13
14
|
unique=True,
|
|
14
15
|
help_text="auto updated for unique constraint",
|
|
15
|
-
null=True,
|
|
16
16
|
editable=False,
|
|
17
17
|
)
|
|
18
18
|
|
edc_dashboard/middleware.py
CHANGED
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
from django.conf import settings
|
|
2
2
|
|
|
3
3
|
from .dashboard_templates import dashboard_templates
|
|
4
|
+
from .middleware_mixins import EdcTemplateMiddlewareMixin
|
|
4
5
|
from .url_names import url_names
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
class DashboardMiddleware:
|
|
8
|
+
class DashboardMiddleware(EdcTemplateMiddlewareMixin):
|
|
8
9
|
def __init__(self, get_response):
|
|
9
10
|
self.get_response = get_response
|
|
10
11
|
|
|
11
12
|
def __call__(self, request):
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
except AttributeError:
|
|
15
|
-
request.url_name_data = url_names.registry
|
|
16
|
-
try:
|
|
17
|
-
request.template_data
|
|
18
|
-
except AttributeError:
|
|
19
|
-
request.template_data = {}
|
|
20
|
-
response = self.get_response(request)
|
|
21
|
-
return response
|
|
13
|
+
self.check_for_required_request_attrs(request)
|
|
14
|
+
return self.get_response(request)
|
|
22
15
|
|
|
23
16
|
def process_view(self, request, *args):
|
|
24
17
|
"""Adds/Updates references to urls and templates."""
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
except AttributeError:
|
|
29
|
-
pass
|
|
18
|
+
request.url_name_data.update(**url_names.registry)
|
|
19
|
+
template_data = getattr(settings, "DASHBOARD_BASE_TEMPLATES", {})
|
|
20
|
+
template_data.update(**dashboard_templates)
|
|
30
21
|
request.template_data.update(**template_data)
|
|
31
22
|
|
|
32
23
|
def process_template_response(self, request, response):
|
|
24
|
+
if getattr(response, "context_data", None):
|
|
25
|
+
response.context_data.update(**request.url_name_data)
|
|
26
|
+
response.context_data.update(**request.template_data)
|
|
33
27
|
return response
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
class EdcTemplateMiddlewareMixin:
|
|
2
|
+
def check_for_required_request_attrs(self, request):
|
|
3
|
+
try:
|
|
4
|
+
request.url_name_data # noqa: B018
|
|
5
|
+
except AttributeError:
|
|
6
|
+
request.url_name_data = {}
|
|
7
|
+
try:
|
|
8
|
+
request.template_data # noqa: B018
|
|
9
|
+
except AttributeError:
|
|
10
|
+
request.template_data = {}
|