mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-09 16:12:53 +00:00
[domain] Healthcare (#10664)
* Medical module for erpnext * Changes in core for Medical module * patient registration updated * fix - appointment invioce - fields missing * pages- indicator instead of bg-color * Lab Test field renamed service type * Department added Lab Test * procedure name in prescription * fixes sample collection * filter disabled patient * fix patient admission * updated patient age * availability check msg updated * fixes, removed procedure from invoice * sample print renamed * fixes, validation * service desk physician in filter * refactor scheduler * Appointment -field property - set only once = 1 * Appointment - Mark closed and pending buttons removed * Appointment - readonly = 1 if value set * Appointment - availabilty * Appointment - Cancel - info - cancel invoice * Appointment - set pending appointments * Dosage form - new DT * Drug Prescription - Dosage form added * Facility - Floor - removed from Fecility * Floor - removed * Lab Test Template - item creation validation * Procedure - Create Procedure * Procedure Appointment - new DT * Service Unit - Floor reference removed * Zone Fcilities - Unused DT removed * Appointment Desk - fixed * Service Desk - method pointing from procedure changed to procedure_appointment * Consultation print - got featured * Consultation - removed patient refernce to procedure prescription * Procedure Prescription - removed patient refernce * Lab Test - Changed field properties and value * Lab Test - field property changed * Lab Test - methods rewrite - lab test doc creation * Lab Test - create lab test from invoice and consultaion - got changed * Button History changed to Medical Record * Service Desk - Updated * Notification - Procedure Appointment * fix-get procedure prescription * fix field added to test prescription * msgprint on invoice creation * fix data on install * Merge branch erpnext/develop * fixes- minor * Setup wizard - Create Sensitivity * Appointment - Validate and Save if there is no schedule for Physician * Consultation - Button create vital signs and medical record * Review Type - New DocType * Review Detail and Treatment Plan - Childs - Consultation * Patient Medical Record - field Attach doc * Consultation - New Fields * Consultation - Manage new Fields - Medical record add action * Patient Relation - Child DocType - Patient * Patient - Patient Relation added * Patient - collapsible = 1 * Laboratory Settings - fields - message for lab test * Laboratory Settings - get message for lab test * SMS text for lab test and invoice test report * Procedure Stock Detail - Stock detail for Procedure and Template * Template Stage Detail - Stage detail for Procedure Template * Procedure Stage Detail - Stage detail for Procedure * Service Unit - field - warehouse * Scheduler - msg - content changed * Laboratory Settings - defualt - msg content * Invoice Test Report - msg print * Print Format-Changed-Consultation-Invoice Test Report-Lab Test * OP Settings - Expnse Account for Stock Entry in Procedure * Procedure and Procedure Template - Manage Stock Stage and Sample Collection * Procedure Appointment - Manage Stock and Stage * Lab Test - fixed - resource not find * Invoice Test Report - fixed - resource not find * Procedure - doc reload after insert * Patient Medical Record - fixed - refernce missed * Create Vital Signs -on client side * Rename module Medical to Healthcare * Remove In Patient (IP) Feature. * Rename - Procedure to Clinical Procedure * Remove spaces in Naming Series * Rename Duration to Drug Prescription Duration * Duration to Drug Prescription Duration * Merge All Settings to Healthcare Settings * Healthcare settings - import fixed * Procedure related documents are removed * Appointment Desk and Sevrvice Desk are removed * Consultation - minimal * Consultation - minimal * Consultation - minimal - patient detials in collapsible section * Message Print to Alerts * Patient - some fields removed * Patient - create consultation - message print to alerts * Consultation - show patient details updated * Setup wizard - Duration to Drug Prescritpion Duration * Healthcare Settings - patient registration - fee collection * Lab Test - Create Sales Invoice bug fixed * Healthcare menu rearranged * Healthcare Settings - Optimised and Rearragnged * Healthcare Settings - Expense account removed * Receivable account removed from patient * Patient - Optimised and Rearragnged * Removed Referring Physician * Healthcare Settings - bold headings removed * Physician - Patient - Fields are Segregated * Remove Service Unit * Remove - Service Type * Consultation invoice * Lab Test - invoice * Patient - Invoice * Rename Appointment to Patient Appointment * wip * Patient Dashboard, Physician Form cleanup * Dosage renamed to Prescription Dosage * Renamed Drug Prescription Duration to Prescription Duration * Patient Appointment booking modal * Patient Age - calculate by dob * Remove - scheduler * Consultation - Appointment to Patient Appointment * Patient Dashboard - rearranged * Patient Appointment * Removed rer_physician from lab test and consultation * Patient Appontment Changes * Appointment and Consultation - optimized * Patient Appointment - fee validity code optimized * Consultation and Patient Appointment - Invoice validate two side * fix: #13 remove relation to admission * Healthcare - Patient Portal * fix import error * domain Healthcare added on install * Removed - Invoice Test Report * Physician Schedule - menu * Consultation - patient details - re write * New Doctype-Medical Code * Consultation - Daignosis codification * Medical Code - Codification - Settings * Medical Code Standard - Medical Code - Codification - Settings * fix appointment calendar * fix appointment analytics * Menu Medical Code Standard * New Doctype - Medical Code Standard * Set Physician Role insted of IP Physician and OP Physician Role * fixed some json files * Medical code - permission to physician * Unused Childs - Work Schedule and User List - Removed * Label Procedure to Lab Test * Lab Test and Patient - code optimised * Add Item Groups - setup wizard * Healthcare Settings - add Role - Medical Administrator * Healthcare - Demo setup - Make Demo * Fee Validity - Logic Test * Test Fee Validity - Optimised * Healthcare Doctypes - Restricted to Domain Healthcare * Domainify - remove Healthcare Roles - Other Domains * Healthcare doctypes - beta checked * Codacy fixes * Codacy - fixes * Codacy - fixes * Codacy - fixes * Codacy - fixes * Codacy - fixes * Lab Test - print hide =1 for some fields * Consultation - Codification field label to Medical Coding * Codacy fixes - import frappe and etc. * Codacy fixes - import frappe in test_vital_signs * Codacy fixes * Codacy fixes * Codacy fixes and remove delete perm for patient * send_sms - import form frappe * Healthcare Settings * Lab Prescription - Consultation - Test Code - read_only = 0 * Portal fixes * Patient Appointment - filter physician - if has schedule * Physician - IP Charge - Removed * test - files * Web Form - Patient Profile - removed * Role Medical Administrator to Healthcare Administrator * WIP healthcare documentation * Coday - fixes * Travis - fixes * Lab Test Report - menu * Reorder Healthcare settings - group lab config to bottom * Sample Collection - New - allow Sample and patient Selection * Rate - similar behaviour and Label as in Item Standard Selling Rate * Healthcare documentation * Lab Test Samples to Lab Test sample * Commplaints to Complaint * Commplaints to Complaint * Antibiotics to Antibiotic * Appointment Token Number - remove * View - Medical record * Codacy fixes * update healthcare docs * Cleanup Docs - Search, quick entry, trsck change, etc. * [minor] ux changes
This commit is contained in:
committed by
Makarand Bauskar
parent
ff667695ad
commit
f056974bc5
1
erpnext/healthcare/page/__init__.py
Normal file
1
erpnext/healthcare/page/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,209 @@
|
||||
frappe.pages['appointment-analytic'].on_page_load = function(wrapper) {
|
||||
frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: 'Appointment Analytics',
|
||||
single_column: true
|
||||
});
|
||||
new erpnext.AppointmentAnalytics(wrapper);
|
||||
frappe.breadcrumbs.add("Medical");
|
||||
};
|
||||
|
||||
erpnext.AppointmentAnalytics = frappe.views.TreeGridReport.extend({
|
||||
init: function(wrapper) {
|
||||
this._super({
|
||||
title: __("Appointment Analytics"),
|
||||
parent: $(wrapper).find('.layout-main'),
|
||||
page: wrapper.page,
|
||||
doctypes: ["Patient Appointment", "Physician", "Medical Department", "Appointment Type", "Patient"],
|
||||
tree_grid: { show: true }
|
||||
});
|
||||
|
||||
this.tree_grids = {
|
||||
"Medical Department": {
|
||||
label: __("Department"),
|
||||
show: true,
|
||||
item_key: "physician",
|
||||
parent_field: "department",
|
||||
formatter: function(item) {
|
||||
return item.name;
|
||||
}
|
||||
},
|
||||
"Physician": {
|
||||
label: __("Physician"),
|
||||
show: true,
|
||||
item_key: "physician",
|
||||
formatter: function(item) {
|
||||
return item.name;
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
setup_columns: function() {
|
||||
this.tree_grid = this.tree_grids[this.tree_type];
|
||||
|
||||
var std_columns = [
|
||||
{id: "_check", name: __("Plot"), field: "_check", width: 40,
|
||||
formatter: this.check_formatter},
|
||||
{id: "name", name: this.tree_grid.label, field: "name", width: 300,
|
||||
formatter: this.tree_formatter},
|
||||
{id: "total", name: "Total", field: "total", plot: false,
|
||||
formatter: this.currency_formatter}
|
||||
];
|
||||
|
||||
this.make_date_range_columns();
|
||||
this.columns = std_columns.concat(this.columns);
|
||||
},
|
||||
filters: [
|
||||
{fieldtype:"Select", label: __("Tree Type"), fieldname: "tree_type",
|
||||
options:["Physician", "Medical Department"], filter: function(val, item, opts, me) {
|
||||
return me.apply_zero_filter(val, item, opts, me);}},
|
||||
{fieldtype:"Select", label: __("Status"), fieldname: "status",
|
||||
options:[
|
||||
{label: __("Select Status"), value: "Select Status..."},
|
||||
{label: __("Open"), value: "Open"},
|
||||
{label: __("Closed"), value: "Closed"},
|
||||
{label: __("Pending"), value: "Pending"},
|
||||
{label: __("Scheduled"), value: "Scheduled"},
|
||||
{label: __("Cancelled"), value: "Cancelled"}]},
|
||||
{fieldtype:"Select", label: __("Type"), link:"Appointment Type", fieldname: "type",
|
||||
default_value: __("Select Type...")},
|
||||
{fieldtype:"Select", label: __("Physician"), link:"Physician", fieldname: "physician",
|
||||
default_value: __("Select Physician..."), filter: function(val, item, opts) {
|
||||
return val == opts.default_value || item.name == val || item._show;
|
||||
}, link_formatter: {filter_input: "physician"}},
|
||||
{fieldtype:"Select", label: __("Department"), link:"Medical Department", fieldname: "department",
|
||||
default_value: __("Select Department..."), filter: function(val, item, opts) {
|
||||
return val == opts.default_value || item.department == val || item._show;
|
||||
}, link_formatter: {filter_input: "department"}},
|
||||
{fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
|
||||
{fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
|
||||
{fieldtype:"Select", label: __("Range"), fieldname: "range",
|
||||
options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"},
|
||||
{label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"},
|
||||
{label: __("Yearly"), value: "Yearly"}]}
|
||||
],
|
||||
setup_filters: function() {
|
||||
this._super();
|
||||
this.trigger_refresh_on_change(["tree_type", "physician", "department", "status", "type"]);
|
||||
|
||||
// this.show_zero_check()
|
||||
this.setup_chart_check();
|
||||
},
|
||||
init_filter_values: function() {
|
||||
this._super();
|
||||
this.filter_inputs.range.val('Quarterly');
|
||||
},
|
||||
prepare_data: function() {
|
||||
var me = this;
|
||||
if (!this.tl) {
|
||||
this.tl = frappe.report_dump.data["Patient Appointment"];
|
||||
}
|
||||
if(!this.data || me.item_type != me.tree_type) {
|
||||
var items = null;
|
||||
if(me.tree_type=='Physician') {
|
||||
items = frappe.report_dump.data["Physician"];
|
||||
} if(me.tree_type=='Medical Department') {
|
||||
items = this.prepare_tree("Physician", "Medical Department");
|
||||
}
|
||||
me.item_type = me.tree_type;
|
||||
me.parent_map = {};
|
||||
me.item_by_name = {};
|
||||
me.data = [];
|
||||
|
||||
$.each(items, function(i, v) {
|
||||
var d = copy_dict(v);
|
||||
|
||||
me.data.push(d);
|
||||
me.item_by_name[d.name] = d;
|
||||
if(d[me.tree_grid.parent_field]) {
|
||||
me.parent_map[d.name] = d[me.tree_grid.parent_field];
|
||||
}
|
||||
me.reset_item_values(d);
|
||||
});
|
||||
|
||||
this.set_indent();
|
||||
|
||||
|
||||
} else {
|
||||
// otherwise, only reset values
|
||||
$.each(this.data, function(i, d) {
|
||||
me.reset_item_values(d);
|
||||
});
|
||||
}
|
||||
this.prepare_balances();
|
||||
if(me.tree_grid.show) {
|
||||
this.set_totals(false);
|
||||
this.update_groups();
|
||||
} else {
|
||||
this.set_totals(true);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
prepare_balances: function() {
|
||||
var me = this;
|
||||
var from_date = frappe.datetime.str_to_obj(this.from_date);
|
||||
var status = this.status;
|
||||
var type = this.type;
|
||||
var to_date = frappe.datetime.str_to_obj(this.to_date);
|
||||
$.each(this.tl, function(i, tl) {
|
||||
if (me.is_default('company') ? true : tl.company === me.company) {
|
||||
|
||||
var date = frappe.datetime.str_to_obj(tl.appointment_date);
|
||||
if (date >= from_date && date <= to_date) {
|
||||
var item = me.item_by_name[tl[me.tree_grid.item_key]] ||
|
||||
me.item_by_name['Not Set'];
|
||||
|
||||
var d = tl.appointment_date.split(" ")[0];
|
||||
if(status == "Select Status..." && type=="Select Type...")
|
||||
{
|
||||
item[me.column_map[d].field] += 1;
|
||||
|
||||
}else if (status !== "Select Status..." && type == "Select Type..."){
|
||||
if(status === tl.status){item[me.column_map[d].field] += 1;}
|
||||
}else if (status == "Select Status..." && type !== "Select Type..."){
|
||||
if(type === tl.appointment_type){item[me.column_map[d].field] += 1;}
|
||||
}else {
|
||||
if(type === tl.appointment_type && status === tl.status){item[me.column_map[d].field] += 1;}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
update_groups: function() {
|
||||
var me = this;
|
||||
|
||||
$.each(this.data, function(i, item) {
|
||||
var parent = me.parent_map[item.name];
|
||||
while(parent) {
|
||||
var parent_group = me.item_by_name[parent];
|
||||
|
||||
$.each(me.columns, function(c, col) {
|
||||
if (col.formatter == me.currency_formatter) {
|
||||
parent_group[col.field] =
|
||||
flt(parent_group[col.field])
|
||||
+ flt(item[col.field]);
|
||||
}
|
||||
});
|
||||
parent = me.parent_map[parent];
|
||||
}
|
||||
});
|
||||
},
|
||||
set_totals: function(sort) {
|
||||
var me = this;
|
||||
$.each(this.data, function(i, d) {
|
||||
d.total = 0.0;
|
||||
$.each(me.columns, function(i, col) {
|
||||
if(col.formatter==me.currency_formatter && !col.hidden && col.field!="total")
|
||||
d.total += d[col.field];
|
||||
});
|
||||
});
|
||||
|
||||
if(sort)this.data = this.data.sort(function(a, b) { return b.total - a.total; });
|
||||
|
||||
if(!this.checked) {
|
||||
this.data[0].checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"content": null,
|
||||
"creation": "2016-08-18 12:29:52.497819",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"idx": 0,
|
||||
"modified": "2016-08-18 12:29:52.497819",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "appointment-analytic",
|
||||
"owner": "Administrator",
|
||||
"page_name": "Appointment Analytics",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Physician"
|
||||
}
|
||||
],
|
||||
"script": null,
|
||||
"standard": "Yes",
|
||||
"style": null,
|
||||
"title": "Appointment Analytics"
|
||||
}
|
||||
1
erpnext/healthcare/page/medical_record/__init__.py
Normal file
1
erpnext/healthcare/page/medical_record/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
73
erpnext/healthcare/page/medical_record/medical_record.css
Normal file
73
erpnext/healthcare/page/medical_record/medical_record.css
Normal file
@@ -0,0 +1,73 @@
|
||||
#page-medical_record .label {
|
||||
display: inline-block;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
#page-medical_record .list-row {
|
||||
border: none;
|
||||
padding: 0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.medical_record-label {
|
||||
max-width: 100px;
|
||||
margin-bottom: -4px;
|
||||
}
|
||||
|
||||
.date-indicator {
|
||||
background:none;
|
||||
font-size:12px;
|
||||
vertical-align:middle;
|
||||
font-weight:bold;
|
||||
color:#6c7680;
|
||||
}
|
||||
.date-indicator::after {
|
||||
margin:0 -4px 0 12px;
|
||||
content:'';
|
||||
display:inline-block;
|
||||
height:8px;
|
||||
width:8px;
|
||||
border-radius:8px;
|
||||
background: #d1d8dd;
|
||||
}
|
||||
|
||||
.date-indicator.blue {
|
||||
color: #5e64ff;
|
||||
}
|
||||
|
||||
.date-indicator.blue::after {
|
||||
background: #5e64ff;
|
||||
}
|
||||
|
||||
.medical_record-message {
|
||||
border-left: 1px solid #d1d8dd;
|
||||
padding: 15px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.medical_record-date {
|
||||
padding: 15px;
|
||||
padding-right: 0px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#page-medical_record .plot-wrapper {
|
||||
padding: 20px 15px;
|
||||
border-bottom: 1px solid #d1d8dd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#page-medical_record .plot {
|
||||
height: 140px ;
|
||||
width: 97% ;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#page-medical_record .list-filters {
|
||||
display: none ;
|
||||
}
|
||||
|
||||
#page-medical_record .octicon-heart {
|
||||
color: #ff5858;
|
||||
margin: 0px 5px;
|
||||
}
|
||||
182
erpnext/healthcare/page/medical_record/medical_record.js
Normal file
182
erpnext/healthcare/page/medical_record/medical_record.js
Normal file
@@ -0,0 +1,182 @@
|
||||
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 += "<br><b>Email :</b> " + data.email;
|
||||
if(data.mobile) details += "<br><b>Mobile :</b> " + data.mobile;
|
||||
if(data.occupation) details += "<br><b>Occupation :</b> " + data.occupation;
|
||||
if(data.blood_group) details += "<br><b>Blood group : </b> " + data.blood_group;
|
||||
if(data.allergies) details += "<br><br><b>Allergies : </b> "+ data.allergies;
|
||||
if(data.medication) details += "<br><b>Medication : </b> "+ data.medication;
|
||||
if(data.alcohol_current_use) details += "<br><br><b>Alcohol use : </b> "+ data.alcohol_current_use;
|
||||
if(data.alcohol_past_use) details += "<br><b>Alcohol past use : </b> "+ data.alcohol_past_use;
|
||||
if(data.tobacco_current_use) details += "<br><b>Tobacco use : </b> "+ data.tobacco_current_use;
|
||||
if(data.tobacco_past_use) details += "<br><b>Tobacco past use : </b> "+ data.tobacco_past_use;
|
||||
if(data.medical_history) details += "<br><br><b>Medical history : </b> "+ data.medical_history;
|
||||
if(data.surgical_history) details += "<br><b>Surgical history : </b> "+ data.surgical_history;
|
||||
if(data.surrounding_factors) details += "<br><br><b>Occupational hazards : </b> "+ data.surrounding_factors;
|
||||
if(data.other_risk_factors) details += "<br><b>Other risk factors : </b> " + data.other_risk_factors;
|
||||
if(data.patient_details) details += "<br><br><b>More info : </b> " + data.patient_details;
|
||||
|
||||
if(details){
|
||||
details = "<div style='padding-left:10px; font-size:13px;' align='center'></br><b class='text-muted'>Patient Details</b>" + details + "</div>";
|
||||
}
|
||||
|
||||
var vitals = "";
|
||||
if(data.temperature) vitals += "<br><b>Temperature :</b> " + data.temperature;
|
||||
if(data.pulse) vitals += "<br><b>Pulse :</b> " + data.pulse;
|
||||
if(data.respiratory_rate) vitals += "<br><b>Respiratory Rate :</b> " + data.respiratory_rate;
|
||||
if(data.bp) vitals += "<br><b>BP :</b> " + data.bp;
|
||||
if(data.bmi) vitals += "<br><b>BMI :</b> " + data.bmi;
|
||||
if(data.height) vitals += "<br><b>Height :</b> " + data.height;
|
||||
if(data.weight) vitals += "<br><b>Weight :</b> " + data.weight;
|
||||
if(data.signs_date) vitals += "<br><b>Date :</b> " + data.signs_date;
|
||||
|
||||
if(vitals){
|
||||
vitals = "<div style='padding-left:10px; font-size:13px;' align='center'></br><b class='text-muted'>Vital Signs</b>" + vitals + "<br></div>";
|
||||
details = vitals + details;
|
||||
}
|
||||
if(details) details += "<div align='center'><br><a class='btn btn-default btn-sm edit-details'>Edit Details</a></b> </div>";
|
||||
|
||||
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: $("<div></div>").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 = $('<div class="list-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;
|
||||
}
|
||||
});
|
||||
23
erpnext/healthcare/page/medical_record/medical_record.json
Normal file
23
erpnext/healthcare/page/medical_record/medical_record.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"content": null,
|
||||
"creation": "2016-06-09 11:33:14.025787",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"icon": "icon-play",
|
||||
"idx": 0,
|
||||
"modified": "2017-03-06 11:20:40.174661",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "medical_record",
|
||||
"owner": "Administrator",
|
||||
"page_name": "medical_record",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Physician"
|
||||
}
|
||||
],
|
||||
"script": null,
|
||||
"standard": "Yes",
|
||||
"style": null,
|
||||
"title": "Medical Record"
|
||||
}
|
||||
24
erpnext/healthcare/page/medical_record/medical_record.py
Normal file
24
erpnext/healthcare/page/medical_record/medical_record.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- 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
|
||||
@@ -0,0 +1,21 @@
|
||||
<div class="row medical_record-row" data-creation="{%= creation.split(" ")[0] + " 00:00:00" %}">
|
||||
<div class="col-xs-3 text-right medical_record-date"><span class="{%= date_class %}">
|
||||
{%= date_sep || "" %}</span>
|
||||
</div>
|
||||
<div class="col-xs-9 medical_record-message"
|
||||
data-doctype="{%= reference_doctype %}"
|
||||
data-docname="{%= reference_name %}"
|
||||
title="{%= by %} / {%= dateutil.str_to_user(creation) %}">
|
||||
<span class="avatar avatar-small">
|
||||
<div class="avatar-frame" style="background-image: url({{ imgsrc }});"></div>
|
||||
<!-- <img src="{%= imgsrc %}"> -->
|
||||
</span>
|
||||
<span class="small">
|
||||
{% if (reference_doctype && reference_name) { %}
|
||||
{%= __("{0}: {1}", [link, "<strong>" + subject + "</strong>"]) %}
|
||||
{% } else { %}
|
||||
{%= subject %}
|
||||
{% } %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,5 @@
|
||||
<div class="text-center col-sm-9" style="padding: 40px;">
|
||||
|
||||
<p>{%= __("Select Patient") %}</p>
|
||||
<p class="patient" style="margin: auto; max-width: 300px; margin-bottom: 20px;"></p>
|
||||
</div>
|
||||
Reference in New Issue
Block a user