clinicedc 2.0.7__py3-none-any.whl → 2.0.9__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 (142) hide show
  1. {clinicedc-2.0.7.dist-info → clinicedc-2.0.9.dist-info}/METADATA +4 -3
  2. {clinicedc-2.0.7.dist-info → clinicedc-2.0.9.dist-info}/RECORD +136 -137
  3. {clinicedc-2.0.7.dist-info → clinicedc-2.0.9.dist-info}/WHEEL +1 -1
  4. edc_action_item/auths.py +37 -32
  5. edc_action_item/models/action_model_mixin.py +1 -2
  6. edc_action_item/models/signals.py +22 -23
  7. edc_action_item/site_action_items.py +5 -9
  8. edc_action_item/utils.py +3 -3
  9. edc_adverse_event/auths.py +55 -51
  10. edc_adverse_event/model_mixins/ae_tmg/ae_tmg_methods_model_mixin.py +2 -4
  11. edc_appointment/auths.py +14 -10
  12. edc_appointment/creators/appointment_creator.py +1 -1
  13. edc_appointment/creators/appointments_creator.py +1 -1
  14. edc_appointment/model_mixins/appointment_methods_model_mixin.py +2 -3
  15. edc_appointment/model_mixins/appointment_model_mixin.py +31 -28
  16. edc_appointment/models/appointment.py +1 -1
  17. edc_appointment/utils.py +19 -24
  18. edc_auth/auth_objects/__init__.py +2 -20
  19. edc_auth/auth_objects/default_groups.py +13 -11
  20. edc_auth/auth_objects/default_roles.py +26 -24
  21. edc_auth/auth_updater/auth_updater.py +13 -2
  22. edc_auth/auth_updater/group_updater.py +12 -10
  23. edc_auth/auth_updater/role_updater.py +2 -2
  24. edc_auth/constants.py +10 -0
  25. edc_auth/import_users.py +3 -3
  26. edc_auth/migrations/0036_alter_userprofile_alternate_email_and_more.py +88 -0
  27. edc_auth/models/user_profile.py +14 -11
  28. edc_auth/site_auths.py +80 -67
  29. edc_consent/auths.py +18 -12
  30. edc_constants/constants.py +1 -0
  31. edc_crf/auths.py +5 -0
  32. edc_dashboard/auths.py +10 -6
  33. edc_dashboard/url_config.py +92 -83
  34. edc_dashboard/url_names.py +4 -4
  35. edc_dashboard/view_mixins/url_request_context_mixin.py +6 -5
  36. edc_data_manager/admin/data_query_admin.py +12 -11
  37. edc_data_manager/auths.py +37 -34
  38. edc_data_manager/rule/query_rule_wrapper.py +7 -7
  39. edc_export/archive_exporter.py +3 -2
  40. edc_export/auths.py +32 -28
  41. edc_export/model_exporter/model_exporter.py +4 -1
  42. edc_facility/auths.py +8 -3
  43. edc_facility/facility.py +8 -9
  44. edc_form_label/custom_label_condition.py +11 -8
  45. edc_form_label/form_label.py +1 -1
  46. edc_form_runners/auths.py +11 -6
  47. edc_form_validators/applicable_field_validator.py +7 -6
  48. edc_form_validators/base_form_validator.py +8 -9
  49. edc_form_validators/other_specify_field_validator.py +2 -8
  50. edc_form_validators/required_field_validator.py +19 -16
  51. edc_identifier/research_identifier.py +11 -10
  52. edc_identifier/simple_identifier.py +8 -2
  53. edc_lab/auths.py +26 -23
  54. edc_lab/lab/aliquot_creator.py +5 -8
  55. edc_lab/lab/primary_aliquot.py +14 -5
  56. edc_lab/migrations/0038_alter_aliquot_slug_alter_box_slug_alter_boxitem_slug_and_more.py +112 -0
  57. edc_lab/model_mixins/requisition/requisition_model_mixin.py +6 -8
  58. edc_lab/models/aliquot.py +2 -2
  59. edc_lab/models/manifest/manifest.py +2 -2
  60. edc_lab/models/manifest/manifest_item.py +1 -1
  61. edc_lab_dashboard/auths.py +16 -11
  62. edc_lab_results/calculate_missing.py +8 -8
  63. edc_lab_results/form_validator_mixins/blood_results_form_validator_mixin.py +2 -2
  64. edc_lab_results/get_summary.py +26 -25
  65. edc_lab_results/model_mixins/blood_result_model_mixin.py +2 -0
  66. edc_label/auths.py +6 -1
  67. edc_label/label_template.py +8 -8
  68. edc_list_data/load_model_data.py +3 -3
  69. edc_list_data/post_migrate_signals.py +1 -1
  70. edc_list_data/preload_data.py +2 -2
  71. edc_list_data/row.py +1 -1
  72. edc_list_data/site_list_data.py +6 -5
  73. edc_locator/auths.py +18 -13
  74. edc_metadata/auths.py +11 -7
  75. edc_metadata/metadata/metadata.py +1 -1
  76. edc_metadata/metadata_rules/crf/crf_rule.py +1 -1
  77. edc_metadata/metadata_rules/metadata_rule_evaluator.py +5 -3
  78. edc_metadata/metadata_rules/rule.py +2 -3
  79. edc_metadata/metadata_rules/rule_evaluator.py +1 -1
  80. edc_metadata/model_mixins/updates/updates_crf_metadata_model_mixin.py +7 -4
  81. edc_metadata/model_mixins/updates/updates_requisition_metadata_model_mixin.py +5 -2
  82. edc_metadata/models/signals.py +10 -11
  83. edc_navbar/auths.py +18 -13
  84. edc_notification/auths.py +9 -4
  85. edc_notification/notification/graded_event_notification.py +2 -2
  86. edc_notification/notification/model_notification.py +3 -30
  87. edc_notification/notification/new_model_notification.py +1 -1
  88. edc_notification/notification/notification.py +1 -1
  89. edc_notification/notification/updated_model_notification.py +2 -2
  90. edc_offstudy/auths.py +12 -7
  91. edc_pdutils/df_exporters/csv_model_exporter.py +5 -2
  92. edc_pharmacy/auths.py +19 -15
  93. edc_pharmacy/models/medication/formulation.py +5 -7
  94. edc_pharmacy/prescribe/create_prescription.py +3 -3
  95. edc_pharmacy/utils/confirm_stock.py +1 -1
  96. edc_pharmacy/utils/confirm_stock_at_site.py +1 -1
  97. edc_pharmacy/views/confirmation_at_site_view.py +6 -9
  98. edc_prn/admin_site.py +5 -0
  99. edc_prn/prn.py +10 -11
  100. edc_prn/urls.py +11 -0
  101. edc_protocol_incident/action_items.py +4 -4
  102. edc_protocol_incident/auths.py +27 -20
  103. edc_pylabels/auths.py +6 -1
  104. edc_qareports/auths.py +11 -7
  105. edc_randomization/admin.py +30 -24
  106. edc_randomization/auths.py +12 -7
  107. edc_randomization/randomizer.py +22 -20
  108. edc_randomization/utils.py +17 -16
  109. edc_refusal/auths.py +7 -2
  110. edc_refusal/model_mixins.py +1 -1
  111. edc_registration/auths.py +28 -23
  112. edc_registration/model_mixins/updates_or_creates_registered_subject_model_mixin.py +13 -4
  113. edc_registration/models/registered_subject.py +1 -1
  114. edc_reportable/utils/get_reference_range_collection.py +2 -3
  115. edc_reportable/utils/load_data.py +1 -1
  116. edc_review_dashboard/auths.py +23 -18
  117. edc_screening/age_evaluator.py +3 -3
  118. edc_screening/auths.py +35 -30
  119. edc_screening/eligibility.py +1 -1
  120. edc_screening/gender_evaluator.py +1 -1
  121. edc_screening/model_mixins/eligibility_model_mixin.py +0 -2
  122. edc_screening/model_mixins/screening_methods_model_mixin.py +1 -1
  123. edc_screening/screening_eligibility.py +2 -4
  124. edc_screening/utils.py +9 -9
  125. edc_search/generate_slug.py +26 -0
  126. edc_search/model_mixins.py +10 -21
  127. edc_sites/auths.py +8 -3
  128. edc_subject_dashboard/auths.py +27 -22
  129. edc_timepoint/apps.py +0 -21
  130. edc_unblinding/auths.py +9 -4
  131. edc_utils/__init__.py +3 -1
  132. edc_utils/show_urls.py +29 -2
  133. edc_visit_schedule/auths.py +6 -1
  134. edc_visit_schedule/site_visit_schedules.py +2 -2
  135. edc_visit_tracking/models/signals.py +2 -2
  136. edc_form_label/models.py +0 -0
  137. edc_search/constants.py +0 -1
  138. edc_search/models.py +0 -0
  139. edc_search/search_slug.py +0 -51
  140. edc_search/updater.py +0 -30
  141. edc_search/wsgi.py +0 -7
  142. {clinicedc-2.0.7.dist-info → clinicedc-2.0.9.dist-info}/licenses/LICENSE +0 -0
edc_utils/show_urls.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # https://github.com/django-extensions/django-extensions/blob/master/django_extensions/management/commands/show_urls.py
3
3
 
4
4
  from django.core.exceptions import ViewDoesNotExist
5
- from django.urls import URLPattern, URLResolver
5
+ from django.urls import URLPattern, URLResolver, get_resolver
6
6
 
7
7
 
8
8
  class RegexURLPattern:
@@ -21,7 +21,26 @@ def describe_pattern(p):
21
21
  return str(p.pattern)
22
22
 
23
23
 
24
- def show_urls(urlpatterns, base="", namespace=None, search=None):
24
+ def show_namespaces():
25
+ """Returns a list of all registered URL namespaces."""
26
+ resolver = get_resolver()
27
+ return list(resolver.namespace_dict.keys())
28
+
29
+
30
+ def show_urls():
31
+ """Return a list of all URL patterns in the project."""
32
+ urls = []
33
+ resolver = get_resolver()
34
+ url_patterns = resolver.url_patterns
35
+ for pattern in url_patterns:
36
+ try:
37
+ urls.append(f"URL: {pattern.pattern} -> View: {pattern.callback.__name__}")
38
+ except AttributeError:
39
+ urls.append(f"URL: {pattern.pattern}")
40
+ return urls
41
+
42
+
43
+ def show_urls_from_patterns(urlpatterns, base="", namespace=None, search=None):
25
44
  urls = extract_views_from_urlpatterns(urlpatterns, base=base, namespace=namespace)
26
45
  if search:
27
46
  return [url[1] for url in urls if search in url[1]]
@@ -29,6 +48,14 @@ def show_urls(urlpatterns, base="", namespace=None, search=None):
29
48
 
30
49
 
31
50
  def show_url_names(urlpatterns, base="", namespace=None, search=None):
51
+ """Returns a list of url names.
52
+
53
+ For example:
54
+ resolver = get_resolver()
55
+ url_patterns = resolver.url_patterns
56
+ pprint(show_url_names(url_patterns))
57
+ """
58
+
32
59
  urls = extract_views_from_urlpatterns(urlpatterns, base=base, namespace=namespace)
33
60
  if search:
34
61
  return [url[2] for url in urls if search in url[2]]
@@ -1,4 +1,9 @@
1
1
  from edc_auth.constants import EVERYONE
2
2
  from edc_auth.site_auths import site_auths
3
3
 
4
- site_auths.update_group("edc_visit_schedule.view_subjectschedulehistory", name=EVERYONE)
4
+
5
+ def update_site_auths() -> None:
6
+ site_auths.update_group("edc_visit_schedule.view_subjectschedulehistory", name=EVERYONE)
7
+
8
+
9
+ update_site_auths()
@@ -163,10 +163,10 @@ class SiteVisitSchedules:
163
163
  for schedule in visit_schedule.schedules.values():
164
164
  try:
165
165
  model_name = getattr(schedule, attr)
166
- except (AttributeError, TypeError):
166
+ except (AttributeError, TypeError) as e:
167
167
  raise SiteVisitScheduleError(
168
168
  f"Invalid attr for Schedule. See {schedule}. Got {attr}."
169
- )
169
+ ) from e
170
170
  if model_name and model_name == model:
171
171
  ret.append([visit_schedule, schedule])
172
172
  if not ret:
@@ -51,8 +51,8 @@ def subject_visit_missed_on_post_delete(sender, instance, using, **kwargs) -> No
51
51
  instance.related_visit.reason = SCHEDULED
52
52
  instance.related_visit.reason_unscheduled = NOT_APPLICABLE
53
53
  instance.related_visit.info_source = PATIENT
54
- instance.related_visit.info_source_other = None
55
- instance.related_visit.comment = None
54
+ instance.related_visit.info_source_other = ""
55
+ instance.related_visit.comment = ""
56
56
  instance.related_visit.modified = instance.modified
57
57
  instance.related_visit.user_modified = instance.user_modified
58
58
  instance.related_visit.save_base(
edc_form_label/models.py DELETED
File without changes
edc_search/constants.py DELETED
@@ -1 +0,0 @@
1
- SEARCH_SLUG_SEP = "|"
edc_search/models.py DELETED
File without changes
edc_search/search_slug.py DELETED
@@ -1,51 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
- from typing import TYPE_CHECKING
5
-
6
- from django.apps import apps as django_apps
7
- from django.core.management.color import color_style
8
- from django.utils.text import slugify
9
- from django_crypto_fields.fields import BaseField
10
-
11
- from .constants import SEARCH_SLUG_SEP
12
-
13
- style = color_style()
14
- if TYPE_CHECKING:
15
- from edc_model.models import BaseUuidModel
16
-
17
- from .model_mixins import SearchSlugModelMixin
18
-
19
- class Model(SearchSlugModelMixin, BaseUuidModel):
20
- pass
21
-
22
-
23
- class SearchSlug:
24
- def __init__(
25
- self, obj: Model | SearchSlugModelMixin = None, fields: tuple[str] | None = None
26
- ):
27
- self.warning = None
28
- self.slug = ""
29
- self.model_cls = None
30
- self.fields = None
31
- if obj and fields:
32
- self.model_cls = django_apps.get_model(obj._meta.label_lower)
33
- self.fields = self.get_safe_fields(fields)
34
- values = []
35
- for field in fields:
36
- value = obj
37
- for f in field.split("."):
38
- value = getattr(value, f)
39
- values.append(value)
40
- slugs = [slugify(item or "") for item in values]
41
- slug = SEARCH_SLUG_SEP.join(slugs)
42
- if len(slug) > 250:
43
- self.warning = f"Warning! Search slug string exceeds 250 chars. See {obj!r}\n"
44
- sys.stdout.write(style.WARNING(self.warning))
45
- self.slug = slug[:250]
46
-
47
- def get_safe_fields(self, fields) -> tuple[str]:
48
- encrypted_fields = tuple(
49
- [fld.name for fld in self.model_cls._meta.fields if isinstance(fld, BaseField)]
50
- )
51
- return tuple([f for f in fields if f not in encrypted_fields])
edc_search/updater.py DELETED
@@ -1,30 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- from .search_slug import SearchSlug
6
-
7
- if TYPE_CHECKING:
8
- from edc_model.models import BaseUuidModel
9
-
10
- from .model_mixins import SearchSlugModelMixin
11
-
12
- class Model(SearchSlugModelMixin, BaseUuidModel):
13
- pass
14
-
15
-
16
- class SearchSlugDuplicateFields(Exception): # noqa: N818
17
- pass
18
-
19
-
20
- class SearchSlugUpdater:
21
- search_slug_cls = SearchSlug
22
-
23
- def __init__(self, fields: tuple[str], model_obj: Model | SearchSlugModelMixin = None):
24
- if len(fields) > len(list(set(fields))):
25
- raise SearchSlugDuplicateFields(
26
- f"Duplicate search slug fields detected. Got {fields}. See {self!r}"
27
- )
28
- search_slug = self.search_slug_cls(obj=model_obj, fields=fields)
29
- self.warning = search_slug.warning
30
- self.slug = search_slug.slug
edc_search/wsgi.py DELETED
@@ -1,7 +0,0 @@
1
- import os
2
-
3
- from django.core.wsgi import get_wsgi_application
4
-
5
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "edc_search.settings")
6
-
7
- application = get_wsgi_application()