2025-08-12 13:33:25 +03:00

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