Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add delivery-type, year, quarter filter to admin report #401

Merged
merged 9 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion commcare_connect/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def user(db) -> User:

@pytest.fixture()
def opportunity():
factory = OpportunityFactory()
factory = OpportunityFactory(is_test=False)
OpportunityVerificationFlagsFactory(opportunity=factory)
return factory

Expand Down
9 changes: 9 additions & 0 deletions commcare_connect/opportunity/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ class Meta:
model = "opportunity.HQApiKey"


class DeliveryTypeFactory(DjangoModelFactory):
name = Faker("name")
slug = Faker("pystr")

class Meta:
model = "opportunity.DeliveryType"


class OpportunityFactory(DjangoModelFactory):
organization = SubFactory(OrganizationFactory)
name = Faker("name")
Expand All @@ -47,6 +55,7 @@ class OpportunityFactory(DjangoModelFactory):
budget_per_visit = Faker("pyint", min_value=1, max_value=10)
total_budget = Faker("pyint", min_value=1000, max_value=10000)
api_key = SubFactory(HQApiKeyFactory)
delivery_type = SubFactory(DeliveryTypeFactory)

class Meta:
model = "opportunity.Opportunity"
Expand Down
24 changes: 24 additions & 0 deletions commcare_connect/reports/tables.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from django.urls import reverse
from django.utils.html import format_html
from django_tables2 import columns, tables


class AdminReportTable(tables.Table):
quarter = columns.Column(verbose_name="Quarter")
delivery_type = columns.Column(verbose_name="Delivery Type")
users = columns.Column(verbose_name="Active Users")
services = columns.Column(verbose_name="Verified Services")
approved_payments = columns.Column(verbose_name="Acknowledged Payments")
Expand All @@ -12,3 +15,24 @@ class AdminReportTable(tables.Table):
class Meta:
empty_text = "No data for this quarter."
orderable = False
row_attrs = {"id": lambda record: f"row{record['quarter'][0]}-{record['quarter'][1]}"}

def render_quarter(self, value):
return f"{value[0]} Q{value[1]}"

def render_delivery_type(self, record):
if record["delivery_type"] != "All":
return record["delivery_type"]
url = reverse("reports:delivery_stats_report")
return format_html(
"""<button type="button" class="btn btn-primary btn-sm"
hx-get='{url}?year={year}&quarter={quarter}&by_delivery_type=on&drilldown'
hx-target='#row{year}-{quarter}'
hx-swap="outerHTML"
hx-select="tbody tr">
View all types
</button>""",
url=url,
year=record["quarter"][0],
quarter=record["quarter"][1],
)
Empty file.
64 changes: 64 additions & 0 deletions commcare_connect/reports/tests/test_reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import datetime
import math

import pytest
from factory.faker import Faker

from commcare_connect.conftest import MobileUserFactory
from commcare_connect.opportunity.models import CompletedWorkStatus, Opportunity, VisitValidationStatus
from commcare_connect.opportunity.tests.factories import (
CompletedWorkFactory,
DeliverUnitFactory,
OpportunityAccessFactory,
PaymentUnitFactory,
UserVisitFactory,
)
from commcare_connect.reports.views import _get_table_data_for_quarter


@pytest.mark.django_db
def test_delivery_stats(opportunity: Opportunity):
payment_units = PaymentUnitFactory.create_batch(2, opportunity=opportunity)
mobile_users = MobileUserFactory.create_batch(5)
for payment_unit in payment_units:
DeliverUnitFactory.create_batch(2, payment_unit=payment_unit, app=opportunity.deliver_app, optional=False)
access_objects = []
for mobile_user in mobile_users:
access = OpportunityAccessFactory(user=mobile_user, opportunity=opportunity, accepted=True)
access_objects.append(access)
for payment_unit in payment_units:
completed_work = CompletedWorkFactory(
opportunity_access=access,
payment_unit=payment_unit,
status=CompletedWorkStatus.approved.value,
)
for deliver_unit in payment_unit.deliver_units.all():
UserVisitFactory(
opportunity=opportunity,
user=mobile_user,
deliver_unit=deliver_unit,
status=VisitValidationStatus.approved.value,
opportunity_access=access,
completed_work=completed_work,
visit_date=Faker("date_this_month"),
)

quarter = math.ceil(datetime.datetime.utcnow().month / 12 * 4)

# delivery_type filter not applied
all_data = _get_table_data_for_quarter((datetime.datetime.utcnow().year, quarter), None)
assert all_data["users"] == 5
assert all_data["services"] == 10
assert all_data["beneficiaries"] == 10

# test delivery_type filter
filtered_data = _get_table_data_for_quarter(
(datetime.datetime.utcnow().year, quarter), opportunity.delivery_type.slug
)
assert filtered_data == all_data

# unknown delivery-type should have no data
unknown_delivery_type_data = _get_table_data_for_quarter((datetime.datetime.utcnow().year, quarter), "unknown")
assert unknown_delivery_type_data["users"] == 0
assert unknown_delivery_type_data["services"] == 0
assert unknown_delivery_type_data["beneficiaries"] == 0
2 changes: 1 addition & 1 deletion commcare_connect/reports/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
app_name = "reports"

urlpatterns = [
path("delivery_stats", views.delivery_stats_report, name="delivery_stats_report"),
path("program_dashboard", views.program_dashboard_report, name="program_dashboard_report"),
path("api/visit_map_data/", views.visit_map_data, name="visit_map_data"),
path("delivery_stats", view=views.DeliveryStatsReportView.as_view(), name="delivery_stats_report"),
]
Loading
Loading