Merge pull request #21508 from ruchamahabal/fix-healthcare

fix: Healthcare Fixes
This commit is contained in:
rohitwaghchaure
2020-04-29 22:13:55 +05:30
committed by GitHub
11 changed files with 259 additions and 56 deletions

View File

@@ -80,6 +80,7 @@ frappe.ui.form.on('Clinical Procedure', {
frappe.call({ frappe.call({
method: 'complete_procedure', method: 'complete_procedure',
doc: frm.doc, doc: frm.doc,
freeze: true,
callback: function(r) { callback: function(r) {
if (r.message) { if (r.message) {
frappe.show_alert({ frappe.show_alert({
@@ -87,8 +88,8 @@ frappe.ui.form.on('Clinical Procedure', {
['<a class="bold" href="#Form/Stock Entry/'+ r.message + '">' + r.message + '</a>']), ['<a class="bold" href="#Form/Stock Entry/'+ r.message + '">' + r.message + '</a>']),
indicator: 'green' indicator: 'green'
}); });
frm.reload_doc();
} }
frm.reload_doc();
} }
}); });
} }
@@ -111,9 +112,10 @@ frappe.ui.form.on('Clinical Procedure', {
frappe.call({ frappe.call({
doc: frm.doc, doc: frm.doc,
method: 'make_material_receipt', method: 'make_material_receipt',
freeze: true,
callback: function(r) { callback: function(r) {
if (!r.exc) { if (!r.exc) {
cur_frm.reload_doc(); frm.reload_doc();
let doclist = frappe.model.sync(r.message); let doclist = frappe.model.sync(r.message);
frappe.set_route('Form', doclist[0].doctype, doclist[0].name); frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
} }
@@ -122,7 +124,7 @@ frappe.ui.form.on('Clinical Procedure', {
} }
); );
} else { } else {
cur_frm.reload_doc(); frm.reload_doc();
} }
} }
} }

View File

@@ -87,7 +87,8 @@ class ClinicalProcedure(Document):
else: else:
frappe.throw(_('Please set Customer in Patient {0}').format(frappe.bold(self.patient)), title=_('Customer Not Found')) frappe.throw(_('Please set Customer in Patient {0}').format(frappe.bold(self.patient)), title=_('Customer Not Found'))
frappe.db.set_value('Clinical Procedure', self.name, 'status', 'Completed') self.db_set('status', 'Completed')
if self.consume_stock and self.items: if self.consume_stock and self.items:
return stock_entry return stock_entry
@@ -245,9 +246,9 @@ def make_procedure(source_name, target_doc=None):
def insert_clinical_procedure_to_medical_record(doc): def insert_clinical_procedure_to_medical_record(doc):
subject = cstr(doc.procedure_template) subject = frappe.bold(_("Clinical Procedure conducted: ")) + cstr(doc.procedure_template) + "<br>"
if doc.practitioner: if doc.practitioner:
subject += ' ' + doc.practitioner subject += frappe.bold(_('Healthcare Practitioner: ')) + doc.practitioner
if subject and doc.notes: if subject and doc.notes:
subject += '<br/>' + doc.notes subject += '<br/>' + doc.notes

View File

@@ -24,6 +24,8 @@ erpnext.ExerciseEditor = Class.extend({
this.exercise_cards = $('<div class="exercise-cards"></div>').appendTo(this.wrapper); this.exercise_cards = $('<div class="exercise-cards"></div>').appendTo(this.wrapper);
this.row = $('<div class="exercise-row"></div>').appendTo(this.wrapper);
let me = this; let me = this;
this.exercise_toolbar.find(".btn-add") this.exercise_toolbar.find(".btn-add")
@@ -32,7 +34,7 @@ erpnext.ExerciseEditor = Class.extend({
me.show_add_card_dialog(frm); me.show_add_card_dialog(frm);
}); });
if (frm.doc.steps_table.length > 0) { if (frm.doc.steps_table && frm.doc.steps_table.length > 0) {
this.make_cards(frm); this.make_cards(frm);
this.make_buttons(frm); this.make_buttons(frm);
} }
@@ -41,7 +43,6 @@ erpnext.ExerciseEditor = Class.extend({
make_cards: function(frm) { make_cards: function(frm) {
var me = this; var me = this;
$(me.exercise_cards).empty(); $(me.exercise_cards).empty();
this.row = $('<div class="exercise-row"></div>').appendTo(me.exercise_cards);
$.each(frm.doc.steps_table, function(i, step) { $.each(frm.doc.steps_table, function(i, step) {
$(repl(` $(repl(`
@@ -78,6 +79,7 @@ erpnext.ExerciseEditor = Class.extend({
frm.doc.steps_table.pop(id); frm.doc.steps_table.pop(id);
frm.refresh_field('steps_table'); frm.refresh_field('steps_table');
$('#col-'+id).remove(); $('#col-'+id).remove();
frm.dirty();
}, 300); }, 300);
}); });
}, },
@@ -106,7 +108,10 @@ erpnext.ExerciseEditor = Class.extend({
], ],
primary_action: function() { primary_action: function() {
let data = d.get_values(); let data = d.get_values();
let i = frm.doc.steps_table.length; let i = 0;
if (frm.doc.steps_table) {
i = frm.doc.steps_table.length;
}
$(repl(` $(repl(`
<div class="exercise-col col-sm-4" id="%(col_id)s"> <div class="exercise-col col-sm-4" id="%(col_id)s">
<div class="card h-100 exercise-card" id="%(card_id)s"> <div class="card h-100 exercise-card" id="%(card_id)s">
@@ -165,9 +170,10 @@ erpnext.ExerciseEditor = Class.extend({
frm.doc.steps_table[id].image = data.image; frm.doc.steps_table[id].image = data.image;
frm.doc.steps_table[id].description = data.step_description; frm.doc.steps_table[id].description = data.step_description;
refresh_field('steps_table'); refresh_field('steps_table');
frm.dirty();
new_dialog.hide(); new_dialog.hide();
}, },
primary_action_label: __("Save"), primary_action_label: __("Edit"),
}); });
new_dialog.set_values({ new_dialog.set_values({

View File

@@ -288,23 +288,23 @@ def insert_lab_test_to_medical_record(doc):
table_row = False table_row = False
subject = cstr(doc.lab_test_name) subject = cstr(doc.lab_test_name)
if doc.practitioner: if doc.practitioner:
subject += " "+ doc.practitioner subject += frappe.bold(_("Healthcare Practitioner: "))+ doc.practitioner + "<br>"
if doc.normal_test_items: if doc.normal_test_items:
item = doc.normal_test_items[0] item = doc.normal_test_items[0]
comment = "" comment = ""
if item.lab_test_comment: if item.lab_test_comment:
comment = str(item.lab_test_comment) comment = str(item.lab_test_comment)
table_row = item.lab_test_name table_row = frappe.bold(_("Lab Test Conducted: ")) + item.lab_test_name
if item.lab_test_event: if item.lab_test_event:
table_row += " " + item.lab_test_event table_row += frappe.bold(_("Lab Test Event: ")) + item.lab_test_event
if item.result_value: if item.result_value:
table_row += " " + item.result_value table_row += " " + frappe.bold(_("Lab Test Result: ")) + item.result_value
if item.normal_range: if item.normal_range:
table_row += " normal_range("+item.normal_range+")" table_row += " " + _("Normal Range:") + item.normal_range
table_row += " "+comment table_row += " " + comment
elif doc.special_test_items: elif doc.special_test_items:
item = doc.special_test_items[0] item = doc.special_test_items[0]
@@ -316,12 +316,12 @@ def insert_lab_test_to_medical_record(doc):
item = doc.sensitivity_test_items[0] item = doc.sensitivity_test_items[0]
if item.antibiotic and item.antibiotic_sensitivity: if item.antibiotic and item.antibiotic_sensitivity:
table_row = item.antibiotic +" "+ item.antibiotic_sensitivity table_row = item.antibiotic + " " + item.antibiotic_sensitivity
if table_row: if table_row:
subject += "<br/>"+table_row subject += "<br>" + table_row
if doc.lab_test_comment: if doc.lab_test_comment:
subject += "<br/>"+ cstr(doc.lab_test_comment) subject += "<br>" + cstr(doc.lab_test_comment)
medical_record = frappe.new_doc("Patient Medical Record") medical_record = frappe.new_doc("Patient Medical Record")
medical_record.patient = doc.patient medical_record.patient = doc.patient

View File

@@ -18,6 +18,9 @@ class PatientEncounter(Document):
def after_insert(self): def after_insert(self):
insert_encounter_to_medical_record(self) insert_encounter_to_medical_record(self)
def on_submit(self):
update_encounter_medical_record(self)
def on_cancel(self): def on_cancel(self):
if self.appointment: if self.appointment:
frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Open') frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Open')
@@ -66,22 +69,26 @@ def delete_medical_record(encounter):
frappe.db.delete_doc_if_exists('Patient Medical Record', 'reference_name', encounter.name) frappe.db.delete_doc_if_exists('Patient Medical Record', 'reference_name', encounter.name)
def set_subject_field(encounter): def set_subject_field(encounter):
subject = encounter.practitioner + '\n' subject = frappe.bold(_('Healthcare Practitioner: ')) + encounter.practitioner + '<br>'
if encounter.symptoms: if encounter.symptoms:
subject += _('Symptoms: ') + cstr(encounter.symptoms) + '\n' subject += frappe.bold(_('Symptoms: ')) + '<br>'
for entry in encounter.symptoms:
subject += cstr(entry.complaint) + '<br>'
else: else:
subject += _('No Symptoms') + '\n' subject += frappe.bold(_('No Symptoms')) + '<br>'
if encounter.diagnosis: if encounter.diagnosis:
subject += _('Diagnosis: ') + cstr(encounter.diagnosis) + '\n' subject += frappe.bold(_('Diagnosis: ')) + '<br>'
for entry in encounter.diagnosis:
subject += cstr(entry.diagnosis) + '<br>'
else: else:
subject += _('No Diagnosis') + '\n' subject += frappe.bold(_('No Diagnosis')) + '<br>'
if encounter.drug_prescription: if encounter.drug_prescription:
subject += '\n' + _('Drug(s) Prescribed.') subject += '<br>' + _('Drug(s) Prescribed.')
if encounter.lab_test_prescription: if encounter.lab_test_prescription:
subject += '\n' + _('Test(s) Prescribed.') subject += '<br>' + _('Test(s) Prescribed.')
if encounter.procedure_prescription: if encounter.procedure_prescription:
subject += '\n' + _('Procedure(s) Prescribed.') subject += '<br>' + _('Procedure(s) Prescribed.')
return subject return subject

View File

@@ -57,7 +57,7 @@
}, },
{ {
"fieldname": "subject", "fieldname": "subject",
"fieldtype": "Small Text", "fieldtype": "Text Editor",
"ignore_xss_filter": 1, "ignore_xss_filter": 1,
"label": "Subject" "label": "Subject"
}, },
@@ -125,7 +125,7 @@
], ],
"in_create": 1, "in_create": 1,
"links": [], "links": [],
"modified": "2020-03-23 19:26:59.308383", "modified": "2020-04-29 12:26:57.679402",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Healthcare", "module": "Healthcare",
"name": "Patient Medical Record", "name": "Patient Medical Record",

View File

@@ -21,8 +21,14 @@ class TherapyPlan(Document):
self.status = 'Completed' self.status = 'Completed'
def set_totals(self): def set_totals(self):
total_sessions = sum([int(d.no_of_sessions) for d in self.get('therapy_plan_details')]) total_sessions = 0
total_sessions_completed = sum([int(d.sessions_completed) for d in self.get('therapy_plan_details')]) total_sessions_completed = 0
for entry in self.therapy_plan_details:
if entry.no_of_sessions:
total_sessions += entry.no_of_sessions
if entry.sessions_completed:
total_sessions_completed += entry.sessions_completed
self.db_set('total_sessions', total_sessions) self.db_set('total_sessions', total_sessions)
self.db_set('total_sessions_completed', total_sessions_completed) self.db_set('total_sessions_completed', total_sessions_completed)

View File

@@ -13,23 +13,92 @@ frappe.ui.form.on('Therapy Session', {
refresh: function(frm) { refresh: function(frm) {
if (!frm.doc.__islocal) { if (!frm.doc.__islocal) {
let target = 0; frm.dashboard.add_indicator(__('Counts Targeted: {0}', [frm.doc.total_counts_targeted]), 'blue');
let completed = 0; frm.dashboard.add_indicator(__('Counts Completed: {0}', [frm.doc.total_counts_completed]),
$.each(frm.doc.exercises, function(_i, e) { (frm.doc.total_counts_completed < frm.doc.total_counts_targeted) ? 'orange' : 'green');
target += e.counts_target;
completed += e.counts_completed;
});
frm.dashboard.add_indicator(__('Counts Targetted: {0}', [target]), 'blue');
frm.dashboard.add_indicator(__('Counts Completed: {0}', [completed]), (completed < target) ? 'orange' : 'green');
} }
if (frm.doc.docstatus === 1) { if (frm.doc.docstatus === 1) {
frm.add_custom_button(__('Patient Assessment'),function() { frm.add_custom_button(__('Patient Assessment'), function() {
frappe.model.open_mapped_doc({ frappe.model.open_mapped_doc({
method: 'erpnext.healthcare.doctype.patient_assessment.patient_assessment.create_patient_assessment', method: 'erpnext.healthcare.doctype.patient_assessment.patient_assessment.create_patient_assessment',
frm: frm, frm: frm,
}) })
}, 'Create'); }, 'Create');
frm.add_custom_button(__('Sales Invoice'), function() {
frappe.model.open_mapped_doc({
method: 'erpnext.healthcare.doctype.therapy_session.therapy_session.invoice_therapy_session',
frm: frm,
})
}, 'Create');
}
},
patient: function(frm) {
if (frm.doc.patient) {
frappe.call({
'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
args: {
patient: frm.doc.patient
},
callback: function (data) {
let age = '';
if (data.message.dob) {
age = calculate_age(data.message.dob);
} else if (data.message.age) {
age = data.message.age;
if (data.message.age_as_on) {
age = __('{0} as on {1}', [age, data.message.age_as_on]);
}
}
frm.set_value('patient_age', age);
frm.set_value('gender', data.message.sex);
frm.set_value('patient_name', data.message.patient_name);
}
});
} else {
frm.set_value('patient_age', '');
frm.set_value('gender', '');
frm.set_value('patient_name', '');
}
},
appointment: function(frm) {
if (frm.doc.appointment) {
frappe.call({
'method': 'frappe.client.get',
args: {
doctype: 'Patient Appointment',
name: frm.doc.appointment
},
callback: function(data) {
let values = {
'patient':data.message.patient,
'therapy_type': data.message.therapy_type,
'therapy_plan': data.message.therapy_plan,
'practitioner': data.message.practitioner,
'department': data.message.department,
'start_date': data.message.appointment_date,
'start_time': data.message.appointment_time,
'service_unit': data.message.service_unit,
'company': data.message.company
};
frm.set_value(values);
}
});
} else {
let values = {
'patient': '',
'therapy_type': '',
'therapy_plan': '',
'practitioner': '',
'department': '',
'start_date': '',
'start_time': '',
'service_unit': '',
};
frm.set_value(values);
} }
}, },
@@ -44,6 +113,8 @@ frappe.ui.form.on('Therapy Session', {
callback: function(data) { callback: function(data) {
frm.set_value('duration', data.message.default_duration); frm.set_value('duration', data.message.default_duration);
frm.set_value('rate', data.message.rate); frm.set_value('rate', data.message.rate);
frm.set_value('service_unit', data.message.healthcare_service_unit);
frm.set_value('department', data.message.medical_department);
frm.doc.exercises = []; frm.doc.exercises = [];
$.each(data.message.exercises, function(_i, e) { $.each(data.message.exercises, function(_i, e) {
let exercise = frm.add_child('exercises'); let exercise = frm.add_child('exercises');

View File

@@ -9,9 +9,11 @@
"naming_series", "naming_series",
"appointment", "appointment",
"patient", "patient",
"patient_name",
"patient_age", "patient_age",
"gender", "gender",
"column_break_5", "column_break_5",
"company",
"therapy_plan", "therapy_plan",
"therapy_type", "therapy_type",
"practitioner", "practitioner",
@@ -20,7 +22,6 @@
"duration", "duration",
"rate", "rate",
"location", "location",
"company",
"column_break_12", "column_break_12",
"service_unit", "service_unit",
"start_date", "start_date",
@@ -28,6 +29,10 @@
"invoiced", "invoiced",
"exercises_section", "exercises_section",
"exercises", "exercises",
"section_break_23",
"total_counts_targeted",
"column_break_25",
"total_counts_completed",
"amended_from" "amended_from"
], ],
"fields": [ "fields": [
@@ -159,7 +164,8 @@
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"label": "Company", "label": "Company",
"options": "Company" "options": "Company",
"reqd": 1
}, },
{ {
"default": "0", "default": "0",
@@ -173,11 +179,38 @@
"fieldtype": "Data", "fieldtype": "Data",
"label": "Patient Age", "label": "Patient Age",
"read_only": 1 "read_only": 1
},
{
"fieldname": "total_counts_targeted",
"fieldtype": "Int",
"label": "Total Counts Targeted",
"read_only": 1
},
{
"fieldname": "total_counts_completed",
"fieldtype": "Int",
"label": "Total Counts Completed",
"read_only": 1
},
{
"fieldname": "section_break_23",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_25",
"fieldtype": "Column Break"
},
{
"fetch_from": "patient.patient_name",
"fieldname": "patient_name",
"fieldtype": "Data",
"label": "Patient Name",
"read_only": 1
} }
], ],
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-04-21 13:16:46.378798", "modified": "2020-04-29 16:49:16.286006",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Healthcare", "module": "Healthcare",
"name": "Therapy Session", "name": "Therapy Session",

View File

@@ -6,10 +6,17 @@ from __future__ import unicode_literals
import frappe import frappe
from frappe.model.document import Document from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from frappe import _
from frappe.utils import cstr, getdate
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
class TherapySession(Document): class TherapySession(Document):
def validate(self):
self.set_total_counts()
def on_submit(self): def on_submit(self):
self.update_sessions_count_in_therapy_plan() self.update_sessions_count_in_therapy_plan()
insert_session_medical_record(self)
def on_cancel(self): def on_cancel(self):
self.update_sessions_count_in_therapy_plan(on_cancel=True) self.update_sessions_count_in_therapy_plan(on_cancel=True)
@@ -24,6 +31,18 @@ class TherapySession(Document):
entry.sessions_completed += 1 entry.sessions_completed += 1
therapy_plan.save() therapy_plan.save()
def set_total_counts(self):
target_total = 0
counts_completed = 0
for entry in self.exercises:
if entry.counts_target:
target_total += entry.counts_target
if entry.counts_completed:
counts_completed += entry.counts_completed
self.db_set('total_counts_targeted', target_total)
self.db_set('total_counts_completed', counts_completed)
@frappe.whitelist() @frappe.whitelist()
def create_therapy_session(source_name, target_doc=None): def create_therapy_session(source_name, target_doc=None):
@@ -52,4 +71,62 @@ def create_therapy_session(source_name, target_doc=None):
} }
}, target_doc, set_missing_values) }, target_doc, set_missing_values)
return doc return doc
@frappe.whitelist()
def invoice_therapy_session(source_name, target_doc=None):
def set_missing_values(source, target):
target.customer = frappe.db.get_value('Patient', source.patient, 'customer')
target.due_date = getdate()
target.debit_to = get_receivable_account(source.company)
item = target.append('items', {})
item = get_therapy_item(source, item)
target.set_missing_values(for_validate=True)
doc = get_mapped_doc('Therapy Session', source_name, {
'Therapy Session': {
'doctype': 'Sales Invoice',
'field_map': [
['patient', 'patient'],
['referring_practitioner', 'practitioner'],
['company', 'company'],
['due_date', 'start_date']
]
}
}, target_doc, set_missing_values)
return doc
def get_therapy_item(therapy, item):
item.item_code = frappe.db.get_value('Therapy Type', therapy.therapy_type, 'item')
item.description = _('Therapy Session Charges: {0}').format(therapy.practitioner)
item.income_account = get_income_account(therapy.practitioner, therapy.company)
item.cost_center = frappe.get_cached_value('Company', therapy.company, 'cost_center')
item.rate = therapy.rate
item.amount = therapy.rate
item.qty = 1
item.reference_dt = 'Therapy Session'
item.reference_dn = therapy.name
return item
def insert_session_medical_record(doc):
subject = frappe.bold(_('Therapy: ')) + cstr(doc.therapy_type) + '<br>'
if doc.therapy_plan:
subject += frappe.bold(_('Therapy Plan: ')) + cstr(doc.therapy_plan) + '<br>'
if doc.practitioner:
subject += frappe.bold(_('Healthcare Practitioner: ')) + doc.practitioner
subject += frappe.bold(_('Total Counts Targeted: ')) + cstr(doc.total_counts_targeted) + '<br>'
subject += frappe.bold(_('Total Counts Completed: ')) + cstr(doc.total_counts_completed) + '<br>'
medical_record = frappe.new_doc('Patient Medical Record')
medical_record.patient = doc.patient
medical_record.subject = subject
medical_record.status = 'Open'
medical_record.communication_date = doc.start_date
medical_record.reference_doctype = 'Therapy Session'
medical_record.reference_name = doc.name
medical_record.reference_owner = doc.owner
medical_record.save(ignore_permissions=True)

View File

@@ -35,17 +35,17 @@ def delete_vital_signs_from_medical_record(doc):
def set_subject_field(doc): def set_subject_field(doc):
subject = '' subject = ''
if(doc.temperature): if doc.temperature:
subject += _('Temperature: ') + '\n'+ cstr(doc.temperature) + '. ' subject += frappe.bold(_('Temperature: ')) + cstr(doc.temperature) + '<br>'
if(doc.pulse): if doc.pulse:
subject += _('Pulse: ') + '\n' + cstr(doc.pulse) + '. ' subject += frappe.bold(_('Pulse: ')) + cstr(doc.pulse) + '<br>'
if(doc.respiratory_rate): if doc.respiratory_rate:
subject += _('Respiratory Rate: ') + '\n' + cstr(doc.respiratory_rate) + '. ' subject += frappe.bold(_('Respiratory Rate: ')) + cstr(doc.respiratory_rate) + '<br>'
if(doc.bp): if doc.bp:
subject += _('BP: ') + '\n' + cstr(doc.bp) + '. ' subject += frappe.bold(_('BP: ')) + cstr(doc.bp) + '<br>'
if(doc.bmi): if doc.bmi:
subject += _('BMI: ') + '\n' + cstr(doc.bmi) + '. ' subject += frappe.bold(_('BMI: ')) + cstr(doc.bmi) + '<br>'
if(doc.nutrition_note): if doc.nutrition_note:
subject += _('Note: ') + '\n' + cstr(doc.nutrition_note) + '. ' subject += frappe.bold(_('Note: ')) + cstr(doc.nutrition_note) + '<br>'
return subject return subject