Skip to content

Commit

Permalink
more celery work, add stock transfer confirmation and dispensing
Browse files Browse the repository at this point in the history
  • Loading branch information
erikvw committed Nov 18, 2024
1 parent 200b146 commit b9d057d
Show file tree
Hide file tree
Showing 65 changed files with 2,329 additions and 244 deletions.
2 changes: 2 additions & 0 deletions edc_pharmacy/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
AllocationAdmin,
ContainerAdmin,
ContainerTypeAdmin,
DispenseAdmin,
DispenseItemAdmin,
LocationAdmin,
LotAdmin,
OrderAdmin,
Expand Down
23 changes: 18 additions & 5 deletions edc_pharmacy/admin/actions/prepare_stock_request_items.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from typing import TYPE_CHECKING

from celery.states import PENDING
from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import gettext
from edc_utils.celery import get_task_result

if TYPE_CHECKING:

Expand All @@ -26,8 +28,19 @@ def prepare_stock_request_items_action(modeladmin, request, queryset):
)
else:
stock_request: StockRequest = queryset.first()
url = reverse(
"edc_pharmacy:review_stock_request_url",
kwargs={"stock_request": stock_request.pk},
)
return HttpResponseRedirect(url)
if getattr(get_task_result(stock_request), "status", "") == PENDING:
messages.add_message(
request,
messages.ERROR,
(
f"Stock request {stock_request.request_identifier} is still processing. "
"Please click cancel and check the status column."
),
)
else:
url = reverse(
"edc_pharmacy:review_stock_request_url",
kwargs={"stock_request": stock_request.pk},
)
return HttpResponseRedirect(url)
return None
3 changes: 1 addition & 2 deletions edc_pharmacy/admin/actions/print_labels.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from uuid import uuid4

from django.contrib import admin, messages
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.translation import gettext
Expand All @@ -11,7 +10,7 @@

@admin.action(description="Print labels")
def print_labels(modeladmin, request, queryset):
selected = request.POST.getlist(ACTION_CHECKBOX_NAME)
selected = [str(obj.pk) for obj in queryset]
if len(selected) > 0:
session_uuid = str(uuid4())
request.session[session_uuid] = selected
Expand Down
6 changes: 2 additions & 4 deletions edc_pharmacy/admin/actions/process_repack_request.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from __future__ import annotations

from celery import current_app
from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.html import format_html
from edc_utils.celery import run_task_sync_or_async
from edc_utils.celery import celery_is_active, run_task_sync_or_async

from ...tasks.process_repack_request import process_repack_request_queryset

Expand All @@ -23,8 +22,7 @@ def process_repack_request_action(modeladmin, request, queryset):
repack_request_pks = [obj.pk for obj in queryset]

# if celery is not running, just keep the first pk
i = current_app.control.inspect()
if not i.active():
if not celery_is_active():
repack_request_pks = repack_request_pks[:1]

# run task / func and update or clear the task_id
Expand Down
6 changes: 3 additions & 3 deletions edc_pharmacy/admin/medication/assignment_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ class AssignmentAdmin(ModelAdminMixin, admin.ModelAdmin):
fieldsets = (
(
None,
{"fields": ["name", "display_label"]},
{"fields": ["name", "display_name"]},
),
audit_fieldset_tuple,
)

list_display: Tuple[str, ...] = (
"name",
"display_label",
"display_name",
"created",
"modified",
)

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

def get_readonly_fields(self, request, obj=None):
if obj:
Expand Down
3 changes: 3 additions & 0 deletions edc_pharmacy/admin/stock/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from .allocation_admin import AllocationAdmin
from .container_admin import ContainerAdmin
from .container_type_admin import ContainerTypeAdmin
from .dispense_admin import DispenseAdmin
from .dispense_item_admin import DispenseItemAdmin
from .location_admin import LocationAdmin
from .lot_admin import LotAdmin
from .order_admin import OrderAdmin
Expand All @@ -13,5 +15,6 @@
from .stock_request_admin import StockRequestAdmin
from .stock_request_item_admin import StockRequestItemAdmin
from .stock_transfer_admin import StockTransferAdmin
from .stock_transfer_confirmation_admin import StockTransferConfirmationAdmin
from .stock_transfer_item_admin import StockTransferItemAdmin
from .supplier_admin import SupplierAdmin
12 changes: 9 additions & 3 deletions edc_pharmacy/admin/stock/container_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ContainerAdmin(ModelAdminMixin, admin.ModelAdmin):
"fields": (
[
"name",
"display_name",
"container_type",
"units",
"qty",
Expand All @@ -31,6 +32,7 @@ class ContainerAdmin(ModelAdminMixin, admin.ModelAdmin):
"may_receive_as",
"may_repack_as",
"may_request_as",
"max_per_subject",
"may_dispense_as",
]
)
Expand All @@ -40,14 +42,15 @@ class ContainerAdmin(ModelAdminMixin, admin.ModelAdmin):
)

list_display = (
"name",
"display_name",
"container_type",
"formatted_units",
"decimal_places",
"may_order",
"may_receive",
"may_repack",
"may_request",
"max_per_subject",
"may_dispense",
"created",
"modified",
Expand All @@ -63,8 +66,11 @@ class ContainerAdmin(ModelAdminMixin, admin.ModelAdmin):
"created",
)
radio_fields = {"container_type": admin.VERTICAL, "units": admin.VERTICAL}
search_fields = ("name",)
ordering = ("name",)
search_fields = (
"name",
"display_name",
)
ordering = ("display_name",)

@admin.display(description="Units", ordering="units")
def formatted_units(self, obj):
Expand Down
97 changes: 97 additions & 0 deletions edc_pharmacy/admin/stock/dispense_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from django.contrib import admin
from django.template.loader import render_to_string
from django.urls import reverse
from django_audit_fields.admin import audit_fieldset_tuple
from edc_utils.date import to_local

from ...admin_site import edc_pharmacy_admin
from ...forms import DispenseForm
from ...models import Dispense
from ..model_admin_mixin import ModelAdminMixin


@admin.register(Dispense, site=edc_pharmacy_admin)
class DispenseAdmin(ModelAdminMixin, admin.ModelAdmin):
change_list_title = "Pharmacy: Dispense"
change_form_title = "Pharmacy: Dispense"
show_object_tools = True
show_cancel = True
list_per_page = 20

form = DispenseForm

fieldsets = (
(
"Section A: Dispense",
{
"fields": (
"dispense_identifier",
"dispense_datetime",
"location",
"rx",
"dispensed_by",
)
},
),
audit_fieldset_tuple,
)

list_display = (
"identifier",
"dispense_date",
"subject",
"formulation",
"location",
"dispense_item_changelist",
"stock_changelist",
)

search_fields = (
"id",
"rx__subject_identifier",
)

list_filter = (
"dispense_datetime",
"location__display_name",
)

readonly_fields = (
"dispense_identifier",
"dispense_datetime",
"rx",
"location",
"dispensed_by",
)

@admin.display(description="Dispense #", ordering="-dispense_identifier")
def identifier(self, obj):
return obj.dispense_identifier

@admin.display(
description="Subject #", ordering="rx__registered_subject__subject_identifier"
)
def subject(self, obj):
return obj.rx.registered_subject.subject_identifier

@admin.display(description="Formulation")
def formulation(self, obj):
return "<BR>".join([o.display_name for o in obj.rx.medications.all()])

@admin.display(description="Dispense date", ordering="dispense_datetime")
def dispense_date(self, obj):
return to_local(obj.dispense_datetime).date()

@admin.display(description="Dispense items")
def dispense_item_changelist(self, obj):
url = reverse("edc_pharmacy_admin:edc_pharmacy_dispenseitem_changelist")
url = f"{url}?q={obj.id}"
context = dict(url=url, label="Dispense items", title="Go to items")
return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)

@admin.display(description="Stock")
def stock_changelist(self, obj):
url = reverse("edc_pharmacy_admin:edc_pharmacy_stock_changelist")
url = f"{url}?q={obj.id}"
context = dict(url=url, label="Stock", title="Go to stock")
return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
95 changes: 95 additions & 0 deletions edc_pharmacy/admin/stock/dispense_item_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from django.contrib import admin
from django.template.loader import render_to_string
from django.urls import reverse
from django_audit_fields.admin import audit_fieldset_tuple
from edc_utils.date import to_local

from ...admin_site import edc_pharmacy_admin
from ...models import DispenseItem
from ..model_admin_mixin import ModelAdminMixin


@admin.register(DispenseItem, site=edc_pharmacy_admin)
class DispenseItemAdmin(ModelAdminMixin, admin.ModelAdmin):
change_list_title = "Pharmacy: Dispense items"
change_form_title = "Pharmacy: Dispense item"
show_object_tools = True
show_cancel = True
list_per_page = 20

fieldsets = (
(
"Section A: Repack",
{
"fields": (
"dispense_item_identifier",
"dispense_item_datetime",
"dispense",
"stock",
)
},
),
audit_fieldset_tuple,
)

list_display = (
"identifier",
"subject",
"location",
"dispense_date",
"dispense_changelist",
"stock_changelist",
"dispensed_by",
)

search_fields = ("id", "dispense__id", "stock__code", "dispense__rx__subject_identifier")

readonly_fields = (
"dispense_item_identifier",
"dispense_item_datetime",
"dispense",
"stock",
)

@admin.display(description="Dispense #", ordering="-dispense_item_identifier")
def identifier(self, obj):
return obj.dispense_item_identifier

@admin.display(
description="Subject #",
ordering="dispense__rx__registered_subject__subject_identifier",
)
def subject(self, obj):
return obj.dispense.rx.registered_subject.subject_identifier

@admin.display(
description="Location",
ordering="dispense__location",
)
def location(self, obj):
return obj.dispense.location

@admin.display(
description="dispensed by",
ordering="dispense__dispensed_by",
)
def dispensed_by(self, obj):
return obj.dispense.dispensed_by

@admin.display(description="item date", ordering="dispense_item_datetime")
def dispense_date(self, obj):
return to_local(obj.dispense_item_datetime).date()

@admin.display(description="DISPENSE #")
def dispense_changelist(self, obj):
url = reverse("edc_pharmacy_admin:edc_pharmacy_dispense_changelist")
url = f"{url}?q={obj.dispense.id}"
context = dict(url=url, label=obj.dispense.dispense_identifier, title="Go to dispense")
return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)

@admin.display(description="Stock #")
def stock_changelist(self, obj):
url = reverse("edc_pharmacy_admin:edc_pharmacy_stock_changelist")
url = f"{url}?q={obj.stock.code}"
context = dict(url=url, label=obj.stock.code, title="Go to stock")
return render_to_string("edc_pharmacy/stock/items_as_link.html", context=context)
Loading

0 comments on commit b9d057d

Please sign in to comment.