Browse Source
* feat: added rehab sub-module doctypes * feat: rehab module * feat: prescribe procedures in Patient Encounter * feat: create Therapy Plan on Encounter submission * feat: manage item for Therapy Type * feat: book appointments, get prescribed therapies for Therapy Sessions * feat: invoice Therapy Sessions * feat: plan completion progress bar and exercise countsindicators * feat: Motor Assessment Scale * feat: add editable card view for exercise steps * fix: add rehab in healthcare desk page * fix: card deletion not working when child table is hidden * feat: automatically fetch therapies according to Body Part * fix: added tests for Therapy Type and Plan * fix: add exercises according to body parts in Therapy Type * fix: label for Exercise Instructions * fix: exercise cards css * feat: add dashboard for Therapy Plan * feat: Patient Assessment Template and Patient Assessment * feat: add title fields in Therapy Plan and Session * fix: remove Motor Assessment Scale * fix: fetch assessment description * feat: create Patient Assessment from Therapy Session * fix: anti pattern code * fix: update desk page * fix: exercise card rendering * fix(test): filter out disabled Items in test_mapper * fix: get stock uom from Stock Settings for Therapy Type Item creation * fix: multiline SQL query * fix: permissions for DocTypes Co-authored-by: Nabin Hait <nabinhait@gmail.com>develop
Rucha Mahabal
4 years ago
committed by
GitHub
80 changed files with 2928 additions and 65 deletions
@ -0,0 +1,8 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Body Part', { |
|||
// refresh: function(frm) {
|
|||
|
|||
// }
|
|||
}); |
@ -0,0 +1,45 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "field:body_part", |
|||
"creation": "2020-04-10 12:21:55.036402", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"body_part" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "body_part", |
|||
"fieldtype": "Data", |
|||
"in_list_view": 1, |
|||
"label": "Body Part", |
|||
"reqd": 1, |
|||
"unique": 1 |
|||
} |
|||
], |
|||
"links": [], |
|||
"modified": "2020-04-10 12:26:44.087985", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Body Part", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class BodyPart(Document): |
|||
pass |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
# import frappe |
|||
import unittest |
|||
|
|||
class TestBodyPart(unittest.TestCase): |
|||
pass |
@ -0,0 +1,32 @@ |
|||
{ |
|||
"actions": [], |
|||
"creation": "2020-04-10 12:23:15.259816", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"body_part" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "body_part", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Body Part", |
|||
"options": "Body Part", |
|||
"reqd": 1 |
|||
} |
|||
], |
|||
"istable": 1, |
|||
"links": [], |
|||
"modified": "2020-04-10 12:25:23.101749", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Body Part Link", |
|||
"owner": "Administrator", |
|||
"permissions": [], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class BodyPartLink(Document): |
|||
pass |
@ -0,0 +1,61 @@ |
|||
{ |
|||
"actions": [], |
|||
"creation": "2020-03-11 09:25:00.968572", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"exercise_type", |
|||
"difficulty_level", |
|||
"counts_target", |
|||
"counts_completed", |
|||
"assistance_level" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "exercise_type", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Exercise Type", |
|||
"options": "Exercise Type", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fetch_from": "exercise_type.difficulty_level", |
|||
"fieldname": "difficulty_level", |
|||
"fieldtype": "Link", |
|||
"label": "Difficulty Level", |
|||
"options": "Exercise Difficulty Level" |
|||
}, |
|||
{ |
|||
"fieldname": "counts_target", |
|||
"fieldtype": "Int", |
|||
"in_list_view": 1, |
|||
"label": "Counts Target" |
|||
}, |
|||
{ |
|||
"depends_on": "eval:doc.parenttype==\"Therapy\";", |
|||
"fieldname": "counts_completed", |
|||
"fieldtype": "Int", |
|||
"label": "Counts Completed" |
|||
}, |
|||
{ |
|||
"fieldname": "assistance_level", |
|||
"fieldtype": "Select", |
|||
"label": "Assistance Level", |
|||
"options": "\nPassive\nActive Assist\nActive" |
|||
} |
|||
], |
|||
"istable": 1, |
|||
"links": [], |
|||
"modified": "2020-04-10 13:41:06.662351", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Exercise", |
|||
"owner": "Administrator", |
|||
"permissions": [], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class Exercise(Document): |
|||
pass |
@ -0,0 +1,8 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Exercise Difficulty Level', { |
|||
// refresh: function(frm) {
|
|||
|
|||
// }
|
|||
}); |
@ -0,0 +1,45 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "field:difficulty_level", |
|||
"creation": "2020-03-29 21:12:55.835941", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"difficulty_level" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "difficulty_level", |
|||
"fieldtype": "Data", |
|||
"in_list_view": 1, |
|||
"label": "Difficulty Level", |
|||
"reqd": 1, |
|||
"unique": 1 |
|||
} |
|||
], |
|||
"links": [], |
|||
"modified": "2020-03-31 23:14:33.554066", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Exercise Difficulty Level", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class ExerciseDifficultyLevel(Document): |
|||
pass |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
# import frappe |
|||
import unittest |
|||
|
|||
class TestExerciseDifficultyLevel(unittest.TestCase): |
|||
pass |
@ -0,0 +1,180 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Exercise Type', { |
|||
refresh: function(frm) { |
|||
let wrapper = frm.fields_dict.steps_html.wrapper; |
|||
|
|||
frm.ExerciseEditor = new erpnext.ExerciseEditor(frm, wrapper); |
|||
} |
|||
}); |
|||
|
|||
erpnext.ExerciseEditor = Class.extend({ |
|||
init: function(frm, wrapper) { |
|||
this.wrapper = wrapper; |
|||
this.frm = frm; |
|||
this.make(frm, wrapper); |
|||
}, |
|||
|
|||
make: function(frm, wrapper) { |
|||
$(this.wrapper).empty(); |
|||
|
|||
this.exercise_toolbar = $('<p>\ |
|||
<button class="btn btn-default btn-add btn-xs" style="margin-left: 10px;"></button>').appendTo(this.wrapper); |
|||
|
|||
this.exercise_cards = $('<div class="exercise-cards"></div>').appendTo(this.wrapper); |
|||
|
|||
let me = this; |
|||
|
|||
this.exercise_toolbar.find(".btn-add") |
|||
.html(__('Add')) |
|||
.on("click", function() { |
|||
me.show_add_card_dialog(frm); |
|||
}); |
|||
|
|||
if (frm.doc.steps_table.length > 0) { |
|||
this.make_cards(frm); |
|||
this.make_buttons(frm); |
|||
} |
|||
}, |
|||
|
|||
make_cards: function(frm) { |
|||
var me = this; |
|||
$(me.exercise_cards).empty(); |
|||
this.row = $('<div class="exercise-row"></div>').appendTo(me.exercise_cards); |
|||
|
|||
$.each(frm.doc.steps_table, function(i, step) { |
|||
$(repl(` |
|||
<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-body exercise-card-body"> |
|||
<img src=%(image_src)s class="card-img-top" alt="..."> |
|||
<h4 class="card-title">%(title)s</h4> |
|||
<p class="card-text text-truncate">%(description)s</p> |
|||
</div> |
|||
<div class="card-footer"> |
|||
<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button> |
|||
<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button> |
|||
</div> |
|||
</div> |
|||
</div>`, {image_src: step.image, title: step.title, description: step.description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row); |
|||
}); |
|||
}, |
|||
|
|||
make_buttons: function(frm) { |
|||
let me = this; |
|||
$('.btn-edit').on('click', function() { |
|||
let id = $(this).attr('data-id'); |
|||
me.show_edit_card_dialog(frm, id); |
|||
}); |
|||
|
|||
$('.btn-del').on('click', function() { |
|||
let id = $(this).attr('data-id'); |
|||
$('#card-'+id).addClass("zoomOutDelete"); |
|||
|
|||
setTimeout(() => { |
|||
// not using grid_rows[id].remove because
|
|||
// grid_rows is not defined when the table is hidden
|
|||
frm.doc.steps_table.pop(id); |
|||
frm.refresh_field('steps_table'); |
|||
$('#col-'+id).remove(); |
|||
}, 300); |
|||
}); |
|||
}, |
|||
|
|||
show_add_card_dialog: function(frm) { |
|||
let me = this; |
|||
let d = new frappe.ui.Dialog({ |
|||
title: __('Add Exercise Step'), |
|||
fields: [ |
|||
{ |
|||
"label": "Title", |
|||
"fieldname": "title", |
|||
"fieldtype": "Data", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"label": "Attach Image", |
|||
"fieldname": "image", |
|||
"fieldtype": "Attach Image" |
|||
}, |
|||
{ |
|||
"label": "Step Description", |
|||
"fieldname": "step_description", |
|||
"fieldtype": "Long Text" |
|||
} |
|||
], |
|||
primary_action: function() { |
|||
let data = d.get_values(); |
|||
let i = frm.doc.steps_table.length; |
|||
$(repl(` |
|||
<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-body exercise-card-body"> |
|||
<img src=%(image_src)s class="card-img-top" alt="..."> |
|||
<h4 class="card-title">%(title)s</h4> |
|||
<p class="card-text text-truncate">%(description)s</p> |
|||
</div> |
|||
<div class="card-footer"> |
|||
<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button> |
|||
<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button> |
|||
</div> |
|||
</div> |
|||
</div>`, {image_src: data.image, title: data.title, description: data.step_description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row); |
|||
let step = frappe.model.add_child(frm.doc, 'Exercise Type Step', 'steps_table'); |
|||
step.title = data.title; |
|||
step.image = data.image; |
|||
step.description = data.step_description; |
|||
me.make_buttons(frm); |
|||
frm.refresh_field('steps_table'); |
|||
d.hide(); |
|||
}, |
|||
primary_action_label: __('Add') |
|||
}); |
|||
d.show(); |
|||
}, |
|||
|
|||
show_edit_card_dialog: function(frm, id) { |
|||
let new_dialog = new frappe.ui.Dialog({ |
|||
title: __("Edit Exercise Step"), |
|||
fields: [ |
|||
{ |
|||
"label": "Title", |
|||
"fieldname": "title", |
|||
"fieldtype": "Data", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"label": "Attach Image", |
|||
"fieldname": "image", |
|||
"fieldtype": "Attach Image" |
|||
}, |
|||
{ |
|||
"label": "Step Description", |
|||
"fieldname": "step_description", |
|||
"fieldtype": "Long Text" |
|||
} |
|||
], |
|||
primary_action: () => { |
|||
let data = new_dialog.get_values(); |
|||
$('#card-'+id).find('.card-title').html(data.title); |
|||
$('#card-'+id).find('img').attr('src', data.image); |
|||
$('#card-'+id).find('.card-text').html(data.step_description); |
|||
|
|||
frm.doc.steps_table[id].title = data.title; |
|||
frm.doc.steps_table[id].image = data.image; |
|||
frm.doc.steps_table[id].description = data.step_description; |
|||
refresh_field('steps_table'); |
|||
new_dialog.hide(); |
|||
}, |
|||
primary_action_label: __("Save"), |
|||
}); |
|||
|
|||
new_dialog.set_values({ |
|||
title: frm.doc.steps_table[id].title, |
|||
image: frm.doc.steps_table[id].image, |
|||
step_description: frm.doc.steps_table[id].description |
|||
}); |
|||
new_dialog.show(); |
|||
} |
|||
}); |
@ -0,0 +1,144 @@ |
|||
{ |
|||
"actions": [], |
|||
"creation": "2020-03-29 21:37:03.366344", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"exercise_name", |
|||
"body_parts", |
|||
"column_break_3", |
|||
"difficulty_level", |
|||
"section_break_5", |
|||
"description", |
|||
"section_break_7", |
|||
"exercise_steps", |
|||
"column_break_9", |
|||
"exercise_video", |
|||
"section_break_11", |
|||
"steps_html", |
|||
"section_break_13", |
|||
"steps_table" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "exercise_name", |
|||
"fieldtype": "Data", |
|||
"in_list_view": 1, |
|||
"label": "Exercise Name", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "difficulty_level", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Difficulty Level", |
|||
"options": "Exercise Difficulty Level" |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_3", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_5", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "description", |
|||
"fieldtype": "Long Text", |
|||
"label": "Description" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_7", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "exercise_steps", |
|||
"fieldtype": "Attach", |
|||
"label": "Exercise Instructions" |
|||
}, |
|||
{ |
|||
"fieldname": "exercise_video", |
|||
"fieldtype": "Link", |
|||
"label": "Exercise Video", |
|||
"options": "Video" |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_9", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "steps_html", |
|||
"fieldtype": "HTML", |
|||
"label": "Steps" |
|||
}, |
|||
{ |
|||
"fieldname": "steps_table", |
|||
"fieldtype": "Table", |
|||
"hidden": 1, |
|||
"label": "Steps Table", |
|||
"options": "Exercise Type Step" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_11", |
|||
"fieldtype": "Section Break", |
|||
"label": "Exercise Steps" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_13", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "body_parts", |
|||
"fieldtype": "Table MultiSelect", |
|||
"label": "Body Parts", |
|||
"options": "Body Part Link" |
|||
} |
|||
], |
|||
"links": [], |
|||
"modified": "2020-04-21 13:05:36.555060", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Exercise Type", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Healthcare Administrator", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Physician", |
|||
"share": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,15 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class ExerciseType(Document): |
|||
def autoname(self): |
|||
if self.difficulty_level: |
|||
self.name = ' - '.join(filter(None, [self.exercise_name, self.difficulty_level])) |
|||
else: |
|||
self.name = self.exercise_name |
|||
|
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
# import frappe |
|||
import unittest |
|||
|
|||
class TestExerciseType(unittest.TestCase): |
|||
pass |
@ -0,0 +1,44 @@ |
|||
{ |
|||
"actions": [], |
|||
"creation": "2020-03-31 23:01:18.761967", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"title", |
|||
"image", |
|||
"description" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "title", |
|||
"fieldtype": "Data", |
|||
"in_list_view": 1, |
|||
"label": "Title", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "image", |
|||
"fieldtype": "Attach Image", |
|||
"label": "Image" |
|||
}, |
|||
{ |
|||
"fieldname": "description", |
|||
"fieldtype": "Long Text", |
|||
"in_list_view": 1, |
|||
"label": "Description" |
|||
} |
|||
], |
|||
"istable": 1, |
|||
"links": [], |
|||
"modified": "2020-04-02 20:39:34.258512", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Exercise Type Step", |
|||
"owner": "Administrator", |
|||
"permissions": [], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class ExerciseTypeStep(Document): |
|||
pass |
@ -0,0 +1,86 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Patient Assessment', { |
|||
refresh: function(frm) { |
|||
if (frm.doc.assessment_template) { |
|||
frm.trigger('set_score_range'); |
|||
} |
|||
|
|||
if (!frm.doc.__islocal) { |
|||
frm.trigger('show_patient_progress'); |
|||
} |
|||
}, |
|||
|
|||
assessment_template: function(frm) { |
|||
if (frm.doc.assessment_template) { |
|||
frappe.call({ |
|||
'method': 'frappe.client.get', |
|||
args: { |
|||
doctype: 'Patient Assessment Template', |
|||
name: frm.doc.assessment_template |
|||
}, |
|||
callback: function(data) { |
|||
frm.doc.assessment_sheet = []; |
|||
$.each(data.message.parameters, function(_i, e) { |
|||
let entry = frm.add_child('assessment_sheet'); |
|||
entry.parameter = e.assessment_parameter; |
|||
}); |
|||
|
|||
frm.set_value('scale_min', data.message.scale_min); |
|||
frm.set_value('scale_max', data.message.scale_max); |
|||
frm.set_value('assessment_description', data.message.assessment_description); |
|||
frm.set_value('total_score', data.message.scale_max * data.message.parameters.length); |
|||
frm.trigger('set_score_range'); |
|||
refresh_field('assessment_sheet'); |
|||
} |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
set_score_range: function(frm) { |
|||
let options = []; |
|||
for(let i = frm.doc.scale_min; i <= frm.doc.scale_max; i++) { |
|||
options.push(i); |
|||
} |
|||
frappe.meta.get_docfield('Patient Assessment Sheet', 'score', frm.doc.name).options = [''].concat(options); |
|||
}, |
|||
|
|||
calculate_total_score: function(frm, cdt, cdn) { |
|||
let row = locals[cdt][cdn]; |
|||
let total_score = 0; |
|||
$.each(frm.doc.assessment_sheet || [], function(_i, item) { |
|||
if (item.score) { |
|||
total_score += parseInt(item.score); |
|||
} |
|||
}); |
|||
|
|||
frm.set_value('total_score_obtained', total_score); |
|||
}, |
|||
|
|||
show_patient_progress: function(frm) { |
|||
let bars = []; |
|||
let message = ''; |
|||
let added_min = false; |
|||
|
|||
let title = __('{0} out of {1}', [frm.doc.total_score_obtained, frm.doc.total_score]); |
|||
|
|||
bars.push({ |
|||
'title': title, |
|||
'width': (frm.doc.total_score_obtained / frm.doc.total_score * 100) + '%', |
|||
'progress_class': 'progress-bar-success' |
|||
}); |
|||
if (bars[0].width == '0%') { |
|||
bars[0].width = '0.5%'; |
|||
added_min = 0.5; |
|||
} |
|||
message = title; |
|||
frm.dashboard.add_progress(__('Status'), bars, message); |
|||
}, |
|||
}); |
|||
|
|||
frappe.ui.form.on('Patient Assessment Sheet', { |
|||
score: function(frm, cdt, cdn) { |
|||
frm.events.calculate_total_score(frm, cdt, cdn); |
|||
} |
|||
}); |
@ -0,0 +1,172 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "naming_series:", |
|||
"creation": "2020-04-19 22:45:12.356209", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"naming_series", |
|||
"therapy_session", |
|||
"patient", |
|||
"assessment_template", |
|||
"column_break_4", |
|||
"healthcare_practitioner", |
|||
"assessment_datetime", |
|||
"assessment_description", |
|||
"section_break_7", |
|||
"assessment_sheet", |
|||
"section_break_9", |
|||
"total_score_obtained", |
|||
"column_break_11", |
|||
"total_score", |
|||
"scale_min", |
|||
"scale_max", |
|||
"amended_from" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fetch_from": "therapy_session.patient", |
|||
"fieldname": "patient", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Patient", |
|||
"options": "Patient", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "assessment_template", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Assessment Template", |
|||
"options": "Patient Assessment Template", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "therapy_session", |
|||
"fieldtype": "Link", |
|||
"label": "Therapy Session", |
|||
"options": "Therapy Session" |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_4", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fetch_from": "therapy_session.practitioner", |
|||
"fieldname": "healthcare_practitioner", |
|||
"fieldtype": "Link", |
|||
"label": "Healthcare Practitioner", |
|||
"options": "Healthcare Practitioner" |
|||
}, |
|||
{ |
|||
"fieldname": "assessment_datetime", |
|||
"fieldtype": "Datetime", |
|||
"label": "Assessment Datetime" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_7", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "assessment_sheet", |
|||
"fieldtype": "Table", |
|||
"label": "Assessment Sheet", |
|||
"options": "Patient Assessment Sheet" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_9", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "total_score", |
|||
"fieldtype": "Int", |
|||
"label": "Total Score", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_11", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "total_score_obtained", |
|||
"fieldtype": "Int", |
|||
"label": "Total Score Obtained", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "scale_min", |
|||
"fieldtype": "Int", |
|||
"hidden": 1, |
|||
"label": "Scale Min", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "scale_max", |
|||
"fieldtype": "Int", |
|||
"hidden": 1, |
|||
"label": "Scale Max", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "naming_series", |
|||
"fieldtype": "Select", |
|||
"label": "Naming Series", |
|||
"options": "HLC-PA-.YYYY.-" |
|||
}, |
|||
{ |
|||
"fieldname": "amended_from", |
|||
"fieldtype": "Link", |
|||
"label": "Amended From", |
|||
"no_copy": 1, |
|||
"options": "Patient Assessment", |
|||
"print_hide": 1, |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "assessment_description", |
|||
"fieldtype": "Small Text", |
|||
"label": "Assessment Description" |
|||
} |
|||
], |
|||
"is_submittable": 1, |
|||
"links": [], |
|||
"modified": "2020-04-21 13:23:09.815007", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Patient Assessment", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"cancel": 1, |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"submit": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"cancel": 1, |
|||
"create": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Physician", |
|||
"share": 1, |
|||
"submit": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"title_field": "patient", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,36 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
import frappe |
|||
from frappe.model.document import Document |
|||
from frappe.model.mapper import get_mapped_doc |
|||
|
|||
class PatientAssessment(Document): |
|||
def validate(self): |
|||
self.set_total_score() |
|||
|
|||
def set_total_score(self): |
|||
total_score = 0 |
|||
for entry in self.assessment_sheet: |
|||
total_score += int(entry.score) |
|||
self.total_score_obtained = total_score |
|||
|
|||
@frappe.whitelist() |
|||
def create_patient_assessment(source_name, target_doc=None): |
|||
doc = get_mapped_doc('Therapy Session', source_name, { |
|||
'Therapy Session': { |
|||
'doctype': 'Patient Assessment', |
|||
'field_map': [ |
|||
['therapy_session', 'name'], |
|||
['patient', 'patient'], |
|||
['practitioner', 'practitioner'] |
|||
] |
|||
} |
|||
}, target_doc) |
|||
|
|||
return doc |
|||
|
|||
|
|||
|
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
# import frappe |
|||
import unittest |
|||
|
|||
class TestPatientAssessment(unittest.TestCase): |
|||
pass |
@ -0,0 +1,32 @@ |
|||
{ |
|||
"actions": [], |
|||
"creation": "2020-04-19 19:33:00.115395", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"assessment_parameter" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "assessment_parameter", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Assessment Parameter", |
|||
"options": "Patient Assessment Parameter", |
|||
"reqd": 1 |
|||
} |
|||
], |
|||
"istable": 1, |
|||
"links": [], |
|||
"modified": "2020-04-19 19:33:00.115395", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Patient Assessment Detail", |
|||
"owner": "Administrator", |
|||
"permissions": [], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class PatientAssessmentDetail(Document): |
|||
pass |
@ -0,0 +1,8 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Patient Assessment Parameter', { |
|||
// refresh: function(frm) {
|
|||
|
|||
// }
|
|||
}); |
@ -0,0 +1,45 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "field:assessment_parameter", |
|||
"creation": "2020-04-15 14:34:46.551042", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"assessment_parameter" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "assessment_parameter", |
|||
"fieldtype": "Data", |
|||
"in_list_view": 1, |
|||
"label": "Assessment Parameter", |
|||
"reqd": 1, |
|||
"unique": 1 |
|||
} |
|||
], |
|||
"links": [], |
|||
"modified": "2020-04-20 09:22:19.135196", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Patient Assessment Parameter", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class PatientAssessmentParameter(Document): |
|||
pass |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
# import frappe |
|||
import unittest |
|||
|
|||
class TestPatientAssessmentParameter(unittest.TestCase): |
|||
pass |
@ -0,0 +1,57 @@ |
|||
{ |
|||
"actions": [], |
|||
"creation": "2020-04-19 23:07:02.220244", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"parameter", |
|||
"score", |
|||
"time", |
|||
"column_break_4", |
|||
"comments" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "parameter", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Parameter", |
|||
"options": "Patient Assessment Parameter", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "score", |
|||
"fieldtype": "Select", |
|||
"in_list_view": 1, |
|||
"label": "Score", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "time", |
|||
"fieldtype": "Time", |
|||
"label": "Time" |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_4", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "comments", |
|||
"fieldtype": "Small Text", |
|||
"label": "Comments" |
|||
} |
|||
], |
|||
"istable": 1, |
|||
"links": [], |
|||
"modified": "2020-04-20 09:56:28.746619", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Patient Assessment Sheet", |
|||
"owner": "Administrator", |
|||
"permissions": [], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class PatientAssessmentSheet(Document): |
|||
pass |
@ -0,0 +1,8 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Patient Assessment Template', { |
|||
// refresh: function(frm) {
|
|||
|
|||
// }
|
|||
}); |
@ -0,0 +1,109 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "field:assessment_name", |
|||
"creation": "2020-04-19 19:33:13.204707", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"assessment_name", |
|||
"section_break_2", |
|||
"parameters", |
|||
"assessment_scale_details_section", |
|||
"scale_min", |
|||
"scale_max", |
|||
"column_break_8", |
|||
"assessment_description" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "parameters", |
|||
"fieldtype": "Table", |
|||
"label": "Parameters", |
|||
"options": "Patient Assessment Detail" |
|||
}, |
|||
{ |
|||
"fieldname": "assessment_name", |
|||
"fieldtype": "Data", |
|||
"in_list_view": 1, |
|||
"label": "Assessment Name", |
|||
"reqd": 1, |
|||
"unique": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_2", |
|||
"fieldtype": "Section Break", |
|||
"label": "Assessment Parameters" |
|||
}, |
|||
{ |
|||
"fieldname": "assessment_scale_details_section", |
|||
"fieldtype": "Section Break", |
|||
"label": "Assessment Scale" |
|||
}, |
|||
{ |
|||
"fieldname": "scale_min", |
|||
"fieldtype": "Int", |
|||
"label": "Scale Minimum" |
|||
}, |
|||
{ |
|||
"fieldname": "scale_max", |
|||
"fieldtype": "Int", |
|||
"label": "Scale Maximum" |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_8", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "assessment_description", |
|||
"fieldtype": "Small Text", |
|||
"label": "Assessment Description" |
|||
} |
|||
], |
|||
"links": [], |
|||
"modified": "2020-04-21 13:14:19.075167", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Patient Assessment Template", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Healthcare Administrator", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"create": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Physician", |
|||
"share": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class PatientAssessmentTemplate(Document): |
|||
pass |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
# import frappe |
|||
import unittest |
|||
|
|||
class TestPatientAssessmentTemplate(unittest.TestCase): |
|||
pass |
@ -0,0 +1,57 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
import frappe |
|||
import unittest |
|||
from frappe.utils import getdate |
|||
from erpnext.healthcare.doctype.therapy_type.test_therapy_type import create_therapy_type |
|||
from erpnext.healthcare.doctype.therapy_plan.therapy_plan import make_therapy_session |
|||
from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_healthcare_docs, create_patient |
|||
|
|||
class TestTherapyPlan(unittest.TestCase): |
|||
def test_creation_on_encounter_submission(self): |
|||
patient, medical_department, practitioner = create_healthcare_docs() |
|||
encounter = create_encounter(patient, medical_department, practitioner) |
|||
self.assertTrue(frappe.db.exists('Therapy Plan', encounter.therapy_plan)) |
|||
|
|||
def test_status(self): |
|||
plan = create_therapy_plan() |
|||
self.assertEquals(plan.status, 'Not Started') |
|||
|
|||
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab') |
|||
frappe.get_doc(session).submit() |
|||
self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'In Progress') |
|||
|
|||
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab') |
|||
frappe.get_doc(session).submit() |
|||
self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed') |
|||
|
|||
|
|||
def create_therapy_plan(): |
|||
patient = create_patient() |
|||
therapy_type = create_therapy_type() |
|||
plan = frappe.new_doc('Therapy Plan') |
|||
plan.patient = patient |
|||
plan.start_date = getdate() |
|||
plan.append('therapy_plan_details', { |
|||
'therapy_type': therapy_type.name, |
|||
'no_of_sessions': 2 |
|||
}) |
|||
plan.save() |
|||
return plan |
|||
|
|||
def create_encounter(patient, medical_department, practitioner): |
|||
encounter = frappe.new_doc('Patient Encounter') |
|||
encounter.patient = patient |
|||
encounter.practitioner = practitioner |
|||
encounter.medical_department = medical_department |
|||
therapy_type = create_therapy_type() |
|||
encounter.append('therapies', { |
|||
'therapy_type': therapy_type.name, |
|||
'no_of_sessions': 2 |
|||
}) |
|||
encounter.save() |
|||
encounter.submit() |
|||
return encounter |
@ -0,0 +1,90 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Therapy Plan', { |
|||
setup: function(frm) { |
|||
frm.get_field('therapy_plan_details').grid.editable_fields = [ |
|||
{fieldname: 'therapy_type', columns: 6}, |
|||
{fieldname: 'no_of_sessions', columns: 2}, |
|||
{fieldname: 'sessions_completed', columns: 2} |
|||
]; |
|||
}, |
|||
|
|||
refresh: function(frm) { |
|||
if (!frm.doc.__islocal) { |
|||
frm.trigger('show_progress_for_therapies'); |
|||
} |
|||
|
|||
if (!frm.doc.__islocal && frm.doc.status != 'Completed') { |
|||
let therapy_types = (frm.doc.therapy_plan_details || []).map(function(d){ return d.therapy_type }); |
|||
const fields = [{ |
|||
fieldtype: 'Link', |
|||
label: __('Therapy Type'), |
|||
fieldname: 'therapy_type', |
|||
options: 'Therapy Type', |
|||
reqd: 1, |
|||
get_query: function() { |
|||
return { |
|||
filters: { 'therapy_type': ['in', therapy_types]} |
|||
} |
|||
} |
|||
}]; |
|||
|
|||
frm.add_custom_button(__('Therapy Session'), function() { |
|||
frappe.prompt(fields, data => { |
|||
frappe.call({ |
|||
method: 'erpnext.healthcare.doctype.therapy_plan.therapy_plan.make_therapy_session', |
|||
args: { |
|||
therapy_plan: frm.doc.name, |
|||
patient: frm.doc.patient, |
|||
therapy_type: data.therapy_type |
|||
}, |
|||
freeze: true, |
|||
callback: function(r) { |
|||
if (r.message) { |
|||
frappe.model.sync(r.message); |
|||
frappe.set_route('Form', r.message.doctype, r.message.name); |
|||
} |
|||
} |
|||
}); |
|||
}, __('Select Therapy Type'), __('Create')); |
|||
}, __('Create')); |
|||
} |
|||
}, |
|||
|
|||
show_progress_for_therapies: function(frm) { |
|||
let bars = []; |
|||
let message = ''; |
|||
let added_min = false; |
|||
|
|||
// completed sessions
|
|||
let title = __('{0} sessions completed', [frm.doc.total_sessions_completed]); |
|||
if (frm.doc.total_sessions_completed === 1) { |
|||
title = __('{0} session completed', [frm.doc.total_sessions_completed]); |
|||
} |
|||
title += __(' out of {0}', [frm.doc.total_sessions]); |
|||
|
|||
bars.push({ |
|||
'title': title, |
|||
'width': (frm.doc.total_sessions_completed / frm.doc.total_sessions * 100) + '%', |
|||
'progress_class': 'progress-bar-success' |
|||
}); |
|||
if (bars[0].width == '0%') { |
|||
bars[0].width = '0.5%'; |
|||
added_min = 0.5; |
|||
} |
|||
message = title; |
|||
frm.dashboard.add_progress(__('Status'), bars, message); |
|||
}, |
|||
}); |
|||
|
|||
frappe.ui.form.on('Therapy Plan Detail', { |
|||
no_of_sessions: function(frm) { |
|||
let total = 0; |
|||
$.each(frm.doc.therapy_plan_details, function(_i, e) { |
|||
total += e.no_of_sessions; |
|||
}); |
|||
frm.set_value('total_sessions', total); |
|||
refresh_field('total_sessions'); |
|||
} |
|||
}); |
@ -0,0 +1,151 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "naming_series:", |
|||
"creation": "2020-03-29 20:56:49.758602", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"naming_series", |
|||
"patient", |
|||
"patient_name", |
|||
"column_break_4", |
|||
"status", |
|||
"start_date", |
|||
"section_break_3", |
|||
"therapy_plan_details", |
|||
"title", |
|||
"section_break_9", |
|||
"total_sessions", |
|||
"column_break_11", |
|||
"total_sessions_completed" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "patient", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Patient", |
|||
"options": "Patient", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "start_date", |
|||
"fieldtype": "Date", |
|||
"in_list_view": 1, |
|||
"label": "Start Date", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_3", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "therapy_plan_details", |
|||
"fieldtype": "Table", |
|||
"label": "Therapy Plan Details", |
|||
"options": "Therapy Plan Detail", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "naming_series", |
|||
"fieldtype": "Select", |
|||
"label": "Naming Series", |
|||
"options": "HLC-THP-.YYYY.-" |
|||
}, |
|||
{ |
|||
"fetch_from": "patient.patient_name", |
|||
"fieldname": "patient_name", |
|||
"fieldtype": "Data", |
|||
"label": "Patient Name", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"default": "{patient_name}", |
|||
"fieldname": "title", |
|||
"fieldtype": "Data", |
|||
"hidden": 1, |
|||
"label": "Title", |
|||
"no_copy": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_4", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_9", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "total_sessions", |
|||
"fieldtype": "Int", |
|||
"label": "Total Sessions", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_11", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "total_sessions_completed", |
|||
"fieldtype": "Int", |
|||
"label": "Total Sessions Completed", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "status", |
|||
"fieldtype": "Select", |
|||
"label": "Status", |
|||
"options": "Not Started\nIn Progress\nCompleted\nCancelled", |
|||
"read_only": 1 |
|||
} |
|||
], |
|||
"links": [], |
|||
"modified": "2020-04-21 13:13:43.956014", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Therapy Plan", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Healthcare Administrator", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Physician", |
|||
"share": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"quick_entry": 1, |
|||
"search_fields": "patient", |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"title_field": "patient", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,42 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class TherapyPlan(Document): |
|||
def validate(self): |
|||
self.set_totals() |
|||
self.set_status() |
|||
|
|||
def set_status(self): |
|||
if not self.total_sessions_completed: |
|||
self.status = 'Not Started' |
|||
else: |
|||
if self.total_sessions_completed < self.total_sessions: |
|||
self.status = 'In Progress' |
|||
elif self.total_sessions_completed == self.total_sessions: |
|||
self.status = 'Completed' |
|||
|
|||
def set_totals(self): |
|||
total_sessions = sum([int(d.no_of_sessions) for d in self.get('therapy_plan_details')]) |
|||
total_sessions_completed = sum([int(d.sessions_completed) for d in self.get('therapy_plan_details')]) |
|||
self.db_set('total_sessions', total_sessions) |
|||
self.db_set('total_sessions_completed', total_sessions_completed) |
|||
|
|||
|
|||
@frappe.whitelist() |
|||
def make_therapy_session(therapy_plan, patient, therapy_type): |
|||
therapy_type = frappe.get_doc('Therapy Type', therapy_type) |
|||
|
|||
therapy_session = frappe.new_doc('Therapy Session') |
|||
therapy_session.therapy_plan = therapy_plan |
|||
therapy_session.patient = patient |
|||
therapy_session.therapy_type = therapy_type.name |
|||
therapy_session.duration = therapy_type.default_duration |
|||
therapy_session.rate = therapy_type.rate |
|||
therapy_session.exercises = therapy_type.exercises |
|||
|
|||
return therapy_session.as_dict() |
@ -0,0 +1,13 @@ |
|||
from __future__ import unicode_literals |
|||
from frappe import _ |
|||
|
|||
def get_data(): |
|||
return { |
|||
'fieldname': 'therapy_plan', |
|||
'transactions': [ |
|||
{ |
|||
'label': _('Therapy Sessions'), |
|||
'items': ['Therapy Session'] |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,11 @@ |
|||
frappe.listview_settings['Therapy Plan'] = { |
|||
get_indicator: function(doc) { |
|||
var colors = { |
|||
'Completed': 'green', |
|||
'In Progress': 'orange', |
|||
'Not Started': 'red', |
|||
'Cancelled': 'grey' |
|||
}; |
|||
return [__(doc.status), colors[doc.status], 'status,=,' + doc.status]; |
|||
} |
|||
}; |
@ -0,0 +1,48 @@ |
|||
{ |
|||
"actions": [], |
|||
"creation": "2020-03-29 20:52:57.068731", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"therapy_type", |
|||
"no_of_sessions", |
|||
"sessions_completed" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "therapy_type", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Therapy Type", |
|||
"options": "Therapy Type", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "no_of_sessions", |
|||
"fieldtype": "Int", |
|||
"in_list_view": 1, |
|||
"label": "No of Sessions" |
|||
}, |
|||
{ |
|||
"default": "0", |
|||
"depends_on": "eval:doc.parenttype=='Therapy Plan';", |
|||
"fieldname": "sessions_completed", |
|||
"fieldtype": "Int", |
|||
"label": "Sessions Completed", |
|||
"read_only": 1 |
|||
} |
|||
], |
|||
"istable": 1, |
|||
"links": [], |
|||
"modified": "2020-03-30 22:02:01.740109", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Therapy Plan Detail", |
|||
"owner": "Administrator", |
|||
"permissions": [], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
# import frappe |
|||
from frappe.model.document import Document |
|||
|
|||
class TherapyPlanDetail(Document): |
|||
pass |
@ -0,0 +1,10 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
# import frappe |
|||
import unittest |
|||
|
|||
class TestTherapySession(unittest.TestCase): |
|||
pass |
@ -0,0 +1,60 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Therapy Session', { |
|||
setup: function(frm) { |
|||
frm.get_field('exercises').grid.editable_fields = [ |
|||
{fieldname: 'exercise_type', columns: 7}, |
|||
{fieldname: 'counts_target', columns: 1}, |
|||
{fieldname: 'counts_completed', columns: 1}, |
|||
{fieldname: 'assistance_level', columns: 1} |
|||
]; |
|||
}, |
|||
|
|||
refresh: function(frm) { |
|||
if (!frm.doc.__islocal) { |
|||
let target = 0; |
|||
let completed = 0; |
|||
$.each(frm.doc.exercises, function(_i, e) { |
|||
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) { |
|||
frm.add_custom_button(__('Patient Assessment'),function() { |
|||
frappe.model.open_mapped_doc({ |
|||
method: 'erpnext.healthcare.doctype.patient_assessment.patient_assessment.create_patient_assessment', |
|||
frm: frm, |
|||
}) |
|||
}, 'Create'); |
|||
} |
|||
}, |
|||
|
|||
therapy_type: function(frm) { |
|||
if (frm.doc.therapy_type) { |
|||
frappe.call({ |
|||
'method': 'frappe.client.get', |
|||
args: { |
|||
doctype: 'Therapy Type', |
|||
name: frm.doc.therapy_type |
|||
}, |
|||
callback: function(data) { |
|||
frm.set_value('duration', data.message.default_duration); |
|||
frm.set_value('rate', data.message.rate); |
|||
frm.doc.exercises = []; |
|||
$.each(data.message.exercises, function(_i, e) { |
|||
let exercise = frm.add_child('exercises'); |
|||
exercise.exercise_type = e.exercise_type; |
|||
exercise.difficulty_level = e.difficulty_level; |
|||
exercise.counts_target = e.counts_target; |
|||
exercise.assistance_level = e.assistance_level; |
|||
}); |
|||
refresh_field('exercises'); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
}); |
@ -0,0 +1,218 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "naming_series:", |
|||
"creation": "2020-03-11 08:57:40.669857", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"naming_series", |
|||
"appointment", |
|||
"patient", |
|||
"patient_age", |
|||
"gender", |
|||
"column_break_5", |
|||
"therapy_plan", |
|||
"therapy_type", |
|||
"practitioner", |
|||
"department", |
|||
"details_section", |
|||
"duration", |
|||
"rate", |
|||
"location", |
|||
"company", |
|||
"column_break_12", |
|||
"service_unit", |
|||
"start_date", |
|||
"start_time", |
|||
"invoiced", |
|||
"exercises_section", |
|||
"exercises", |
|||
"amended_from" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "naming_series", |
|||
"fieldtype": "Select", |
|||
"label": "Series", |
|||
"options": "HLC-THP-.YYYY.-" |
|||
}, |
|||
{ |
|||
"fieldname": "appointment", |
|||
"fieldtype": "Link", |
|||
"label": "Appointment", |
|||
"options": "Patient Appointment" |
|||
}, |
|||
{ |
|||
"fieldname": "patient", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Patient", |
|||
"options": "Patient", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fetch_from": "patient.sex", |
|||
"fieldname": "gender", |
|||
"fieldtype": "Link", |
|||
"label": "Gender", |
|||
"options": "Gender", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_5", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "practitioner", |
|||
"fieldtype": "Link", |
|||
"label": "Healthcare Practitioner", |
|||
"options": "Healthcare Practitioner" |
|||
}, |
|||
{ |
|||
"fieldname": "department", |
|||
"fieldtype": "Link", |
|||
"label": "Medical Department", |
|||
"options": "Medical Department" |
|||
}, |
|||
{ |
|||
"fieldname": "details_section", |
|||
"fieldtype": "Section Break", |
|||
"label": "Details" |
|||
}, |
|||
{ |
|||
"fetch_from": "therapy_template.default_duration", |
|||
"fieldname": "duration", |
|||
"fieldtype": "Int", |
|||
"label": "Duration" |
|||
}, |
|||
{ |
|||
"fieldname": "location", |
|||
"fieldtype": "Select", |
|||
"label": "Location", |
|||
"options": "\nCenter\nHome\nTele" |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_12", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fetch_from": "therapy_template.rate", |
|||
"fieldname": "rate", |
|||
"fieldtype": "Currency", |
|||
"label": "Rate" |
|||
}, |
|||
{ |
|||
"fieldname": "exercises_section", |
|||
"fieldtype": "Section Break", |
|||
"label": "Exercises" |
|||
}, |
|||
{ |
|||
"fieldname": "exercises", |
|||
"fieldtype": "Table", |
|||
"label": "Exercises", |
|||
"options": "Exercise" |
|||
}, |
|||
{ |
|||
"depends_on": "eval: doc.therapy_plan", |
|||
"fieldname": "therapy_type", |
|||
"fieldtype": "Link", |
|||
"in_list_view": 1, |
|||
"label": "Therapy Type", |
|||
"options": "Therapy Type", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "therapy_plan", |
|||
"fieldtype": "Link", |
|||
"label": "Therapy Plan", |
|||
"options": "Therapy Plan", |
|||
"reqd": 1, |
|||
"set_only_once": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "amended_from", |
|||
"fieldtype": "Link", |
|||
"label": "Amended From", |
|||
"no_copy": 1, |
|||
"options": "Therapy Session", |
|||
"print_hide": 1, |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "service_unit", |
|||
"fieldtype": "Link", |
|||
"label": "Healthcare Service Unit", |
|||
"options": "Healthcare Service Unit" |
|||
}, |
|||
{ |
|||
"fieldname": "start_date", |
|||
"fieldtype": "Date", |
|||
"label": "Start Date" |
|||
}, |
|||
{ |
|||
"fieldname": "start_time", |
|||
"fieldtype": "Time", |
|||
"label": "Start Time" |
|||
}, |
|||
{ |
|||
"fieldname": "company", |
|||
"fieldtype": "Link", |
|||
"label": "Company", |
|||
"options": "Company" |
|||
}, |
|||
{ |
|||
"default": "0", |
|||
"fieldname": "invoiced", |
|||
"fieldtype": "Check", |
|||
"label": "Invoiced", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "patient_age", |
|||
"fieldtype": "Data", |
|||
"label": "Patient Age", |
|||
"read_only": 1 |
|||
} |
|||
], |
|||
"is_submittable": 1, |
|||
"links": [], |
|||
"modified": "2020-04-21 13:16:46.378798", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Therapy Session", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"cancel": 1, |
|||
"create": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Physician", |
|||
"share": 1, |
|||
"submit": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"quick_entry": 1, |
|||
"search_fields": "patient,appointment,therapy_plan,therapy_type", |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"title_field": "patient", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,55 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
import frappe |
|||
from frappe.model.document import Document |
|||
from frappe.model.mapper import get_mapped_doc |
|||
|
|||
class TherapySession(Document): |
|||
def on_submit(self): |
|||
self.update_sessions_count_in_therapy_plan() |
|||
|
|||
def on_cancel(self): |
|||
self.update_sessions_count_in_therapy_plan(on_cancel=True) |
|||
|
|||
def update_sessions_count_in_therapy_plan(self, on_cancel=False): |
|||
therapy_plan = frappe.get_doc('Therapy Plan', self.therapy_plan) |
|||
for entry in therapy_plan.therapy_plan_details: |
|||
if entry.therapy_type == self.therapy_type: |
|||
if on_cancel: |
|||
entry.sessions_completed -= 1 |
|||
else: |
|||
entry.sessions_completed += 1 |
|||
therapy_plan.save() |
|||
|
|||
|
|||
@frappe.whitelist() |
|||
def create_therapy_session(source_name, target_doc=None): |
|||
def set_missing_values(source, target): |
|||
therapy_type = frappe.get_doc('Therapy Type', source.therapy_type) |
|||
target.exercises = therapy_type.exercises |
|||
|
|||
doc = get_mapped_doc('Patient Appointment', source_name, { |
|||
'Patient Appointment': { |
|||
'doctype': 'Therapy Session', |
|||
'field_map': [ |
|||
['appointment', 'name'], |
|||
['patient', 'patient'], |
|||
['patient_age', 'patient_age'], |
|||
['gender', 'patient_sex'], |
|||
['therapy_type', 'therapy_type'], |
|||
['therapy_plan', 'therapy_plan'], |
|||
['practitioner', 'practitioner'], |
|||
['department', 'department'], |
|||
['start_date', 'appointment_date'], |
|||
['start_time', 'appointment_time'], |
|||
['service_unit', 'service_unit'], |
|||
['company', 'company'], |
|||
['invoiced', 'invoiced'] |
|||
] |
|||
} |
|||
}, target_doc, set_missing_values) |
|||
|
|||
return doc |
@ -0,0 +1,13 @@ |
|||
from __future__ import unicode_literals |
|||
from frappe import _ |
|||
|
|||
def get_data(): |
|||
return { |
|||
'fieldname': 'therapy_session', |
|||
'transactions': [ |
|||
{ |
|||
'label': _('Assessments'), |
|||
'items': ['Patient Assessment'] |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,50 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# See license.txt |
|||
from __future__ import unicode_literals |
|||
|
|||
import frappe |
|||
import unittest |
|||
|
|||
class TestTherapyType(unittest.TestCase): |
|||
def test_therapy_type_item(self): |
|||
therapy_type = create_therapy_type() |
|||
self.assertTrue(frappe.db.exists('Item', therapy_type.item)) |
|||
|
|||
therapy_type.disabled = 1 |
|||
therapy_type.save() |
|||
self.assertEquals(frappe.db.get_value('Item', therapy_type.item, 'disabled'), 1) |
|||
|
|||
def create_therapy_type(): |
|||
exercise = create_exercise_type() |
|||
therapy_type = frappe.db.exists('Therapy Type', 'Basic Rehab') |
|||
if not therapy_type: |
|||
therapy_type = frappe.new_doc('Therapy Type') |
|||
therapy_type.therapy_type = 'Basic Rehab' |
|||
therapy_type.default_duration = 30 |
|||
therapy_type.is_billable = 1 |
|||
therapy_type.rate = 5000 |
|||
therapy_type.item_code = 'Basic Rehab' |
|||
therapy_type.item_name = 'Basic Rehab' |
|||
therapy_type.item_group = 'Services' |
|||
therapy_type.append('exercises', { |
|||
'exercise_type': exercise.name, |
|||
'counts_target': 10, |
|||
'assistance_level': 'Passive' |
|||
}) |
|||
therapy_type.save() |
|||
else: |
|||
therapy_type = frappe.get_doc('Therapy Type', 'Basic Rehab') |
|||
return therapy_type |
|||
|
|||
def create_exercise_type(): |
|||
exercise_type = frappe.db.exists('Exercise Type', 'Sit to Stand') |
|||
if not exercise_type: |
|||
exercise_type = frappe.new_doc('Exercise Type') |
|||
exercise_type.exercise_name = 'Sit to Stand' |
|||
exercise_type.append('steps_table', { |
|||
'title': 'Step 1', |
|||
'description': 'Squat and Rise' |
|||
}) |
|||
exercise_type.save() |
|||
return exercise_type |
@ -0,0 +1,93 @@ |
|||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
|||
// For license information, please see license.txt
|
|||
|
|||
frappe.ui.form.on('Therapy Type', { |
|||
setup: function(frm) { |
|||
frm.get_field('exercises').grid.editable_fields = [ |
|||
{fieldname: 'exercise_type', columns: 7}, |
|||
{fieldname: 'difficulty_level', columns: 1}, |
|||
{fieldname: 'counts_target', columns: 1}, |
|||
{fieldname: 'assistance_level', columns: 1} |
|||
]; |
|||
}, |
|||
|
|||
refresh: function(frm) { |
|||
if (!frm.doc.__islocal) { |
|||
cur_frm.add_custom_button(__('Change Item Code'), function() { |
|||
change_template_code(frm.doc); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
therapy_type: function(frm) { |
|||
if (!frm.doc.item_code) |
|||
frm.set_value('item_code', frm.doc.therapy_type); |
|||
if (!frm.doc.description) |
|||
frm.set_value('description', frm.doc.therapy_type); |
|||
mark_change_in_item(frm); |
|||
}, |
|||
|
|||
rate: function(frm) { |
|||
mark_change_in_item(frm); |
|||
}, |
|||
|
|||
is_billable: function (frm) { |
|||
mark_change_in_item(frm); |
|||
}, |
|||
|
|||
item_group: function(frm) { |
|||
mark_change_in_item(frm); |
|||
}, |
|||
|
|||
description: function(frm) { |
|||
mark_change_in_item(frm); |
|||
}, |
|||
|
|||
medical_department: function(frm) { |
|||
mark_change_in_item(frm); |
|||
} |
|||
}); |
|||
|
|||
let mark_change_in_item = function(frm) { |
|||
if (!frm.doc.__islocal) { |
|||
frm.doc.change_in_item = 1; |
|||
} |
|||
}; |
|||
|
|||
let change_template_code = function(doc) { |
|||
let d = new frappe.ui.Dialog({ |
|||
title:__('Change Item Code'), |
|||
fields:[ |
|||
{ |
|||
'fieldtype': 'Data', |
|||
'label': 'Item Code', |
|||
'fieldname': 'item_code', |
|||
reqd: 1 |
|||
} |
|||
], |
|||
primary_action: function() { |
|||
let values = d.get_values(); |
|||
|
|||
if (values) { |
|||
frappe.call({ |
|||
'method': 'erpnext.healthcare.doctype.therapy_type.therapy_type.change_item_code_from_therapy', |
|||
'args': {item_code: values.item_code, doc: doc}, |
|||
callback: function () { |
|||
cur_frm.reload_doc(); |
|||
frappe.show_alert({ |
|||
message: 'Item Code renamed successfully', |
|||
indicator: 'green' |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
d.hide(); |
|||
}, |
|||
primary_action_label: __('Change Item Code') |
|||
}); |
|||
d.show(); |
|||
|
|||
d.set_values({ |
|||
'item_code': doc.item_code |
|||
}); |
|||
}; |
@ -0,0 +1,211 @@ |
|||
{ |
|||
"actions": [], |
|||
"autoname": "field:therapy_type", |
|||
"creation": "2020-03-29 20:48:31.715063", |
|||
"doctype": "DocType", |
|||
"editable_grid": 1, |
|||
"engine": "InnoDB", |
|||
"field_order": [ |
|||
"disabled", |
|||
"section_break_2", |
|||
"therapy_type", |
|||
"default_duration", |
|||
"medical_department", |
|||
"column_break_3", |
|||
"is_billable", |
|||
"rate", |
|||
"healthcare_service_unit", |
|||
"item_details_section", |
|||
"item", |
|||
"item_code", |
|||
"item_name", |
|||
"item_group", |
|||
"column_break_12", |
|||
"description", |
|||
"section_break_18", |
|||
"therapy_for", |
|||
"add_exercises", |
|||
"section_break_6", |
|||
"exercises", |
|||
"change_in_item" |
|||
], |
|||
"fields": [ |
|||
{ |
|||
"fieldname": "therapy_type", |
|||
"fieldtype": "Data", |
|||
"in_list_view": 1, |
|||
"label": "Therapy Type", |
|||
"reqd": 1, |
|||
"unique": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_3", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"default": "0", |
|||
"fieldname": "is_billable", |
|||
"fieldtype": "Check", |
|||
"label": "Is Billable" |
|||
}, |
|||
{ |
|||
"depends_on": "eval:doc.is_billable;", |
|||
"fieldname": "rate", |
|||
"fieldtype": "Currency", |
|||
"label": "Rate", |
|||
"mandatory_depends_on": "eval:doc.is_billable;" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_6", |
|||
"fieldtype": "Section Break", |
|||
"label": "Exercises" |
|||
}, |
|||
{ |
|||
"fieldname": "exercises", |
|||
"fieldtype": "Table", |
|||
"label": "Exercises", |
|||
"options": "Exercise" |
|||
}, |
|||
{ |
|||
"fieldname": "default_duration", |
|||
"fieldtype": "Int", |
|||
"label": "Default Duration (In Minutes)" |
|||
}, |
|||
{ |
|||
"default": "0", |
|||
"fieldname": "disabled", |
|||
"fieldtype": "Check", |
|||
"label": "Disabled" |
|||
}, |
|||
{ |
|||
"fieldname": "item_details_section", |
|||
"fieldtype": "Section Break", |
|||
"label": "Item Details" |
|||
}, |
|||
{ |
|||
"fieldname": "item", |
|||
"fieldtype": "Link", |
|||
"label": "Item", |
|||
"options": "Item", |
|||
"read_only": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "item_code", |
|||
"fieldtype": "Data", |
|||
"label": "Item Code", |
|||
"reqd": 1, |
|||
"set_only_once": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "item_group", |
|||
"fieldtype": "Link", |
|||
"label": "Item Group", |
|||
"options": "Item Group", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "item_name", |
|||
"fieldtype": "Data", |
|||
"label": "Item Name", |
|||
"reqd": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "column_break_12", |
|||
"fieldtype": "Column Break" |
|||
}, |
|||
{ |
|||
"fieldname": "description", |
|||
"fieldtype": "Small Text", |
|||
"label": "Description" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_2", |
|||
"fieldtype": "Section Break" |
|||
}, |
|||
{ |
|||
"fieldname": "medical_department", |
|||
"fieldtype": "Link", |
|||
"label": "Medical Department", |
|||
"options": "Medical Department" |
|||
}, |
|||
{ |
|||
"default": "0", |
|||
"fieldname": "change_in_item", |
|||
"fieldtype": "Check", |
|||
"hidden": 1, |
|||
"label": "Change In Item", |
|||
"print_hide": 1, |
|||
"read_only": 1, |
|||
"report_hide": 1 |
|||
}, |
|||
{ |
|||
"fieldname": "therapy_for", |
|||
"fieldtype": "Table MultiSelect", |
|||
"label": "Therapy For", |
|||
"options": "Body Part Link" |
|||
}, |
|||
{ |
|||
"fieldname": "healthcare_service_unit", |
|||
"fieldtype": "Link", |
|||
"label": "Healthcare Service Unit", |
|||
"options": "Healthcare Service Unit" |
|||
}, |
|||
{ |
|||
"depends_on": "eval: doc.therapy_for", |
|||
"fieldname": "add_exercises", |
|||
"fieldtype": "Button", |
|||
"label": "Add Exercises", |
|||
"options": "add_exercises" |
|||
}, |
|||
{ |
|||
"fieldname": "section_break_18", |
|||
"fieldtype": "Section Break" |
|||
} |
|||
], |
|||
"links": [], |
|||
"modified": "2020-04-21 13:09:04.006289", |
|||
"modified_by": "Administrator", |
|||
"module": "Healthcare", |
|||
"name": "Therapy Type", |
|||
"owner": "Administrator", |
|||
"permissions": [ |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "System Manager", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"create": 1, |
|||
"delete": 1, |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Healthcare Administrator", |
|||
"share": 1, |
|||
"write": 1 |
|||
}, |
|||
{ |
|||
"email": 1, |
|||
"export": 1, |
|||
"print": 1, |
|||
"read": 1, |
|||
"report": 1, |
|||
"role": "Physician", |
|||
"share": 1, |
|||
"write": 1 |
|||
} |
|||
], |
|||
"quick_entry": 1, |
|||
"sort_field": "modified", |
|||
"sort_order": "DESC", |
|||
"track_changes": 1 |
|||
} |
@ -0,0 +1,122 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors |
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
import frappe |
|||
import json |
|||
from frappe import _ |
|||
from frappe.utils import cint |
|||
from frappe.model.document import Document |
|||
from frappe.model.rename_doc import rename_doc |
|||
|
|||
class TherapyType(Document): |
|||
def validate(self): |
|||
self.enable_disable_item() |
|||
|
|||
def after_insert(self): |
|||
create_item_from_therapy(self) |
|||
|
|||
def on_update(self): |
|||
if self.change_in_item: |
|||
self.update_item_and_item_price() |
|||
|
|||
def enable_disable_item(self): |
|||
if self.is_billable: |
|||
if self.disabled: |
|||
frappe.db.set_value('Item', self.item, 'disabled', 1) |
|||
else: |
|||
frappe.db.set_value('Item', self.item, 'disabled', 0) |
|||
|
|||
def update_item_and_item_price(self): |
|||
if self.is_billable and self.item: |
|||
item_doc = frappe.get_doc('Item', {'item_code': self.item}) |
|||
item_doc.item_name = self.item_name |
|||
item_doc.item_group = self.item_group |
|||
item_doc.description = self.description |
|||
item_doc.disabled = 0 |
|||
item_doc.ignore_mandatory = True |
|||
item_doc.save(ignore_permissions=True) |
|||
|
|||
if self.rate: |
|||
item_price = frappe.get_doc('Item Price', {'item_code': self.item}) |
|||
item_price.item_name = self.item_name |
|||
item_price.price_list_name = self.rate |
|||
item_price.ignore_mandatory = True |
|||
item_price.save() |
|||
|
|||
elif not self.is_billable and self.item: |
|||
frappe.db.set_value('Item', self.item, 'disabled', 1) |
|||
|
|||
self.db_set('change_in_item', 0) |
|||
|
|||
def add_exercises(self): |
|||
exercises = self.get_exercises_for_body_parts() |
|||
last_idx = max([cint(d.idx) for d in self.get('exercises')] or [0,]) |
|||
for i, d in enumerate(exercises): |
|||
ch = self.append('exercises', {}) |
|||
ch.exercise_type = d.parent |
|||
ch.idx = last_idx + i + 1 |
|||
|
|||
def get_exercises_for_body_parts(self): |
|||
body_parts = [entry.body_part for entry in self.therapy_for] |
|||
|
|||
exercises = frappe.db.sql( |
|||
""" |
|||
SELECT DISTINCT |
|||
b.parent, e.name, e.difficulty_level |
|||
FROM |
|||
`tabExercise Type` e, `tabBody Part Link` b |
|||
WHERE |
|||
b.body_part IN %(body_parts)s AND b.parent=e.name |
|||
""", {'body_parts': body_parts}, as_dict=1) |
|||
|
|||
return exercises |
|||
|
|||
|
|||
def create_item_from_therapy(doc): |
|||
disabled = doc.disabled |
|||
if doc.is_billable and not doc.disabled: |
|||
disabled = 0 |
|||
|
|||
uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom') |
|||
|
|||
item = frappe.get_doc({ |
|||
'doctype': 'Item', |
|||
'item_code': doc.item_code, |
|||
'item_name': doc.item_name, |
|||
'item_group': doc.item_group, |
|||
'description': doc.description, |
|||
'is_sales_item': 1, |
|||
'is_service_item': 1, |
|||
'is_purchase_item': 0, |
|||
'is_stock_item': 0, |
|||
'show_in_website': 0, |
|||
'is_pro_applicable': 0, |
|||
'disabled': disabled, |
|||
'stock_uom': uom |
|||
}).insert(ignore_permissions=True, ignore_mandatory=True) |
|||
|
|||
make_item_price(item.name, doc.rate) |
|||
doc.db_set('item', item.name) |
|||
|
|||
|
|||
def make_item_price(item, item_price): |
|||
price_list_name = frappe.db.get_value('Price List', {'selling': 1}) |
|||
frappe.get_doc({ |
|||
'doctype': 'Item Price', |
|||
'price_list': price_list_name, |
|||
'item_code': item, |
|||
'price_list_rate': item_price |
|||
}).insert(ignore_permissions=True, ignore_mandatory=True) |
|||
|
|||
@frappe.whitelist() |
|||
def change_item_code_from_therapy(item_code, doc): |
|||
doc = frappe._dict(json.loads(doc)) |
|||
|
|||
if frappe.db.exists('Item', {'item_code': item_code}): |
|||
frappe.throw(_('Item with Item Code {0} already exists').format(item_code)) |
|||
else: |
|||
rename_doc('Item', doc.item, item_code, ignore_permissions=True) |
|||
frappe.db.set_value('Therapy Type', doc.name, 'item_code', item_code) |
|||
return |
Loading…
Reference in new issue