diff --git a/registrations/management/commands/tests/test_clinic_list.csv b/registrations/management/commands/tests/test_clinic_list.csv new file mode 100644 index 00000000..4cad12f0 --- /dev/null +++ b/registrations/management/commands/tests/test_clinic_list.csv @@ -0,0 +1,3 @@ +organisationunitname,coordinates,OrgUnitType,OU2short,OU3short,OU4short,OU5uid,OU5code,OrgUnitRuralUrban +Test Clinic 1,"[25.69077,-33.54222]",Clinic,Eastern Cape,Sarah Baartman DM,Sundays River Valley LM,rICptExz4NW,110533,Urban +Test Clinic 2,"[26.29404,-32.69994]",Clinic,Eastern Cape,Amathole DM,Raymond Mhlaba LM,QYdJjvibz4e,429442,Urban diff --git a/registrations/management/commands/tests/test_update_clinics.py b/registrations/management/commands/tests/test_update_clinics.py new file mode 100644 index 00000000..c8b9c6ee --- /dev/null +++ b/registrations/management/commands/tests/test_update_clinics.py @@ -0,0 +1,36 @@ +from django.core.management import call_command +from django.test import TestCase + +from registrations.models import ClinicCode + + +class UpdateClinicsTestCase(TestCase): + def test_update_clinics(self): + existing_clinic = ClinicCode.objects.create( + uid="rICptExz4NW", code="110533", value="110533" + ) + + call_command( + "update_clinics", + "./registrations/management/commands/tests/test_clinic_list.csv", + ) + + existing_clinic.refresh_from_db() + self.assertEqual(existing_clinic.name, "Test Clinic 1") + self.assertEqual(existing_clinic.location, "-33.54222+025.69077/") + self.assertEqual(existing_clinic.province, "ZA-EC") + self.assertEqual(existing_clinic.area_type, "Urban") + self.assertEqual(existing_clinic.unit_type, "Clinic") + self.assertEqual(existing_clinic.district, "Sarah Baartman DM") + self.assertEqual(existing_clinic.municipality, "Sundays River Valley LM") + + new_clinic = ClinicCode.objects.get(uid="QYdJjvibz4e") + self.assertEqual(new_clinic.name, "Test Clinic 2") + self.assertEqual(new_clinic.location, "-32.69994+026.29404/") + self.assertEqual(new_clinic.province, "ZA-EC") + self.assertEqual(new_clinic.area_type, "Urban") + self.assertEqual(new_clinic.unit_type, "Clinic") + self.assertEqual(new_clinic.district, "Amathole DM") + self.assertEqual(new_clinic.municipality, "Raymond Mhlaba LM") + + self.assertEqual(ClinicCode.objects.count(), 2) diff --git a/registrations/management/commands/update_clinics.py b/registrations/management/commands/update_clinics.py new file mode 100644 index 00000000..caa3754c --- /dev/null +++ b/registrations/management/commands/update_clinics.py @@ -0,0 +1,71 @@ +import ast +import csv + +import pycountry +from django.core.management.base import BaseCommand + +from registrations.models import ClinicCode + + +def clean_name(name): + return name.lower().replace(" ", "").replace("-", "").split("(")[0] + + +PROVINCES = { + clean_name(p.name): p.code for p in pycountry.subdivisions.get(country_code="ZA") +} + + +class Command(BaseCommand): + + def add_arguments(self, parser): + parser.add_argument("csv_file", nargs="+", type=str) + + def format_location(self, latitude, longitude): + """ + Returns the location in ISO6709 format + """ + + def fractional_part(f): + if not f % 1: + return "" + parts = str(f).split(".") + return f".{parts[1]}" + + # latitude integer part must be fixed width 2, longitude 3 + return ( + f"{int(latitude):+03d}" + f"{fractional_part(latitude)}" + f"{int(longitude):+04d}" + f"{fractional_part(longitude)}" + "/" + ) + + def get_province(self, row): + return PROVINCES[clean_name(row["OU2short"])] + + def get_location(self, row): + lng, lat = ast.literal_eval(row["coordinates"]) + return self.format_location(lat, lng) + + def handle(self, *args, **options): + print(options["csv_file"]) + for csv_file in options["csv_file"]: + reader = csv.DictReader(open(csv_file)) + + for row in reader: + clinic, created = ClinicCode.objects.update_or_create( + uid=row["OU5uid"], + defaults={ + "code": row["OU5code"], + "value": row["OU5code"], + "name": row["organisationunitname"], + "province": self.get_province(row), + "location": self.get_location(row), + "area_type": row["OrgUnitRuralUrban"], + "unit_type": row["OrgUnitType"], + "district": row["OU3short"], + "municipality": row["OU4short"], + }, + ) + print(f"{'Created' if created else 'Updated'}: {clinic.value}") diff --git a/registrations/migrations/0030_cliniccode_area_type_cliniccode_district_and_more.py b/registrations/migrations/0030_cliniccode_area_type_cliniccode_district_and_more.py new file mode 100644 index 00000000..40c9665e --- /dev/null +++ b/registrations/migrations/0030_cliniccode_area_type_cliniccode_district_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.1.7 on 2024-05-27 14:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("registrations", "0029_alter_historicalpositiontracker_options_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="cliniccode", + name="area_type", + field=models.CharField(blank=True, default=None, max_length=50, null=True), + ), + migrations.AddField( + model_name="cliniccode", + name="district", + field=models.CharField(blank=True, default=None, max_length=50, null=True), + ), + migrations.AddField( + model_name="cliniccode", + name="municipality", + field=models.CharField(blank=True, default=None, max_length=50, null=True), + ), + migrations.AddField( + model_name="cliniccode", + name="unit_type", + field=models.CharField(blank=True, default=None, max_length=50, null=True), + ), + ] diff --git a/registrations/models.py b/registrations/models.py index bb7de328..c96f6b8b 100644 --- a/registrations/models.py +++ b/registrations/models.py @@ -245,6 +245,10 @@ class ClinicCode(models.Model): name = models.CharField(max_length=255) province = models.CharField(max_length=6, blank=True, null=True, default=None) location = models.CharField(max_length=255, blank=True, null=True, default=None) + area_type = models.CharField(max_length=50, blank=True, null=True, default=None) + unit_type = models.CharField(max_length=50, blank=True, null=True, default=None) + district = models.CharField(max_length=50, blank=True, null=True, default=None) + municipality = models.CharField(max_length=50, blank=True, null=True, default=None) class Meta: indexes = [models.Index(fields=["value"])]