192 lines
9.5 KiB
Python
192 lines
9.5 KiB
Python
from rest_framework import serializers
|
|
from ..models import (
|
|
Medication, Prescription, InventoryItem, DispenseRecord,
|
|
MedicationAdministration, DrugInteraction
|
|
)
|
|
|
|
|
|
class BaseSerializer(serializers.ModelSerializer):
|
|
"""Base serializer with common functionality"""
|
|
|
|
class Meta:
|
|
fields = ['id']
|
|
read_only_fields = ['created_at', 'updated_at']
|
|
|
|
|
|
class MedicationSerializer(serializers.ModelSerializer):
|
|
"""Serializer for Medication model"""
|
|
dosage_form_display = serializers.CharField(source='get_dosage_form_display', read_only=True)
|
|
route_display = serializers.CharField(source='get_route_display', read_only=True)
|
|
controlled_substance_display = serializers.CharField(source='get_controlled_substance_display', read_only=True)
|
|
|
|
class Meta:
|
|
model = Medication
|
|
fields = [
|
|
'medication_id', 'name', 'generic_name', 'brand_names', 'ndc_number',
|
|
'rxcui', 'dosage_form', 'dosage_form_display', 'strength', 'unit',
|
|
'route', 'route_display', 'manufacturer', 'therapeutic_class',
|
|
'pharmacologic_class', 'controlled_substance', 'controlled_substance_display',
|
|
'dea_schedule', 'pregnancy_category', 'black_box_warning',
|
|
'contraindications', 'side_effects', 'interactions', 'storage_requirements',
|
|
'expiration_tracking', 'lot_tracking', 'is_active', 'created_at', 'updated_at'
|
|
]
|
|
read_only_fields = ['medication_id', 'created_at', 'updated_at']
|
|
|
|
|
|
class PrescriptionSerializer(serializers.ModelSerializer):
|
|
"""Serializer for Prescription model"""
|
|
patient_name = serializers.CharField(source='patient.get_full_name', read_only=True)
|
|
patient_mrn = serializers.CharField(source='patient.mrn', read_only=True)
|
|
prescriber_name = serializers.CharField(source='prescriber.get_full_name', read_only=True)
|
|
medication_name = serializers.CharField(source='medication.name', read_only=True)
|
|
status_display = serializers.CharField(source='get_status_display', read_only=True)
|
|
priority_display = serializers.CharField(source='get_priority_display', read_only=True)
|
|
days_supply = serializers.IntegerField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Prescription
|
|
fields = [
|
|
'prescription_id', 'prescription_number', 'patient', 'patient_name', 'patient_mrn',
|
|
'prescriber', 'prescriber_name', 'medication', 'medication_name', 'dosage',
|
|
'frequency', 'route', 'quantity', 'quantity_dispensed', 'refills_authorized',
|
|
'refills_remaining', 'days_supply', 'date_prescribed', 'date_filled',
|
|
'expiration_date', 'status', 'status_display', 'priority', 'priority_display',
|
|
'instructions', 'indication', 'notes', 'pharmacy_notes', 'daw_code',
|
|
'generic_substitution_allowed', 'prior_authorization_required',
|
|
'prior_authorization_number', 'insurance_coverage', 'copay_amount',
|
|
'patient_paid_amount', 'insurance_paid_amount', 'created_at', 'updated_at'
|
|
]
|
|
read_only_fields = [
|
|
'prescription_id', 'prescription_number', 'quantity_dispensed',
|
|
'refills_remaining', 'days_supply', 'created_at', 'updated_at'
|
|
]
|
|
|
|
|
|
class InventoryItemSerializer(serializers.ModelSerializer):
|
|
"""Serializer for InventoryItem model"""
|
|
medication_name = serializers.CharField(source='medication.name', read_only=True)
|
|
status_display = serializers.CharField(source='get_status_display', read_only=True)
|
|
is_low_stock = serializers.BooleanField(read_only=True)
|
|
is_expired = serializers.BooleanField(read_only=True)
|
|
days_until_expiry = serializers.IntegerField(read_only=True)
|
|
|
|
class Meta:
|
|
model = InventoryItem
|
|
fields = [
|
|
'item_id', 'medication', 'medication_name', 'lot_number', 'expiration_date',
|
|
'quantity_on_hand', 'quantity_allocated', 'quantity_available',
|
|
'unit_cost', 'total_cost', 'reorder_level', 'reorder_quantity',
|
|
'supplier', 'location', 'storage_requirements', 'status', 'status_display',
|
|
'is_low_stock', 'is_expired', 'days_until_expiry', 'last_counted',
|
|
'notes', 'created_at', 'updated_at'
|
|
]
|
|
read_only_fields = [
|
|
'item_id', 'quantity_available', 'total_cost', 'is_low_stock',
|
|
'is_expired', 'days_until_expiry', 'created_at', 'updated_at'
|
|
]
|
|
|
|
|
|
class DispenseRecordSerializer(serializers.ModelSerializer):
|
|
"""Serializer for DispenseRecord model"""
|
|
prescription_number = serializers.CharField(source='prescription.prescription_number', read_only=True)
|
|
patient_name = serializers.CharField(source='prescription.patient.get_full_name', read_only=True)
|
|
medication_name = serializers.CharField(source='prescription.medication.name', read_only=True)
|
|
dispensed_by_name = serializers.CharField(source='dispensed_by.get_full_name', read_only=True)
|
|
|
|
class Meta:
|
|
model = DispenseRecord
|
|
fields = [
|
|
'dispense_id', 'prescription', 'prescription_number', 'patient_name',
|
|
'medication_name', 'quantity_dispensed', 'lot_number', 'expiration_date',
|
|
'date_dispensed', 'dispensed_by', 'dispensed_by_name', 'pharmacy_location',
|
|
'patient_counseled', 'counseled_by', 'medication_guide_provided',
|
|
'patient_signature', 'pickup_person', 'pickup_id_verified',
|
|
'delivery_method', 'delivery_address', 'insurance_claim_submitted',
|
|
'copay_collected', 'notes', 'created_at', 'updated_at'
|
|
]
|
|
read_only_fields = ['dispense_id', 'created_at', 'updated_at']
|
|
|
|
|
|
class MedicationAdministrationSerializer(serializers.ModelSerializer):
|
|
"""Serializer for MedicationAdministration model"""
|
|
patient_name = serializers.CharField(source='patient.get_full_name', read_only=True)
|
|
medication_name = serializers.CharField(source='medication.name', read_only=True)
|
|
administered_by_name = serializers.CharField(source='administered_by.get_full_name', read_only=True)
|
|
status_display = serializers.CharField(source='get_status_display', read_only=True)
|
|
|
|
class Meta:
|
|
model = MedicationAdministration
|
|
fields = [
|
|
'administration_id', 'patient', 'patient_name', 'medication', 'medication_name',
|
|
'dosage_given', 'route_given', 'scheduled_time', 'actual_time',
|
|
'administered_by', 'administered_by_name', 'status', 'status_display',
|
|
'reason_not_given', 'site_of_administration', 'lot_number',
|
|
'expiration_date', 'patient_response', 'adverse_reaction',
|
|
'notes', 'created_at', 'updated_at'
|
|
]
|
|
read_only_fields = ['administration_id', 'created_at', 'updated_at']
|
|
|
|
|
|
class DrugInteractionSerializer(serializers.ModelSerializer):
|
|
"""Serializer for DrugInteraction model"""
|
|
medication1_name = serializers.CharField(source='medication1.name', read_only=True)
|
|
medication2_name = serializers.CharField(source='medication2.name', read_only=True)
|
|
severity_display = serializers.CharField(source='get_severity_display', read_only=True)
|
|
interaction_type_display = serializers.CharField(source='get_interaction_type_display', read_only=True)
|
|
|
|
class Meta:
|
|
model = DrugInteraction
|
|
fields = [
|
|
'interaction_id', 'medication1', 'medication1_name', 'medication2', 'medication2_name',
|
|
'severity', 'severity_display', 'interaction_type', 'interaction_type_display',
|
|
'description', 'clinical_significance', 'mechanism', 'management_recommendations',
|
|
'references', 'is_active', 'created_at', 'updated_at'
|
|
]
|
|
read_only_fields = ['interaction_id', 'created_at', 'updated_at']
|
|
|
|
|
|
class PharmacyStatsSerializer(serializers.Serializer):
|
|
"""Serializer for pharmacy statistics"""
|
|
total_prescriptions = serializers.IntegerField()
|
|
pending_prescriptions = serializers.IntegerField()
|
|
filled_today = serializers.IntegerField()
|
|
low_stock_items = serializers.IntegerField()
|
|
expired_items = serializers.IntegerField()
|
|
total_medications = serializers.IntegerField()
|
|
controlled_substances = serializers.IntegerField()
|
|
inventory_value = serializers.DecimalField(max_digits=12, decimal_places=2)
|
|
prescription_types = serializers.DictField()
|
|
status_breakdown = serializers.DictField()
|
|
|
|
|
|
class PrescriptionFillSerializer(serializers.Serializer):
|
|
"""Serializer for filling prescriptions"""
|
|
prescription_id = serializers.IntegerField()
|
|
quantity_dispensed = serializers.IntegerField()
|
|
lot_number = serializers.CharField()
|
|
expiration_date = serializers.DateField()
|
|
pharmacy_location = serializers.CharField()
|
|
patient_counseled = serializers.BooleanField(default=False)
|
|
counseled_by = serializers.IntegerField(required=False)
|
|
medication_guide_provided = serializers.BooleanField(default=False)
|
|
notes = serializers.CharField(required=False, allow_blank=True)
|
|
|
|
def validate_prescription_id(self, value):
|
|
"""Validate that the prescription exists and can be filled"""
|
|
try:
|
|
prescription = Prescription.objects.get(id=value)
|
|
if prescription.status not in ['PENDING', 'IN_PROGRESS']:
|
|
raise serializers.ValidationError(
|
|
"Prescription cannot be filled with current status."
|
|
)
|
|
return value
|
|
except Prescription.DoesNotExist:
|
|
raise serializers.ValidationError("Invalid prescription ID.")
|
|
|
|
def validate_quantity_dispensed(self, value):
|
|
"""Validate dispensed quantity"""
|
|
if value <= 0:
|
|
raise serializers.ValidationError("Quantity dispensed must be greater than 0.")
|
|
return value
|
|
|