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 Enterprise Case Management Report #35482

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
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
65 changes: 65 additions & 0 deletions corehq/apps/enterprise/enterprise.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from corehq.apps.domain.calculations import sms_in_last
from corehq.apps.domain.models import Domain
from corehq.apps.es import forms as form_es
from corehq.apps.es import filters
from corehq.apps.es.apps import AppES
from corehq.apps.es.users import UserES
from corehq.apps.export.dbaccessors import ODataExportFetcher
from corehq.apps.users.dbaccessors import (
Expand Down Expand Up @@ -383,3 +385,66 @@ def _get_individual_export_rows(self, exports, export_line_counts):
)

return rows


class EnterpriseCaseManagementReport(EnterpriseReport):
title = gettext_lazy('Case Management')

@property
def headers(self):
return [_('Project Space'), _('# Applications'), _('# Surveys Only'), _('# Cases Only'), _('# Mixed')]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# of instead of # for the last 4 columns?


def rows_for_domain(self, domain_obj):
app_query = self.app_query(domain_obj.name)
app_count = app_query.count()

if app_count == 0:
survey_only_count = 0
case_only_count = 0
mixed_count = 0
else:
has_surveys = filters.nested('modules', filters.empty('modules.case_type.exact'))
has_cases = filters.nested('modules', filters.non_null('modules.case_type.exact'))

survey_only_count = app_query.filter(filters.AND(has_surveys, filters.NOT(has_cases))).count()
case_only_count = app_query.filter(filters.AND(has_cases, filters.NOT(has_surveys))).count()
mixed_count = app_query.filter(filters.AND(has_surveys, has_cases)).count()
Comment on lines +409 to +414
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elegant... nice naming and nice logic


return [[domain_obj.name, app_count, survey_only_count, case_only_count, mixed_count],]

@property
def total(self):
num_domains_with_apps = 0
num_domains_using_case_management = 0

for domain_obj in self.domains():
(app_count, uses_case_management) = self.total_for_domain(domain_obj)
if app_count > 0:
if uses_case_management:
num_domains_using_case_management += 1
num_domains_with_apps += 1

if num_domains_with_apps == 0:
return '--'

case_management_percent = num_domains_using_case_management / num_domains_with_apps * 100

return "{:.1f}%".format(case_management_percent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a util function for display percentage with only one digit in 1aec926. Can reuse it after my PR is merged.


def total_for_domain(self, domain_obj):
app_query = self.app_query(domain_obj.name)
app_count = app_query.count()
if app_count > 0:
has_cases = filters.nested('modules', filters.non_null('modules.case_type.exact'))
uses_case_management = app_query.filter(has_cases).count() > 0
else:
uses_case_management = False

return [app_count, uses_case_management]

def app_query(self, domain):
return (
AppES().domain(domain)
.filter(filters.term('doc_type', 'Application'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this to make sure we don't get LinkedApplications or RemoteApps?

.is_build(False)
)