From 5073ac4dcb7bfd46fab64ce1ad261adcbe96ecc2 Mon Sep 17 00:00:00 2001 From: Jamsheer Date: Fri, 12 Jul 2019 12:28:34 +0530 Subject: [PATCH] fix: Patient History (Patient Medical Record) (#17972) * Page - Patient History * Healthcare Utils - get patient vitals * Healthcare Utils - render doc as html for patient history page * Page - Patient History - prcatitioner image in time line * Page - Patient History in menu * fix - page medical history * fix: page patient_history broken img, minor fixes * fix: patient_history page, add pagination, show doc if fetched * fix: Patient Medical Record to Patient History * fix: patient history page - set route options * fix: update to code standards * fix: remove Eidt button form patient history * fix: css update to code standards * fix: Remove page medical_record --- erpnext/config/healthcare.py | 4 +- erpnext/healthcare/doctype/patient/patient.js | 4 +- .../patient_appointment.js | 4 +- .../patient_encounter/patient_encounter.js | 4 +- .../page/medical_record/__init__.py | 1 - .../page/medical_record/medical_record.js | 182 ----------- .../page/medical_record/medical_record.py | 24 -- .../medical_record/medical_record_row.html | 21 -- .../page/medical_record/patient_select.html | 5 - .../page/patient_history/__init__.py | 0 .../patient_history.css} | 64 +++- .../page/patient_history/patient_history.html | 20 ++ .../page/patient_history/patient_history.js | 300 ++++++++++++++++++ .../patient_history.json} | 15 +- .../page/patient_history/patient_history.py | 39 +++ erpnext/healthcare/utils.py | 113 +++++++ erpnext/patches.txt | 1 + .../remove_patient_medical_record_page.py | 7 + 18 files changed, 556 insertions(+), 252 deletions(-) delete mode 100644 erpnext/healthcare/page/medical_record/__init__.py delete mode 100644 erpnext/healthcare/page/medical_record/medical_record.js delete mode 100644 erpnext/healthcare/page/medical_record/medical_record.py delete mode 100644 erpnext/healthcare/page/medical_record/medical_record_row.html delete mode 100644 erpnext/healthcare/page/medical_record/patient_select.html create mode 100644 erpnext/healthcare/page/patient_history/__init__.py rename erpnext/healthcare/page/{medical_record/medical_record.css => patient_history/patient_history.css} (62%) create mode 100644 erpnext/healthcare/page/patient_history/patient_history.html create mode 100644 erpnext/healthcare/page/patient_history/patient_history.js rename erpnext/healthcare/page/{medical_record/medical_record.json => patient_history/patient_history.json} (57%) create mode 100644 erpnext/healthcare/page/patient_history/patient_history.py create mode 100644 erpnext/patches/v12_0/remove_patient_medical_record_page.py diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py index 1311111618..756d22e416 100644 --- a/erpnext/config/healthcare.py +++ b/erpnext/config/healthcare.py @@ -26,8 +26,8 @@ def get_data(): }, { "type": "page", - "name": "medical_record", - "label": _("Patient Medical Record"), + "name": "patient_history", + "label": _("Patient History"), }, { "type": "page", diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js index 169281430c..1a34fe8076 100644 --- a/erpnext/healthcare/doctype/patient/patient.js +++ b/erpnext/healthcare/doctype/patient/patient.js @@ -21,9 +21,9 @@ frappe.ui.form.on('Patient', { }); } if (frm.doc.patient_name && frappe.user.has_role("Physician")) { - frm.add_custom_button(__('Medical Record'), function () { + frm.add_custom_button(__('Patient History'), function () { frappe.route_options = { "patient": frm.doc.name }; - frappe.set_route("medical_record"); + frappe.set_route("patient_history"); },"View"); } if (!frm.doc.__islocal && (frappe.user.has_role("Nursing User") || frappe.user.has_role("Physician"))) { diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js index b3cbd1f753..858145eef3 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js @@ -30,9 +30,9 @@ frappe.ui.form.on('Patient Appointment', { }; }); if(frm.doc.patient){ - frm.add_custom_button(__('Medical Record'), function() { + frm.add_custom_button(__('Patient History'), function() { frappe.route_options = {"patient": frm.doc.patient}; - frappe.set_route("medical_record"); + frappe.set_route("patient_history"); },__("View")); } if(frm.doc.status == "Open"){ diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js index 7ea45688fd..088bc8161b 100644 --- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js +++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js @@ -41,10 +41,10 @@ frappe.ui.form.on('Patient Encounter', { } }); } - frm.add_custom_button(__('Medical Record'), function() { + frm.add_custom_button(__('Patient History'), function() { if (frm.doc.patient) { frappe.route_options = {"patient": frm.doc.patient}; - frappe.set_route("medical_record"); + frappe.set_route("patient_history"); } else { frappe.msgprint(__("Please select Patient")); } diff --git a/erpnext/healthcare/page/medical_record/__init__.py b/erpnext/healthcare/page/medical_record/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/erpnext/healthcare/page/medical_record/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/healthcare/page/medical_record/medical_record.js b/erpnext/healthcare/page/medical_record/medical_record.js deleted file mode 100644 index df19d8f4dc..0000000000 --- a/erpnext/healthcare/page/medical_record/medical_record.js +++ /dev/null @@ -1,182 +0,0 @@ -frappe.provide("frappe.medical_record"); -frappe.pages['medical_record'].on_page_load = function(wrapper) { - var me = this; - var page = frappe.ui.make_app_page({ - parent: wrapper, - title: 'Medical Record', - }); - - frappe.breadcrumbs.add("Medical"); - - page.main.html(frappe.render_template("patient_select", {})); - var patient = frappe.ui.form.make_control({ - parent: page.main.find(".patient"), - df: { - fieldtype: "Link", - options: "Patient", - fieldname: "patient", - change: function(){ - page.main.find(".frappe-list").html(""); - draw_page(patient.get_value(), me); - } - }, - only_input: true, - }); - patient.refresh(); - - - this.page.main.on("click", ".medical_record-message", function() { - var doctype = $(this).attr("data-doctype"), - docname = $(this).attr("data-docname"); - - if (doctype && docname) { - frappe.route_options = { - scroll_to: { "doctype": doctype, "name": docname } - }; - frappe.set_route(["Form", doctype, docname]); - } - }); - - this.page.sidebar.on("click", ".edit-details", function() { - patient = patient.get_value(); - if (patient) { - frappe.set_route(["Form", "Patient", patient]); - } - }); - -}; - -frappe.pages['medical_record'].refresh = function() { - var me = this; - - if(frappe.route_options) { - if(frappe.route_options.patient){ - me.page.main.find(".frappe-list").html(""); - var patient = frappe.route_options.patient; - draw_page(patient,me); - me.page.main.find("[data-fieldname='patient']").val(patient); - frappe.route_options = null; - } - } -}; -var show_patient_info = function(patient, me){ - frappe.call({ - "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail", - args: { - patient: patient - }, - callback: function (r) { - var data = r.message; - var details = ""; - if(data.email) details += "
Email : " + data.email; - if(data.mobile) details += "
Mobile : " + data.mobile; - if(data.occupation) details += "
Occupation : " + data.occupation; - if(data.blood_group) details += "
Blood group : " + data.blood_group; - if(data.allergies) details += "

Allergies : "+ data.allergies; - if(data.medication) details += "
Medication : "+ data.medication; - if(data.alcohol_current_use) details += "

Alcohol use : "+ data.alcohol_current_use; - if(data.alcohol_past_use) details += "
Alcohol past use : "+ data.alcohol_past_use; - if(data.tobacco_current_use) details += "
Tobacco use : "+ data.tobacco_current_use; - if(data.tobacco_past_use) details += "
Tobacco past use : "+ data.tobacco_past_use; - if(data.medical_history) details += "

Medical history : "+ data.medical_history; - if(data.surgical_history) details += "
Surgical history : "+ data.surgical_history; - if(data.surrounding_factors) details += "

Occupational hazards : "+ data.surrounding_factors; - if(data.other_risk_factors) details += "
Other risk factors : " + data.other_risk_factors; - if(data.patient_details) details += "

More info : " + data.patient_details; - - if(details){ - details = "

Patient Details" + details + "
"; - } - - var vitals = ""; - if(data.temperature) vitals += "
Temperature : " + data.temperature; - if(data.pulse) vitals += "
Pulse : " + data.pulse; - if(data.respiratory_rate) vitals += "
Respiratory Rate : " + data.respiratory_rate; - if(data.bp) vitals += "
BP : " + data.bp; - if(data.bmi) vitals += "
BMI : " + data.bmi; - if(data.height) vitals += "
Height : " + data.height; - if(data.weight) vitals += "
Weight : " + data.weight; - if(data.signs_date) vitals += "
Date : " + data.signs_date; - - if(vitals){ - vitals = "

Vital Signs" + vitals + "
"; - details = vitals + details; - } - if(details) details += "

Edit Details
"; - - me.page.sidebar.addClass("col-sm-3"); - me.page.sidebar.html(details); - me.page.wrapper.find(".layout-main-section-wrapper").addClass("col-sm-9"); - } - }); -}; -var draw_page = function(patient, me){ - frappe.model.with_doctype("Patient Medical Record", function() { - me.page.list = new frappe.ui.BaseList({ - hide_refresh: true, - page: me.page, - method: 'erpnext.healthcare.page.medical_record.medical_record.get_feed', - args: {name: patient}, - parent: $("
").appendTo(me.page.main), - render_view: function(values) { - var me = this; - var wrapper = me.page.main.find(".result-list").get(0); - values.map(function (value) { - var row = $('
').data("data", value).appendTo($(wrapper)).get(0); - new frappe.medical_record.Feed(row, value); - }); - }, - show_filters: true, - doctype: "Patient Medical Record", - }); - show_patient_info(patient, me); - me.page.list.run(); - }); -}; - -frappe.medical_record.last_feed_date = false; -frappe.medical_record.Feed = Class.extend({ - init: function(row, data) { - this.scrub_data(data); - this.add_date_separator(row, data); - if(!data.add_class) - data.add_class = "label-default"; - - data.link = ""; - if (data.reference_doctype && data.reference_name) { - data.link = frappe.format(data.reference_name, {fieldtype: "Link", options: data.reference_doctype}, - {label: __(data.reference_doctype)}); - } - - $(row) - .append(frappe.render_template("medical_record_row", data)) - .find("a").addClass("grey"); - }, - scrub_data: function(data) { - data.by = frappe.user.full_name(data.owner); - data.imgsrc = frappe.utils.get_file_link(frappe.user_info(data.owner).image); - - data.icon = "icon-flag"; - }, - add_date_separator: function(row, data) { - var date = frappe.datetime.str_to_obj(data.creation); - var last = frappe.medical_record.last_feed_date; - - if((last && frappe.datetime.obj_to_str(last) != frappe.datetime.obj_to_str(date)) || (!last)) { - var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date)); - if(diff < 1) { - var pdate = 'Today'; - } else if(diff < 2) { - pdate = 'Yesterday'; - } else { - pdate = frappe.datetime.global_date_format(date); - } - data.date_sep = pdate; - data.date_class = pdate=='Today' ? "date-indicator blue" : "date-indicator"; - } else { - data.date_sep = null; - data.date_class = ""; - } - frappe.medical_record.last_feed_date = date; - } -}); diff --git a/erpnext/healthcare/page/medical_record/medical_record.py b/erpnext/healthcare/page/medical_record/medical_record.py deleted file mode 100644 index 22c5852b05..0000000000 --- a/erpnext/healthcare/page/medical_record/medical_record.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2015, ESS LLP and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe -from frappe.utils import cint - -@frappe.whitelist() -def get_feed(start, page_length, name): - """get feed""" - result = frappe.db.sql("""select name, owner, modified, creation, - reference_doctype, reference_name, subject - from `tabPatient Medical Record` - where patient=%(patient)s - order by creation desc - limit %(start)s, %(page_length)s""", - { - "start": cint(start), - "page_length": cint(page_length), - "patient": name - }, as_dict=True) - - return result diff --git a/erpnext/healthcare/page/medical_record/medical_record_row.html b/erpnext/healthcare/page/medical_record/medical_record_row.html deleted file mode 100644 index 9a670c9aa7..0000000000 --- a/erpnext/healthcare/page/medical_record/medical_record_row.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
- {%= date_sep || "" %} -
-
- -
- -
- - {% if (reference_doctype && reference_name) { %} - {%= __("{0}: {1}", [link, "" + subject + ""]) %} - {% } else { %} - {%= subject %} - {% } %} - -
-
diff --git a/erpnext/healthcare/page/medical_record/patient_select.html b/erpnext/healthcare/page/medical_record/patient_select.html deleted file mode 100644 index 321baf738d..0000000000 --- a/erpnext/healthcare/page/medical_record/patient_select.html +++ /dev/null @@ -1,5 +0,0 @@ -
- -

{%= __("Select Patient") %}

-

-
diff --git a/erpnext/healthcare/page/patient_history/__init__.py b/erpnext/healthcare/page/patient_history/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/healthcare/page/medical_record/medical_record.css b/erpnext/healthcare/page/patient_history/patient_history.css similarity index 62% rename from erpnext/healthcare/page/medical_record/medical_record.css rename to erpnext/healthcare/page/patient_history/patient_history.css index 977625bbd1..865d6abee0 100644 --- a/erpnext/healthcare/page/medical_record/medical_record.css +++ b/erpnext/healthcare/page/patient_history/patient_history.css @@ -14,6 +14,10 @@ margin-bottom: -4px; } +.medical_record-row > * { + z-index: -999; +} + .date-indicator { background:none; font-size:12px; @@ -35,6 +39,61 @@ color: #5e64ff; } +.div-bg-color { + background: #fafbfc; +} + +.bg-color-white { + background: #FFFFFF; +} + +.d-flex { + display: flex; +} + +.width-full { + width: 100%; +} + +.p-3 { + padding: 16px; +} + +.mt-2 { + margin-top: 8px; +} + +.mr-3 { + margin-right: 16px; +} + +.Box { + background-color: #fff; + border: 1px solid #d1d5da; + border-radius: 3px; +} + +.flex-column { + flex-direction: column; +} + +.avatar { + display: inline-block; + overflow: hidden; + line-height: 1; + vertical-align: middle; + border-radius: 3px; +} + +.py-3 { + padding-top: 16px; + padding-bottom: 16px; +} + +.border-bottom { + border-bottom: 1px #e1e4e8 solid; +} + .date-indicator.blue::after { background: #5e64ff; } @@ -65,8 +124,3 @@ #page-medical_record .list-filters { display: none ; } - -#page-medical_record .octicon-heart { - color: #ff5858; - margin: 0px 5px; -} diff --git a/erpnext/healthcare/page/patient_history/patient_history.html b/erpnext/healthcare/page/patient_history/patient_history.html new file mode 100644 index 0000000000..7a9446dffd --- /dev/null +++ b/erpnext/healthcare/page/patient_history/patient_history.html @@ -0,0 +1,20 @@ +
+
+

{%= __("Select Patient") %}

+

+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
\ No newline at end of file diff --git a/erpnext/healthcare/page/patient_history/patient_history.js b/erpnext/healthcare/page/patient_history/patient_history.js new file mode 100644 index 0000000000..87fe7edd29 --- /dev/null +++ b/erpnext/healthcare/page/patient_history/patient_history.js @@ -0,0 +1,300 @@ +frappe.provide("frappe.patient_history"); +frappe.pages['patient_history'].on_page_load = function(wrapper) { + var me = this; + var page = frappe.ui.make_app_page({ + parent: wrapper, + title: 'Patient History', + single_column: true + }); + + frappe.breadcrumbs.add("Healthcare"); + let pid = ''; + page.main.html(frappe.render_template("patient_history", {})); + var patient = frappe.ui.form.make_control({ + parent: page.main.find(".patient"), + df: { + fieldtype: "Link", + options: "Patient", + fieldname: "patient", + change: function(){ + if(pid != patient.get_value() && patient.get_value()){ + me.start = 0; + me.page.main.find(".patient_documents_list").html(""); + get_documents(patient.get_value(), me); + show_patient_info(patient.get_value(), me); + show_patient_vital_charts(patient.get_value(), me, "bp", "mmHg", "Blood Pressure"); + } + pid = patient.get_value(); + } + }, + only_input: true, + }); + patient.refresh(); + + if (frappe.route_options){ + patient.set_value(frappe.route_options.patient); + } + + this.page.main.on("click", ".btn-show-chart", function() { + var btn_show_id = $(this).attr("data-show-chart-id"), pts = $(this).attr("data-pts"); + var title = $(this).attr("data-title"); + show_patient_vital_charts(patient.get_value(), me, btn_show_id, pts, title); + }); + + this.page.main.on("click", ".btn-more", function() { + var doctype = $(this).attr("data-doctype"), docname = $(this).attr("data-docname"); + if(me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched') == "1"){ + me.page.main.find("."+docname).hide(); + me.page.main.find("."+docname).parent().find('.document-html').show(); + }else{ + if(doctype && docname){ + let exclude = ["patient", "patient_name", 'patient_sex', "encounter_date"]; + frappe.call({ + method: "erpnext.healthcare.utils.render_doc_as_html", + args:{ + doctype: doctype, + docname: docname, + exclude_fields: exclude + }, + callback: function(r) { + if (r.message){ + me.page.main.find("."+docname).hide(); + me.page.main.find("."+docname).parent().find('.document-html').html(r.message.html+"\ +
"); + me.page.main.find("."+docname).parent().find('.document-html').show(); + me.page.main.find("."+docname).parent().find('.document-html').attr('data-fetched', "1"); + } + }, + freeze: true + }); + } + } + }); + + this.page.main.on("click", ".btn-less", function() { + var docname = $(this).attr("data-docname"); + me.page.main.find("."+docname).parent().find('.document-id').show(); + me.page.main.find("."+docname).parent().find('.document-html').hide(); + }); + me.start = 0; + me.page.main.on("click", ".btn-get-records", function(){ + get_documents(patient.get_value(), me); + }); +}; + +var get_documents = function(patient, me){ + frappe.call({ + "method": "erpnext.healthcare.page.patient_history.patient_history.get_feed", + args: { + name: patient, + start: me.start, + page_length: 20 + }, + callback: function (r) { + var data = r.message; + if(data.length){ + add_to_records(me, data); + }else{ + me.page.main.find(".patient_documents_list").append("


No more records..

"); + me.page.main.find(".btn-get-records").hide(); + } + } + }); +}; + +var add_to_records = function(me, data){ + var details = ""; + me.page.main.find(".patient_documents_list").append(details); + me.start += data.length; + if(data.length===20){ + me.page.main.find(".btn-get-records").show(); + }else{ + me.page.main.find(".btn-get-records").hide(); + me.page.main.find(".patient_documents_list").append("


No more records..

"); + } +}; + +var add_date_separator = function(data) { + var date = frappe.datetime.str_to_obj(data.creation); + + var diff = frappe.datetime.get_day_diff(frappe.datetime.get_today(), frappe.datetime.obj_to_str(date)); + if(diff < 1) { + var pdate = 'Today'; + } else if(diff < 2) { + pdate = 'Yesterday'; + } else { + pdate = frappe.datetime.global_date_format(date); + } + data.date_sep = pdate; + return data; +}; + +var show_patient_info = function(patient, me){ + frappe.call({ + "method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail", + args: { + patient: patient + }, + callback: function (r) { + var data = r.message; + var details = ""; + if(data.image){ + details += "
"; + } + details += "" + data.patient_name +"
" + data.sex; + if(data.email) details += "
" + data.email; + if(data.mobile) details += "
" + data.mobile; + if(data.occupation) details += "

Occupation : " + data.occupation; + if(data.blood_group) details += "
Blood group : " + data.blood_group; + if(data.allergies) details += "

Allergies : "+ data.allergies.replace("\n", "
"); + if(data.medication) details += "
Medication : "+ data.medication.replace("\n", "
"); + if(data.alcohol_current_use) details += "

Alcohol use : "+ data.alcohol_current_use; + if(data.alcohol_past_use) details += "
Alcohol past use : "+ data.alcohol_past_use; + if(data.tobacco_current_use) details += "
Tobacco use : "+ data.tobacco_current_use; + if(data.tobacco_past_use) details += "
Tobacco past use : "+ data.tobacco_past_use; + if(data.medical_history) details += "

Medical history : "+ data.medical_history.replace("\n", "
"); + if(data.surgical_history) details += "
Surgical history : "+ data.surgical_history.replace("\n", "
"); + if(data.surrounding_factors) details += "

Occupational hazards : "+ data.surrounding_factors.replace("\n", "
"); + if(data.other_risk_factors) details += "
Other risk factors : " + data.other_risk_factors.replace("\n", "
"); + if(data.patient_details) details += "

More info : " + data.patient_details.replace("\n", "
"); + + if(details){ + details = "
" + details + "
"; + } + me.page.main.find(".patient_details").html(details); + } + }); +}; + +var show_patient_vital_charts = function(patient, me, btn_show_id, pts, title) { + frappe.call({ + method: "erpnext.healthcare.utils.get_patient_vitals", + args:{ + patient: patient + }, + callback: function(r) { + if (r.message){ + var show_chart_btns_html = "
Blood Pressure\ + Respiratory/Pulse Rate\ + Temperature\ + BMI
"; + me.page.main.find(".show_chart_btns").html(show_chart_btns_html); + var data = r.message; + let labels = [], datasets = []; + let bp_systolic = [], bp_diastolic = [], temperature = []; + let pulse = [], respiratory_rate = [], bmi = [], height = [], weight = []; + for(var i=0; i (d + '').toUpperCase(), + formatTooltipY: d => d + ' ' + pts, + } + }); + }else{ + me.page.main.find(".patient_vital_charts").html(""); + me.page.main.find(".show_chart_btns").html(""); + } + } + }); +}; diff --git a/erpnext/healthcare/page/medical_record/medical_record.json b/erpnext/healthcare/page/patient_history/patient_history.json similarity index 57% rename from erpnext/healthcare/page/medical_record/medical_record.json rename to erpnext/healthcare/page/patient_history/patient_history.json index ca30c3be29..b3892a41c6 100644 --- a/erpnext/healthcare/page/medical_record/medical_record.json +++ b/erpnext/healthcare/page/patient_history/patient_history.json @@ -1,18 +1,21 @@ { "content": null, - "creation": "2016-06-09 11:33:14.025787", + "creation": "2018-08-08 17:09:13.816199", "docstatus": 0, "doctype": "Page", - "icon": "icon-play", + "icon": "", "idx": 0, - "modified": "2018-08-06 11:40:39.705660", + "modified": "2018-08-08 17:09:55.969424", "modified_by": "Administrator", "module": "Healthcare", - "name": "medical_record", + "name": "patient_history", "owner": "Administrator", - "page_name": "medical_record", + "page_name": "patient_history", "restrict_to_domain": "Healthcare", "roles": [ + { + "role": "Healthcare Administrator" + }, { "role": "Physician" } @@ -21,5 +24,5 @@ "standard": "Yes", "style": null, "system_page": 0, - "title": "Medical Record" + "title": "Patient History" } \ No newline at end of file diff --git a/erpnext/healthcare/page/patient_history/patient_history.py b/erpnext/healthcare/page/patient_history/patient_history.py new file mode 100644 index 0000000000..772aa4ef5e --- /dev/null +++ b/erpnext/healthcare/page/patient_history/patient_history.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, ESS LLP and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.utils import cint +from erpnext.healthcare.utils import render_docs_as_html + +@frappe.whitelist() +def get_feed(name, start=0, page_length=20): + """get feed""" + result = frappe.db.sql("""select name, owner, creation, + reference_doctype, reference_name, subject + from `tabPatient Medical Record` + where patient=%(patient)s + order by creation desc + limit %(start)s, %(page_length)s""", + { + "patient": name, + "start": cint(start), + "page_length": cint(page_length) + }, as_dict=True) + return result + +@frappe.whitelist() +def get_feed_for_dt(doctype, docname): + """get feed""" + result = frappe.db.sql("""select name, owner, modified, creation, + reference_doctype, reference_name, subject + from `tabPatient Medical Record` + where reference_name=%(docname)s and reference_doctype=%(doctype)s + order by creation desc""", + { + "docname": docname, + "doctype": doctype + }, as_dict=True) + + return result diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py index 6a226d9c6b..97bb98f677 100644 --- a/erpnext/healthcare/utils.py +++ b/erpnext/healthcare/utils.py @@ -429,3 +429,116 @@ def get_children(doctype, parent, company, is_root=False): occupancy_msg = str(occupied) + " Occupied out of " + str(occupancy_total) each["occupied_out_of_vacant"] = occupancy_msg return hc_service_units + +@frappe.whitelist() +def get_patient_vitals(patient, from_date=None, to_date=None): + if not patient: return + vitals = frappe.db.sql("""select * from `tabVital Signs` where \ + docstatus=1 and patient=%s order by signs_date, signs_time""", \ + (patient), as_dict=1) + if vitals and vitals[0]: + return vitals + else: + return False + +@frappe.whitelist() +def render_docs_as_html(docs): + # docs key value pair {doctype: docname} + docs_html = "
" + for doc in docs: + docs_html += render_doc_as_html(doc['doctype'], doc['docname'])['html'] + "
" + return {'html': docs_html} + +@frappe.whitelist() +def render_doc_as_html(doctype, docname, exclude_fields = []): + #render document as html, three column layout will break + doc = frappe.get_doc(doctype, docname) + meta = frappe.get_meta(doctype) + doc_html = "
" + section_html = "" + section_label = "" + html = "" + sec_on = False + col_on = 0 + has_data = False + for df in meta.fields: + #on section break append append previous section and html to doc html + if df.fieldtype == "Section Break": + if has_data and col_on and sec_on: + doc_html += section_html + html + "
" + elif has_data and not col_on and sec_on: + doc_html += "
" \ + + section_html + html +"
" + while col_on: + doc_html += "
" + col_on -= 1 + sec_on = True + has_data= False + col_on = 0 + section_html = "" + html = "" + if df.label: + section_label = df.label + continue + #on column break append html to section html or doc html + if df.fieldtype == "Column Break": + if sec_on and has_data: + section_html += "
" + section_label + "" + html + "
" + elif has_data: + doc_html += "
" + html + "
" + elif sec_on and not col_on: + section_html += "
" + html = "" + col_on += 1 + if df.label: + html += '
' + df.label + continue + #on table iterate in items and create table based on in_list_view, append to section html or doc html + if df.fieldtype == "Table": + items = doc.get(df.fieldname) + if not items: continue + child_meta = frappe.get_meta(df.options) + if not has_data : has_data = True + table_head = "" + table_row = "" + create_head = True + for item in items: + table_row += '' + for cdf in child_meta.fields: + if cdf.in_list_view: + if create_head: + table_head += '' + cdf.label + '' + if item.get(cdf.fieldname): + table_row += '' + str(item.get(cdf.fieldname)) \ + + '' + else: + table_row += '' + create_head = False + table_row += '' + if sec_on: + section_html += '' + table_head + table_row + '
' + else: + html += '' \ + + table_head + table_row + '
' + continue + #on other field types add label and value to html + if not df.hidden and not df.print_hide and doc.get(df.fieldname) and df.fieldname not in exclude_fields: + html += "
{0} : {1}".format(df.label or df.fieldname, \ + doc.get(df.fieldname)) + if not has_data : has_data = True + if sec_on and col_on and has_data: + doc_html += section_html + html + "
" + elif sec_on and not col_on and has_data: + doc_html += "
" \ + + section_html + html +"
" + if doc_html: + doc_html = "
" %(doctype, docname) + doc_html + "
" + + return {'html': doc_html} diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 571c2dc75b..a29378547e 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -605,6 +605,7 @@ erpnext.patches.v11_1.delete_scheduling_tool erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019 execute:frappe.delete_doc_if_exists("Page", "support-analytics") erpnext.patches.v12_0.make_item_manufacturer +erpnext.patches.v12_0.remove_patient_medical_record_page erpnext.patches.v11_1.move_customer_lead_to_dynamic_column erpnext.patches.v11_1.set_default_action_for_quality_inspection erpnext.patches.v11_1.delete_bom_browser diff --git a/erpnext/patches/v12_0/remove_patient_medical_record_page.py b/erpnext/patches/v12_0/remove_patient_medical_record_page.py new file mode 100644 index 0000000000..904bfe4bf1 --- /dev/null +++ b/erpnext/patches/v12_0/remove_patient_medical_record_page.py @@ -0,0 +1,7 @@ +# Copyright (c) 2019 + +from __future__ import unicode_literals +import frappe + +def execute(): + frappe.delete_doc("Page", "medical_record")