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']
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']
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'])
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']
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
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
def case_es(self): return ReportCaseES(self.domain)
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
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']))