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