From 9b6d7152af10d47348ca55f3a76a6024c9ac6a4f Mon Sep 17 00:00:00 2001 From: Pawan Verma Date: Mon, 9 Oct 2023 15:12:54 +0530 Subject: [PATCH 1/4] Add deliver units to opportunity detail UI, accordion for Learn Modules and Deliver units --- .../opportunity/opportunity_detail.html | 79 ++++++++++++++----- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/commcare_connect/templates/opportunity/opportunity_detail.html b/commcare_connect/templates/opportunity/opportunity_detail.html index 4df65b2c..dc829778 100644 --- a/commcare_connect/templates/opportunity/opportunity_detail.html +++ b/commcare_connect/templates/opportunity/opportunity_detail.html @@ -114,27 +114,64 @@

{{ object.name }}

-

Learn App Modules

- - - - - - - - - - - {% for module in object.learn_app.learn_modules.all %} - - - - - - {% endfor %} - -
NameDescriptionTime Estimate
{{ module.name }}{{ module.description }}{{ module.time_estimate }} hour{{ module.time_estimate|pluralize:",s" }}
-
+
+
+

+ +

+
+
+ + + + + + + + + + {% for module in object.learn_app.learn_modules.all %} + + + + + + {% endfor %} + +
NameDescriptionTime Estimate
{{ module.name }}{{ module.description }}{{ module.time_estimate }} hour{{ module.time_estimate|pluralize:",s" }}
+
+
+
+
+

+ +

+
+
+ + + + + + + + + {% for unit in object.deliver_app.deliver_units.all %} + + + + + {% endfor %} + +
NameSlug
{{ unit.name }}{{ unit.slug }}
+
+
+
+
From 4c3828c383411c09a0e7ad055675ebcdccbee2fc Mon Sep 17 00:00:00 2001 From: Pawan Verma Date: Mon, 9 Oct 2023 20:37:47 +0530 Subject: [PATCH 2/4] Add deliver_unit parsing and helpers --- commcare_connect/opportunity/app_xml.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/commcare_connect/opportunity/app_xml.py b/commcare_connect/opportunity/app_xml.py index da2a525e..87e3e8c2 100644 --- a/commcare_connect/opportunity/app_xml.py +++ b/commcare_connect/opportunity/app_xml.py @@ -22,6 +22,12 @@ class Module: time_estimate: int +@dataclass +class DeliverUnit: + id: str + name: str + + class AppNoBuildException(CommCareHQAPIException): pass @@ -31,6 +37,11 @@ def get_connect_blocks_for_app(domain: str, app_id: str) -> list[Module]: return list(itertools.chain.from_iterable(extract_connect_blocks(form_xml) for form_xml in form_xmls)) +def get_deliver_units_for_app(domain: str, app_id: str) -> list[DeliverUnit]: + form_xmls = get_form_xml_for_app(domain, app_id) + return list(itertools.chain.from_iterable(extract_deliver_units(form_xml) for form_xml in form_xmls)) + + def get_form_xml_for_app(domain: str, app_id: str) -> list[str]: """Download the CCZ for the given app and return the XML for each form.""" @@ -74,6 +85,18 @@ def extract_modules(xml: ET.Element): yield Module(slug, name, description, int(time_estimate) if time_estimate is not None else None) +def extract_deliver_units(form_xml): + xml = ET.fromstring(form_xml) + yield from extract_deliver_unit(xml) + + +def extract_deliver_unit(xml: ET.Element): + for block in xml.findall(f".//{XMLNS_PREFIX}deliver"): + slug = block.get("id") + name = get_element_text(block, "name") + yield DeliverUnit(slug, name) + + def get_element_text(parent, name) -> str | None: element = parent.find(f"{XMLNS_PREFIX}{name}") return element.text if element is not None else None From 48df51b4b66790c2cbd9a06c852aba4995eb8ae5 Mon Sep 17 00:00:00 2001 From: Pawan Verma Date: Mon, 9 Oct 2023 20:38:43 +0530 Subject: [PATCH 3/4] Add save deliver_units on opportunity creation --- commcare_connect/opportunity/tasks.py | 21 ++++++++++++++++----- commcare_connect/opportunity/views.py | 4 ++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/commcare_connect/opportunity/tasks.py b/commcare_connect/opportunity/tasks.py index ed337d80..7524cca1 100644 --- a/commcare_connect/opportunity/tasks.py +++ b/commcare_connect/opportunity/tasks.py @@ -4,22 +4,30 @@ from django.core.files.storage import storages from django.utils.timezone import now -from commcare_connect.opportunity.app_xml import get_connect_blocks_for_app +from commcare_connect.opportunity.app_xml import get_connect_blocks_for_app, get_deliver_units_for_app from commcare_connect.opportunity.export import export_empty_payment_table, export_user_visit_data from commcare_connect.opportunity.forms import DateRanges -from commcare_connect.opportunity.models import LearnModule, Opportunity, OpportunityAccess, VisitValidationStatus +from commcare_connect.opportunity.models import ( + DeliverUnit, + LearnModule, + Opportunity, + OpportunityAccess, + VisitValidationStatus, +) from commcare_connect.users.helpers import invite_user from commcare_connect.users.models import User from config import celery_app @celery_app.task() -def create_learn_modules_assessments(opportunity_id): +def create_learn_modules_and_deliver_units(opportunity_id): opportunity = Opportunity.objects.filter(id=opportunity_id).first() learn_app = opportunity.learn_app - connect_blocks = get_connect_blocks_for_app(learn_app.cc_domain, learn_app.cc_app_id) + deliver_app = opportunity.deliver_app + learn_app_connect_blocks = get_connect_blocks_for_app(learn_app.cc_domain, learn_app.cc_app_id) + deliver_app_connect_blocks = get_deliver_units_for_app(deliver_app.cc_domain, deliver_app.cc_app_id) - for block in connect_blocks: + for block in learn_app_connect_blocks: LearnModule.objects.update_or_create( app=learn_app, slug=block.id, @@ -30,6 +38,9 @@ def create_learn_modules_assessments(opportunity_id): }, ) + for block in deliver_app_connect_blocks: + DeliverUnit.objects.get_or_create(app=deliver_app, slug=block.id, defaults=dict(name=block.name)) + @celery_app.task() def add_connect_users(user_list: list[str], opportunity_id: str): diff --git a/commcare_connect/opportunity/views.py b/commcare_connect/opportunity/views.py index a6ff21e1..66c1793a 100644 --- a/commcare_connect/opportunity/views.py +++ b/commcare_connect/opportunity/views.py @@ -33,7 +33,7 @@ from commcare_connect.opportunity.tables import OpportunityAccessTable, PaymentTable, UserStatusTable, UserVisitTable from commcare_connect.opportunity.tasks import ( add_connect_users, - create_learn_modules_assessments, + create_learn_modules_and_deliver_units, generate_payment_export, generate_visit_export, ) @@ -75,7 +75,7 @@ def get_form_kwargs(self): def form_valid(self, form: OpportunityCreationForm) -> HttpResponse: response = super().form_valid(form) - create_learn_modules_assessments.delay(self.object.id) + create_learn_modules_and_deliver_units.delay(self.object.id) return response From 6fc12416796f2f55a9fd97c43da8fc1a0f55ae5b Mon Sep 17 00:00:00 2001 From: Pawan Verma Date: Wed, 11 Oct 2023 11:22:36 +0530 Subject: [PATCH 4/4] Rename column to ID --- commcare_connect/templates/opportunity/opportunity_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commcare_connect/templates/opportunity/opportunity_detail.html b/commcare_connect/templates/opportunity/opportunity_detail.html index dc829778..34a88f69 100644 --- a/commcare_connect/templates/opportunity/opportunity_detail.html +++ b/commcare_connect/templates/opportunity/opportunity_detail.html @@ -156,7 +156,7 @@

Name - Slug + ID