Skip to content

Commit

Permalink
Merge pull request #157 from dimagi/pkv/opportunity-details-ui-delive…
Browse files Browse the repository at this point in the history
…r-units

Add deliver units to opportunity detail UI, accordion for Learn Modules and Deliver units
  • Loading branch information
pxwxnvermx authored Oct 12, 2023
2 parents 7274405 + 6fc1241 commit 800af1b
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 28 deletions.
23 changes: 23 additions & 0 deletions commcare_connect/opportunity/app_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ class Module:
time_estimate: int


@dataclass
class DeliverUnit:
id: str
name: str


class AppNoBuildException(CommCareHQAPIException):
pass

Expand All @@ -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."""

Expand Down Expand Up @@ -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
21 changes: 16 additions & 5 deletions commcare_connect/opportunity/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@
from django.core.files.storage import default_storage
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,
Expand All @@ -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):
Expand Down
4 changes: 2 additions & 2 deletions commcare_connect/opportunity/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
Expand Down Expand Up @@ -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


Expand Down
79 changes: 58 additions & 21 deletions commcare_connect/templates/opportunity/opportunity_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,64 @@ <h1 class="display-5 mb-0">{{ object.name }}</h1>
</tr>
</tbody>
</table>
<h4>Learn App Modules</h4>

<table class="table border table-custom">
<thead class="table-light">
<tr>
<th>Name</th>
<th>Description</th>
<th>Time Estimate</th>
</tr>
</thead>
<tbody>
{% for module in object.learn_app.learn_modules.all %}
<tr>
<td>{{ module.name }}</td>
<td>{{ module.description }}</td>
<td>{{ module.time_estimate }} hour{{ module.time_estimate|pluralize:",s" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<hr/>
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#learn-app-modules" aria-expanded="true" aria-controls="collapseOne">
Learn App Modules
</button>
</h2>
<div id="learn-app-modules" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body p-0 m-0">
<table class="table table-borderless table-custom">
<thead class="table-light">
<tr>
<th>Name</th>
<th>Description</th>
<th>Time Estimate</th>
</tr>
</thead>
<tbody>
{% for module in object.learn_app.learn_modules.all %}
<tr>
<td>{{ module.name }}</td>
<td>{{ module.description }}</td>
<td>{{ module.time_estimate }} hour{{ module.time_estimate|pluralize:",s" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingTwo">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#deliver-units" aria-expanded="false" aria-controls="collapseTwo">
Deliver Units
</button>
</h2>
<div id="deliver-units" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#accordionExample">
<div class="accordion-body p-0 m-0">
<table class="table table-borderless table-custom">
<thead class="table-light">
<tr>
<th>Name</th>
<th>ID</th>
</tr>
</thead>
<tbody>
{% for unit in object.deliver_app.deliver_units.all %}
<tr>
<td>{{ unit.name }}</td>
<td>{{ unit.slug }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>

<div class="pt-2 px-4">
Expand Down

0 comments on commit 800af1b

Please sign in to comment.