@@ -945,3 +945,176 @@ def validate(self, validated_data):
945945 health_instance = HealthData .objects .create (** health_data )
946946 validated_data ["health" ] = health_instance
947947 return validated_data
948+
949+
950+ # Public, flattened serializer for Health Local Units (Type Code = 2)
951+ class _CodeNameSerializer (serializers .Serializer ):
952+ code = serializers .IntegerField ()
953+ name = serializers .CharField ()
954+
955+
956+ class HealthLocalUnitFlatSerializer (serializers .ModelSerializer ):
957+ # LocalUnit basics
958+ id = serializers .IntegerField (read_only = True )
959+ country_id = serializers .IntegerField (source = "country.id" , read_only = True )
960+ country_name = serializers .CharField (source = "country.name" , read_only = True )
961+ country_iso3 = serializers .CharField (source = "country.iso3" , read_only = True )
962+ type_code = serializers .IntegerField (source = "type.code" , read_only = True )
963+ type_name = serializers .CharField (source = "type.name" , read_only = True )
964+ status_display = serializers .CharField (source = "get_status_display" , read_only = True )
965+ location = serializers .SerializerMethodField ()
966+
967+ # HealthData flattened
968+ affiliation = serializers .SerializerMethodField ()
969+ functionality = serializers .SerializerMethodField ()
970+ health_facility_type = serializers .SerializerMethodField ()
971+ primary_health_care_center = serializers .SerializerMethodField ()
972+ hospital_type = serializers .SerializerMethodField ()
973+
974+ general_medical_services = serializers .SerializerMethodField ()
975+ specialized_medical_beyond_primary_level = serializers .SerializerMethodField ()
976+ blood_services = serializers .SerializerMethodField ()
977+ professional_training_facilities = serializers .SerializerMethodField ()
978+
979+ class Meta :
980+ model = LocalUnit
981+ fields = (
982+ # LocalUnit
983+ "id" ,
984+ "country_id" ,
985+ "country_name" ,
986+ "country_iso3" ,
987+ "local_branch_name" ,
988+ "english_branch_name" ,
989+ "address_loc" ,
990+ "address_en" ,
991+ "city_loc" ,
992+ "city_en" ,
993+ "postcode" ,
994+ "phone" ,
995+ "email" ,
996+ "link" ,
997+ "focal_person_loc" ,
998+ "focal_person_en" ,
999+ "date_of_data" ,
1000+ "subtype" ,
1001+ "type_code" ,
1002+ "type_name" ,
1003+ "status" ,
1004+ "status_display" ,
1005+ "location" ,
1006+ # HealthData core
1007+ "affiliation" ,
1008+ "other_affiliation" ,
1009+ "functionality" ,
1010+ "focal_point_email" ,
1011+ "focal_point_phone_number" ,
1012+ "focal_point_position" ,
1013+ "health_facility_type" ,
1014+ "other_facility_type" ,
1015+ "primary_health_care_center" ,
1016+ "speciality" ,
1017+ "hospital_type" ,
1018+ "is_teaching_hospital" ,
1019+ "is_in_patient_capacity" ,
1020+ "is_isolation_rooms_wards" ,
1021+ "maximum_capacity" ,
1022+ "number_of_isolation_rooms" ,
1023+ "is_warehousing" ,
1024+ "is_cold_chain" ,
1025+ "ambulance_type_a" ,
1026+ "ambulance_type_b" ,
1027+ "ambulance_type_c" ,
1028+ "general_medical_services" ,
1029+ "specialized_medical_beyond_primary_level" ,
1030+ "other_services" ,
1031+ "blood_services" ,
1032+ "professional_training_facilities" ,
1033+ "total_number_of_human_resource" ,
1034+ "general_practitioner" ,
1035+ "specialist" ,
1036+ "residents_doctor" ,
1037+ "nurse" ,
1038+ "dentist" ,
1039+ "nursing_aid" ,
1040+ "midwife" ,
1041+ "other_medical_heal" ,
1042+ "other_profiles" ,
1043+ "feedback" ,
1044+ )
1045+
1046+ # NOTE: HealthData direct field mappings via source
1047+ other_affiliation = serializers .CharField (source = "health.other_affiliation" , read_only = True )
1048+ focal_point_email = serializers .EmailField (source = "health.focal_point_email" , read_only = True )
1049+ focal_point_phone_number = serializers .CharField (source = "health.focal_point_phone_number" , read_only = True )
1050+ focal_point_position = serializers .CharField (source = "health.focal_point_position" , read_only = True )
1051+ other_facility_type = serializers .CharField (source = "health.other_facility_type" , read_only = True )
1052+ speciality = serializers .CharField (source = "health.speciality" , read_only = True )
1053+ is_teaching_hospital = serializers .BooleanField (source = "health.is_teaching_hospital" , read_only = True )
1054+ is_in_patient_capacity = serializers .BooleanField (source = "health.is_in_patient_capacity" , read_only = True )
1055+ is_isolation_rooms_wards = serializers .BooleanField (source = "health.is_isolation_rooms_wards" , read_only = True )
1056+ maximum_capacity = serializers .IntegerField (source = "health.maximum_capacity" , read_only = True )
1057+ number_of_isolation_rooms = serializers .IntegerField (source = "health.number_of_isolation_rooms" , read_only = True )
1058+ is_warehousing = serializers .BooleanField (source = "health.is_warehousing" , read_only = True )
1059+ is_cold_chain = serializers .BooleanField (source = "health.is_cold_chain" , read_only = True )
1060+ ambulance_type_a = serializers .IntegerField (source = "health.ambulance_type_a" , read_only = True )
1061+ ambulance_type_b = serializers .IntegerField (source = "health.ambulance_type_b" , read_only = True )
1062+ ambulance_type_c = serializers .IntegerField (source = "health.ambulance_type_c" , read_only = True )
1063+ other_services = serializers .CharField (source = "health.other_services" , read_only = True )
1064+ total_number_of_human_resource = serializers .IntegerField (source = "health.total_number_of_human_resource" , read_only = True )
1065+ general_practitioner = serializers .IntegerField (source = "health.general_practitioner" , read_only = True )
1066+ specialist = serializers .IntegerField (source = "health.specialist" , read_only = True )
1067+ residents_doctor = serializers .IntegerField (source = "health.residents_doctor" , read_only = True )
1068+ nurse = serializers .IntegerField (source = "health.nurse" , read_only = True )
1069+ dentist = serializers .IntegerField (source = "health.dentist" , read_only = True )
1070+ nursing_aid = serializers .IntegerField (source = "health.nursing_aid" , read_only = True )
1071+ midwife = serializers .IntegerField (source = "health.midwife" , read_only = True )
1072+ other_medical_heal = serializers .BooleanField (source = "health.other_medical_heal" , read_only = True )
1073+ other_profiles = serializers .CharField (source = "health.other_profiles" , read_only = True )
1074+ feedback = serializers .CharField (source = "health.feedback" , read_only = True )
1075+
1076+ def get_location (self , unit ) -> dict :
1077+ return {"lat" : unit .location .y , "lng" : unit .location .x }
1078+
1079+ def _code_name (self , obj ):
1080+ if not obj :
1081+ return None
1082+ return {"code" : obj .code , "name" : obj .name }
1083+
1084+ def _code_name_list (self , qs ):
1085+ return [{"code" : x .code , "name" : x .name } for x in qs .all ()] if qs is not None else []
1086+
1087+ def get_affiliation (self , obj ):
1088+ return self ._code_name (getattr (obj .health , "affiliation" , None ) if obj .health else None )
1089+
1090+ def get_functionality (self , obj ):
1091+ return self ._code_name (getattr (obj .health , "functionality" , None ) if obj .health else None )
1092+
1093+ def get_health_facility_type (self , obj ):
1094+ if not obj .health or not obj .health .health_facility_type :
1095+ return None
1096+ ft = obj .health .health_facility_type
1097+ data = {"code" : ft .code , "name" : ft .name }
1098+ # Attach image_url if request in context
1099+ request = self .context .get ("request" ) if self .context else None
1100+ if request :
1101+ data ["image_url" ] = FacilityType .get_image_map (ft .code , request )
1102+ return data
1103+
1104+ def get_primary_health_care_center (self , obj ):
1105+ return self ._code_name (getattr (obj .health , "primary_health_care_center" , None ) if obj .health else None )
1106+
1107+ def get_hospital_type (self , obj ):
1108+ return self ._code_name (getattr (obj .health , "hospital_type" , None ) if obj .health else None )
1109+
1110+ def get_general_medical_services (self , obj ):
1111+ return self ._code_name_list (obj .health .general_medical_services if obj .health else None )
1112+
1113+ def get_specialized_medical_beyond_primary_level (self , obj ):
1114+ return self ._code_name_list (obj .health .specialized_medical_beyond_primary_level if obj .health else None )
1115+
1116+ def get_blood_services (self , obj ):
1117+ return self ._code_name_list (obj .health .blood_services if obj .health else None )
1118+
1119+ def get_professional_training_facilities (self , obj ):
1120+ return self ._code_name_list (obj .health .professional_training_facilities if obj .health else None )
0 commit comments