diff --git a/data/districts_points.csv b/data/districts_points.csv new file mode 100644 index 000000000..abb32b35a --- /dev/null +++ b/data/districts_points.csv @@ -0,0 +1,30 @@ +dname,code,longitude,latitude +Balaka,36,35.05315978998695,-15.04847375 +Blantyre,29,35.0035694,-15.7862543 +Chikwawa,33,34.72283932431507,-16.21538195 +Chiladzulu,28,35.20553617052023,-15.754719999999999 +Chitipa,01,33.41202427956999,-9.9728541 +Dedza,17,34.31965143966403,-14.2374479 +Dowa,13,33.7781079828639,-13.53875785 +Karonga,02,33.86619181196623,-10.08474695 +Kasungu,10,33.472356695915096,-12.992487650000001 +Likoma,06,34.734435755418986,-12.066386300000001 +Lilongwe,15,33.768144,-13.9875107 +Machinga,26,35.60258156267952,-14.902749700000001 +Mangochi,25,35.32636243192955,-14.1406247 +Mchinji,16,33.020473863724945,-13.782889749999999 +Mulanje,32,35.54125499990176,-15.91088 +Mwanza,30,34.51465953401936,-15.61360315 +Mzimba North,07,33.5843626,-11.8989048 +Mzimba South,05,33.5843626,-11.8989048 +Neno,37,34.68322049013118,-15.51371825 +Nkhatabay,03,34.68322049013118,-15.51371825 +Nkhotakota,11,34.032917703204646,-12.8321965 +Nsanje,34,35.101108793623865,-16.7199917 +Ntcheu,18,34.765831629561944,-14.83041285 +Ntchisi,12,33.854627197691315,-13.27698805 +Phalombe,35,35.66505231082681,-15.69220705 +Rumphi,04,33.85071177603609,-10.790932649999998 +Salima,14,34.452369976445496,-13.762898400000001 +Thyolo,31,35.14491322382413,-16.128774749999998 +Zomba,27,35.3268273,-15.3863208 \ No newline at end of file diff --git a/data/facilities_points.csv b/data/facilities_points.csv new file mode 100644 index 000000000..5e06c7c7a --- /dev/null +++ b/data/facilities_points.csv @@ -0,0 +1,27 @@ +facility_id,latitude,longitude +2439,-14.98498,34.94959 +2440,-14.990816,34.960833 +2441,-14.84268,35.17081 +2442,-15.05425,34.92264 +2443,-14.91088,35.05326 +7617,-15.77128,34.98156 +7618,-15.77733,34.88548 +7621,-15.52963,35.02973 +10253,-15.7781,35.03946 +10255,-15.80214,35.021 +7629,-15.80918,35.01977 +10259,-15.817047,35.014587 +1910,-13.94454,33.77083 +1912,-13.99164, 33.77561 +1954,-13.98131,33.82105 +1930,-13.77074,33.80477 +1947,-14.04389,34.1036 +7350,-14.6996,34.9732 +7352,-14.36298,35.44253 +7365,-14.48191,35.26527 +7368,-16.033665667119127,34.98522945745857 +7371,-14.3637,35.50221 +6519,-13.88028,34.36721 +6501,-13.66454,34.38503 +6502,-13.98973,34.51545 +6512,-13.76214,34.42199 \ No newline at end of file diff --git a/data/malawian_names.csv b/data/malawian_names.csv new file mode 100644 index 000000000..89890dbb5 --- /dev/null +++ b/data/malawian_names.csv @@ -0,0 +1,150 @@ +fname,lname +Grace,Banda +Chimwemwe,Phiri +Gift,Nyirenda +Blessings,Chirwa +Mercy,Mwale +Chisomo,Nkhoma +Emmanuel,Mkandawire +Martha,Gondwe +Memory,Kamanga +Mary,Mhango +Alinafe,Munthali +Mphatso,Moyo +Joseph,Mbewe +Esther,Tembo +James,Jere +Peter,Kumwenda +John,Manda +Innocent,Msiska +Chikondi,Ngwira +Patrick,Kaunda +Madalitso,Nyirongo +Ruth,Nkhata +Charles,Mvula +Patricia,Nyasulu +Chifundo,Chisale +Catherine,Gama +Andrew,Mhone +Charity,Kamwendo +Thokozani,Zimba +Kondwani,Soko +Precious,Mtambo +Isaac,Chavula +Steven,Magombo +Agness,Msukwa +Francis,Mphande +Yamikani,Kazembe +Moses,Lungu +Daniel,Chunga +Frank,Shaba +Maria,Mussa +Paul,Kondowe +Annie,Chipeta +George,Longwe +Alice,Nyondo +Christopher,Ngoma +Samuel,Saidi +Elizabeth,Chirambo +Linda,Kachingwe +Beatrice,Msowoya +Richard,Chiwaya +Bertha,Bwanali +Vincent,Luhanga +Stella,Kayira +Lucy,Mtonga +Christina,Samson +Emily,Kayange +Joyce,Harawa +Rose,Malunga +Davie,Hara +Brenda,Mponda +Florence,Kalua +Robert,Chiumia +Gloria,Juma +Loveness,Ngulube +Ellen,Dickson +Ethel,Mwafulirwa +Bridget,Moses +Judith,Zulu +Henry,Chisi +Rabecca,Mumba +Doreen,Ndhlovu +Faith,Chawinga +Felix,Mbale +Getrude,Kaonga +Ireen,Maluwa +Victor,Mwanza +Eunice,Chibwana +William,Maseko +Angella,Mwandira +Victoria,Yohane +Veronica,Mwase +Monica,Mandala +Mirriam,Samuel +Jane,Mughogho +Pilirani,Zgambo +Violet,Saka +Prisca,Tambala +Michael,Botha +Alex,Majawa +Eliza,Masamba +Cecilia,Sichali +Dorothy,Frank +Yohane,Ng'ambi +Mathews,Jumbe +Alfred,Khonje +Magret,Kawonga +Sarah,Maganga +Martin,Makina +Edward,Nkosi +Clement,Singini +Chikumbutso,Gomani +Samson,Mlenga +Esnart,Chimwaza +Mike,Mangani +Kelvin,Mfune +Aubrey,Chilongo +Thomas,Milanzi +Tadala,Kalonga +Bright,Sakala +Tiyamike,Makawa +Evelyn,Thom +Rhoda,Master +Tiwonge,Makwinja +Happy,Chimaliro +Janet,Patrick +Naomi,Kanyenda +Caroline,Kamoto +Dalitso,Chikopa +Chrissy,Chabwera +Gladys,Josephy +Zione,Maulidi +Maxwell,Kambalame +Noel,Ngambi +Vitumbiko,Chinyama +Jonathan,Kaliati +Enock,Matola +Regina,Robert +Austin,Simwaka +Wezzie,Chimwala +David,Matemba +Tionge,Ndalama +Chifuniro,Nkhonjera +Brian,Kaira +Susan,Kanyika +Aaron,Sibale +Maggie,Chima +Patience,Chiona +Amos,Kapalamula +Flora,Bandawe +Shadreck,Kalima +Phillip,Mzumara +Prince,Selemani +Alick,Moffat +Owen,Ng'oma +Nelson,Chimombo +Maureen,Julius +Chipiliro,Kayuni +Fanny,Zuze +Wongani,Simbeye \ No newline at end of file diff --git a/generate_data.py b/generate_data.py new file mode 100644 index 000000000..99f15657f --- /dev/null +++ b/generate_data.py @@ -0,0 +1,117 @@ +from rapidsms.models import Contact, Connection, Backend +from logistics.models import ContactRole, SupplyPoint, Product, SupplyPointType, ProductReportsHelper, StockRequest +from rapidsms.contrib.locations.models import Location, Point, LocationType +from logistics.util import config +from logistics.shortcuts import create_stock_report +from geopy.geocoders import Nominatim +from phone_gen import PhoneNumber +import os +import pandas as pd +from datetime import datetime +import random +# read data from csv files +DATA_DIR = os.path.join(os.getcwd(), "data") +name_data_fpath = os.path.join(DATA_DIR, "malawian_names.csv") +district_data_fpath = os.path.join(DATA_DIR, "districts_points.csv") +facility_data_fpath = os.path.join(DATA_DIR, "facilities_points.csv") + +names_data = pd.read_csv(name_data_fpath) +fnames = list(names_data["fname"].values) +lnames = list(names_data["lname"].values) + +district_data = pd.read_csv(district_data_fpath, dtype={'code':str}) +district_codes = list(district_data["code"].values) +district_latitudes = list(district_data["latitude"].values) +district_longitudes = list(district_data["longitude"].values) + +facility_data = pd.read_csv(facility_data_fpath) +facility_ids = list(facility_data["facility_id"].values) +fac_latitudes = list(facility_data["latitude"].values) +fac_longitudes = list(facility_data["longitude"].values) + +# 1. Populate initial coordinates (all districts, 26 facilities across 5 districts) +# a) Populate coordinates for all districts +for (code, lat, long) in zip(district_codes, district_latitudes, district_longitudes): + supply_point = SupplyPoint.objects.get(code=code) + location = supply_point.location + point = Point(latitude=lat, longitude=long) + point.save() + location.point = point + location.save() + +# b) Populate coordinates for health facilities +for (id, lat, long) in zip(facility_ids, fac_latitudes, fac_longitudes): + supply_point = SupplyPoint.objects.get(pk=id) + location = supply_point.location + point = Point(latitude=lat, longitude=long) + point.save() + location.point = point + location.save() + +# 2. Register contacts and supply points for the health facilities +# a) retrieve supply points and respective codes +locations = Location.objects.filter(point__isnull=False, type_id='facility') +location_codes = [loc.code for loc in locations] +supply_points = SupplyPoint.objects.filter(code__in=location_codes) + +# b) iterate locations and create new locations, supply points, contacts, associate products, and record product stock +hsa_loc_type = LocationType.objects.get(slug='hsa') +hsa_sup_point_type = SupplyPointType.objects.get(code='hsa') +hsa_contact_role = ContactRole.objects.get(code='hsa') +backend = Backend.objects.get(pk=1) +phone_number_gen = PhoneNumber("MW") + +for supply_point in supply_points: + for i in range(1, 5): + # generate id and name + hsa_id = "%s%02d" % (supply_point.code, i) + contact_name = "%s %s" % (random.choice(fnames), random.choice(lnames)) + print(f"Processing {contact_name} {hsa_id}") + # create location + hsa_loc = Location.objects.create(name=contact_name, type=hsa_loc_type, code=hsa_id, parent=supply_point.location) + # create supply point + sp = SupplyPoint.objects.create(name=contact_name, code=hsa_id, type=config.hsa_supply_point_type(),location=hsa_loc, supplied_by=supply_point) + + # create contact + contact = Contact(name=contact_name, supply_point=sp, role=hsa_contact_role,is_active=True,is_approved=True) + contact.save() + + # create connection + phone_number = phone_number_gen.mobile_number() + connection = Connection(backend=backend, identity=phone_number, contact=contact) + connection.save() + + # associate with products + available_products = [p for p in Product.objects.filter(type__base_level='h', is_active=True)] + selected_products = random.sample(available_products, k=5) + + soh_report = [] + rec_report = [] + + for product in selected_products: + sp.activate_product(product) + contact.commodities.add(product) + contact.save() + + soh_quantity = random.randint(1, product.average_monthly_consumption) + rec_quantity = random.randint(1, product.average_monthly_consumption) + 5 + soh_report.append(f"{product.sms_code} {soh_quantity}") + rec_report.append(f"{product.sms_code} {rec_quantity}") + + # add stock records + # report stock on hand using SOH message pattern + soh_text = " ".join(soh_report) + soh_stock_report = create_stock_report("soh",sp,soh_text) + stock_requests = StockRequest.create_from_report(soh_stock_report,contact) + + # confirm readiness of order + #pending_reqs = StockRequest.pending_requests().filter(supply_point=supply_point) + for req in stock_requests: + req.approve(contact, datetime.utcnow(), req.amount_requested) + + # confirm receipt of products + rec_text = " ".join(soh_report) + rec_stock_report = ProductReportsHelper(sp,'rec') + rec_stock_report.newparse(rec_text) + rec_stock_report.save() + StockRequest.close_pending_from_receipt_report(rec_stock_report, contact)