Skip to content

Commit

Permalink
confirm, allocated, transfer, ...
Browse files Browse the repository at this point in the history
  • Loading branch information
erikvw committed Nov 13, 2024
1 parent 4661681 commit 5a571d2
Show file tree
Hide file tree
Showing 97 changed files with 2,696 additions and 793 deletions.
1 change: 1 addition & 0 deletions edc_pharmacy/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
StockAdmin,
StockRequestAdmin,
StockRequestItemAdmin,
StockTransferAdmin,
SupplierAdmin,
)
7 changes: 4 additions & 3 deletions edc_pharmacy/admin/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from .confirm_stock import confirm_repacked_stock_action, confirm_stock_action
from .create_stock_request_items import create_stock_request_items_action
from .delete_items_for_stock_request import delete_items_for_stock_request_action
from .go_to_allocated_stock import go_to_allocated_stock
from .go_to_add_repack_request import go_to_add_repack_request_action
from .go_to_allocations import go_to_allocations
from .go_to_stock import go_to_stock
from .print_labels import print_labels
from .print_stock_labels import print_stock_labels
from .process_repack_request import process_repack_request_action
from .repack_stock import repack_stock_action
from .update_label_configuration import update_label_configuration_action
from .transfer_stock import transfer_stock_action
1 change: 0 additions & 1 deletion edc_pharmacy/admin/actions/create_stock_request_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ def create_stock_request_items_action(modeladmin, request, queryset):
df = df.reset_index(drop=True)

# df_in_stock = in_stock_for_subjects_df(stock_request_obj)
# breakpoint()
# df = df.merge(
# df_in_stock[["in_stock", "stock_identifier"]], on="stock_identifier", how="left"
# )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from django.utils.translation import gettext


@admin.display(description="Repack stock item into ...")
def repack_stock_action(modeladmin, request, queryset):
@admin.display(description="Repack stock")
def go_to_add_repack_request_action(modeladmin, request, queryset):
if queryset.count() > 1 or queryset.count() == 0:
messages.add_message(
request,
Expand All @@ -23,7 +23,7 @@ def repack_stock_action(modeladmin, request, queryset):
url = reverse("edc_pharmacy_admin:edc_pharmacy_repackrequest_add")
url = (
f"{url}?next=edc_pharmacy_admin:edc_pharmacy_stock_changelist,q"
f"&q=={obj.id}&from_stock={obj.id}"
f"&q={obj.id}&from_stock={obj.id}"
)
return HttpResponseRedirect(url)
return None
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from django.utils.translation import gettext


@admin.display(description="Go to allocate stock")
def go_to_allocated_stock(modeladmin, request, queryset):
@admin.display(description="Go to allocations")
def go_to_allocations(modeladmin, request, queryset):
if queryset.count() > 1 or queryset.count() == 0:
messages.add_message(
request,
Expand Down
18 changes: 18 additions & 0 deletions edc_pharmacy/admin/actions/print_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from uuid import uuid4

from django.contrib import admin
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from django.http import HttpResponseRedirect
from django.urls import reverse


@admin.action(description="Print labels")
def print_labels(modeladmin, request, queryset):
selected = request.POST.getlist(ACTION_CHECKBOX_NAME)
session_uuid = str(uuid4())
request.session[session_uuid] = selected
url = reverse(
"edc_pharmacy:print_labels_url",
kwargs={"session_uuid": session_uuid, "model": "stock"},
)
return HttpResponseRedirect(url)
27 changes: 24 additions & 3 deletions edc_pharmacy/admin/actions/process_repack_request.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
from __future__ import annotations

from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import gettext

from ...utils import process_repack_request


@admin.action(description="Process repack request")
def process_repack_request_action(modeladmin, request, queryset):
for repackage_obj in queryset:
for i in range(0, int(repackage_obj.qty)):
process_repack_request(repackage_obj)
if queryset.count() > 1 or queryset.count() == 0:
messages.add_message(
request,
messages.ERROR,
gettext("Select one and only one item"),
)
else:
repack_obj = queryset.first()
if repack_obj.processed:
messages.add_message(
request, messages.ERROR, "Nothing to do. Repack request already processed"
)
else:
process_repack_request(repack_obj)
url = reverse("edc_pharmacy_admin:edc_pharmacy_repackrequest_changelist")
url = f"{url}?q={repack_obj.id}"
return HttpResponseRedirect(url)
return None
22 changes: 22 additions & 0 deletions edc_pharmacy/admin/actions/transfer_stock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from __future__ import annotations

from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import gettext


@admin.action(description="Transfer stock to site")
def transfer_stock_action(modeladmin, request, queryset):
if queryset.count() > 1 or queryset.count() == 0:
messages.add_message(
request,
messages.ERROR,
gettext("Select one and only one item"),
)
else:
url = reverse(
"edc_pharmacy:transfer_stock_url", kwargs={"stock_transfer": queryset.first().pk}
)
return HttpResponseRedirect(url)
return None
5 changes: 0 additions & 5 deletions edc_pharmacy/admin/actions/update_label_configuration.py

This file was deleted.

59 changes: 50 additions & 9 deletions edc_pharmacy/admin/list_filters.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from django.contrib.admin import SimpleListFilter
from django.contrib.sites.shortcuts import get_current_site
from edc_constants.choices import YES_NO
from edc_constants.constants import NO
from django.db.models import Count
from edc_constants.choices import YES_NO, YES_NO_NA
from edc_constants.constants import NO, NOT_APPLICABLE, YES

from ..models import Medication, Rx, Stock
from ..models import Medication, Rx
from ..utils import blinded_user


class MedicationsListFilter(SimpleListFilter):
Expand Down Expand Up @@ -37,16 +39,55 @@ class AllocationListFilter(SimpleListFilter):
parameter_name = "allocated"

def lookups(self, request, model_admin):
return YES_NO
return YES_NO_NA

def queryset(self, request, queryset):
qs = None
if self.value():
isnull = True if self.value() == NO else False
qs = Stock.objects.filter(allocation__isnull=isnull)
from_stock = False
if "from_stock" in [f.name for f in queryset.model._meta.get_fields()]:
from_stock = True
if self.value() == YES:
opts = dict(from_stock__isnull=False) if from_stock else {}
qs = queryset.filter(allocation__isnull=False, **opts)
elif self.value() == NO:
opts = dict(from_stock__isnull=False) if from_stock else {}
qs = queryset.filter(allocation__isnull=True, **opts)
elif self.value() == NOT_APPLICABLE:
opts = dict(from_stock__isnull=True) if from_stock else {}
qs = queryset.filter(allocation__isnull=True, **opts)
return qs


class AssignmentListFilter(SimpleListFilter):
title = "Assignment"
parameter_name = "assignment"
lookup_str = "assignment__name"

def lookups(self, request, model_admin):
groupby = model_admin.model.objects.values(self.lookup_str).annotate(
count=Count(self.lookup_str)
)
if not blinded_user(request):
choices = []
for name in [ann.get(self.lookup_str) for ann in groupby]:
choices.append((name, name or "None"))
return tuple(choices)
return ("****", "****"), ("****", "****")

def queryset(self, request, queryset):
qs = None
if self.value():
qs = queryset.filter(**{self.lookup_str: self.value()})
return qs


class ProductAssignmentListFilter(AssignmentListFilter):
title = "Assignment"
parameter_name = "product_assignment"
lookup_str = "product__assignment__name"


class HasOrderNumFilter(SimpleListFilter):
title = "Has Order #"
parameter_name = "has_order_num"
Expand All @@ -58,7 +99,7 @@ def queryset(self, request, queryset):
qs = None
if self.value():
isnull = True if self.value() == NO else False
qs = Stock.objects.filter(receive_item__order_item__order__isnull=isnull)
qs = queryset.filter(receive_item__order_item__order__isnull=isnull)
return qs


Expand All @@ -73,7 +114,7 @@ def queryset(self, request, queryset):
qs = None
if self.value():
isnull = True if self.value() == NO else False
qs = Stock.objects.filter(receive_item__receive__isnull=isnull)
qs = queryset.filter(receive_item__receive__isnull=isnull)
return qs


Expand All @@ -88,5 +129,5 @@ def queryset(self, request, queryset):
qs = None
if self.value():
isnull = True if self.value() == NO else False
qs = Stock.objects.filter(repack_request__isnull=isnull)
qs = queryset.filter(repack_request__isnull=isnull)
return qs
6 changes: 6 additions & 0 deletions edc_pharmacy/admin/medication/assignment_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Meta:
@admin.register(Assignment, site=edc_pharmacy_admin)
class AssignmentAdmin(ModelAdminMixin, admin.ModelAdmin):
show_object_tools = True
show_cancel = True

form = AssignmentForm

Expand All @@ -37,3 +38,8 @@ class AssignmentAdmin(ModelAdminMixin, admin.ModelAdmin):
)

search_fields: Tuple[str, ...] = ("name", "display_label")

def get_readonly_fields(self, request, obj=None):
if obj:
return self.readonly_fields + ("name",)
return self.readonly_fields
2 changes: 2 additions & 0 deletions edc_pharmacy/admin/prescription/rx_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

@admin.register(Rx, site=edc_pharmacy_admin)
class RxAdmin(ModelAdminSubjectDashboardMixin, admin.ModelAdmin):
show_cancel = True
show_object_tools = True
list_per_page = 20

form = RxForm

Expand Down
14 changes: 14 additions & 0 deletions edc_pharmacy/admin/remove_fields_for_blinded_users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.core.handlers.wsgi import WSGIRequest
from edc_randomization.blinding import user_is_blinded_from_request


def remove_fields_for_blinded_users(request: WSGIRequest, fields: tuple) -> tuple:
"""You need to secure custom SimpleListFilters yourself"""
if user_is_blinded_from_request(request):
fields = list(fields)
for f in fields:
if isinstance(f, str):
if "assignment" in f or "lot_no" in f:
fields.remove(f)
fields = tuple(fields)
return fields
2 changes: 2 additions & 0 deletions edc_pharmacy/admin/stock/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
from .stock_admin import StockAdmin
from .stock_request_admin import StockRequestAdmin
from .stock_request_item_admin import StockRequestItemAdmin
from .stock_transfer_admin import StockTransferAdmin
from .stock_transfer_item_admin import StockTransferItemAdmin
from .supplier_admin import SupplierAdmin
27 changes: 24 additions & 3 deletions edc_pharmacy/admin/stock/allocation_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,44 @@
from django.template.loader import render_to_string
from django.urls import NoReverseMatch, reverse
from django.utils.translation import gettext
from django_audit_fields import audit_fieldset_tuple
from edc_utils.date import to_local

from ...admin_site import edc_pharmacy_admin
from ...models import Allocation
from ..list_filters import AssignmentListFilter
from ..model_admin_mixin import ModelAdminMixin


@admin.register(Allocation, site=edc_pharmacy_admin)
class AllocationAdmin(ModelAdminMixin, admin.ModelAdmin):
change_list_title = "Pharmacy: Stock Allocations"
change_form_title = "Pharmacy: Stock Allocation"
change_list_title = "Pharmacy: Allocations"
change_form_title = "Pharmacy: Allocation"
show_object_tools = True
show_cancel = True
list_per_page = 20

ordering = (
"registered_subject__subject_identifier",
"allocation_datetime",
)

fieldsets = (
(
None,
{
"fields": (
"allocation_identifier",
"allocation_datetime",
"stock_request_item",
"registered_subject",
"allocated_by",
)
},
),
audit_fieldset_tuple,
)

list_display = (
"identifier",
"allocation_date",
Expand All @@ -31,11 +51,12 @@ class AllocationAdmin(ModelAdminMixin, admin.ModelAdmin):
"allocated_by",
)

list_filter = ("allocation_datetime", "allocated_by")
list_filter = (AssignmentListFilter, "allocation_datetime", "allocated_by")

search_fields = ("id", "stock_request_item__id", "stock_request_item__stock_request__id")

readonly_fields = (
"assignment",
"allocation_identifier",
"allocation_datetime",
"registered_subject",
Expand Down
6 changes: 6 additions & 0 deletions edc_pharmacy/admin/stock/container_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
class ContainerAdmin(ModelAdminMixin, admin.ModelAdmin):
change_list_title = "Pharmacy: Containers"
show_object_tools = True
list_per_page = 20

form = ContainerForm

Expand Down Expand Up @@ -94,3 +95,8 @@ def may_request(self, obj):
@admin.display(description="dispense", ordering="may_dispense_as", boolean=True)
def may_dispense(self, obj):
return obj.may_dispense_as

def get_readonly_fields(self, request, obj=None):
if obj:
return self.readonly_fields + ("name",)
return self.readonly_fields
10 changes: 10 additions & 0 deletions edc_pharmacy/admin/stock/location_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

@admin.register(Location, site=edc_pharmacy_admin)
class LocationAdmin(ModelAdminMixin, admin.ModelAdmin):
show_cancel = True
ordering = ("name",)
list_per_page = 20

form = LocationForm

Expand All @@ -26,3 +28,11 @@ class LocationAdmin(ModelAdminMixin, admin.ModelAdmin):
)

search_fields = ["id", "name"]

def get_readonly_fields(self, request, obj=None):
if obj:
return self.readonly_fields + (
"name",
"display_name",
)
return self.readonly_fields
Loading

0 comments on commit 5a571d2

Please sign in to comment.