Beispiel #1
0
    def get_pact_cases(cls):
        # query couch to get reduce count of all PACT cases
        case_es = ReportCaseES(PACT_DOMAIN)
        total_count = CommCareCase.get_db().view('hqcase/types_by_domain',
                                                 key=["pact", PACT_CASE_TYPE]).first().get('value', 100)
        fields = ['_id', 'name', 'pactid.#value']
        query = case_es.base_query(terms={'type': PACT_CASE_TYPE},
                                   fields=fields,
                                   start=0,
                                   size=total_count)
        query['filter']['and'].append({"prefix": {"dot_status.#value": "dot"}})

        results = case_es.run_query(query)
        for res in results['hits']['hits']:
            yield res['fields']
Beispiel #2
0
    def get_pact_cases(cls):
        #query couch to get reduce count of all PACT cases
        case_es = ReportCaseES(PACT_DOMAIN)
        total_count = CommCareCase.get_db().view('hqcase/types_by_domain',
                                                 key=["pact", PACT_CASE_TYPE]).first().get('value', 100)
        fields = ['_id', 'name', 'pactid.#value']
        query = case_es.base_query(terms={'type': PACT_CASE_TYPE},
                                   fields=fields,
                                   start=0,
                                   size=total_count)
        query['filter']['and'].append({"prefix": {"dot_status.#value": "dot"}})

        results = case_es.run_query(query)
        for res in results['hits']['hits']:
            yield res['fields']
Beispiel #3
0
    def get_pact_cases(cls):
        # query couch to get reduce count of all PACT cases
        case_es = ReportCaseES(PACT_DOMAIN)
        # why 'or 100'??
        total_count = \
            get_number_of_cases_in_domain('pact', type=PACT_CASE_TYPE) or 100
        fields = ['_id', 'name', 'pactid.#value']
        query = case_es.base_query(terms={'type': PACT_CASE_TYPE},
                                   fields=fields,
                                   start=0,
                                   size=total_count)
        query['filter']['and'].append({"prefix": {"dot_status.#value": "dot"}})

        results = case_es.run_query(query)
        for res in results['hits']['hits']:
            yield res['fields']
def get_due_list_records(target_date, owner_id=None, task_types=None, case_es=None, size=MAX_ES_RESULTS, case_type='task'):
    '''
    A drill-down of the get_due_list_by_task_name, this returns the records for a particular
    set of types (which is the type of vaccination)
    '''
    case_es = case_es or ReportCaseES(BIHAR_DOMAIN)
    es_type = None

    # The type of vaccination is stored in the `name` field in ElasticSearch
    # so we filter on `name.exact` so that "OPV 1" is not tokenized into two words

    base_query = case_es.base_query(start=0, size=size)

    owner_filter = {"match_all":{}} if owner_id is None else {"term": {"owner_id": owner_id}}

    name_filter = {"match_all":{}} if not task_types else {"terms": {"task_id.#value": task_types}}
    filter = {
        "and": [
            owner_filter,
            name_filter,
            {"term": {"closed": False}},
            {"term": {"type": case_type}},
            {"range": {"date_eligible.#value": {"to": target_date.isoformat() }}},
            {"range": {"date_expires.#value": {"from": target_date.isoformat()}}},
        ]
    }

    base_query['filter']['and'] += filter['and']
    es_result = case_es.run_query(base_query, es_type=es_type)
    return (result['_source'] for result in es_result['hits']['hits'])
def get_due_list_by_task_name(target_date, owner_id=None, case_es=None, size=0, case_type='task'):
    case_es = case_es or ReportCaseES(BIHAR_DOMAIN)
    es_type=None
    facet_name = 'vaccination_names'

    # The type of vaccination is stored in the `name` field in ElasticSearch
    # so we can get the sums directly as facets on `name.exact` where the `.exact`
    # is to avoid tokenization so that "OPV 1" does not create two facets.

    base_query = case_es.base_query(start=0, size=size)

    owner_filter = {"match_all":{}} if owner_id is None else {"term": {"owner_id": owner_id}}

    filter = {
        "and": [
            owner_filter,
            {"term": {"closed": False}},
            {"term": {"type": case_type}},
            {"range": {"date_eligible.#value": {"to": json_format_date(target_date)}}},
            {"range": {"date_expires.#value": {"from": json_format_date(target_date)}}},
        ]
    }

    base_query['filter']['and'] += filter['and']
    base_query['facets'] = {
        facet_name: {
            "terms": {"field":"task_id.#value", "size": 1000},
            "facet_filter": filter # This controls the records processed for the summation
        }
    }
    es_result = case_es.run_query(base_query, es_type=es_type)
    return ((facet['term'], facet['count']) for facet in es_result['facets'][facet_name]['terms'])
Beispiel #6
0
    def get_pact_cases(cls):
        # query couch to get reduce count of all PACT cases
        case_es = ReportCaseES(PACT_DOMAIN)
        # why 'or 100'??
        total_count = \
            get_number_of_cases_in_domain_of_type('pact', case_type=PACT_CASE_TYPE) or 100
        fields = ['_id', 'name', 'pactid.#value']
        query = case_es.base_query(terms={'type': PACT_CASE_TYPE},
                                   fields=fields,
                                   start=0,
                                   size=total_count)
        query['filter']['and'].append({"prefix": {"dot_status.#value": "dot"}})

        results = case_es.run_query(query)
        for res in results['hits']['hits']:
            yield res['fields']
Beispiel #7
0
def get_patient_display_cache(case_ids):
    """
    For a given set of case_ids, return name and pact_ids
    """
    if len(case_ids) == 0:
        return {}
    case_es = ReportCaseES(PACT_DOMAIN)
    query = {
        "fields": [
            "_id",
            "name",
        ],
        "script_fields": {
            "case_id": {
                "script": "_source._id"
            },
            "pactid": get_report_script_field("pactid"),
            "first_name": get_report_script_field("first_name"),
            "last_name": get_report_script_field("last_name"),
        },
        "filter": {
            "and": [
                {
                    "term": {
                        "domain.exact": "pact"
                    }
                },
                {
                    "ids": {
                        "values": case_ids,
                    }
                }
            ]
        },
        "size": len(case_ids)
    }
    res = case_es.run_query(query)

    from pact.reports.patient import PactPatientInfoReport

    ret = {}
    for entry in res['hits']['hits']:
        case_id = entry['fields']['case_id']
        ret[case_id] = entry['fields']
        ret[case_id]['url'] = PactPatientInfoReport.get_url(*['pact']) + "?patient_id=%s" % case_id

    return ret
Beispiel #8
0
def get_patient_display_cache(case_ids):
    """
    For a given set of case_ids, return name and pact_ids
    """
    if len(case_ids) == 0:
        return {}
    case_es = ReportCaseES(PACT_DOMAIN)
    query = {
        "fields": [
            "_id",
            "name",
        ],
        "script_fields": {
            "case_id": {
                "script": "_source._id"
            },
            "pactid": get_report_script_field("pactid"),
            "first_name": get_report_script_field("first_name"),
            "last_name": get_report_script_field("last_name"),
        },
        "filter": {
            "and": [
                {
                    "term": {
                        "domain.exact": "pact"
                    }
                },
                {
                    "ids": {
                        "values": case_ids,
                    }
                }
            ]
        },
        "size": len(case_ids)
    }
    res = case_es.run_query(query)

    from pact.reports.patient import PactPatientInfoReport

    ret = {}
    for entry in res['hits']['hits']:
        case_id = entry['fields']['case_id']
        ret[case_id] = entry['fields']
        ret[case_id]['url'] = PactPatientInfoReport.get_url(*['pact']) + "?patient_id=%s" % case_id

    return ret
Beispiel #9
0
 def __init__(self, request, casedoc, *args, **kwargs):
     super(PactPatientForm, self).__init__(*args, **kwargs)
     self.casedoc = casedoc
     self.fields['hp'].choices = get_hp_choices()
     self.case_es = ReportCaseES(request.domain)
     for name, field in self.fields.items():
         if name == CASE_ART_REGIMEN_PROP:
             #these really should be a widget of some type
             #dereference the artregimen, dot_a_one...etc to become the comma separated regimen string for the form
             art_regimen_initial = self.casedoc.art_regimen_label_string()
             casedoc_value = art_regimen_initial
         elif name == CASE_NONART_REGIMEN_PROP:
             nonart_regimen_initial = self.casedoc.nonart_regimen_label_string(
             )
             casedoc_value = nonart_regimen_initial
         else:
             casedoc_value = getattr(self.casedoc, name, '')
         field.initial = casedoc_value
Beispiel #10
0
 def case_es(self):
     return ReportCaseES(self.domain)
Beispiel #11
0
class PatientListDashboardReport(PactElasticTabularReportMixin):
    name = "All Patients"
    slug = "patients"
    ajax_pagination = True
    asynchronous = True
    default_sort = {"pactid": "asc"}
    report_template_path = "reports/async/tabular.html"
    flush_layout = True

    fields = [
        'pact.reports.patient_list.PactPrimaryHPField',
        'pact.reports.patient_list.HPStatusField',
        'pact.reports.patient_list.DOTStatus',
    ]
    case_es = ReportCaseES(PACT_DOMAIN)
    xform_es = ReportXFormES(PACT_DOMAIN)

    def get_pact_cases(self):
        query = self.case_es.base_query(start=0, size=None)
        query['fields'] = ['_id', 'name', 'pactid.#value']
        results = self.case_es.run_query(query)
        for res in results['hits']['hits']:
            yield res['fields']

    @property
    def headers(self):
        headers = DataTablesHeader(
            DataTablesColumn("PACT ID", prop_name="pactid.#value"),
            DataTablesColumn("Name", prop_name="name", sortable=False, span=3),
            DataTablesColumn("Primary HP", prop_name="hp.#value"),
            DataTablesColumn("Opened On", prop_name="opened_on"),
            DataTablesColumn("Last Modified", prop_name="modified_on"),
            DataTablesColumn("HP Status", prop_name="hp_status.#value"),
            DataTablesColumn("DOT Status", prop_name='dot_status.#value'),
            DataTablesColumn("Status", prop_name="closed"),
            DataTablesColumn("Submissions", sortable=False),
        )
        return headers

    def case_submits_facet_dict(self, limit):
        query = query_per_case_submissions_facet(self.request.domain, limit=limit)
        results = self.xform_es.run_query(query)
        case_id_count_map = {}
        for f in results['facets']['case_submissions']['terms']:
            case_id_count_map[f['term']] = f['count']
        return case_id_count_map

    @property
    def rows(self):
        """
            Override this method to create a functional tabular report.
            Returns 2D list of rows.
            [['row1'],[row2']]
        """
        def _format_row(row_field_dict):
            yield row_field_dict.get("pactid.#value", '---').replace('_', ' ').title()
            yield self.pact_case_link(row_field_dict['_id'], row_field_dict.get("name", "---")),
            yield row_field_dict.get("hp.#value", "---")
            yield self.format_date(row_field_dict.get("opened_on"))
            yield self.format_date(row_field_dict.get("modified_on"))
            yield self.render_hp_status(row_field_dict.get("hp_status.#value"))
            yield self.pact_dot_link(row_field_dict['_id'], row_field_dict.get("dot_status.#value"))
            #for closed on, do two checks:
            if row_field_dict.get('closed', False):
                #it's closed
                yield "Closed (%s)" % self.format_date(row_field_dict.get('closed_on'))
            else:
                yield "Active"

            yield facet_dict.get(row_field_dict['_id'], 0)

        res = self.es_results
        if res.has_key('error'):
            pass
        else:
            #hack, do a facet query here
            facet_dict = self.case_submits_facet_dict(SIZE_LIMIT)
            for result in res['hits']['hits']:
                yield list(_format_row(result['fields']))

    @property
    def es_results(self):
        fields = [
            "_id",
            "name",
            "pactid.#value",
            "opened_on",
            "modified_on",
            "hp_status.#value",
            "hp.#value",
            "dot_status.#value",
            "closed_on",
            "closed"
        ]
        full_query = self.case_es.base_query(terms={'type': PACT_CASE_TYPE}, fields=fields,
                                             start=self.pagination.start,
                                             size=self.pagination.count)
        full_query['sort'] = self.get_sorting_block()

        def status_filtering(slug, field, prefix, any_field, default):
            if self.request.GET.get(slug, None) is not None:
                field_status_filter_query = self.request.GET[slug]

                if field_status_filter_query == "":
                    #silly double default checker here - set default or the any depending on preference
                    field_status_filter_query = default

                if field_status_filter_query is None:
                    return
                else:
                    if field_status_filter_query.startswith(prefix):
                        field_status_prefix = field_status_filter_query
                    elif field_status_filter_query == any_field:
                        field_status_prefix = prefix
                    else:
                        field_status_prefix = None
                        full_query['filter']['and'].append({"term": {field: field_status_filter_query.lower()}})

                    if field_status_prefix is not None:
                        field_filter = {"prefix": {field: field_status_prefix.lower()}}
                        full_query['filter']['and'].append(field_filter)

        status_filtering(DOTStatus.slug, "dot_status.#value", "DOT", DOTStatus.ANY_DOT, None)
        status_filtering(HPStatusField.slug, "hp_status.#value", "HP", HPStatusField.ANY_HP, HPStatusField.ANY_HP)

        #primary_hp filter from the user filter
        if self.request.GET.get(PactPrimaryHPField.slug, "") != "":
            primary_hp_term = self.request.GET[PactPrimaryHPField.slug]
            primary_hp_filter = {"term": {"hp.#value": primary_hp_term}}
            full_query['filter']['and'].append(primary_hp_filter)
        return self.case_es.run_query(full_query)

    def pact_case_link(self, case_id, name):
        try:
            return html.mark_safe("<a class='ajax_dialog' href='%s'>%s</a>" % (
                html.escape(
                    PactPatientInfoReport.get_url(*[self.domain]) + "?patient_id=%s" % case_id),
                html.escape(name),
                ))
        except NoReverseMatch:
            return "%s (bad ID format)" % name

    def render_hp_status(self, status):
        if status is None or status == '':
            return ''
        else:
            if status.lower() == 'discharged':
                css = 'label'
            else:
                css = 'label label-info'
            return '<span class="%s">%s</span>' % (css, status)

    def pact_dot_link(self, case_id, status):

        if status is None or status == '':
            return ''

        try:
            return html.mark_safe("<span class='label label-info'>%s</span> <a class='ajax_dialog' href='%s'>Report</a>" % (
                html.escape(status),
                html.escape(
                    PactDOTReport.get_url(*[self.domain]) + "?dot_patient=%s" % case_id),
                ))
        except NoReverseMatch:
            return "%s (bad ID format)" % status
Beispiel #12
0
class PactCHWProfileReport(PactDrilldownReportMixin,
                           PactElasticTabularReportMixin):
    slug = "chw_profile"
    description = "CHW Profile"
    view_mode = 'info'
    ajax_pagination = True
    xform_es = ReportXFormES(PACT_DOMAIN)
    case_es = ReportCaseES(PACT_DOMAIN)
    default_sort = {"received_on": "desc"}

    name = "CHW Profile"

    hide_filters = True
    filters = []

    def pact_case_link(self, case_id):
        #stop the madness
        from pact.reports.patient import PactPatientInfoReport

        try:
            return PactPatientInfoReport.get_url(
                *[self.domain]) + "?patient_id=%s" % case_id
        except NoReverseMatch:
            return "#"

    def pact_dot_link(self, case_id):
        from pact.reports.dot import PactDOTReport

        try:
            return PactDOTReport.get_url(
                *[self.domain]) + "?dot_patient=%s" % case_id
        except NoReverseMatch:
            return "#"

    def get_assigned_patients(self):
        """get list of patients and their submissions on who this chw is assigned as primary hp"""
        fields = [
            "_id", "name", "pactid.#value", "hp_status.#value",
            "dot_status.#value"
        ]
        case_query = self.case_es.base_query(terms={
            'type':
            PACT_CASE_TYPE,
            'hp.#value':
            self.get_user().raw_username
        },
                                             fields=fields,
                                             size=100)

        case_query['filter']['and'].append(
            {'not': {
                'term': {
                    'hp_status.#value': 'discharged'
                }
            }})
        chw_patients_res = self.case_es.run_query(case_query)
        assigned_patients = [
            x['fields'] for x in chw_patients_res['hits']['hits']
        ]

        for x in assigned_patients:
            x['info_url'] = self.pact_case_link(x['_id'])
            if x['dot_status.#value'] is not None or x[
                    'dot_status.#value'] != "":
                x['dot_url'] = self.pact_dot_link(x['_id'])
        return sorted(assigned_patients, key=lambda x: int(x['pactid.#value']))

    def get_fields(self):
        if self.view_mode == 'submissions':
            yield 'corehq.apps.reports.filters.users.UserTypeFilter'
            yield 'corehq.apps.reports.filters.dates.DatespanFilter'

    @memoized
    def get_user(self):
        if hasattr(self, 'request') and 'chw_id' in self.request.GET:
            self._user_doc = CommCareUser.get(self.request.GET['chw_id'])
            return self._user_doc
        else:
            return None

    @property
    def report_context(self):
        user_doc = self.get_user()
        self.view_mode = self.request.GET.get('view', 'info')
        self.interval = self.request.GET.get('interval', 7)

        ret = {
            'user_doc':
            user_doc,
            'view_mode':
            self.view_mode,
            'chw_root_url':
            PactCHWProfileReport.get_url(*[self.request.domain]) +
            "?chw_id=%s" % self.request.GET['chw_id']
        }

        if self.view_mode == 'info':
            self.hide_filters = True
            self.report_template_path = "pact/chw/pact_chw_profile_info.html"
            ret['assigned_patients'] = self.get_assigned_patients()
        elif self.view_mode == 'submissions':
            tabular_context = super(PactCHWProfileReport, self).report_context
            tabular_context.update(ret)
            self.report_template_path = "pact/chw/pact_chw_profile_submissions.html"
            return tabular_context
        elif self.view_mode == 'schedule':
            scheduled_context = chw_schedule.chw_calendar_submit_report(
                self.request, user_doc.raw_username, interval=self.interval)
            ret.update(scheduled_context)
            self.report_template_path = "pact/chw/pact_chw_profile_schedule.html"
        else:
            raise Http404
        return ret

    #submission stuff
    @property
    def headers(self):
        return DataTablesHeader(
            DataTablesColumn("Show Form", sortable=False, span=1),
            DataTablesColumn("Pact ID", sortable=False, span=1),
            DataTablesColumn("Received",
                             prop_name="received_on",
                             sortable=True,
                             span=1),
            DataTablesColumn("Encounter Date", sortable=False, span=1),
            DataTablesColumn("Form",
                             prop_name="form.#type",
                             sortable=True,
                             span=1),
        )

    @property
    def es_results(self):
        user = self.get_user()
        fields = [
            "_id", "form.#type", "received_on", "form.meta.timeStart",
            "form.meta.timeEnd"
        ]
        query = self.xform_es.base_query(
            terms={'form.meta.username': user.raw_username},
            fields=fields,
            start=self.pagination.start,
            size=self.pagination.count)
        query['script_fields'] = {}
        query['script_fields'].update(pact_script_fields())
        query['script_fields'].update(case_script_field())
        query['sort'] = self.get_sorting_block()
        return self.xform_es.run_query(query)

    @property
    def rows(self):
        """
            Override this method to create a functional tabular report.
            Returns 2D list of rows.
            [['row1'],[row2']]
        """
        if self.get_user() is not None:

            def _format_row(row_field_dict):
                yield mark_safe(
                    "<a class='ajax_dialog' href='%s'>View</a>" %
                    (reverse('render_form_data',
                             args=[self.domain, row_field_dict['_id']])))
                yield row_field_dict['script_pact_id']
                yield self.format_date(row_field_dict["received_on"].replace(
                    '_', ' ').title())
                yield self.format_date(row_field_dict['script_encounter_date'])
                yield row_field_dict["form.#type"].replace(
                    '_', ' ').title().strip()

            res = self.es_results
            if 'error' in res:
                pass
            else:
                for result in res['hits']['hits']:
                    yield list(_format_row(result['fields']))