meta-edc 0.3.32__py3-none-any.whl → 0.3.34__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.
Files changed (46) hide show
  1. meta_analytics/dataframes/__init__.py +15 -0
  2. meta_analytics/dataframes/glucose_endpoints/endpoint_by_date.py +22 -13
  3. meta_analytics/dataframes/glucose_endpoints/glucose_endpoints_by_date.py +49 -21
  4. meta_auth/auth_objects.py +15 -0
  5. meta_auth/auths.py +5 -2
  6. meta_edc/settings/debug.py +2 -2
  7. meta_edc/settings/defaults.py +4 -0
  8. meta_edc/urls.py +1 -0
  9. {meta_edc-0.3.32.dist-info → meta_edc-0.3.34.dist-info}/METADATA +6 -3
  10. {meta_edc-0.3.32.dist-info → meta_edc-0.3.34.dist-info}/RECORD +45 -34
  11. {meta_edc-0.3.32.dist-info → meta_edc-0.3.34.dist-info}/WHEEL +1 -1
  12. meta_pharmacy/admin.py +128 -0
  13. meta_pharmacy/admin_site.py +5 -0
  14. meta_pharmacy/apps.py +3 -0
  15. meta_pharmacy/constants.py +10 -0
  16. meta_pharmacy/forms.py +65 -0
  17. meta_pharmacy/migrations/0002_initial.py +693 -0
  18. meta_pharmacy/migrations/0003_auto_20240909_2335.py +64 -0
  19. meta_pharmacy/models.py +102 -0
  20. meta_pharmacy/urls.py +8 -0
  21. meta_prn/action_items.py +9 -1
  22. meta_reports/admin/__init__.py +1 -0
  23. meta_reports/admin/dbviews/__init__.py +1 -0
  24. meta_reports/admin/dbviews/imp_substitutions_admin.py +88 -0
  25. meta_reports/migrations/0017_auto_20240819_1711.py +1 -0
  26. meta_reports/migrations/0047_impsubstitutions.py +56 -0
  27. meta_reports/migrations/0048_auto_20240909_2338.py +48 -0
  28. meta_reports/models/__init__.py +1 -0
  29. meta_reports/models/dbviews/__init__.py +1 -0
  30. meta_reports/models/dbviews/imp_substitutions/__init__.py +1 -0
  31. meta_reports/models/dbviews/imp_substitutions/unmanaged_model.py +37 -0
  32. meta_reports/models/dbviews/imp_substitutions/view_definition.py +20 -0
  33. meta_reports/models/dbviews/on_study_missing_values/qa_cases.py +0 -1
  34. meta_sites/tests/test_sites.py +1 -1
  35. meta_subject/migrations/0107_auto_20220415_0043.py +28 -22
  36. meta_subject/migrations/0126_auto_20220719_2142.py +4 -4
  37. meta_subject/migrations/0131_auto_20220722_0411.py +28 -23
  38. meta_subject/migrations/0132_auto_20220722_1825.py +10 -6
  39. meta_subject/migrations/0135_auto_20220722_2212.py +39 -35
  40. meta_subject/migrations/0150_auto_20220914_0039.py +15 -11
  41. meta_analytics/notebooks/meta_endpoints.ipynb +0 -201
  42. /meta_analytics/dataframes/{glucose_endpoints/constants.py → constants.py} +0 -0
  43. /meta_analytics/dataframes/{glucose_endpoints/utils.py → utils.py} +0 -0
  44. {meta_edc-0.3.32.dist-info → meta_edc-0.3.34.dist-info}/AUTHORS +0 -0
  45. {meta_edc-0.3.32.dist-info → meta_edc-0.3.34.dist-info}/LICENSE +0 -0
  46. {meta_edc-0.3.32.dist-info → meta_edc-0.3.34.dist-info}/top_level.txt +0 -0
meta_pharmacy/admin.py ADDED
@@ -0,0 +1,128 @@
1
+ from django.contrib import admin
2
+ from django_audit_fields.admin import audit_fieldset_tuple
3
+ from edc_model_admin.dashboard import ModelAdminSubjectDashboardMixin
4
+ from edc_model_admin.history import SimpleHistoryAdmin
5
+ from edc_pharmacy.admin.list_filters import MedicationsListFilter
6
+ from edc_sites.admin import SiteModelAdminMixin
7
+
8
+ from .admin_site import meta_pharmacy_admin
9
+ from .forms import RxForm, SubstitutionsForm
10
+ from .models import Rx, Substitutions
11
+
12
+
13
+ @admin.register(Substitutions, site=meta_pharmacy_admin)
14
+ class SubstitutionsAdmin(
15
+ SiteModelAdminMixin,
16
+ ModelAdminSubjectDashboardMixin,
17
+ SimpleHistoryAdmin,
18
+ ):
19
+ """Admin class for meta_pharmacy.Substitutions"""
20
+
21
+ form = SubstitutionsForm
22
+
23
+ autocomplete_fields = ["rx"]
24
+
25
+ add_instructions = "This form is used to record any substitions made for IMP refills"
26
+
27
+ fieldsets = (
28
+ (
29
+ None,
30
+ {"fields": ("report_datetime",)},
31
+ ),
32
+ ("Original label on bottle", {"fields": ("sid", "visit_no")}),
33
+ (
34
+ "Substitution / Changed label",
35
+ {
36
+ "description": "The label on this bottle has been changed to the following",
37
+ "fields": ("dispensed_sid", "updated_visit_no"),
38
+ },
39
+ ),
40
+ (
41
+ "Subject",
42
+ {
43
+ "fields": ("rx",),
44
+ },
45
+ ),
46
+ audit_fieldset_tuple,
47
+ )
48
+
49
+ list_display = (
50
+ "sid",
51
+ "dispensed_sid",
52
+ "arm_match",
53
+ "subject_identifier",
54
+ "report_datetime",
55
+ )
56
+
57
+ radio_fields = {"arm_match": admin.VERTICAL}
58
+
59
+ list_filter = ("arm_match", "report_datetime")
60
+
61
+ search_fields = ["subject_identifier", "sid", "dispensed_sid"]
62
+
63
+
64
+ @admin.register(Rx, site=meta_pharmacy_admin)
65
+ class RxAdmin(ModelAdminSubjectDashboardMixin, admin.ModelAdmin):
66
+ """Admin class for proxy model of edc_pharmacy.Rx"""
67
+
68
+ show_object_tools = True
69
+
70
+ form = RxForm
71
+
72
+ fieldsets = (
73
+ (
74
+ None,
75
+ {
76
+ "fields": (
77
+ "subject_identifier",
78
+ "report_datetime",
79
+ "rx_name",
80
+ "rx_date",
81
+ "medications",
82
+ "clinician_initials",
83
+ "notes",
84
+ )
85
+ },
86
+ ),
87
+ (
88
+ "Randomization",
89
+ {
90
+ "fields": ("rando_sid", "randomizer_name", "weight_in_kgs"),
91
+ },
92
+ ),
93
+ audit_fieldset_tuple,
94
+ )
95
+
96
+ filter_horizontal = ("medications",)
97
+
98
+ list_display = (
99
+ "subject_identifier",
100
+ "dashboard",
101
+ "rx_medications",
102
+ "rando_sid",
103
+ "rx_date",
104
+ "weight_in_kgs",
105
+ "rx_name",
106
+ )
107
+
108
+ list_filter = ("report_datetime", MedicationsListFilter, "site")
109
+
110
+ search_fields = (
111
+ "id",
112
+ "subject_identifier",
113
+ "rando_sid",
114
+ "registered_subject__initials",
115
+ "medications__name",
116
+ "site__id",
117
+ "rx_name",
118
+ )
119
+
120
+ readonly_fields = (
121
+ "rando_sid",
122
+ "weight_in_kgs",
123
+ "rx_name",
124
+ )
125
+
126
+ @admin.display
127
+ def rx_medications(self, obj):
128
+ return ", ".join([obj.display_name for obj in obj.medications.all()])
@@ -0,0 +1,5 @@
1
+ from edc_model_admin.admin_site import EdcAdminSite
2
+
3
+ from .apps import AppConfig
4
+
5
+ meta_pharmacy_admin = EdcAdminSite(name="meta_pharmacy_admin", app_label=AppConfig.name)
meta_pharmacy/apps.py CHANGED
@@ -15,6 +15,9 @@ def post_migrate_populate_pharmacy_models(sender=None, **kwargs): # noqa
15
15
  class AppConfig(DjangoAppConfig):
16
16
  name = "meta_pharmacy"
17
17
  verbose_name = "META Pharmacy"
18
+ include_in_administration_section = True
19
+ has_exportable_data = True
20
+ default_auto_field = "django.db.models.BigAutoField"
18
21
 
19
22
  def ready(self):
20
23
  post_migrate.connect(post_migrate_populate_pharmacy_models, sender=self)
@@ -1 +1,11 @@
1
+ from edc_constants.constants import OK
2
+
1
3
  METFORMIN = "metformin"
4
+ REVIEW = "REVIEW"
5
+ MISSING_SUBJECT_IDENTIFIER = "MISSING_SUBJECT_IDENTIFIER"
6
+
7
+ SUBSTITUTION_STATUS = (
8
+ (OK, "ok"),
9
+ (MISSING_SUBJECT_IDENTIFIER, "Missing Subject ID"),
10
+ (REVIEW, "review"),
11
+ )
meta_pharmacy/forms.py ADDED
@@ -0,0 +1,65 @@
1
+ from django import forms
2
+ from django.core.exceptions import ObjectDoesNotExist
3
+ from edc_form_validators.form_validator import FormValidator
4
+ from edc_form_validators.form_validator_mixins import FormValidatorMixin
5
+ from edc_model_form.mixins import BaseModelFormMixin
6
+ from edc_offstudy.modelform_mixins import OffstudyNonCrfModelFormMixin
7
+ from edc_prn.modelform_mixins import PrnFormValidatorMixin
8
+ from edc_sites.forms import SiteModelFormMixin
9
+
10
+ from .models import Rx, Substitutions
11
+
12
+
13
+ class SubstitutionsFormValidator(PrnFormValidatorMixin, FormValidator):
14
+ pass
15
+
16
+
17
+ class SubstitutionsForm(
18
+ SiteModelFormMixin,
19
+ OffstudyNonCrfModelFormMixin,
20
+ BaseModelFormMixin,
21
+ FormValidatorMixin,
22
+ forms.ModelForm,
23
+ ):
24
+ form_validator_cls = SubstitutionsFormValidator
25
+
26
+ def clean(self):
27
+ if self.cleaned_data.get("sid"):
28
+ try:
29
+ obj = Rx.objects.get(rando_sid=self.cleaned_data.get("sid"))
30
+ except ObjectDoesNotExist:
31
+ raise forms.ValidationError({"sid": "Unknown SID for this trial"})
32
+ else:
33
+ if obj.site.id != self.site.id:
34
+ raise forms.ValidationError(
35
+ {
36
+ "sid": (
37
+ "Unknown SID for this trial site. "
38
+ f"Expected SITE {obj.site.id}."
39
+ )
40
+ }
41
+ )
42
+ if self.cleaned_data.get("dispensed_sid"):
43
+ try:
44
+ Rx.objects.get(
45
+ rando_sid=self.cleaned_data.get("dispensed_sid"),
46
+ )
47
+ except ObjectDoesNotExist:
48
+ raise forms.ValidationError({"dispensed_sid": "Unknown SID for this trial"})
49
+
50
+ class Meta:
51
+ model = Substitutions
52
+ fields = "__all__"
53
+
54
+
55
+ class RxForm(forms.ModelForm):
56
+
57
+ subject_identifier = forms.CharField(
58
+ label="Subject Identifier",
59
+ required=False,
60
+ widget=forms.TextInput(attrs={"readonly": "readonly"}),
61
+ )
62
+
63
+ class Meta:
64
+ model = Rx
65
+ fields = "__all__"