Exemple #1
0
def dots_submissions_by_case(case_id, query_date, username=None):
    """
    Actually run query for username submissions
    todo: do terms for the pact_ids instead of individual term?
    """
    xform_es = ReportXFormES(PACT_DOMAIN)
    script_fields = {
        "doc_id": get_report_script_field('_id', is_known=True),
        "pact_id": get_report_script_field("form.pact_id"),
        "encounter_date": get_report_script_field('form.encounter_date'),
        "username": get_report_script_field('form.meta.username', is_known=True),
        "visit_type": get_report_script_field('form.visit_type'),
        "visit_kept": get_report_script_field('form.visit_kept'),
        "contact_type": get_report_script_field('form.contact_type'),
        "observed_art": get_report_script_field('form.observed_art'),
        "observed_non_art": get_report_script_field('form.observed_non_art'),
        "observer_non_art_dose": get_report_script_field('form.observed_non_art_dose'),
        "observed_art_dose": get_report_script_field('form.observed_art_dose'),
        "pillbox_check": get_report_script_field('form.pillbox_check.check'),
        "scheduled": get_report_script_field('form.scheduled'),
    }

    term_block = {'form.#type': 'dots_form'}
    if username is not None:
        term_block['form.meta.username'] = username
    query = xform_es.by_case_id_query(PACT_DOMAIN, case_id, terms=term_block,
                                      date_field='form.encounter_date.#value', startdate=query_date,
                                      enddate=query_date)
    query['sort'] = {'received_on': 'asc'}
    query['script_fields'] = script_fields
    query['size'] = 1
    query['from'] = 0
    res = xform_es.run_query(query)
    print(json.dumps(res, indent=2))
    return res
Exemple #2
0
def dots_submissions_by_case(case_id, query_date, username=None):
    """
    Actually run query for username submissions
    todo: do terms for the pact_ids instead of individual term?
    """
    xform_es = ReportXFormES(PACT_DOMAIN)
    script_fields = {
        "doc_id": get_report_script_field('_id', is_known=True),
        "pact_id": get_report_script_field("form.pact_id"),
        "encounter_date": get_report_script_field('form.encounter_date'),
        "username": get_report_script_field('form.meta.username', is_known=True),
        "visit_type": get_report_script_field('form.visit_type'),
        "visit_kept": get_report_script_field('form.visit_kept'),
        "contact_type": get_report_script_field('form.contact_type'),
        "observed_art": get_report_script_field('form.observed_art'),
        "observed_non_art": get_report_script_field('form.observed_non_art'),
        "observer_non_art_dose": get_report_script_field('form.observed_non_art_dose'),
        "observed_art_dose": get_report_script_field('form.observed_art_dose'),
        "pillbox_check": get_report_script_field('form.pillbox_check.check'),
        "scheduled": get_report_script_field('form.scheduled'),
    }

    term_block = {'form.#type': 'dots_form'}
    if username is not None:
        term_block['form.meta.username'] = username
    query = xform_es.by_case_id_query(PACT_DOMAIN, case_id, terms=term_block,
                                      date_field='form.encounter_date.#value', startdate=query_date,
                                      enddate=query_date)
    query['sort'] = {'received_on': 'asc'}
    query['script_fields'] = script_fields
    query['size'] = 1
    query['from'] = 0
    res = xform_es.run_query(query)
    print simplejson.dumps(res, indent=2)
    return res
Exemple #3
0
    def report_context(self):
        ret = {}
        if 'dot_patient' not in self.request.GET or self.request.GET.get(
                'dot_patient') == "":
            self.report_template_path = "pact/dots/dots_report_nopatient.html"
            return ret
        submit_id = self.request.GET.get('submit_id', None)
        ret['dot_case_id'] = self.request.GET['dot_patient']
        casedoc = PactPatientCase.get(ret['dot_case_id'])
        ret['patient_case'] = casedoc
        start_date_str = self.request.GET.get(
            'startdate',
            json_format_date(datetime.utcnow() - timedelta(days=7)))
        end_date_str = self.request.GET.get(
            'enddate', json_format_date(datetime.utcnow()))

        start_date = datetime.combine(iso_string_to_date(start_date_str),
                                      time())
        end_date = datetime.combine(iso_string_to_date(end_date_str), time())

        ret['startdate'] = start_date_str
        ret['enddate'] = end_date_str

        dcal = DOTCalendarReporter(casedoc,
                                   start_date=start_date,
                                   end_date=end_date,
                                   submit_id=submit_id)
        ret['dot_calendar'] = dcal

        unique_visits = dcal.unique_xforms()
        xform_es = ReportXFormES(PACT_DOMAIN)

        q = xform_es.base_query(size=len(unique_visits))
        lvisits = list(unique_visits)
        if len(lvisits) > 0:
            q['filter']['and'].append({"ids": {"values": lvisits}})
            #todo double check pactid/caseid matches
        q['sort'] = {'received_on': 'desc'}
        res = xform_es.run_query(q)

        #ugh, not storing all form data by default - need to get?
        ret['sorted_visits'] = [
            DOTSubmission.wrap(x['_source']) for x in [
                x for x in res['hits']['hits']
                if x['_source']['xmlns'] == XMLNS_DOTS_FORM
            ]
        ]
        return ret
Exemple #4
0
    def es_results(self):
        if not self.patient_id:
            return None

        full_query = ReportXFormES.by_case_id_query(self.request.domain,
                                                    self.patient_id)
        full_query.update({
            "fields": [
                "_id",
                "received_on",
                "form.meta.timeEnd",
                "form.meta.timeStart",
                "form.meta.username",
                "form.#type",
            ],
            "sort":
            self.get_sorting_block(),
            "size":
            self.pagination.count,
            "from":
            self.pagination.start
        })
        full_query['script_fields'] = pact_script_fields()
        res = self.xform_es.run_query(full_query)
        return res
    def handle(self, **options):
        xform_es = ReportXFormES(PACT_DOMAIN)
        offset = 0

        q = REPORT_XFORM_MISSING_DOTS_QUERY
        q['size'] = CHUNK_SIZE

        while True:
            #            q['from'] = offset
            res = xform_es.run_query(q)
            print("####### Query block total: %s" % res['hits']['total'])
            print(res['hits']['hits'])
            if len(res['hits'].get('hits', [])) == 0:
                break
            else:
                for hit in res['hits']['hits']:
                    doc_id = hit['_id']
                    if doc_id in self.seen_doc_ids:
                        continue
                    else:
                        self.seen_doc_ids[doc_id] = 1
            offset += CHUNK_SIZE
Exemple #6
0
    def report_context(self):
        ret = {}
        if not self.request.GET.has_key('dot_patient') or self.request.GET.get('dot_patient') == "":
            self.report_template_path = "pact/dots/dots_report_nopatient.html"
            return ret
        submit_id = self.request.GET.get('submit_id', None)
        ret['dot_case_id'] = self.request.GET['dot_patient']
        casedoc = PactPatientCase.get(ret['dot_case_id'])
        ret['patient_case'] = casedoc
        start_date_str = self.request.GET.get('startdate',
                                              (datetime.utcnow() - timedelta(days=7)).strftime(
                                                  '%Y-%m-%d'))
        end_date_str = self.request.GET.get('enddate', datetime.utcnow().strftime("%Y-%m-%d"))

        start_date = datetime.strptime(start_date_str, "%Y-%m-%d")
        end_date = datetime.strptime(end_date_str, "%Y-%m-%d")

        ret['startdate'] = start_date_str
        ret['enddate'] = end_date_str

        dcal = DOTCalendarReporter(casedoc, start_date=start_date, end_date=end_date, submit_id=submit_id)
        ret['dot_calendar'] = dcal

        unique_visits = dcal.unique_xforms()
        xform_es = ReportXFormES(PACT_DOMAIN)

        q = xform_es.base_query(size=len(unique_visits))
        lvisits = list(unique_visits)
        if len(lvisits) > 0:
            q['filter']['and'].append({"ids": {"values": lvisits}})
            #todo double check pactid/caseid matches
        q['sort'] = {'received_on': 'desc'}
        res = xform_es.run_query(q)

        #ugh, not storing all form data by default - need to get?
        ret['sorted_visits'] = [DOTSubmission.wrap(x['_source']) for x in
                                filter(lambda x: x['_source']['xmlns'] == XMLNS_DOTS_FORM,
                                       res['hits']['hits'])]
        return ret
    def handle_noargs(self, **options):
        xform_es = ReportXFormES(PACT_DOMAIN)
        offset = 0

        q = REPORT_XFORM_MISSING_DOTS_QUERY
        q['size'] = CHUNK_SIZE

        while True:
#            q['from'] = offset
            res = xform_es.run_query(q)
            print "####### Query block total: %s" % res['hits']['total']
            print res['hits']['hits']
            if len(res['hits'].get('hits', [])) == 0:
                break
            else:
                for hit in res['hits']['hits']:
                    doc_id = hit['_id']
                    if self.seen_doc_ids.has_key(doc_id):
                        continue
                    else:
                        self.seen_doc_ids[doc_id ] =1
            offset += CHUNK_SIZE
Exemple #8
0
    def es_results(self):
        if not self.patient_id:
            return None

        full_query = ReportXFormES.by_case_id_query(self.request.domain, self.patient_id)
        full_query.update({
            "fields": [
                "_id",
                "received_on",
                "form.meta.timeEnd",
                "form.meta.timeStart",
                "form.meta.username",
                "form.#type",
            ],
            "sort": self.get_sorting_block(),
            "size": self.pagination.count,
            "from": self.pagination.start
        })
        full_query['script_fields'] = pact_script_fields()
        res = self.xform_es.run_query(full_query)
        return res
Exemple #9
0
class PactFormAPI(DomainAPI):
    xform_es = ReportXFormES(PACT_DOMAIN)

    @classmethod
    def allowed_domain(self, domain):
        return PACT_DOMAIN

    @classmethod
    def api_version(cls):
        return "1"

    @classmethod
    def api_name(cls):
        return "pact_formdata"

    @method_decorator(httpdigest)
    @method_decorator(login_or_digest)
    def get(self, *args, **kwargs):
        """
        Download prior progress note submissions for local access
        """
        db = XFormInstance.get_db()
        couch_user = CouchUser.from_django_user(self.request.user)
        username = couch_user.raw_username
        if hasattr(localsettings, 'debug_pact_user'):
            username = getattr(localsettings, 'debug_pact_user')(username)

        offset =0
        limit_count=200
        total_count = 0

        query = {
            "query": {
                "filtered": {
                    "filter": {
                        "and": [
                            {"term": {"domain.exact": "pact"}},
                            {"term": {"form.#type": "progress_note"}},
                            {"term": {"form.meta.username": username}}
                        ]
                    },
                    "query": {"match_all": {}}
                }
            },
            "sort": {"received_on": "asc"},
            "size": limit_count,
            "fields": ['_id', 'external_blobs']
        }
        query['script_fields'] = {}
        query['script_fields'].update(pact_script_fields())
        query['script_fields'].update(case_script_field())

        res = self.xform_es.run_query(query)

        my_patients_ever_submitted_query = query_per_case_submissions_facet(PACT_DOMAIN, username)
        patients_res = self.xform_es.run_query(my_patients_ever_submitted_query)

        #filter by active/discharged?
        #get all the forms
        #get all the patients
        #get all patients to determine which to filter.

        active_patients = []
        for pt in []:
            #if pt.hp_status == "Discharged":
                #continue
            case_id = pt['script_case_id']
            active_patients.append(case_id)

        def return_iterator():
            yield "<restoredata>"
            for result in res['hits']['hits']:
                data_row = result['fields']

#                if data_row['script_case_id'] not in active_patients:
#                    continue
                try:
                    xml_str = (BlobHelper(data_row, db, CODES.form_xml)
                        .fetch_attachment('form.xml').decode('utf-8')
                        .replace("<?xml version=\'1.0\' ?>", '')
                        .replace("<?xml version='1.0' encoding='UTF-8' ?>", ''))
                    yield xml_str
                except Exception as ex:
                    logging.error("for downloader: error fetching attachment: %s" % ex)
            yield "</restoredata>"

        response = HttpResponse(return_iterator(), content_type='text/xml')
        return response
Exemple #10
0
class PactPatientInfoReport(PactDrilldownReportMixin,
                            PactElasticTabularReportMixin):
    slug = "patient"
    description = "some patient"

    hide_filters = True
    filters = []
    ajax_pagination = True
    xform_es = ReportXFormES(PACT_DOMAIN)

    default_sort = {"received_on": "desc"}

    name = "Patient Info"

    @use_timeago
    def decorator_dispatcher(self, request, *args, **kwargs):
        return super(PactPatientInfoReport,
                     self).decorator_dispatcher(request, *args, **kwargs)

    @property
    def patient_id(self):
        return self.request.GET.get('patient_id')

    def get_case(self):
        if self.patient_id is None:
            return None
        return PactPatientCase.get(self.patient_id)

    @property
    def report_context(self):
        from pact import api
        ret = {}
        try:
            patient_doc = self.get_case()
            has_error = False
        except Exception as ex:
            logging.exception(
                'problem getting pact patient data for patient {}. {}'.format(
                    self.patient_id, ex))
            has_error = True
            patient_doc = None

        if patient_doc is None:
            self.report_template_path = "pact/patient/nopatient.html"
            if has_error:
                ret['error_message'] = "Patient not found"
            else:
                ret['error_message'] = "No patient selected"
            return ret

        view_mode = self.request.GET.get('view', 'info')
        ret['patient_doc'] = patient_doc
        ret['pt_root_url'] = patient_doc.get_info_url()
        ret['view_mode'] = view_mode

        if view_mode == 'info':
            self.report_template_path = "pact/patient/pactpatient_info.html"
            ret['cloudcare_addr_edit_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_ADDRESS)
            ret['cloudcare_pn_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_PROGRESS_NOTE)
            ret['cloudcare_dot_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_DOT)
            ret['cloudcare_bw_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_BLOODWORK)
        elif view_mode == 'submissions':
            tabular_context = super(PactPatientInfoReport, self).report_context
            tabular_context.update(ret)
            self.report_template_path = "pact/patient/pactpatient_submissions.html"
            return tabular_context
        elif view_mode == 'schedule':
            the_form = ScheduleForm()
            ret['schedule_form'] = the_form
            ret['schedule_fields'] = json.dumps(list(the_form.fields.keys()))
            self.report_template_path = "pact/patient/pactpatient_schedule.html"
        elif view_mode == 'edit':
            the_form = PactPatientForm(self.request, patient_doc)
            ret['patient_form'] = the_form
            self.report_template_path = "pact/patient/pactpatient_edit.html"
        elif view_mode == 'providers':
            self.report_template_path = "pact/patient/pactpatient_providers.html"
        elif view_mode == 'careplan':
            ret.update(
                case_hierarchy_context(
                    patient_doc,
                    lambda case_id: reverse('case_data',
                                            args=[PACT_DOMAIN, case_id]),
                    show_view_buttons=False))
            self.report_template_path = "pact/patient/pactpatient_careplan.html"
        else:
            raise Http404
        return ret

    @property
    def headers(self):
        return DataTablesHeader(
            DataTablesColumn("Show Form", sortable=False, span=1),
            DataTablesColumn("Received", prop_name="received_on", span=1),
            DataTablesColumn("Created Date",
                             prop_name="form.meta.timeStart",
                             span=1),
            DataTablesColumn("Encounter Date", sortable=False, span=1),
            DataTablesColumn("Form", prop_name="form.#type", span=1),
            DataTablesColumn("CHW", prop_name="form.meta.username", span=1))

    @property
    def es_results(self):
        if not self.patient_id:
            return None

        full_query = ReportXFormES.by_case_id_query(self.request.domain,
                                                    self.patient_id)
        full_query.update({
            "fields": [
                "_id",
                "received_on",
                "form.meta.timeEnd",
                "form.meta.timeStart",
                "form.meta.username",
                "form.#type",
            ],
            "sort":
            self.get_sorting_block(),
            "size":
            self.pagination.count,
            "from":
            self.pagination.start
        })
        full_query['script_fields'] = pact_script_fields()
        res = self.xform_es.run_query(full_query)
        return res

    @property
    def rows(self):
        if self.patient_id:

            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 self.format_date(row_field_dict["received_on"].replace(
                    '_', ' '))
                yield self.format_date(
                    row_field_dict.get("form.meta.timeStart", ""))
                if row_field_dict["script_encounter_date"] != None:
                    yield row_field_dict["script_encounter_date"]
                else:
                    yield "---"
                yield row_field_dict["form.#type"].replace('_', ' ').title()
                yield row_field_dict.get("form.meta.username", "")

            res = self.es_results
            if 'error' in res:
                pass
            else:
                for result in res['hits']['hits']:
                    yield list(_format_row(result['fields']))
Exemple #11
0
class PactPatientInfoReport(PactDrilldownReportMixin,
                            PactElasticTabularReportMixin):
    slug = "patient"
    description = "some patient"

    hide_filters = True
    filters = []
    ajax_pagination = True
    xform_es = ReportXFormES(PACT_DOMAIN)

    default_sort = {"received_on": "desc"}

    name = "Patient Info"

    @use_timeago
    def decorator_dispatcher(self, request, *args, **kwargs):
        return super(PactPatientInfoReport,
                     self).decorator_dispatcher(request, *args, **kwargs)

    @property
    def patient_id(self):
        return self.request.GET.get('patient_id')

    def get_case(self):
        if self.patient_id is None:
            return None
        return PactPatientCase.get(self.patient_id)

    @property
    def report_context(self):
        from pact import api
        ret = {}
        try:
            patient_doc = self.get_case()
            has_error = False
        except Exception, ex:
            logging.exception(
                u'problem getting pact patient data for patient {}. {}'.format(
                    self.patient_id, ex))
            has_error = True
            patient_doc = None

        if patient_doc is None:
            self.report_template_path = "pact/patient/nopatient.html"
            if has_error:
                ret['error_message'] = "Patient not found"
            else:
                ret['error_message'] = "No patient selected"
            return ret

        view_mode = self.request.GET.get('view', 'info')
        ret['patient_doc'] = patient_doc
        ret['pt_root_url'] = patient_doc.get_info_url()
        ret['view_mode'] = view_mode

        if view_mode == 'info':
            self.report_template_path = "pact/patient/pactpatient_info.html"
            ret['cloudcare_addr_edit_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_ADDRESS)
            ret['cloudcare_pn_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_PROGRESS_NOTE)
            ret['cloudcare_dot_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_DOT)
            ret['cloudcare_bw_url'] = api.get_cloudcare_url(
                patient_doc._id, api.FORM_BLOODWORK)
        elif view_mode == 'submissions':
            tabular_context = super(PactPatientInfoReport, self).report_context
            tabular_context.update(ret)
            self.report_template_path = "pact/patient/pactpatient_submissions.html"
            return tabular_context
        elif view_mode == 'schedule':
            the_form = ScheduleForm()
            ret['schedule_form'] = the_form
            ret['schedule_fields'] = json.dumps(the_form.fields.keys())
            self.report_template_path = "pact/patient/pactpatient_schedule.html"
        elif view_mode == 'edit':
            the_form = PactPatientForm(self.request, patient_doc)
            ret['patient_form'] = the_form
            self.report_template_path = "pact/patient/pactpatient_edit.html"
        elif view_mode == 'providers':
            self.report_template_path = "pact/patient/pactpatient_providers.html"
        elif view_mode == 'careplan':
            ret.update({
                'case_hierarchy_options': {
                    "show_view_buttons":
                    False,
                    "get_case_url":
                    lambda case_id: reverse('case_details',
                                            args=[PACT_DOMAIN, case_id])
                },
                'case': patient_doc,
            })
            self.report_template_path = "pact/patient/pactpatient_careplan.html"
        else:
            raise Http404
        return ret
Exemple #12
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
Exemple #13
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']))
Exemple #14
0
class PatientInfoReport(CustomProjectReport, DrilldownReportMixin,
                        ElasticProjectInspectionReport,
                        ProjectReportParametersMixin):
    slug = "patient"

    hide_filters = True
    filters = []
    ajax_pagination = True
    asynchronous = True
    emailable = False
    xform_es = ReportXFormES(SUCCEED_DOMAIN)

    default_sort = {"received_on": "desc"}

    def __init__(self, request, base_context=None, domain=None, **kwargs):
        self.view_mode = request.GET.get('view', 'info')
        super(PatientInfoReport, self).__init__(request, base_context, domain,
                                                **kwargs)

    @property
    def fields(self):
        if self.view_mode == 'submissions' and self.submission_user_access:
            return [
                'custom.succeed.fields.PatientFormNameFilter',
                'corehq.apps.reports.standard.cases.filters.CaseSearchFilter'
            ]
        else:
            return []

    @property
    def base_template_filters(self):
        if self.view_mode == 'submissions' and self.submission_user_access:
            return 'succeed/report.html'
        else:
            return super(PatientInfoReport, self).base_template_filters

    @property
    def name(self):
        if self.view_mode == 'submissions':
            return "Patient Submissions"
        if self.view_mode == 'status':
            return 'Manage Patient Status'
        return "Patient Info"

    def get_case(self):
        if self.request.GET.get('patient_id', None) is None:
            return None
        return CommCareCase.get(self.request.GET['patient_id'])

    @property
    def submission_user_access(self):
        user = self.request.couch_user
        if user and (is_pi(user) or is_cm(user) or is_chw(user)):
            return True
        return False

    @property
    def patient_status_access(self):
        user = self.request.couch_user
        if user and is_pm_or_pi(user):
            return True
        return False

    @property
    def report_context(self):
        ret = {}

        try:
            case = self.get_case()
            has_error = False
        except ResourceNotFound:

            has_error = True
            case = None
class PatientSubmissionReport(PatientDetailsReport):
    slug = "patient_submissions"
    name = 'Patient Submissions'
    xform_es = ReportXFormES(SUCCEED_DOMAIN)
    ajax_pagination = True
    asynchronous = True
    default_sort = {
        "received_on": "desc"
    }

    @property
    def base_template_filters(self):
        return 'succeed/report.html'

    @property
    def fields(self):
        return ['custom.succeed.fields.PatientFormNameFilter',
                'corehq.apps.reports.standard.cases.filters.CaseSearchFilter']

    @property
    def headers(self):
        return DataTablesHeader(
            # In order to get dafault_sort working as expected, first column cannot contain a 'prop_name'.
            DataTablesColumn("", visible=False),
            DataTablesColumn("Form Name", prop_name='@name'),
            DataTablesColumn("Submitted By", prop_name='form.meta.username'),
            DataTablesColumn("Completed", prop_name='received_on'))


    @property
    def es_results(self):
        if not self.request.GET.has_key('patient_id'):
            return None
        full_query = {
            'query': {
                "filtered": {
                    "filter": {
                        "and": [
                            {"term": {"domain.exact": self.request.domain}},
                            {"term": {"doc_type": "xforminstance"}},
                            {
                                "nested": {
                                    "path": "form.case",
                                    "filter": {
                                        "or": [
                                            {
                                                "term": {
                                                    "@case_id": "%s" % self.request.GET[
                                                        'patient_id']
                                                }
                                            },
                                            {
                                                "term": {
                                                    "case_id": "%s" % self.request.GET['patient_id']
                                                }
                                            }
                                        ]
                                    }
                                }
                            }
                        ]
                    },
                    "query": {"match_all": {}}
                }
            },
            "sort": self.get_sorting_block(),
            "size": self.pagination.count,
            "from": self.pagination.start
        }

        form_name_group = self.request.GET.get('form_name_group', None)
        form_name_xmnls = self.request.GET.get('form_name_xmlns', None)
        search_string = SearchFilter.get_value(self.request, self.domain)

        if search_string:
            query_block = {"queryString": {"query": "*" + search_string + "*"}}
            full_query["query"]["filtered"]["query"] = query_block

        if form_name_group and form_name_xmnls == '':
            xmlns_terms = []
            forms = filter(lambda obj: obj['val'] == form_name_group, SUBMISSION_SELECT_FIELDS)[0]
            for form in forms['next']:
                xmlns_terms.append(form['val'])

            full_query['query']['filtered']['filter']['and'].append({"terms": {"xmlns.exact": xmlns_terms}})

        if form_name_xmnls:
            full_query['query']['filtered']['filter']['and'].append({"term": {"xmlns.exact": form_name_xmnls}})

        res = self.xform_es.run_query(full_query)
        return res

    @property
    def rows(self):
        if self.request.GET.has_key('patient_id'):
            def _format_row(row_field_dict):
                return [None, self.submit_history_form_link(row_field_dict["_id"],
                                                      row_field_dict['_source'].get('es_readable_name', EMPTY_FIELD)),
                        row_field_dict['_source']['form']['meta'].get('username', EMPTY_FIELD),
                        self.form_completion_time(row_field_dict['_source']['form']['meta'].get('timeEnd', EMPTY_FIELD))
                ]

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

    def submit_history_form_link(self, form_id, form_name):
        url = reverse('render_form_data', args=[self.domain, form_id])
        return html.mark_safe("<a class='ajax_dialog' href='%s' target='_blank'>%s</a>" % (url, html.escape(form_name)))

    def form_completion_time(self, date_string):
        if date_string != EMPTY_FIELD:
            return format_date(date_string, INTERACTION_OUTPUT_DATE_FORMAT, localize=True)
        else:
            return EMPTY_FIELD

    @property
    def report_context(self):
        ret = super(PatientSubmissionReport, self).report_context
        ret['view_mode'] = 'submissions'
        tabular_context = super(PatientDetailsReport, self).report_context
        tabular_context.update(ret)
        self.report_template_path = "patient_submissions.html"
        tabular_context['patient_id'] = self.request_params['patient_id']
        return tabular_context