From 05853efeb728a4547a51ed35a1a55d17cceed899 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 12 Mar 2020 17:44:46 +0530 Subject: [PATCH] feat: Healthcare Domain Workspace with chart and shortcuts --- .../desk_page/healthcare/healthcare.json | 86 +++++++++++++++---- .../patient_appointment.py | 11 +-- erpnext/healthcare/utils.py | 42 ++++----- 3 files changed, 97 insertions(+), 42 deletions(-) diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json index 0160cd48ec..d948cee5a0 100644 --- a/erpnext/healthcare/desk_page/healthcare/healthcare.json +++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json @@ -1,28 +1,50 @@ { "cards": [ { - "icon": "icon-cog", - "links": "[\n {\n \"label\": \"Healthcare Settings\",\n \"name\": \"Healthcare Settings\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Department\",\n \"name\": \"Medical Department\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appointment Type\",\n \"name\": \"Appointment Type\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Prescription Dosage\",\n \"name\": \"Prescription Dosage\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Prescription Duration\",\n \"name\": \"Prescription Duration\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Complaint\",\n \"name\": \"Complaint\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Diagnosis\",\n \"name\": \"Diagnosis\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test Sample\",\n \"name\": \"Lab Test Sample\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test UOM\",\n \"name\": \"Lab Test UOM\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Antibiotic\",\n \"name\": \"Antibiotic\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Sensitivity\",\n \"name\": \"Sensitivity\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Lab Test Template\",\n \"name\": \"Lab Test Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Clinical Procedure Template\",\n \"name\": \"Clinical Procedure Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Service Unit Type\",\n \"name\": \"Healthcare Service Unit Type\",\n \"type\": \"doctype\"\n }\n]", - "title": "Settings" - }, - { - "icon": "icon-list", - "links": "[\n {\n \"label\": \"Lab Test\",\n \"name\": \"Lab Test\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Sample Collection\",\n \"name\": \"Sample Collection\",\n \"type\": \"doctype\"\n },\n {\n \"is_query_report\": true,\n \"label\": \"Lab Test Report\",\n \"name\": \"Lab Test Report\",\n \"type\": \"report\"\n }\n]", - "title": "Laboratory" - }, - { - "icon": "icon-list", - "links": "[\n {\n \"label\": \"Patient\",\n \"name\": \"Patient\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Practitioner\",\n \"name\": \"Healthcare Practitioner\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Practitioner Schedule\",\n \"name\": \"Practitioner Schedule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Code Standard\",\n \"name\": \"Medical Code Standard\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Medical Code\",\n \"name\": \"Medical Code\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Healthcare Service Unit\",\n \"name\": \"Healthcare Service Unit\",\n \"type\": \"doctype\"\n }\n]", + "icon": "", + "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]", "title": "Masters" }, + { + "icon": "", + "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]", + "title": "Consultation Setup" + }, { "icon": "icon-star", - "links": "[\n {\n \"label\": \"Patient Appointment\",\n \"name\": \"Patient Appointment\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Patient Encounter\",\n \"name\": \"Patient Encounter\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Record Patient Vitals\",\n \"label\": \"Vital Signs\",\n \"name\": \"Vital Signs\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Patient History\",\n \"name\": \"patient_history\",\n \"type\": \"page\"\n },\n {\n \"label\": \"Appointment Analytics\",\n \"name\": \"appointment-analytic\",\n \"type\": \"page\"\n },\n {\n \"label\": \"Clinical Procedure\",\n \"name\": \"Clinical Procedure\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Inpatient Record\",\n \"name\": \"Inpatient Record\",\n \"type\": \"doctype\"\n }\n]", + "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]", "title": "Consultation" + }, + { + "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]", + "title": "Settings" + }, + { + "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]", + "title": "Laboratory Setup" + }, + { + "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]", + "title": "Laboratory" + }, + { + "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t}\n]", + "title": "Records and History" + }, + { + "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t}\n]", + "title": "Reports" } ], "category": "Domains", - "charts": [], + "charts": [ + { + "chart_name": "Patient Appointments", + "label": "Patient Appointments", + "size": "Full" + } + ], + "charts_label": "", "creation": "2020-03-02 17:23:17.919682", "developer_mode_only": 0, "disable_user_customization": 0, @@ -30,7 +52,7 @@ "doctype": "Desk Page", "idx": 0, "label": "Healthcare", - "modified": "2020-03-05 11:27:25.682521", + "modified": "2020-03-12 17:24:45.970847", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare", @@ -38,5 +60,37 @@ "pin_to_bottom": 0, "pin_to_top": 0, "restrict_to_domain": "Healthcare", - "shortcuts": [] + "shortcuts": [ + { + "format": "{} Open", + "is_query_report": 0, + "link_to": "Patient Appointment", + "stats_filter": "{\n \"status\": \"Open\"\n}", + "type": "DocType" + }, + { + "format": "{} Active", + "is_query_report": 0, + "link_to": "Patient", + "stats_filter": "{\n \"status\": \"Active\"\n}", + "type": "DocType" + }, + { + "format": "{} Vacant", + "is_query_report": 0, + "link_to": "Healthcare Service Unit", + "stats_filter": "{\n \"occupancy_status\": \"Vacant\"\n}", + "type": "DocType" + }, + { + "is_query_report": 0, + "link_to": "Healthcare Practitioner", + "type": "DocType" + }, + { + "is_query_report": 0, + "link_to": "patient_history", + "type": "Page" + } + ] } \ No newline at end of file diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py index d329e5db31..c12ae86f39 100755 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py @@ -432,11 +432,12 @@ def get_procedure_prescribed(patient): where ct.patient='{0}' and pp.parent=ct.name and pp.appointment_booked=0 order by ct.creation desc""".format(patient)) + def update_appointment_status(): # update the status of appointments daily + appointments = frappe.get_all('Patient Appointment', { + 'status': ('not in', ['Closed', 'Cancelled']) + }, as_dict=1) - frappe.db.sql("""update `tabPatient Appointment` set status = 'Open' - where appointment_date = CURDATE() and status = 'Scheduled'""") - - frappe.db.sql("""update `tabPatient Appointment` set status = 'Expired' - where appointment_date < CURDATE() and status NOT IN ('Closed', 'Cancelled')""") \ No newline at end of file + for appointment in appointments: + frappe.get_doc('Patient Appointment', appointment.name).set_status() \ No newline at end of file diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py index 639621cfd3..4bf0bdb81d 100644 --- a/erpnext/healthcare/utils.py +++ b/erpnext/healthcare/utils.py @@ -471,50 +471,50 @@ def get_drugs_to_invoice(encounter): @frappe.whitelist() def get_children(doctype, parent, company, is_root=False): - parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_') + parent_fieldname = "parent_" + doctype.lower().replace(" ", "_") fields = [ - 'name as value', - 'is_group as expandable', - 'lft', - 'rgt' + "name as value", + "is_group as expandable", + "lft", + "rgt" ] - # fields = [ 'name', 'is_group', 'lft', 'rgt' ] - filters = [['ifnull(`{0}`,'')'.format(parent_fieldname), '=', '' if is_root else parent]] + # fields = [ "name", "is_group", "lft", "rgt" ] + filters = [["ifnull(`{0}`,'')".format(parent_fieldname), "=", "" if is_root else parent]] if is_root: - fields += ['service_unit_type'] if doctype == 'Healthcare Service Unit' else [] - filters.append(['company', '=', company]) + fields += ["service_unit_type"] if doctype == "Healthcare Service Unit" else [] + filters.append(["company", "=", company]) else: - fields += ['service_unit_type', 'allow_appointments', 'inpatient_occupancy', 'occupancy_status'] if doctype == 'Healthcare Service Unit' else [] - fields += [parent_fieldname + ' as parent'] + fields += ["service_unit_type", "allow_appointments", "inpatient_occupancy", "occupancy_status"] if doctype == "Healthcare Service Unit" else [] + fields += [parent_fieldname + " as parent"] hc_service_units = frappe.get_list(doctype, fields=fields, filters=filters) - if doctype == 'Healthcare Service Unit': + if doctype == "Healthcare Service Unit": for each in hc_service_units: - occupancy_msg = '' - if each['expandable'] == 1: + occupancy_msg = "" + if each["expandable"] == 1: occupied = False vacant = False - child_list = frappe.db.sql(''' + child_list = frappe.db.sql(""" select name, occupancy_status from `tabHealthcare Service Unit` where inpatient_occupancy = 1 and - lft > %s and rgt < %s''', - (each['lft'], each['rgt'])) + lft > %s and rgt < %s""", + (each["lft"], each["rgt"])) for child in child_list: if not occupied: occupied = 0 - if child[1] == 'Occupied': + if child[1] == "Occupied": occupied += 1 if not vacant: vacant = 0 - if child[1] == 'Vacant': + if child[1] == "Vacant": vacant += 1 if vacant and occupied: occupancy_total = vacant + occupied - occupancy_msg = str(occupied) + ' Occupied out of ' + str(occupancy_total) - each['occupied_out_of_vacant'] = occupancy_msg + occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total) + each["occupied_out_of_vacant"] = occupancy_msg return hc_service_units