""" Admin configuration for pharmacy app. """ from django.contrib import admin from django.utils.html import format_html from django.urls import reverse from django.utils import timezone from .models import ( Medication, Prescription, InventoryItem, DispenseRecord, MedicationAdministration, DrugInteraction ) @admin.register(Medication) class MedicationAdmin(admin.ModelAdmin): """ Admin interface for Medication model. """ list_display = [ 'generic_name', 'brand_name', 'strength', 'dosage_form', 'controlled_substance_schedule', 'formulary_status', 'is_active' ] list_filter = [ 'dosage_form', 'controlled_substance_schedule', 'formulary_status', 'is_active', 'drug_class', 'created_at' ] search_fields = [ 'generic_name', 'brand_name', 'ndc_number', 'rxcui', 'drug_class' ] readonly_fields = ['medication_id', 'created_at', 'updated_at'] fieldsets = ( ('Basic Information', { 'fields': ( 'medication_id', 'generic_name', 'brand_name', 'drug_class' ) }), ('Drug Identification', { 'fields': ( 'ndc_number', 'rxcui', 'controlled_substance_schedule' ) }), ('Formulation', { 'fields': ( 'dosage_form', 'strength', 'unit_of_measure' ) }), ('Clinical Information', { 'fields': ( 'indications', 'contraindications', 'side_effects', 'warnings' ) }), ('Dosing Information', { 'fields': ( 'adult_dose_range', 'pediatric_dose_range', 'max_daily_dose', 'routes_of_administration', 'administration_instructions' ) }), ('Storage and Handling', { 'fields': ( 'storage_requirements', 'special_handling' ) }), ('Formulary and Availability', { 'fields': ( 'formulary_status', 'is_active', 'is_available' ) }), ('Pricing', { 'fields': ( 'unit_cost', 'awp' ) }), ('Manufacturer', { 'fields': ( 'manufacturer', 'manufacturer_ndc' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at', 'created_by' ) }), ) def get_queryset(self, request): """Filter by tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): return qs.filter(tenant=request.user.tenant) return qs.none() def save_model(self, request, obj, form, change): """Set tenant and created_by.""" if not change: obj.tenant = request.user.tenant obj.created_by = request.user super().save_model(request, obj, form, change) class DispenseRecordInline(admin.TabularInline): """ Inline admin for dispense records. """ model = DispenseRecord extra = 0 readonly_fields = ['dispense_id', 'created_at'] fields = [ 'inventory_item', 'quantity_dispensed', 'date_dispensed', 'dispensed_by', 'status', 'patient_counseled' ] @admin.register(Prescription) class PrescriptionAdmin(admin.ModelAdmin): """ Admin interface for Prescription model. """ list_display = [ 'prescription_number', 'patient_name', 'medication_name', 'prescriber', 'status', 'date_prescribed', 'expiration_date' ] list_filter = [ 'status', 'date_prescribed', 'verified', 'electronic_prescription', 'generic_substitution_allowed', 'prior_authorization_required' ] search_fields = [ 'prescription_number', 'patient__first_name', 'patient__last_name', 'patient__mrn', 'medication__generic_name', 'medication__brand_name' ] readonly_fields = [ 'prescription_id', 'prescription_number', 'created_at', 'updated_at' ] inlines = [DispenseRecordInline] fieldsets = ( ('Prescription Information', { 'fields': ( 'prescription_id', 'prescription_number', 'patient', 'prescriber', 'encounter' ) }), ('Medication', { 'fields': ( 'medication', 'quantity_prescribed', 'quantity_unit' ) }), ('Dosing Instructions', { 'fields': ( 'dosage_instructions', 'frequency', 'duration' ) }), ('Refills', { 'fields': ( 'refills_authorized', 'refills_remaining' ) }), ('Dates', { 'fields': ( 'date_prescribed', 'date_written', 'expiration_date' ) }), ('Status', { 'fields': ( 'status', 'verified', 'verified_by', 'verified_datetime' ) }), ('Clinical Information', { 'fields': ( 'indication', 'diagnosis_code' ) }), ('Instructions', { 'fields': ( 'pharmacy_notes', 'patient_instructions' ) }), ('Prior Authorization', { 'fields': ( 'prior_authorization_required', 'prior_authorization_number', 'prior_authorization_expiry' ) }), ('Substitution', { 'fields': ( 'generic_substitution_allowed', 'dispense_as_written' ) }), ('Electronic Prescription', { 'fields': ( 'electronic_prescription', 'e_prescription_id' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at' ) }), ) def patient_name(self, obj): """Get patient name.""" return obj.patient.get_full_name() patient_name.short_description = 'Patient' def medication_name(self, obj): """Get medication name.""" return obj.medication.display_name medication_name.short_description = 'Medication' def get_queryset(self, request): """Filter by tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): return qs.filter(tenant=request.user.tenant) return qs.none() def save_model(self, request, obj, form, change): """Set tenant.""" if not change: obj.tenant = request.user.tenant super().save_model(request, obj, form, change) @admin.register(InventoryItem) class InventoryItemAdmin(admin.ModelAdmin): """ Admin interface for InventoryItem model. """ list_display = [ 'medication_name', 'lot_number', 'quantity_on_hand', 'quantity_available', 'expiration_date', 'status', 'needs_reorder_display' ] list_filter = [ 'status', 'expiration_date', 'received_date', 'quality_checked', 'storage_location' ] search_fields = [ 'medication__generic_name', 'medication__brand_name', 'lot_number', 'supplier', 'storage_location' ] readonly_fields = [ 'inventory_id', 'quantity_available', 'total_cost', 'created_at', 'updated_at' ] fieldsets = ( ('Inventory Information', { 'fields': ( 'inventory_id', 'medication', 'lot_number', 'expiration_date' ) }), ('Quantity', { 'fields': ( 'quantity_on_hand', 'quantity_allocated', 'quantity_available' ) }), ('Reorder Information', { 'fields': ( 'reorder_point', 'reorder_quantity' ) }), ('Location', { 'fields': ( 'storage_location', 'bin_location' ) }), ('Cost Information', { 'fields': ( 'unit_cost', 'total_cost' ) }), ('Supplier Information', { 'fields': ( 'supplier', 'purchase_order_number' ) }), ('Dates', { 'fields': ( 'received_date', 'last_counted' ) }), ('Status', { 'fields': ( 'status', ) }), ('Quality Control', { 'fields': ( 'quality_checked', 'quality_check_date', 'quality_notes' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at', 'created_by' ) }), ) def medication_name(self, obj): """Get medication name.""" return obj.medication.display_name medication_name.short_description = 'Medication' def needs_reorder_display(self, obj): """Display reorder status.""" if obj.needs_reorder: return format_html('Yes') return format_html('No') needs_reorder_display.short_description = 'Needs Reorder' def get_queryset(self, request): """Filter by tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): return qs.filter(tenant=request.user.tenant) return qs.none() def save_model(self, request, obj, form, change): """Set tenant and created_by.""" if not change: obj.tenant = request.user.tenant obj.created_by = request.user super().save_model(request, obj, form, change) @admin.register(DispenseRecord) class DispenseRecordAdmin(admin.ModelAdmin): """ Admin interface for DispenseRecord model. """ list_display = [ 'prescription_number', 'patient_name', 'medication_name', 'quantity_dispensed', 'date_dispensed', 'dispensed_by', 'status' ] list_filter = [ 'status', 'date_dispensed', 'is_refill', 'patient_counseled', 'quality_check_performed' ] search_fields = [ 'prescription__prescription_number', 'prescription__patient__first_name', 'prescription__patient__last_name', 'inventory_item__medication__generic_name' ] readonly_fields = [ 'dispense_id', 'total_price', 'quantity_remaining', 'created_at', 'updated_at' ] fieldsets = ( ('Dispense Information', { 'fields': ( 'dispense_id', 'prescription', 'inventory_item' ) }), ('Quantity', { 'fields': ( 'quantity_dispensed', 'quantity_remaining' ) }), ('Date and Staff', { 'fields': ( 'date_dispensed', 'dispensed_by', 'verified_by' ) }), ('Pricing', { 'fields': ( 'unit_price', 'total_price', 'copay_amount', 'insurance_amount' ) }), ('Patient Information', { 'fields': ( 'patient_counseled', 'counseling_notes' ) }), ('Refill Information', { 'fields': ( 'is_refill', 'refill_number' ) }), ('Status', { 'fields': ( 'status', ) }), ('Pickup Information', { 'fields': ( 'picked_up_by', 'pickup_datetime', 'identification_verified' ) }), ('Quality Control', { 'fields': ( 'quality_check_performed', 'quality_notes' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at' ) }), ) def prescription_number(self, obj): """Get prescription number.""" return obj.prescription.prescription_number prescription_number.short_description = 'Prescription #' def patient_name(self, obj): """Get patient name.""" return obj.patient.get_full_name() patient_name.short_description = 'Patient' def medication_name(self, obj): """Get medication name.""" return obj.medication.display_name medication_name.short_description = 'Medication' @admin.register(MedicationAdministration) class MedicationAdministrationAdmin(admin.ModelAdmin): """ Admin interface for MedicationAdministration model. """ list_display = [ 'patient_name', 'medication_name', 'scheduled_datetime', 'actual_datetime', 'status', 'administered_by' ] list_filter = [ 'status', 'scheduled_datetime', 'route_given', 'double_checked' ] search_fields = [ 'patient__first_name', 'patient__last_name', 'prescription__medication__generic_name' ] readonly_fields = [ 'administration_id', 'created_at', 'updated_at' ] fieldsets = ( ('Administration Information', { 'fields': ( 'administration_id', 'prescription', 'patient', 'encounter' ) }), ('Scheduled vs Actual', { 'fields': ( 'scheduled_datetime', 'actual_datetime' ) }), ('Dosage', { 'fields': ( 'dose_given', 'route_given' ) }), ('Status', { 'fields': ( 'status', ) }), ('Staff', { 'fields': ( 'administered_by', 'witnessed_by' ) }), ('Reason for Not Given', { 'fields': ( 'reason_not_given', 'reason_notes' ) }), ('Patient Response', { 'fields': ( 'patient_response', 'side_effects_observed' ) }), ('Site Information', { 'fields': ( 'injection_site', 'site_condition' ) }), ('Verification', { 'fields': ( 'double_checked', 'double_checked_by' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at' ) }), ) def patient_name(self, obj): """Get patient name.""" return obj.patient.get_full_name() patient_name.short_description = 'Patient' def medication_name(self, obj): """Get medication name.""" return obj.medication.display_name medication_name.short_description = 'Medication' @admin.register(DrugInteraction) class DrugInteractionAdmin(admin.ModelAdmin): """ Admin interface for DrugInteraction model. """ list_display = [ 'medication_1_name', 'medication_2_name', 'severity', 'interaction_type', 'evidence_level', 'is_active' ] list_filter = [ 'severity', 'interaction_type', 'evidence_level', 'is_active' ] search_fields = [ 'medication_1__generic_name', 'medication_1__brand_name', 'medication_2__generic_name', 'medication_2__brand_name' ] readonly_fields = [ 'interaction_id', 'created_at', 'updated_at' ] fieldsets = ( ('Interaction Information', { 'fields': ( 'interaction_id', 'medication_1', 'medication_2' ) }), ('Severity and Type', { 'fields': ( 'severity', 'interaction_type' ) }), ('Interaction Details', { 'fields': ( 'mechanism', 'clinical_effect' ) }), ('Management', { 'fields': ( 'management_recommendations', 'monitoring_parameters' ) }), ('Evidence', { 'fields': ( 'evidence_level', 'references' ) }), ('Status', { 'fields': ( 'is_active', ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at', 'created_by' ) }), ) def medication_1_name(self, obj): """Get first medication name.""" return obj.medication_1.display_name medication_1_name.short_description = 'Medication 1' def medication_2_name(self, obj): """Get second medication name.""" return obj.medication_2.display_name medication_2_name.short_description = 'Medication 2' def get_queryset(self, request): """Filter by tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): return qs.filter(tenant=request.user.tenant) return qs.none() def save_model(self, request, obj, form, change): """Set tenant and created_by.""" if not change: obj.tenant = request.user.tenant obj.created_by = request.user super().save_model(request, obj, form, change)