clinicedc 2.0.34__py3-none-any.whl → 2.0.36__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.34.dist-info → clinicedc-2.0.36.dist-info}/METADATA +1 -1
- {clinicedc-2.0.34.dist-info → clinicedc-2.0.36.dist-info}/RECORD +155 -165
- {clinicedc-2.0.34.dist-info → clinicedc-2.0.36.dist-info}/WHEEL +1 -1
- edc_action_item/templatetags/action_item_extras.py +1 -1
- edc_adverse_event/form_validator_mixins/death_report_form_validator.py +1 -1
- edc_adverse_event/form_validator_mixins/requires_death_report_form_validator_mixin.py +5 -3
- edc_adverse_event/form_validators/death_report_tmg.py +2 -2
- edc_adverse_event/modeladmin_mixins/ae_tmg_admin_mixin.py +1 -1
- edc_adverse_event/modeladmin_mixins/utils.py +1 -1
- edc_adverse_event/utils.py +1 -1
- edc_appointment/admin/appointment_admin.py +24 -24
- edc_appointment/admin/list_filters.py +5 -5
- edc_appointment/appointment_reason_updater.py +6 -5
- edc_appointment/appointment_status_updater.py +2 -2
- edc_appointment/context_processors.py +1 -2
- edc_appointment/creators/appointment_creator.py +9 -8
- edc_appointment/creators/unscheduled_appointment_creator.py +31 -24
- edc_appointment/creators/utils.py +35 -37
- edc_appointment/exceptions.py +3 -3
- edc_appointment/form_runners.py +2 -2
- edc_appointment/form_validator_mixins/next_appointment_crf_form_validator_mixin.py +5 -5
- edc_appointment/form_validator_mixins/window_period_form_validator_mixin.py +7 -7
- edc_appointment/form_validators/appointment_form_validator.py +16 -23
- edc_appointment/management/commands/close_appointments.py +3 -3
- edc_appointment/management/commands/reset_visit_code_sequences.py +1 -1
- edc_appointment/management/commands/update_appointment_status.py +2 -2
- edc_appointment/management/commands/update_skipped_appointments.py +7 -7
- edc_appointment/managers.py +6 -7
- edc_appointment/model_mixins/appointment_model_mixin.py +3 -4
- edc_appointment/modeladmin_mixins/next_appointment_crf_modeladmin_mixin.py +2 -2
- edc_appointment/modelform_mixins/next_appointment_crf_modelform_mixins.py +25 -24
- edc_appointment/models/signals.py +1 -1
- edc_appointment/skip_appointments.py +10 -29
- edc_appointment/utils.py +43 -47
- edc_appointment/view_mixins/appointment_view_mixin.py +11 -13
- edc_appointment/views/unscheduled_appointment_view.py +5 -6
- edc_consent/consent_definition.py +5 -13
- edc_consent/consent_definition_extension.py +0 -2
- edc_consent/form_validators/consent_definition_form_validator_mixin.py +25 -30
- edc_consent/form_validators/subject_consent_form_validator.py +3 -3
- edc_consent/modelform_mixins/consent_modelform_mixin/consent_modelform_validation_mixin.py +1 -1
- edc_consent/modelform_mixins/requires_consent_modelform_mixin.py +4 -5
- edc_consent/site_consents.py +13 -14
- edc_crf/crf_form_validator.py +13 -19
- edc_crf/crf_form_validator_mixins.py +2 -17
- edc_data_manager/admin/actions.py +1 -1
- edc_data_manager/admin/data_query_admin.py +1 -1
- edc_dx/form_validators/result_form_validator_mixin.py +1 -1
- edc_dx_review/medical_date.py +1 -1
- edc_egfr/egfr.py +4 -8
- edc_egfr/form_validator_mixins/egfr_form_validator_mixins.py +2 -2
- edc_facility/facility.py +7 -11
- edc_facility/holidays.py +3 -3
- edc_facility/models/holiday.py +1 -1
- edc_form_runners/form_runner.py +15 -16
- edc_form_validators/base_form_validator.py +5 -1
- edc_form_validators/date_range_validator.py +49 -61
- edc_form_validators/date_validator.py +1 -1
- edc_form_validators/extra_mixins/study_day_form_validator.py +1 -1
- edc_lab/form_validators/crf_requisition_form_validator_mixin.py +21 -15
- edc_lab/form_validators/requisition_form_validator_mixin.py +3 -3
- edc_lab_results/form_validator_mixins/blood_results_form_validator_mixin.py +1 -1
- edc_ltfu/modelform_mixins.py +1 -1
- edc_metadata/metadata/metadata.py +20 -7
- edc_metadata/metadata_rules/logic.py +5 -4
- edc_metadata/metadata_rules/predicate.py +22 -24
- edc_model_form/mixins/report_datetime_modelform_mixin.py +1 -5
- edc_offstudy/model_mixins/offstudy_model_mixin.py +1 -1
- edc_offstudy/modelform_mixins/crf/offstudy_crf_modelform_mixin.py +2 -2
- edc_offstudy/utils.py +4 -4
- edc_pdf_reports/crf_pdf_report.py +2 -1
- edc_pdutils/helper.py +3 -3
- edc_pdutils/utils/convert_dates_from_model.py +4 -3
- edc_pharmacy/admin/actions/confirm_stock.py +3 -3
- edc_pharmacy/admin/actions/delete_items_for_stock_request.py +4 -3
- edc_pharmacy/admin/actions/delete_order_items.py +7 -3
- edc_pharmacy/admin/actions/delete_receive_items.py +5 -3
- edc_pharmacy/admin/actions/process_repack_request.py +7 -11
- edc_pharmacy/admin/autocomplete_admin.py +1 -1
- edc_pharmacy/admin/list_filters.py +48 -46
- edc_pharmacy/admin/medication/assignment_admin.py +4 -4
- edc_pharmacy/admin/medication/dosage_guideline_admin.py +3 -3
- edc_pharmacy/admin/medication/formulation_admin.py +5 -5
- edc_pharmacy/admin/medication/medication_admin.py +3 -3
- edc_pharmacy/admin/prescription/rx_admin.py +2 -2
- edc_pharmacy/admin/prescription/rx_refill_admin.py +11 -17
- edc_pharmacy/admin/remove_fields_for_blinded_users.py +1 -1
- edc_pharmacy/admin/reports/stock_availability_admin.py +12 -8
- edc_pharmacy/admin/stock/allocation_admin.py +13 -17
- edc_pharmacy/admin/stock/allocation_proxy_admin.py +1 -2
- edc_pharmacy/admin/stock/confirmation_admin.py +4 -8
- edc_pharmacy/admin/stock/confirmation_at_site_item_admin.py +1 -1
- edc_pharmacy/admin/stock/container_admin.py +3 -3
- edc_pharmacy/admin/stock/location_admin.py +3 -6
- edc_pharmacy/admin/stock/lot_admin.py +9 -12
- edc_pharmacy/admin/stock/order_admin.py +2 -5
- edc_pharmacy/admin/stock/order_item_admin.py +14 -22
- edc_pharmacy/admin/stock/product_admin.py +6 -9
- edc_pharmacy/admin/stock/receive_admin.py +2 -2
- edc_pharmacy/admin/stock/receive_item_admin.py +3 -3
- edc_pharmacy/admin/stock/repack_request_admin.py +7 -10
- edc_pharmacy/admin/stock/stock_adjustment_admin.py +1 -1
- edc_pharmacy/admin/stock/stock_admin.py +17 -28
- edc_pharmacy/admin/stock/stock_proxy_admin.py +3 -4
- edc_pharmacy/admin/stock/stock_request_admin.py +6 -10
- edc_pharmacy/admin/stock/stock_request_item_admin.py +9 -18
- edc_pharmacy/admin/stock/stock_transfer_admin.py +5 -5
- edc_pharmacy/admin/stock/stock_transfer_item_admin.py +3 -3
- edc_pharmacy/admin/stock/storage_bin_admin.py +1 -1
- edc_pharmacy/admin/stock/storage_bin_item_admin.py +2 -2
- edc_pharmacy/form_validators/crf/study_medication_form_validator.py +27 -27
- edc_pharmacy/forms/stock/confirmation_form.py +2 -2
- edc_pharmacy/forms/stock/dispense_form.py +2 -2
- edc_pharmacy/forms/stock/lot_form.py +6 -6
- edc_pharmacy/forms/stock/order_form.py +4 -6
- edc_pharmacy/forms/stock/product_form.py +2 -3
- edc_pharmacy/forms/stock/receive_form.py +4 -4
- edc_pharmacy/forms/stock/receive_item_form.py +7 -5
- edc_pharmacy/forms/stock/repack_request_form.py +10 -8
- edc_pharmacy/forms/stock/stock_form.py +2 -3
- edc_pharmacy/forms/stock/stock_request_form.py +10 -8
- edc_pharmacy/forms/stock/stock_request_item_form.py +6 -5
- edc_pharmacy/forms/stock/stock_transfer_form.py +16 -14
- edc_pharmacy/forms/stock/supplier_form.py +2 -2
- edc_pharmacy/labels/label_data.py +2 -3
- edc_pharmacy/model_mixins/study_medication_crf_model_mixin.py +1 -1
- edc_pharmacy/models/medication/dosage_guideline.py +3 -3
- edc_pharmacy/models/model_mixins.py +12 -10
- edc_pharmacy/models/prescription/rx.py +1 -1
- edc_pharmacy/models/prescription/rx_refill.py +1 -1
- edc_pharmacy/models/signals.py +2 -3
- edc_pharmacy/models/storage/utils.py +4 -4
- edc_pharmacy/pdf_reports/manifest_pdf_report.py +3 -6
- edc_pharmacy/pdf_reports/stock_pdf_report.py +1 -3
- edc_pharmacy/refill/refill_creator.py +3 -4
- edc_protocol/validators.py +10 -16
- edc_reportable/forms/reportables_form_validator_mixin.py +1 -1
- edc_screening/form_validator_mixins.py +2 -1
- edc_transfer/form_validators.py +1 -1
- edc_transfer/model_mixins.py +1 -1
- edc_utils/age.py +17 -15
- edc_utils/date.py +7 -7
- edc_utils/text.py +7 -6
- edc_visit_schedule/exceptions.py +8 -0
- edc_visit_schedule/model_mixins/off_schedule_model_mixin.py +1 -1
- edc_visit_schedule/model_mixins/on_schedule_model_mixin.py +1 -1
- edc_visit_schedule/modelform_mixins/off_schedule_modelform_mixin.py +1 -3
- edc_visit_schedule/schedule/visit_collection.py +1 -1
- edc_visit_schedule/schedule/window.py +0 -2
- edc_visit_schedule/subject_schedule.py +1 -1
- edc_visit_schedule/utils.py +4 -4
- edc_visit_schedule/visit/visit.py +9 -3
- edc_visit_schedule/visit/window_period.py +1 -1
- edc_visit_tracking/form_validators/visit_form_validator.py +1 -1
- edc_metadata/metadata_wrappers/__init__.py +0 -5
- edc_metadata/metadata_wrappers/crf_metadata_wrapper.py +0 -5
- edc_metadata/metadata_wrappers/crf_metadata_wrappers.py +0 -8
- edc_metadata/metadata_wrappers/metadata_wrapper.py +0 -74
- edc_metadata/metadata_wrappers/metadata_wrappers.py +0 -33
- edc_metadata/metadata_wrappers/requisition_metadata_wrapper.py +0 -26
- edc_metadata/metadata_wrappers/requisition_metadata_wrappers.py +0 -10
- edc_pharmacy/management/__init__.py +0 -0
- edc_pharmacy/management/commands/__init__.py +0 -0
- edc_pharmacy/management/commands/update_initial_pharmacy_data.py +0 -10
- {clinicedc-2.0.34.dist-info → clinicedc-2.0.36.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,12 +3,12 @@ from django.contrib import admin
|
|
|
3
3
|
from django.template.loader import render_to_string
|
|
4
4
|
from django.urls import reverse
|
|
5
5
|
from django.utils import timezone
|
|
6
|
-
from django.utils.html import format_html
|
|
7
6
|
from django.utils.safestring import mark_safe
|
|
8
7
|
from django_audit_fields.admin import audit_fieldset_tuple
|
|
9
8
|
|
|
10
9
|
from edc_appointment.models import Appointment
|
|
11
|
-
from edc_utils import
|
|
10
|
+
from edc_utils.age import formatted_age
|
|
11
|
+
from edc_utils.text import convert_php_dateformat
|
|
12
12
|
|
|
13
13
|
from ...admin_site import edc_pharmacy_admin
|
|
14
14
|
from ...forms import RxRefillForm
|
|
@@ -20,7 +20,7 @@ from ..model_admin_mixin import ModelAdminMixin
|
|
|
20
20
|
class RxRefillAdmin(ModelAdminMixin, admin.ModelAdmin):
|
|
21
21
|
show_object_tools = True
|
|
22
22
|
|
|
23
|
-
ordering
|
|
23
|
+
ordering = ("refill_start_datetime",)
|
|
24
24
|
|
|
25
25
|
autocomplete_fields = ("dosage_guideline", "formulation")
|
|
26
26
|
|
|
@@ -64,7 +64,7 @@ class RxRefillAdmin(ModelAdminMixin, admin.ModelAdmin):
|
|
|
64
64
|
audit_fieldset_tuple,
|
|
65
65
|
)
|
|
66
66
|
|
|
67
|
-
list_display
|
|
67
|
+
list_display = (
|
|
68
68
|
"subject_identifier",
|
|
69
69
|
"dashboard",
|
|
70
70
|
"duration",
|
|
@@ -78,7 +78,7 @@ class RxRefillAdmin(ModelAdminMixin, admin.ModelAdmin):
|
|
|
78
78
|
"verified_datetime",
|
|
79
79
|
)
|
|
80
80
|
|
|
81
|
-
list_filter
|
|
81
|
+
list_filter = (
|
|
82
82
|
"active",
|
|
83
83
|
"refill_start_datetime",
|
|
84
84
|
"refill_end_datetime",
|
|
@@ -88,7 +88,7 @@ class RxRefillAdmin(ModelAdminMixin, admin.ModelAdmin):
|
|
|
88
88
|
"site",
|
|
89
89
|
)
|
|
90
90
|
|
|
91
|
-
search_fields
|
|
91
|
+
search_fields = (
|
|
92
92
|
"id",
|
|
93
93
|
"site__id",
|
|
94
94
|
"rx__id",
|
|
@@ -115,14 +115,8 @@ class RxRefillAdmin(ModelAdminMixin, admin.ModelAdmin):
|
|
|
115
115
|
else "???"
|
|
116
116
|
)
|
|
117
117
|
context = dict(
|
|
118
|
-
refill_start_date=
|
|
119
|
-
|
|
120
|
-
mark_safe(" ".join(refill_start_date)), # nosec B703, B308
|
|
121
|
-
),
|
|
122
|
-
refill_end_date=format_html(
|
|
123
|
-
"{}",
|
|
124
|
-
mark_safe(" ".join(refill_end_date)), # nosec B703, B308
|
|
125
|
-
),
|
|
118
|
+
refill_start_date=mark_safe(" ".join(refill_start_date)), # nosec B703, B308 # noqa: S308
|
|
119
|
+
refill_end_date=mark_safe(" ".join(refill_end_date)), # nosec B703, B308 # noqa: S308
|
|
126
120
|
number_of_days=obj.number_of_days,
|
|
127
121
|
)
|
|
128
122
|
return render_to_string("edc_pharmacy/duration.html", context=context)
|
|
@@ -177,7 +171,7 @@ class RxRefillInlineAdmin(admin.StackedInline):
|
|
|
177
171
|
|
|
178
172
|
model = RxRefill
|
|
179
173
|
|
|
180
|
-
fields
|
|
174
|
+
fields = (
|
|
181
175
|
"dosage_guideline",
|
|
182
176
|
"formulation",
|
|
183
177
|
"refill_start_datetime",
|
|
@@ -188,8 +182,8 @@ class RxRefillInlineAdmin(admin.StackedInline):
|
|
|
188
182
|
"frequency_units",
|
|
189
183
|
)
|
|
190
184
|
|
|
191
|
-
search_fields
|
|
185
|
+
search_fields = ("dosage_guideline__medication__name",)
|
|
192
186
|
|
|
193
|
-
ordering
|
|
187
|
+
ordering = ("refill_start_datetime",)
|
|
194
188
|
|
|
195
189
|
extra = 0
|
|
@@ -5,7 +5,7 @@ from edc_randomization.blinding import user_is_blinded_from_request
|
|
|
5
5
|
from .list_filters import AssignmentListFilter
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def remove_fields_for_blinded_users(request: WSGIRequest, fields: tuple) -> tuple:
|
|
8
|
+
def remove_fields_for_blinded_users(request: WSGIRequest, fields: tuple) -> tuple[str, ...]:
|
|
9
9
|
"""You need to secure custom SimpleListFilters yourself"""
|
|
10
10
|
if user_is_blinded_from_request(request):
|
|
11
11
|
fields = list(fields)
|
|
@@ -66,8 +66,8 @@ class StockAvailabilityModelAdmin(
|
|
|
66
66
|
queryset_filter: dict | None = None
|
|
67
67
|
qa_report_list_display_insert_pos = 3
|
|
68
68
|
include_note_column = False
|
|
69
|
-
ordering =
|
|
70
|
-
list_display =
|
|
69
|
+
ordering = ("relative_days",)
|
|
70
|
+
list_display = (
|
|
71
71
|
"dashboard",
|
|
72
72
|
"subject",
|
|
73
73
|
"site",
|
|
@@ -77,17 +77,17 @@ class StockAvailabilityModelAdmin(
|
|
|
77
77
|
"formatted_codes",
|
|
78
78
|
"formatted_bins",
|
|
79
79
|
"last_updated",
|
|
80
|
-
|
|
80
|
+
)
|
|
81
81
|
|
|
82
|
-
list_filter =
|
|
82
|
+
list_filter = (
|
|
83
83
|
HasCodesListFilter,
|
|
84
84
|
("appt_date", DateRangeFilterBuilder()),
|
|
85
85
|
("relative_days", NumericRangeFilterBuilder()),
|
|
86
86
|
"visit_code",
|
|
87
87
|
"site_id",
|
|
88
|
-
|
|
88
|
+
)
|
|
89
89
|
|
|
90
|
-
search_fields =
|
|
90
|
+
search_fields = ("subject_identifier",)
|
|
91
91
|
|
|
92
92
|
def get_queryset(self, request) -> QuerySet:
|
|
93
93
|
update_report(self, request)
|
|
@@ -99,13 +99,17 @@ class StockAvailabilityModelAdmin(
|
|
|
99
99
|
@admin.display(description="Codes", ordering="codes")
|
|
100
100
|
def formatted_codes(self, obj):
|
|
101
101
|
if obj.codes:
|
|
102
|
-
return format_html(
|
|
102
|
+
return format_html(
|
|
103
|
+
'<span style="font-family:courier;">{codes}</span>', codes=obj.codes
|
|
104
|
+
)
|
|
103
105
|
return None
|
|
104
106
|
|
|
105
107
|
@admin.display(description="Bins", ordering="bins")
|
|
106
108
|
def formatted_bins(self, obj):
|
|
107
109
|
if obj.codes:
|
|
108
|
-
return format_html(
|
|
110
|
+
return format_html(
|
|
111
|
+
'<span style="font-family:courier;">{bins}</span>', bins=obj.bins
|
|
112
|
+
)
|
|
109
113
|
return None
|
|
110
114
|
|
|
111
115
|
@admin.display(description="subject", ordering="subject_identifier")
|
|
@@ -22,10 +22,10 @@ class TransferredFilter(SimpleListFilter):
|
|
|
22
22
|
title = "Transferred"
|
|
23
23
|
parameter_name = "transferred"
|
|
24
24
|
|
|
25
|
-
def lookups(self, request, model_admin):
|
|
25
|
+
def lookups(self, request, model_admin): # noqa: ARG002
|
|
26
26
|
return (YES, YES), (NO, NO)
|
|
27
27
|
|
|
28
|
-
def queryset(self, request, queryset):
|
|
28
|
+
def queryset(self, request, queryset): # noqa: ARG002
|
|
29
29
|
qs = None
|
|
30
30
|
if self.value():
|
|
31
31
|
if self.value() == YES:
|
|
@@ -39,10 +39,10 @@ class DispensedFilter(SimpleListFilter):
|
|
|
39
39
|
title = "Dispensed"
|
|
40
40
|
parameter_name = "dispensed"
|
|
41
41
|
|
|
42
|
-
def lookups(self, request, model_admin):
|
|
42
|
+
def lookups(self, request, model_admin): # noqa: ARG002
|
|
43
43
|
return (YES, YES), (NO, NO)
|
|
44
44
|
|
|
45
|
-
def queryset(self, request, queryset):
|
|
45
|
+
def queryset(self, request, queryset): # noqa: ARG002
|
|
46
46
|
qs = None
|
|
47
47
|
if self.value():
|
|
48
48
|
if self.value() == YES:
|
|
@@ -56,10 +56,10 @@ class HasStockFilter(SimpleListFilter):
|
|
|
56
56
|
title = "Orphaned"
|
|
57
57
|
parameter_name = "orphaned"
|
|
58
58
|
|
|
59
|
-
def lookups(self, request, model_admin):
|
|
59
|
+
def lookups(self, request, model_admin): # noqa: ARG002
|
|
60
60
|
return (YES, YES), (NO, NO)
|
|
61
61
|
|
|
62
|
-
def queryset(self, request, queryset):
|
|
62
|
+
def queryset(self, request, queryset): # noqa: ARG002
|
|
63
63
|
qs = None
|
|
64
64
|
if self.value():
|
|
65
65
|
if self.value() == YES:
|
|
@@ -71,7 +71,6 @@ class HasStockFilter(SimpleListFilter):
|
|
|
71
71
|
|
|
72
72
|
@admin.register(Allocation, site=edc_pharmacy_admin)
|
|
73
73
|
class AllocationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
74
|
-
|
|
75
74
|
change_list_title = "Pharmacy: Allocations"
|
|
76
75
|
change_form_title = "Pharmacy: Allocation"
|
|
77
76
|
history_list_display = ()
|
|
@@ -79,7 +78,7 @@ class AllocationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
79
78
|
show_cancel = True
|
|
80
79
|
list_per_page = 20
|
|
81
80
|
|
|
82
|
-
actions =
|
|
81
|
+
actions = ("delete_selected",)
|
|
83
82
|
|
|
84
83
|
ordering = (
|
|
85
84
|
"registered_subject__subject_identifier",
|
|
@@ -145,18 +144,15 @@ class AllocationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
145
144
|
|
|
146
145
|
def get_list_display(self, request):
|
|
147
146
|
fields = super().get_list_display(request)
|
|
148
|
-
|
|
149
|
-
return fields
|
|
147
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
150
148
|
|
|
151
149
|
def get_list_filter(self, request):
|
|
152
150
|
fields = super().get_list_filter(request)
|
|
153
|
-
|
|
154
|
-
return fields
|
|
151
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
155
152
|
|
|
156
153
|
def get_search_fields(self, request):
|
|
157
154
|
fields = super().get_search_fields(request)
|
|
158
|
-
|
|
159
|
-
return fields
|
|
155
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
160
156
|
|
|
161
157
|
@admin.display(description="ALLOCATION #", ordering="allocation_identifier")
|
|
162
158
|
def identifier(self, obj):
|
|
@@ -168,12 +164,12 @@ class AllocationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
168
164
|
|
|
169
165
|
@admin.display(description="T", boolean=True)
|
|
170
166
|
def transferred(self, obj):
|
|
171
|
-
return
|
|
167
|
+
return bool(obj.stock.stocktransferitem)
|
|
172
168
|
|
|
173
169
|
@admin.display(description="D", boolean=True)
|
|
174
170
|
def dispensed(self, obj):
|
|
175
171
|
if obj:
|
|
176
|
-
return
|
|
172
|
+
return bool(get_related_or_none(obj.stock, "dispenseitem"))
|
|
177
173
|
return None
|
|
178
174
|
|
|
179
175
|
@admin.display(description="Product", ordering="stock__product")
|
|
@@ -207,7 +203,7 @@ class AllocationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
207
203
|
return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
|
|
208
204
|
|
|
209
205
|
@admin.display(description="Subject #", ordering="registered_subject__subject_identifier")
|
|
210
|
-
def dashboard(self, obj=None, label=None):
|
|
206
|
+
def dashboard(self, obj=None, label=None): # noqa: ARG002
|
|
211
207
|
context = {}
|
|
212
208
|
try:
|
|
213
209
|
url = reverse(
|
|
@@ -9,9 +9,8 @@ from .allocation_admin import AllocationAdmin
|
|
|
9
9
|
|
|
10
10
|
@admin.register(AllocationProxy, site=edc_pharmacy_admin)
|
|
11
11
|
class AllocationProxyAdmin(AllocationAdmin):
|
|
12
|
-
|
|
13
12
|
@admin.display(description="Assignment")
|
|
14
|
-
def assignment(self, obj):
|
|
13
|
+
def assignment(self, obj): # noqa: ARG002
|
|
15
14
|
return None
|
|
16
15
|
|
|
17
16
|
@admin.display(description="Stock #")
|
|
@@ -16,7 +16,6 @@ from edc_utils.date import to_local
|
|
|
16
16
|
|
|
17
17
|
@admin.register(Confirmation, site=edc_pharmacy_admin)
|
|
18
18
|
class ConfirmationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
19
|
-
|
|
20
19
|
change_list_title = "Pharmacy: Confirmed stock"
|
|
21
20
|
change_form_title = "Pharmacy: Confirmed stock"
|
|
22
21
|
history_list_display = ()
|
|
@@ -26,7 +25,7 @@ class ConfirmationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
26
25
|
|
|
27
26
|
form = ConfirmationForm
|
|
28
27
|
|
|
29
|
-
actions =
|
|
28
|
+
actions = ("delete_selected",)
|
|
30
29
|
|
|
31
30
|
fieldsets = (
|
|
32
31
|
(
|
|
@@ -56,18 +55,15 @@ class ConfirmationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
56
55
|
|
|
57
56
|
def get_list_display(self, request):
|
|
58
57
|
fields = super().get_list_display(request)
|
|
59
|
-
|
|
60
|
-
return fields
|
|
58
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
61
59
|
|
|
62
60
|
def get_list_filter(self, request):
|
|
63
61
|
fields = super().get_list_filter(request)
|
|
64
|
-
|
|
65
|
-
return fields
|
|
62
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
66
63
|
|
|
67
64
|
def get_search_fields(self, request):
|
|
68
65
|
fields = super().get_search_fields(request)
|
|
69
|
-
|
|
70
|
-
return fields
|
|
66
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
71
67
|
|
|
72
68
|
@admin.display(description="CONFIRMED #", ordering="confirmation_identifier")
|
|
73
69
|
def identifier(self, obj):
|
|
@@ -68,7 +68,7 @@ class ContainerAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
68
68
|
"may_dispense_as",
|
|
69
69
|
"created",
|
|
70
70
|
)
|
|
71
|
-
radio_fields = {"container_type": admin.VERTICAL, "units": admin.VERTICAL}
|
|
71
|
+
radio_fields = {"container_type": admin.VERTICAL, "units": admin.VERTICAL} # noqa: RUF012
|
|
72
72
|
search_fields = (
|
|
73
73
|
"name",
|
|
74
74
|
"display_name",
|
|
@@ -105,7 +105,7 @@ class ContainerAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
105
105
|
def may_dispense(self, obj):
|
|
106
106
|
return obj.may_dispense_as
|
|
107
107
|
|
|
108
|
-
def get_readonly_fields(self, request, obj=None):
|
|
108
|
+
def get_readonly_fields(self, request, obj=None): # noqa: ARG002
|
|
109
109
|
if obj:
|
|
110
|
-
return self.readonly_fields
|
|
110
|
+
return tuple({*self.readonly_fields, "name"})
|
|
111
111
|
return self.readonly_fields
|
|
@@ -40,12 +40,9 @@ class LocationAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
40
40
|
),
|
|
41
41
|
)
|
|
42
42
|
|
|
43
|
-
search_fields =
|
|
43
|
+
search_fields = ("id", "name", "contact_name")
|
|
44
44
|
|
|
45
|
-
def get_readonly_fields(self, request, obj=None):
|
|
45
|
+
def get_readonly_fields(self, request, obj=None): # noqa: ARG002
|
|
46
46
|
if obj:
|
|
47
|
-
return self.readonly_fields
|
|
48
|
-
"name",
|
|
49
|
-
"display_name",
|
|
50
|
-
)
|
|
47
|
+
return tuple({*self.readonly_fields, "name", "display_name"})
|
|
51
48
|
return self.readonly_fields
|
|
@@ -65,7 +65,7 @@ class LotAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
65
65
|
audit_fieldset_tuple,
|
|
66
66
|
)
|
|
67
67
|
|
|
68
|
-
list_filter
|
|
68
|
+
list_filter = (
|
|
69
69
|
"lot_no",
|
|
70
70
|
"expiration_date",
|
|
71
71
|
"product",
|
|
@@ -75,7 +75,7 @@ class LotAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
75
75
|
"modified",
|
|
76
76
|
)
|
|
77
77
|
|
|
78
|
-
list_display
|
|
78
|
+
list_display = (
|
|
79
79
|
"lot_no",
|
|
80
80
|
"expiration_date",
|
|
81
81
|
"product",
|
|
@@ -84,13 +84,13 @@ class LotAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
84
84
|
"created",
|
|
85
85
|
"modified",
|
|
86
86
|
)
|
|
87
|
-
radio_fields
|
|
87
|
+
radio_fields = {"assignment": admin.VERTICAL} # noqa: RUF012
|
|
88
88
|
|
|
89
|
-
search_fields
|
|
89
|
+
search_fields = ("lot_no",)
|
|
90
90
|
|
|
91
|
-
ordering
|
|
91
|
+
ordering = ("-expiration_date",)
|
|
92
92
|
|
|
93
|
-
def get_readonly_fields(self, request, obj=None):
|
|
93
|
+
def get_readonly_fields(self, request, obj=None): # noqa: ARG002
|
|
94
94
|
# if obj:
|
|
95
95
|
# return self.readonly_fields + ("lot_no", "product", "assignment")
|
|
96
96
|
return self.readonly_fields
|
|
@@ -114,15 +114,12 @@ class LotAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
114
114
|
|
|
115
115
|
def get_list_display(self, request):
|
|
116
116
|
fields = super().get_list_display(request)
|
|
117
|
-
|
|
118
|
-
return fields
|
|
117
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
119
118
|
|
|
120
119
|
def get_list_filter(self, request):
|
|
121
120
|
fields = super().get_list_filter(request)
|
|
122
|
-
|
|
123
|
-
return fields
|
|
121
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
124
122
|
|
|
125
123
|
def get_search_fields(self, request):
|
|
126
124
|
fields = super().get_search_fields(request)
|
|
127
|
-
|
|
128
|
-
return fields
|
|
125
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
@@ -54,7 +54,7 @@ class OrderAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
54
54
|
"modified",
|
|
55
55
|
)
|
|
56
56
|
list_filter = ("sent", "status", "order_datetime")
|
|
57
|
-
radio_fields = {"status": admin.VERTICAL}
|
|
57
|
+
radio_fields = {"status": admin.VERTICAL} # noqa: RUF012
|
|
58
58
|
search_fields = ("id", "order_identifier", "title")
|
|
59
59
|
readonly_fields = ("order_identifier", "sent")
|
|
60
60
|
|
|
@@ -95,10 +95,7 @@ class OrderAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
95
95
|
"edc_pharmacy/stock/items_as_link.html", context=context
|
|
96
96
|
)
|
|
97
97
|
rendered = [add_order_items_button, order_items_link]
|
|
98
|
-
return
|
|
99
|
-
"{}",
|
|
100
|
-
mark_safe("<BR>".join([r for r in rendered if r])), # nosec B703, B308
|
|
101
|
-
)
|
|
98
|
+
return mark_safe("<BR>".join([r for r in rendered if r])) # noqa: S308
|
|
102
99
|
|
|
103
100
|
@admin.display(description="Order date", ordering="order_datetime")
|
|
104
101
|
def order_date(self, obj):
|
|
@@ -3,7 +3,6 @@ from decimal import Decimal
|
|
|
3
3
|
from django.contrib import admin, messages
|
|
4
4
|
from django.template.loader import render_to_string
|
|
5
5
|
from django.urls import reverse
|
|
6
|
-
from django.utils.html import format_html
|
|
7
6
|
from django.utils.safestring import mark_safe
|
|
8
7
|
from django.utils.translation import gettext as _
|
|
9
8
|
from django_audit_fields.admin import audit_fieldset_tuple
|
|
@@ -32,8 +31,8 @@ class OrderItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
32
31
|
|
|
33
32
|
form = OrderItemForm
|
|
34
33
|
ordering = ("-order_item_identifier",)
|
|
35
|
-
autocomplete_fields =
|
|
36
|
-
actions =
|
|
34
|
+
autocomplete_fields = ("product", "container")
|
|
35
|
+
actions = (delete_order_items_action,)
|
|
37
36
|
|
|
38
37
|
fieldsets = (
|
|
39
38
|
(
|
|
@@ -66,7 +65,7 @@ class OrderItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
66
65
|
OrderItemStatusListFilter,
|
|
67
66
|
ProductAssignmentListFilter,
|
|
68
67
|
)
|
|
69
|
-
radio_fields = {"status": admin.VERTICAL}
|
|
68
|
+
radio_fields = {"status": admin.VERTICAL} # noqa: RUF012
|
|
70
69
|
search_fields = (
|
|
71
70
|
"id",
|
|
72
71
|
"order__id",
|
|
@@ -79,33 +78,29 @@ class OrderItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
79
78
|
|
|
80
79
|
def get_list_display(self, request):
|
|
81
80
|
fields = super().get_list_display(request)
|
|
82
|
-
|
|
83
|
-
return fields
|
|
81
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
84
82
|
|
|
85
83
|
def get_list_filter(self, request):
|
|
86
84
|
fields = super().get_list_filter(request)
|
|
87
|
-
|
|
88
|
-
return fields
|
|
85
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
89
86
|
|
|
90
87
|
def get_search_fields(self, request):
|
|
91
88
|
fields = super().get_search_fields(request)
|
|
92
|
-
|
|
93
|
-
return fields
|
|
89
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
94
90
|
|
|
95
|
-
def get_readonly_fields(self, request, obj=None):
|
|
91
|
+
def get_readonly_fields(self, request, obj=None): # noqa: ARG002
|
|
96
92
|
if obj:
|
|
97
|
-
return self.readonly_fields
|
|
93
|
+
return tuple({*self.readonly_fields, "order"})
|
|
98
94
|
return self.readonly_fields
|
|
99
95
|
|
|
100
96
|
def get_queryset(self, request):
|
|
101
97
|
queryset = super().get_queryset(request)
|
|
102
98
|
msg = _("All order items have been received")
|
|
103
|
-
if not message_in_queue(request, msg)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
)
|
|
108
|
-
messages.add_message(request, messages.INFO, msg)
|
|
99
|
+
if not message_in_queue(request, msg) and (
|
|
100
|
+
queryset.values("unit_qty").filter(unit_qty=0).count()
|
|
101
|
+
== queryset.model.objects.values("unit_qty").all().count()
|
|
102
|
+
):
|
|
103
|
+
messages.add_message(request, messages.INFO, msg)
|
|
109
104
|
return queryset
|
|
110
105
|
|
|
111
106
|
@admin.display(description="ORDER ITEM #", ordering="-order_item_identifier")
|
|
@@ -185,10 +180,7 @@ class OrderItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
185
180
|
received_items_link,
|
|
186
181
|
]
|
|
187
182
|
renders = [r for r in renders if r]
|
|
188
|
-
return
|
|
189
|
-
"{}",
|
|
190
|
-
mark_safe("<BR>".join(renders)), # nosec B703, B308
|
|
191
|
-
)
|
|
183
|
+
return mark_safe("<BR>".join(renders)) # noqa: S308
|
|
192
184
|
|
|
193
185
|
@staticmethod
|
|
194
186
|
def get_receive_obj(obj: OrderItem) -> Receive | None:
|
|
@@ -55,28 +55,25 @@ class ProductAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
55
55
|
)
|
|
56
56
|
ordering = ("product_identifier",)
|
|
57
57
|
readonly_fields = ("product_identifier", "name")
|
|
58
|
-
radio_fields = {"assignment": admin.VERTICAL}
|
|
58
|
+
radio_fields = {"assignment": admin.VERTICAL} # noqa: RUF012
|
|
59
59
|
|
|
60
60
|
@admin.display(description="PRODUCT #", ordering="product_identifier")
|
|
61
61
|
def identifier(self, obj):
|
|
62
62
|
return obj.product_identifier.split("-")[0]
|
|
63
63
|
|
|
64
|
-
def get_readonly_fields(self, request, obj=None):
|
|
64
|
+
def get_readonly_fields(self, request, obj=None): # noqa: ARG002
|
|
65
65
|
if obj:
|
|
66
|
-
return self.readonly_fields
|
|
66
|
+
return tuple({*self.readonly_fields, "formulation", "assignment"})
|
|
67
67
|
return self.readonly_fields
|
|
68
68
|
|
|
69
69
|
def get_list_display(self, request):
|
|
70
70
|
fields = super().get_list_display(request)
|
|
71
|
-
|
|
72
|
-
return fields
|
|
71
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
73
72
|
|
|
74
73
|
def get_list_filter(self, request):
|
|
75
74
|
fields = super().get_list_filter(request)
|
|
76
|
-
|
|
77
|
-
return fields
|
|
75
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
78
76
|
|
|
79
77
|
def get_search_fields(self, request):
|
|
80
78
|
fields = super().get_search_fields(request)
|
|
81
|
-
|
|
82
|
-
return fields
|
|
79
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
@@ -25,8 +25,8 @@ class ReceiveAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
25
25
|
|
|
26
26
|
form = ReceiveForm
|
|
27
27
|
ordering = ("-receive_identifier",)
|
|
28
|
-
actions =
|
|
29
|
-
autocomplete_fields =
|
|
28
|
+
actions = (print_labels_from_receive, confirm_received_stock_action)
|
|
29
|
+
autocomplete_fields = ("supplier",)
|
|
30
30
|
|
|
31
31
|
fieldsets = (
|
|
32
32
|
(
|
|
@@ -27,7 +27,7 @@ class ReceiveItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
27
27
|
include_audit_fields_in_list_display = False
|
|
28
28
|
ordering = ("-receive_item_identifier",)
|
|
29
29
|
|
|
30
|
-
actions =
|
|
30
|
+
actions = (delete_receive_items_action, print_labels_from_receive_item)
|
|
31
31
|
|
|
32
32
|
fieldsets = (
|
|
33
33
|
(
|
|
@@ -143,9 +143,9 @@ class ReceiveItemAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
143
143
|
def identifier(self, obj):
|
|
144
144
|
return obj.receive_item_identifier
|
|
145
145
|
|
|
146
|
-
def get_readonly_fields(self, request, obj=None):
|
|
146
|
+
def get_readonly_fields(self, request, obj=None): # noqa: ARG002
|
|
147
147
|
if obj:
|
|
148
|
-
return self.readonly_fields
|
|
148
|
+
return tuple({*self.readonly_fields, "receive"})
|
|
149
149
|
return self.readonly_fields
|
|
150
150
|
|
|
151
151
|
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
|
@@ -44,13 +44,13 @@ class RequestRepackAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
44
44
|
|
|
45
45
|
ordering = ("-repack_identifier",)
|
|
46
46
|
|
|
47
|
-
autocomplete_fields =
|
|
47
|
+
autocomplete_fields = ("from_stock", "container")
|
|
48
48
|
form = RepackRequestForm
|
|
49
|
-
actions =
|
|
49
|
+
actions = (
|
|
50
50
|
process_repack_request_action,
|
|
51
51
|
print_labels_from_repack_request,
|
|
52
52
|
confirm_repacked_stock_action,
|
|
53
|
-
|
|
53
|
+
)
|
|
54
54
|
|
|
55
55
|
change_list_note = render_to_string(
|
|
56
56
|
"edc_pharmacy/stock/instructions/repack_instructions.html"
|
|
@@ -106,18 +106,15 @@ class RequestRepackAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
106
106
|
|
|
107
107
|
def get_list_display(self, request):
|
|
108
108
|
fields = super().get_list_display(request)
|
|
109
|
-
|
|
110
|
-
return fields
|
|
109
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
111
110
|
|
|
112
111
|
def get_list_filter(self, request):
|
|
113
112
|
fields = super().get_list_filter(request)
|
|
114
|
-
|
|
115
|
-
return fields
|
|
113
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
116
114
|
|
|
117
115
|
def get_search_fields(self, request):
|
|
118
116
|
fields = super().get_search_fields(request)
|
|
119
|
-
|
|
120
|
-
return fields
|
|
117
|
+
return remove_fields_for_blinded_users(request, fields)
|
|
121
118
|
|
|
122
119
|
@admin.display(description="Repack date", ordering="repack_datetime")
|
|
123
120
|
def repack_date(self, obj):
|
|
@@ -168,7 +165,7 @@ class RequestRepackAdmin(ModelAdminMixin, SimpleHistoryAdmin):
|
|
|
168
165
|
result = get_task_result(obj)
|
|
169
166
|
return getattr(result, "status", None)
|
|
170
167
|
|
|
171
|
-
def get_readonly_fields(self, request, obj=None):
|
|
168
|
+
def get_readonly_fields(self, request, obj=None): # noqa: ARG002
|
|
172
169
|
if obj and (obj.processed_qty or Decimal(0)) > Decimal(0):
|
|
173
170
|
f = [
|
|
174
171
|
"repack_identifier",
|