From 913299b6e9784c95687439f6b05865ae4578c769 Mon Sep 17 00:00:00 2001 From: Fleury Butoyi Date: Thu, 30 May 2024 13:14:04 +0200 Subject: [PATCH 1/7] Checking if there is at least a proposal review field before create an org unit change request --- setuper/review_change_proposal.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/setuper/review_change_proposal.py b/setuper/review_change_proposal.py index 6c698f1ccc..a246a962b6 100644 --- a/setuper/review_change_proposal.py +++ b/setuper/review_change_proposal.py @@ -50,6 +50,7 @@ def setup_review_change_proposal(account_name, iaso_client): "status": status, } validation = None + proposal_review = None if len(groups) > 0: data["new_groups"] = groups approved_fields.append("new_groups") @@ -64,11 +65,12 @@ def setup_review_change_proposal(account_name, iaso_client): if len(new_reference_instances) > 0: data["new_reference_instances"] = new_reference_instances approved_fields.append("new_reference_instances") - proposal_review = iaso_client.post("/api/orgunits/changes/", json=data) - if status == "approved" or status == "rejected": - validation = { - "approved_fields": approved_fields, - "status": status, - "rejection_comment": status, - } - iaso_client.patch(f"/api/orgunits/changes/{proposal_review['id']}/", json=validation) + if len(approved_fields) > 0: + proposal_review = iaso_client.post("/api/orgunits/changes/", json=data) + if status == "approved" or status == "rejected": + validation = { + "approved_fields": approved_fields, + "status": status, + "rejection_comment": status, + } + iaso_client.patch(f"/api/orgunits/changes/{proposal_review['id']}/", json=validation) From 0b7a0e60c6d5a6d118a9a137e44a858efc17248d Mon Sep 17 00:00:00 2001 From: Fleury Butoyi Date: Fri, 31 May 2024 13:16:00 +0200 Subject: [PATCH 2/7] setting up sub org unit type when importing data from gpkg file --- setuper/pyramid.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/setuper/pyramid.py b/setuper/pyramid.py index e7a1814416..31497724e6 100644 --- a/setuper/pyramid.py +++ b/setuper/pyramid.py @@ -15,6 +15,7 @@ def setup_orgunits(account_name, iaso_client): test_file = "data/small_sample.gpkg" geopackage_file = {"file": (test_file, open(test_file, "rb"), "application/octet-stream")} task = iaso_client.post("/api/tasks/create/importgpkg/", files=geopackage_file, data=data) + print("-- Importing org units") iaso_client.wait_task_completion(task) @@ -26,5 +27,27 @@ def setup_orgunits(account_name, iaso_client): "searches": [{"validation_status": "all", "color": "f4511e", "source": data_source_id}], } task = iaso_client.post("/api/tasks/create/orgunitsbulkupdate/", json=data) - + update_org_unit_sub_type(iaso_client, project_id) iaso_client.wait_task_completion(task) + + +def update_org_unit_sub_type(iaso_client, project_id): + print("-- Updating org unit sub type") + org_unit_types = iaso_client.get("/api/v2/orgunittypes/")["orgUnitTypes"] + for org_unit_type in org_unit_types: + org_unit_type_level = org_unit_type["depth"] + org_unit_type_id = org_unit_type["id"] + sub_unit_type_ids = [ + org_unit_type["id"] + for org_unit_type in org_unit_types + if org_unit_type["depth"] == (org_unit_type_level + 1) + ] + if len(sub_unit_type_ids) > 0: + current_type = { + "name": org_unit_type["name"], + "short_name": org_unit_type["short_name"], + "project_ids": [project_id], + "sub_unit_type_ids": sub_unit_type_ids, + } + # Updating default sub type + iaso_client.patch(f"/api/v2/orgunittypes/{org_unit_type_id}/", json=current_type) From 00b48e0989ff08d95b494bbfe79cebfddc38a8c7 Mon Sep 17 00:00:00 2001 From: Fleury Butoyi Date: Fri, 31 May 2024 13:21:48 +0200 Subject: [PATCH 3/7] Adding test for importing org unit and setting up sub org unit type --- .../test_import_with_sub_org_unit_type.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 iaso/tests/gpkg/test_import_with_sub_org_unit_type.py diff --git a/iaso/tests/gpkg/test_import_with_sub_org_unit_type.py b/iaso/tests/gpkg/test_import_with_sub_org_unit_type.py new file mode 100644 index 0000000000..dcdb24568e --- /dev/null +++ b/iaso/tests/gpkg/test_import_with_sub_org_unit_type.py @@ -0,0 +1,45 @@ +from iaso.gpkg.import_gpkg import import_gpkg_file +from iaso.models import Account, Project +from iaso.test import APITestCase + + +class OrgUnitImportFromGPKG(APITestCase): + @classmethod + def setUpTestData(cls): + cls.account = Account.objects.create(name="a") + cls.user_test = cls.create_user_with_profile(username="test", account=cls.account) + cls.project = Project.objects.create(name="Project 1", account=cls.account, app_id="test_app_id") + + def test_minimal_import_with_sub_org_unit_type(self): + import_gpkg_file( + "./iaso/tests/fixtures/gpkg/minimal.gpkg", + project_id=self.project.id, + source_name="test", + version_number=1, + validation_status="new", + description="", + ) + self.client.force_authenticate(self.user_test) + response = self.client.get("/api/v2/orgunittypes/") + org_unit_types = response.json()["orgUnitTypes"] + + for org_unit_type in org_unit_types: + current_level = org_unit_type["depth"] + current_id = org_unit_type["id"] + sub_unit_type_ids = [ + org_unit_type["id"] for org_unit_type in org_unit_types if org_unit_type["depth"] == (current_level + 1) + ] + + if len(sub_unit_type_ids) > 0: + current_type = { + "name": org_unit_type["name"], + "short_name": org_unit_type["short_name"], + "project_ids": [self.project.id], + "sub_unit_type_ids": sub_unit_type_ids, + } + response = self.client.patch(f"/api/v2/orgunittypes/{current_id}/", data=current_type, format="json") + self.assertJSONResponse(response, 200) + self.assertHasField(response.json(), "sub_unit_types", list) + new_sub_units = response.json()["sub_unit_types"] + new_sub_unit_ids = [sub_unit_type["id"] for sub_unit_type in new_sub_units] + self.assertEqual(new_sub_unit_ids, sub_unit_type_ids) From 12d69924161c10ad8795bc823477e6540c0332af Mon Sep 17 00:00:00 2001 From: Fleury Butoyi Date: Tue, 4 Jun 2024 00:20:29 +0200 Subject: [PATCH 4/7] Remove unused params for org unit seeding --- setuper/setuper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuper/setuper.py b/setuper/setuper.py index 796e4f3012..24b3dd9ccb 100644 --- a/setuper/setuper.py +++ b/setuper/setuper.py @@ -54,7 +54,7 @@ def setup_account(account_name): account_name = "".join(random.choices(string.ascii_lowercase, k=7)) print("Creating account:", account_name) iaso_client = setup_account(account_name) - setup_orgunits(account_name, iaso_client=iaso_client) + setup_orgunits(iaso_client=iaso_client) if seed_default_health_facility_form: setup_health_facility_level_default_form(account_name, iaso_client=iaso_client) From 70f954803bb733705ceacb88b0dbb62e3d5c07af Mon Sep 17 00:00:00 2001 From: Fleury Butoyi Date: Tue, 4 Jun 2024 07:58:31 +0200 Subject: [PATCH 5/7] Refactoring update sub type function --- setuper/pyramid.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/setuper/pyramid.py b/setuper/pyramid.py index 31497724e6..86b2dd73b0 100644 --- a/setuper/pyramid.py +++ b/setuper/pyramid.py @@ -1,4 +1,4 @@ -def setup_orgunits(account_name, iaso_client): +def setup_orgunits(iaso_client): project_id = iaso_client.get("/api/projects/")["projects"][0]["id"] sources = iaso_client.get("/api/datasources/")["sources"] data_source_id = sources[0]["id"] @@ -27,13 +27,14 @@ def setup_orgunits(account_name, iaso_client): "searches": [{"validation_status": "all", "color": "f4511e", "source": data_source_id}], } task = iaso_client.post("/api/tasks/create/orgunitsbulkupdate/", json=data) - update_org_unit_sub_type(iaso_client, project_id) + org_unit_types = iaso_client.get("/api/v2/orgunittypes/")["orgUnitTypes"] + update_org_unit_sub_type(iaso_client, project_id, org_unit_types) iaso_client.wait_task_completion(task) -def update_org_unit_sub_type(iaso_client, project_id): +def update_org_unit_sub_type(iaso_client, project_id, org_unit_types): print("-- Updating org unit sub type") - org_unit_types = iaso_client.get("/api/v2/orgunittypes/")["orgUnitTypes"] + updated_with_sub_types = [] for org_unit_type in org_unit_types: org_unit_type_level = org_unit_type["depth"] org_unit_type_id = org_unit_type["id"] @@ -50,4 +51,7 @@ def update_org_unit_sub_type(iaso_client, project_id): "sub_unit_type_ids": sub_unit_type_ids, } # Updating default sub type - iaso_client.patch(f"/api/v2/orgunittypes/{org_unit_type_id}/", json=current_type) + updated_with_sub_types.append( + iaso_client.patch(f"/api/v2/orgunittypes/{org_unit_type_id}/", json=current_type) + ) + return updated_with_sub_types From 828ab0b8ce1258813de120be57aaf40bf90a3696 Mon Sep 17 00:00:00 2001 From: Fleury Butoyi Date: Tue, 4 Jun 2024 08:00:10 +0200 Subject: [PATCH 6/7] Fix test for update org unit sub type --- .../test_import_with_sub_org_unit_type.py | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/iaso/tests/gpkg/test_import_with_sub_org_unit_type.py b/iaso/tests/gpkg/test_import_with_sub_org_unit_type.py index dcdb24568e..a8296abbed 100644 --- a/iaso/tests/gpkg/test_import_with_sub_org_unit_type.py +++ b/iaso/tests/gpkg/test_import_with_sub_org_unit_type.py @@ -1,6 +1,7 @@ from iaso.gpkg.import_gpkg import import_gpkg_file from iaso.models import Account, Project from iaso.test import APITestCase +from setuper.pyramid import update_org_unit_sub_type class OrgUnitImportFromGPKG(APITestCase): @@ -21,25 +22,10 @@ def test_minimal_import_with_sub_org_unit_type(self): ) self.client.force_authenticate(self.user_test) response = self.client.get("/api/v2/orgunittypes/") - org_unit_types = response.json()["orgUnitTypes"] + self.assertJSONResponse(response, 200) + response_data = response.json() - for org_unit_type in org_unit_types: - current_level = org_unit_type["depth"] - current_id = org_unit_type["id"] - sub_unit_type_ids = [ - org_unit_type["id"] for org_unit_type in org_unit_types if org_unit_type["depth"] == (current_level + 1) - ] + updated_with_sub_types = update_org_unit_sub_type(self.client, self.project.id, response_data["orgUnitTypes"]) - if len(sub_unit_type_ids) > 0: - current_type = { - "name": org_unit_type["name"], - "short_name": org_unit_type["short_name"], - "project_ids": [self.project.id], - "sub_unit_type_ids": sub_unit_type_ids, - } - response = self.client.patch(f"/api/v2/orgunittypes/{current_id}/", data=current_type, format="json") - self.assertJSONResponse(response, 200) - self.assertHasField(response.json(), "sub_unit_types", list) - new_sub_units = response.json()["sub_unit_types"] - new_sub_unit_ids = [sub_unit_type["id"] for sub_unit_type in new_sub_units] - self.assertEqual(new_sub_unit_ids, sub_unit_type_ids) + for org_unit_type_with in updated_with_sub_types: + self.assertJSONResponse(org_unit_type_with, 200) From 71e05adda38288607769ccd930683179e4f3ff1e Mon Sep 17 00:00:00 2001 From: Fleury Butoyi Date: Tue, 4 Jun 2024 08:02:19 +0200 Subject: [PATCH 7/7] Adding setuper folder in docker --- docker-compose.yml | 27 +++++++++++++-------------- setuper/__init__.py | 0 2 files changed, 13 insertions(+), 14 deletions(-) create mode 100644 setuper/__init__.py diff --git a/docker-compose.yml b/docker-compose.yml index 4935f29197..b14a717518 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,7 @@ services: - ./manage.py:/opt/app/manage.py - ./hat:/opt/app/hat - ./iaso:/opt/app/iaso + - ./setuper:/opt/app/setuper - ./beanstalk_worker:/opt/app/beanstalk_worker - ./django_sql_dashboard_export:/opt/app/django_sql_dashboard_export - ./media:/opt/app/media @@ -39,16 +40,16 @@ services: RDS_DB_NAME: THEME_PRIMARY_COLOR: THEME_SECONDARY_COLOR: - THEME_PRIMARY_BACKGROUND_COLOR: - #OpenHexa API token - OPENHEXA_TOKEN: - #OpenHexa API url - OPENHEXA_URL: - #OpenHexa pipeline ID - LQAS_PIPELINE: - #Optional: the version of the pipeline to run - LQAS_PIPELINE_VERSION: - # "prod", "staging" or "custom". Use "custom" for local testing + THEME_PRIMARY_BACKGROUND_COLOR: #OpenHexa API token + + OPENHEXA_TOKEN: #OpenHexa API url + + OPENHEXA_URL: #OpenHexa pipeline ID + + LQAS_PIPELINE: #Optional: the version of the pipeline to run + + LQAS_PIPELINE_VERSION: # "prod", "staging" or "custom". Use "custom" for local testing + OH_PIPELINE_TARGET: FAVICON_PATH: @@ -77,8 +78,7 @@ services: WFP_AUTH_ACCOUNT: WFP_EMAIL_RECIPIENTS_NEW_ACCOUNT: DISABLE_PASSWORD_LOGINS: - SERVER_URL: - # Limit logging in dev to not overflow terminal + SERVER_URL: # Limit logging in dev to not overflow terminal logging: &iaso_logging driver: "json-file" options: @@ -86,8 +86,7 @@ services: command: start_dev db: - image: - iaso/postgis + image: iaso/postgis # Workaround until there is a stable Postgis image for Apple Silicon build: docker/db logging: *iaso_logging diff --git a/setuper/__init__.py b/setuper/__init__.py new file mode 100644 index 0000000000..e69de29bb2