Clinical procedure (#13540)

* Clinical Procesdure Template and Clinical Procedure Doctype

* Consultation - Create procedure and procedure prescription

* Patient Appointment - Create Procedure and Procedure appointment invoice

* Physician Schedule - Validate slot overlap

* Clinical Procedure Item - batch_no for Clinical Procedure not for Template

* Clinical Procedure - manage item batch_no

* Codacy - fixes

* Yet another Codacy and travic-ci fix

* Codacy - fixes

* Clinical Procedure - Codacy fix

* Permissions updated

* fixed Qty Indicators, Minor fixes

* Patient appointment for procedure prescription

* Doctype Patient Service Unit to Healthcare Service Unit

* Add healthcare service unit tree root

* Healthcare Service Unit - Tree view script

* Healthcare Service Unit - allow appointments check

* Clinical Procedure - remove unused variable

* Clinical Procedure - Get actual quantity from ledger - fix

* Clinical Procedure - apply transilation for message

* Warehouse in Healthcare Service Unit

* Service Unit in Clinical Procedure

* Codacy fix

* Missing semicolon
This commit is contained in:
Jamsheer 2018-05-16 10:54:00 +05:30 committed by Rushabh Mehta
parent 915877553a
commit 0cde6ae3c5
41 changed files with 3588 additions and 95 deletions

View File

@ -33,6 +33,11 @@ def get_data():
"type": "page",
"name": "appointment-analytic",
"label": _("Appointment Analytics"),
},
{
"type": "doctype",
"name": "Clinical Procedure",
"label": _("Clinical Procedure"),
}
]
},
@ -89,8 +94,8 @@ def get_data():
},
{
"type": "doctype",
"name": "Patient Service Unit",
"label": _("Patient Service Unit")
"name": "Healthcare Service Unit",
"label": _("Healthcare Service Unit")
}
]
},
@ -157,6 +162,11 @@ def get_data():
"type": "doctype",
"name": "Lab Test Template",
"label": _("Lab Test Template")
},
{
"type": "doctype",
"name": "Clinical Procedure Template",
"label": _("Clinical Procedure Template"),
}
]
}

View File

@ -0,0 +1,305 @@
// Copyright (c) 2017, ESS LLP and contributors
// For license information, please see license.txt
frappe.ui.form.on('Clinical Procedure', {
setup: function(frm) {
frm.set_query('batch_no', 'items', function(doc, cdt, cdn) {
var item = locals[cdt][cdn];
if(!item.item_code) {
frappe.throw(__("Please enter Item Code to get Batch Number"));
} else {
if (frm.doc.status == 'In Progress') {
var filters = {
'item_code': item.item_code,
'posting_date': frm.doc.start_date || frappe.datetime.nowdate()
};
if(frm.doc.warehouse) filters["warehouse"] = frm.doc.warehouse;
} else {
filters = {
'item_code': item.item_code
};
}
return {
query : "erpnext.controllers.queries.get_batch_no",
filters: filters
};
}
});
},
refresh: function(frm) {
frm.set_query("patient", function () {
return {
filters: {"disabled": 0}
};
});
frm.set_query("appointment", function () {
return {
filters: {
"procedure_template": ["not in", null],
"status": ['in', 'Open, Scheduled']
}
};
});
frm.set_query("service_unit", function(){
return {
filters: {
"is_group": false,
"allow_appointments": true
}
};
});
if(frm.doc.consume_stock){
frm.set_indicator_formatter('item_code',
function(doc) { return (doc.qty<=doc.actual_qty) ? "green" : "orange" ; });
}
if (!frm.doc.__islocal && frm.doc.status == 'In Progress'){
if(frm.doc.consume_stock){
var btn_label = 'Complete and Consume';
var msg = 'Complete '+frm.doc.name+' and Consume Stock?';
}else{
btn_label = 'Complete';
msg = 'Complete '+frm.doc.name+'?';
}
frm.add_custom_button(__(btn_label), function () {
frappe.confirm(
__(msg),
function(){
frappe.call({
doc: frm.doc,
method: "complete",
callback: function(r) {
if(!r.exc){
cur_frm.reload_doc();
}
}
});
}
);
});
}else if (frm.doc.status == 'Draft') {
frm.add_custom_button(__("Start"), function () {
frappe.call({
doc: frm.doc,
method: "start",
callback: function(r) {
if(!r.exc){
if(frm.doc.status == 'Draft'){
frappe.confirm(
__("Stock quantity to start procedure is not available in the warehouse. Do you want to record a Stock Transfer"),
function(){
frappe.call({
doc: frm.doc,
method: "make_material_transfer",
callback: function(r) {
if(!r.exc){
cur_frm.reload_doc();
var doclist = frappe.model.sync(r.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
}
}
});
}
);
}else{
cur_frm.reload_doc();
}
}
}
});
});
}
if (frm.doc.__islocal){
frm.set_df_property("consumables", "hidden", 1);
}else{
frm.set_df_property("consumables", "hidden", 0);
}
},
onload: function(frm){
if(frm.doc.status == 'Completed'){
frm.set_df_property("items", "read_only", 1);
}
if(frm.is_new()) {
frm.add_fetch("procedure_template", "medical_department", "medical_department");
frm.set_value("start_time", null);
}
},
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 = age+" as on "+data.message.age_as_on;
}
}
frm.set_value("patient_age", age);
frm.set_value("patient_sex", data.message.sex);
}
});
}else{
frm.set_value("patient_age", "");
frm.set_value("patient_sex", "");
}
},
appointment: function(frm) {
if(frm.doc.appointment){
frappe.call({
"method": "frappe.client.get",
args: {
doctype: "Patient Appointment",
name: frm.doc.appointment
},
callback: function (data) {
frm.set_value("patient", data.message.patient);
frm.set_value("procedure_template", data.message.procedure_template);
frm.set_value("medical_department", data.message.department);
frm.set_value("start_date", data.message.appointment_date);
frm.set_value("start_time", data.message.appointment_time);
frm.set_value("notes", data.message.notes);
frm.set_value("service_unit", data.message.service_unit);
}
});
}
},
procedure_template: function(frm) {
if(frm.doc.procedure_template){
frappe.call({
"method": "frappe.client.get",
args: {
doctype: "Clinical Procedure Template",
name: frm.doc.procedure_template
},
callback: function (data) {
frm.set_value("medical_department", data.message.medical_department);
frm.set_value("consume_stock", data.message.consume_stock);
if(!frm.doc.warehouse){
frappe.call({
method: "frappe.client.get_value",
args: {
doctype: "Stock Settings",
fieldname: "default_warehouse"
},
callback: function (data) {
frm.set_value("warehouse", data.message.default_warehouse);
}
});
}
}
});
}else{
frm.set_value("consume_stock", 0);
}
},
service_unit: function(frm) {
if(frm.doc.service_unit){
frappe.call({
method: "frappe.client.get_value",
args:{
fieldname: "warehouse",
doctype: "Healthcare Service Unit",
filters:{name: frm.doc.service_unit},
},
callback: function(data) {
if(data.message){
frm.set_value("warehouse", data.message.warehouse);
}
}
});
}
}
});
cur_frm.set_query("procedure_template", function(doc) {
return {
filters: {
'medical_department': doc.medical_department
}
};
});
cur_frm.set_query("appointment", function() {
return {
filters: {
status:['in',["Open"]]
}
};
});
frappe.ui.form.on('Clinical Procedure Item', {
qty: function(frm, cdt, cdn){
var d = locals[cdt][cdn];
frappe.model.set_value(cdt, cdn, "transfer_qty", d.qty*d.conversion_factor);
},
uom: function(doc, cdt, cdn){
var d = locals[cdt][cdn];
if(d.uom && d.item_code){
return frappe.call({
method: "erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details",
args: {
item_code: d.item_code,
uom: d.uom,
qty: d.qty
},
callback: function(r) {
if(r.message) {
frappe.model.set_value(cdt, cdn, r.message);
}
}
});
}
},
item_code: function(frm, cdt, cdn) {
var d = locals[cdt][cdn];
let args = null;
if(d.item_code) {
args = {
'item_code' : d.item_code,
'transfer_qty' : d.transfer_qty,
'company' : frm.doc.company,
'quantity' : d.qty
};
return frappe.call({
doc: frm.doc,
method: "get_item_details",
args: args,
callback: function(r) {
if(r.message) {
var d = locals[cdt][cdn];
$.each(r.message, function(k, v){
d[k] = v;
});
refresh_field("items");
}
}
});
}
}
});
var calculate_age = function(birth) {
var ageMS = Date.parse(Date()) - Date.parse(birth);
var age = new Date();
age.setTime(ageMS);
var years = age.getFullYear() - 1970;
return years + " Year(s) " + age.getMonth() + " Month(s) " + age.getDate() + " Day(s)";
};
// List Stock items
cur_frm.set_query("item_code", "items", function() {
return {
filters: {
is_stock_item:1
}
};
});

View File

@ -0,0 +1,697 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "naming_series:",
"beta": 1,
"creation": "2017-04-07 12:52:43.542429",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
"no_copy": 0,
"options": "PRO-",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "appointment",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Appointment",
"length": 0,
"no_copy": 0,
"options": "Patient Appointment",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "patient",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Patient",
"length": 0,
"no_copy": 0,
"options": "Patient",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "patient_age",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Age",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "patient_sex",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Gender",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "procedure_template",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Procedure Template",
"length": 0,
"no_copy": 0,
"options": "Clinical Procedure Template",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "medical_department",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Medical Department",
"length": 0,
"no_copy": 0,
"options": "Medical Department",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_7",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "service_unit",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Service Unit",
"length": 0,
"no_copy": 0,
"options": "Healthcare Service Unit",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warehouse",
"length": 0,
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
"fieldname": "start_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Start Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "start_time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Time",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sample",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sample",
"length": 0,
"no_copy": 0,
"options": "Sample Collection",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "is_invoiced",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is Invoiced",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "notes",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Notes",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "consume_stock",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Consume Stock",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.consume_stock == 1",
"fieldname": "consumables",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Consumables",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Consumables",
"length": 0,
"no_copy": 0,
"options": "Clinical Procedure Item",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "status",
"fieldtype": "Select",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Status",
"length": 0,
"no_copy": 0,
"options": "Draft\nIn Progress\nCompleted\nPending\nCancelled",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-05-04 11:23:32.884076",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedure",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Nursing User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,183 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, ESS LLP and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cint, flt, nowdate, nowtime
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
from erpnext.healthcare.doctype.lab_test.lab_test import create_sample_doc
from erpnext.stock.stock_ledger import get_previous_sle
class ClinicalProcedure(Document):
def validate(self):
if self.consume_stock and not self.status == 'Draft':
if not self.warehouse:
frappe.throw(("Set warehouse for Procedure {0} ").format(self.name))
self.set_actual_qty()
def before_insert(self):
if self.consume_stock:
set_stock_items(self, self.procedure_template, "Clinical Procedure Template")
self.set_actual_qty();
def after_insert(self):
if self.appointment:
frappe.db.set_value("Patient Appointment", self.appointment, "status", "Closed")
template = frappe.get_doc("Clinical Procedure Template", self.procedure_template)
if template.sample:
patient = frappe.get_doc("Patient", self.patient)
sample_collection = create_sample_doc(template, patient, None)
frappe.db.set_value("Clinical Procedure", self.name, "sample", sample_collection.name)
self.reload()
def complete(self):
if self.consume_stock:
create_stock_entry(self)
frappe.db.set_value("Clinical Procedure", self.name, "status", 'Completed')
def start(self):
allow_start = self.set_actual_qty()
if allow_start:
self.status = 'In Progress'
else:
self.status = 'Draft'
self.save()
def set_actual_qty(self):
allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock"))
allow_start = True
for d in self.get('items'):
previous_sle = get_previous_sle({
"item_code": d.item_code,
"warehouse": self.warehouse,
"posting_date": nowdate(),
"posting_time": nowtime()
})
# get actual stock at source warehouse
d.actual_qty = previous_sle.get("qty_after_transaction") or 0
# validate qty
if not allow_negative_stock and d.actual_qty < d.qty:
allow_start = False
return allow_start
def make_material_transfer(self):
stock_entry = frappe.new_doc("Stock Entry")
stock_entry.purpose = "Material Transfer"
stock_entry.to_warehouse = self.warehouse
expense_account = get_account(None, "expense_account", "Healthcare Settings", self.company)
for item in self.items:
if item.qty > item.actual_qty:
se_child = stock_entry.append('items')
se_child.item_code = item.item_code
se_child.item_name = item.item_name
se_child.uom = item.uom
se_child.stock_uom = item.stock_uom
se_child.qty = flt(item.qty-item.actual_qty)
se_child.t_warehouse = self.warehouse
# in stock uom
se_child.transfer_qty = flt(item.transfer_qty)
se_child.conversion_factor = flt(item.conversion_factor)
cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
se_child.cost_center = cost_center
se_child.expense_account = expense_account
return stock_entry.as_dict()
def get_item_details(self, args=None):
item = frappe.db.sql("""select stock_uom, description, image, item_name,
expense_account, buying_cost_center, item_group from `tabItem`
where name = %s
and disabled=0
and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)""",
(args.get('item_code'), nowdate()), as_dict = 1)
if not item:
frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get('item_code')))
item = item[0]
ret = {
'uom' : item.stock_uom,
'stock_uom' : item.stock_uom,
'item_name' : item.item_name,
'quantity' : 0,
'transfer_qty' : 0,
'conversion_factor' : 1
}
return ret
@frappe.whitelist()
def set_stock_items(doc, stock_detail_parent, parenttype):
item_dict = get_item_dict("Clinical Procedure Item", stock_detail_parent, parenttype)
for d in item_dict:
se_child = doc.append('items')
se_child.item_code = d["item_code"]
se_child.item_name = d["item_name"]
se_child.uom = d["uom"]
se_child.stock_uom = d["stock_uom"]
se_child.qty = flt(d["qty"])
# in stock uom
se_child.transfer_qty = flt(d["transfer_qty"])
se_child.conversion_factor = flt(d["conversion_factor"])
if d["batch_no"]:
se_child.batch_no = d["batch_no"]
return doc
def get_item_dict(table, parent, parenttype):
query = """select * from `tab{table}` where parent = '{parent}' and parenttype = '{parenttype}' """
return frappe.db.sql(query.format(table=table, parent=parent, parenttype=parenttype), as_dict=True)
def create_stock_entry(doc):
stock_entry = frappe.new_doc("Stock Entry")
stock_entry = set_stock_items(stock_entry, doc.name, "Clinical Procedure")
stock_entry.purpose = "Material Issue"
stock_entry.from_warehouse = doc.warehouse
stock_entry.company = doc.company
expense_account = get_account(None, "expense_account", "Healthcare Settings", doc.company)
for item_line in stock_entry.items:
cost_center = frappe.db.get_value('Company', doc.company, 'cost_center')
#item_line.s_warehouse = warehouse #deaful source warehouse set, stock entry to copy to lines
item_line.cost_center = cost_center
#if not expense_account:
# expense_account = frappe.db.get_value("Item", item_line.item_code, "expense_account")
item_line.expense_account = expense_account
stock_entry.insert(ignore_permissions = True)
stock_entry.submit()
@frappe.whitelist()
def create_procedure(appointment):
appointment = frappe.get_doc("Patient Appointment",appointment)
procedure = frappe.new_doc("Clinical Procedure")
procedure.appointment = appointment.name
procedure.patient = appointment.patient
procedure.patient_age = appointment.patient_age
procedure.patient_sex = appointment.patient_sex
procedure.procedure_template = appointment.procedure_template
procedure.medical_department = appointment.department
procedure.start_date = appointment.appointment_date
procedure.start_time = appointment.appointment_time
procedure.notes = appointment.notes
procedure.service_unit = appointment.service_unit
consume_stock = frappe.db.get_value("Clinical Procedure Template", appointment.procedure_template, "consume_stock")
if consume_stock == 1:
procedure.consume_stock = True
warehouse = False
if appointment.service_unit:
warehouse = frappe.db.get_value("Healthcare Service Unit", appointment.service_unit, "warehouse")
if not warehouse:
warehouse = frappe.db.get_value("Stock Settings", None, "default_warehouse")
if warehouse:
procedure.warehouse = warehouse
return procedure.as_dict()

View File

@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Patient Service Unit", function (assert) {
QUnit.test("test: Clinical Procedure", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
// insert a new Patient Service Unit
() => frappe.tests.make('Patient Service Unit', [
// insert a new Clinical Procedure
() => frappe.tests.make('Clinical Procedure', [
// values to be set
{key: 'value'}
]),

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, ESS LLP and Contributors
# See license.txt
from __future__ import unicode_literals
import unittest
class TestClinicalProcedure(unittest.TestCase):
pass

View File

@ -0,0 +1,385 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 1,
"creation": "2017-10-05 16:15:10.876952",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 3,
"fieldname": "item_code",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Item",
"length": 0,
"no_copy": 0,
"options": "Item",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "barcode",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Barcode",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "item_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Item Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Quantity",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "UOM",
"length": 0,
"no_copy": 0,
"options": "UOM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "batch_no",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Batch",
"length": 0,
"no_copy": 0,
"options": "Batch",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "conversion_factor",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Conversion Factor",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "stock_uom",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Stock UOM",
"length": 0,
"no_copy": 0,
"options": "UOM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "transfer_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Transfer Qty",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "actual_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Actual Qty (at source/target)",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-03-28 14:34:03.796229",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedure Item",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, earthians and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.model.document import Document
class ClinicalProcedureItem(Document):
pass

View File

@ -0,0 +1,175 @@
// Copyright (c) 2017, earthians and contributors
// For license information, please see license.txt
frappe.ui.form.on('Clinical Procedure Template', {
template: function(frm) {
if(!frm.doc.item_code)
frm.set_value("item_code", frm.doc.template);
if(!frm.doc.description)
frm.set_value("description", frm.doc.template);
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);
},
refresh: function(frm) {
frm.fields_dict["items"].grid.set_column_disp("barcode", false);
frm.fields_dict["items"].grid.set_column_disp("batch_no", false);
cur_frm.set_df_property("item_code", "read_only", frm.doc.__islocal ? 0 : 1);
if(!frm.doc.__islocal) {
cur_frm.add_custom_button(__('Change Item Code'), function() {
change_template_code(frm.doc);
} );
if(frm.doc.disabled == 1){
cur_frm.add_custom_button(__('Enable Template'), function() {
enable_template(frm.doc);
} );
}
else{
cur_frm.add_custom_button(__('Disable Template'), function() {
disable_template(frm.doc);
} );
}
}
}
});
var mark_change_in_item = function(frm) {
if(!frm.doc.__islocal){
frm.doc.change_in_item = 1;
}
};
var disable_template = function(doc){
frappe.call({
method: "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.disable_enable_template",
args: {status: 1, name: doc.name, item_code: doc.item_code, is_billable: doc.is_billable},
callback: function(){
cur_frm.reload_doc();
}
});
};
var enable_template = function(doc){
frappe.call({
method: "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.disable_enable_template",
args: {status: 0, name: doc.name, item_code: doc.item_code, is_billable: doc.is_billable},
callback: function(){
cur_frm.reload_doc();
}
});
};
var change_template_code = function(doc){
var d = new frappe.ui.Dialog({
title:__("Change Template Code"),
fields:[
{
"fieldtype": "Data",
"label": "Template Code",
"fieldname": "Item Code",
reqd:1
},
{
"fieldtype": "Button",
"label": __("Change Code"),
click: function() {
var values = d.get_values();
if(!values)
return;
change_item_code_from_template(values["Item Code"], doc);
d.hide();
}
}
]
});
d.show();
d.set_values({
'Item Code': doc.item_code
});
};
var change_item_code_from_template = function(item_code, doc){
frappe.call({
"method": "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.change_item_code_from_template",
"args": {item_code: item_code, doc: doc},
callback: function () {
cur_frm.reload_doc();
frappe.show_alert({
message: "Item Code renamed successfully",
indicator: "green"
});
}
});
};
frappe.ui.form.on('Clinical Procedure Item', {
qty: function(frm, cdt, cdn){
var d = locals[cdt][cdn];
frappe.model.set_value(cdt, cdn, "transfer_qty", d.qty*d.conversion_factor);
},
uom: function(doc, cdt, cdn){
var d = locals[cdt][cdn];
if(d.uom && d.item_code){
return frappe.call({
method: "erpnext.stock.doctype.stock_entry.stock_entry.get_uom_details",
args: {
item_code: d.item_code,
uom: d.uom,
qty: d.qty
},
callback: function(r) {
if(r.message) {
frappe.model.set_value(cdt, cdn, r.message);
}
}
});
}
},
item_code: function(frm, cdt, cdn) {
var d = locals[cdt][cdn];
if(d.item_code) {
let args = {
'item_code' : d.item_code,
'transfer_qty' : d.transfer_qty,
'company' : frm.doc.company,
'quantity' : d.qty
};
return frappe.call({
doc: frm.doc,
method: "get_item_details",
args: args,
callback: function(r) {
if(r.message) {
var d = locals[cdt][cdn];
$.each(r.message, function(k, v){
d[k] = v;
});
refresh_field("items");
}
}
});
}
}
});
// List Stock items
cur_frm.set_query("item_code", "items", function() {
return {
filters: {
is_stock_item:1
}
};
});

View File

@ -0,0 +1,783 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 1,
"autoname": "field:template",
"beta": 1,
"creation": "2017-10-05 14:59:55.438359",
"custom": 0,
"description": "Procedure Template",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "template",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Template Name",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "item_code",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item Code",
"length": 0,
"no_copy": 1,
"options": "Item",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "item_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Item Group",
"length": 0,
"no_copy": 0,
"options": "Item Group",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "medical_department",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Medical Department",
"length": 0,
"no_copy": 0,
"options": "Medical Department",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "is_billable",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is Billable",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "is_billable",
"fieldname": "rate",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Rate",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 1,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_9",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "consume_stock",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Stock Consumption",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.consume_stock == 1",
"fieldname": "consumables",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Consumables",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Items",
"length": 0,
"no_copy": 0,
"options": "Clinical Procedure Item",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"depends_on": "",
"fieldname": "sample_collection",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sample Collection",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sample",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sample",
"length": 0,
"no_copy": 0,
"options": "Lab Test Sample",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sample_uom",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "UOM",
"length": 0,
"no_copy": 0,
"options": "sample.sample_uom",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sample_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Quantity",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_21",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sample_details",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 1,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Collection Details",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "change_in_item",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Change In Item",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disabled",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "item",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item",
"length": 0,
"no_copy": 1,
"options": "Item",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-04-27 18:04:32.209983",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Clinical Procedure Template",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Medical Administrator",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Nursing User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 0
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"delete": 0,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Physician",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
"search_fields": "template",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "template",
"track_changes": 1,
"track_seen": 1
}

View File

@ -0,0 +1,130 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, earthians and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe, json
from frappe import _
from frappe.model.document import Document
from frappe.utils import nowdate
class ClinicalProcedureTemplate(Document):
def on_update(self):
#Item and Price List update --> if (change_in_item)
if(self.change_in_item and self.is_billable == 1 and self.item):
updating_item(self)
if(self.rate != 0.0):
updating_rate(self)
elif(self.is_billable == 0 and self.item):
frappe.db.set_value("Item",self.item,"disabled",1)
frappe.db.set_value(self.doctype,self.name,"change_in_item",0)
self.reload()
def after_insert(self):
create_item_from_template(self)
#Call before delete the template
def on_trash(self):
if(self.item):
try:
frappe.delete_doc("Item",self.item)
except Exception:
frappe.throw("""Not permitted. Please disable the Procedure Template""")
def get_item_details(self, args=None):
item = frappe.db.sql("""select stock_uom, description, image, item_name,
expense_account, buying_cost_center, item_group from `tabItem`
where name = %s
and disabled=0
and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)""",
(args.get('item_code'), nowdate()), as_dict = 1)
if not item:
frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get('item_code')))
item = item[0]
ret = {
'uom' : item.stock_uom,
'stock_uom' : item.stock_uom,
'item_name' : item.item_name,
'quantity' : 0,
'transfer_qty' : 0,
'conversion_factor' : 1
}
return ret
def updating_item(self):
frappe.db.sql("""update `tabItem` set item_name=%s, item_group=%s, disabled=0,
description=%s, modified=NOW() where item_code=%s""",
(self.template, self.item_group , self.description, self.item))
def updating_rate(self):
frappe.db.sql("""update `tabItem Price` set item_name=%s, price_list_rate=%s, modified=NOW() where
item_code=%s""",(self.template, self.rate, self.item))
def create_item_from_template(doc):
if(doc.is_billable == 1):
disabled = 0
else:
disabled = 1
#insert item
item = frappe.get_doc({
"doctype": "Item",
"item_code": doc.template,
"item_name":doc.template,
"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": "Unit"
}).insert(ignore_permissions=True)
#insert item price
#get item price list to insert item price
if(doc.rate != 0.0):
price_list_name = frappe.db.get_value("Price List", {"selling": 1})
if(doc.rate):
make_item_price(item.name, price_list_name, doc.rate)
else:
make_item_price(item.name, price_list_name, 0.0)
#Set item to the template
frappe.db.set_value("Clinical Procedure Template", doc.name, "item", item.name)
doc.reload() #refresh the doc after insert.
def make_item_price(item, price_list_name, item_price):
frappe.get_doc({
"doctype": "Item Price",
"price_list": price_list_name,
"item_code": item,
"price_list_rate": item_price
}).insert(ignore_permissions=True)
@frappe.whitelist()
def change_item_code_from_template(item_code, doc):
args = json.loads(doc)
doc = frappe._dict(args)
if(frappe.db.exists({
"doctype": "Item",
"item_code": item_code})):
frappe.throw(_("Code {0} already exist").format(item_code))
else:
frappe.rename_doc("Item", doc.item_code, item_code, ignore_permissions = True)
frappe.db.set_value("Clinical Procedure Template", doc.name, "item_code", item_code)
return
@frappe.whitelist()
def disable_enable_template(status, name, item_code):
frappe.db.set_value("Clinical Procedure Template", name, "disabled", status)
if (frappe.db.exists({ #set Item's disabled field to status
"doctype": "Item",
"item_code": item_code})):
frappe.db.set_value("Item", item_code, "disabled", status)
return

View File

@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Clinical Procedure Template", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
// insert a new Clinical Procedure Template
() => frappe.tests.make('Clinical Procedure Template', [
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@ -4,5 +4,5 @@
from __future__ import unicode_literals
import unittest
class TestPatientServiceUnit(unittest.TestCase):
class TestClinicalProcedureTemplate(unittest.TestCase):
pass

View File

@ -35,6 +35,10 @@ frappe.ui.form.on('Consultation', {
create_medical_record(frm);
},"Create");
frm.add_custom_button(__("Procedure"),function(){
btn_create_procedure(frm);
},"Create");
frm.set_query("patient", function () {
return {
filters: {"disabled": 0}
@ -127,6 +131,17 @@ var btn_create_vital_signs = function (frm) {
frappe.new_doc("Vital Signs");
};
var btn_create_procedure = function (frm) {
if(!frm.doc.patient){
frappe.throw("Please select patient");
}
frappe.route_options = {
"patient": frm.doc.patient,
"medical_department": frm.doc.visit_department
};
frappe.new_doc("Clinical Procedure");
};
frappe.ui.form.on("Consultation", "appointment", function(frm){
if(frm.doc.appointment){
frappe.call({
@ -238,6 +253,25 @@ frappe.ui.form.on("Drug Prescription", {
}
});
frappe.ui.form.on("Procedure Prescription", {
procedure: function(frm, cdt, cdn) {
var child = locals[cdt][cdn];
if(child.procedure){
frappe.call({
"method": "frappe.client.get_value",
args: {
doctype: "Clinical Procedure Template",
fieldname: "medical_department",
filters: {name: child.procedure}
},
callback: function (data) {
frappe.model.set_value(cdt, cdn, 'department',data.message.medical_department);
}
});
}
}
});
var calculate_age = function(birth) {
var ageMS = Date.parse(Date()) - Date.parse(birth);

View File

@ -874,6 +874,67 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sb_procedures",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Procedures",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "procedure_prescription",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Procedures",
"length": 0,
"no_copy": 1,
"options": "Procedure Prescription",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -945,7 +1006,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-02-19 11:35:13.826577",
"modified": "2018-03-19 11:35:13.826577",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Consultation",

View File

@ -125,5 +125,7 @@ def set_subject_field(consultation):
subject +="\nDrug(s) Prescribed. "
if(consultation.test_prescription):
subject += "\nTest(s) Prescribed."
if(consultation.procedure_prescription):
subject += "\nProcedure(s) Prescribed."
return subject

View File

@ -0,0 +1,42 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Healthcare Service Unit', {
onload: function(frm) {
frm.list_route = "Tree/Healthcare Service Unit";
// get query select healthcare service unit
frm.fields_dict['parent_healthcare_service_unit'].get_query = function(doc) {
return{
filters:[
['Healthcare Service Unit', 'is_group', '=', 1],
['Healthcare Service Unit', 'name', '!=', doc.healthcare_service_unit_name]
]
};
};
},
refresh: function(frm) {
frm.trigger("set_root_readonly");
frm.add_custom_button(__("Healthcare Service Unit Tree"), function() {
frappe.set_route("Tree", "Healthcare Service Unit");
});
},
set_root_readonly: function(frm) {
// read-only for root healthcare service unit
frm.set_intro("");
if(!frm.doc.parent_healthcare_service_unit) {
frm.set_read_only();
frm.set_intro(__("This is a root healthcare service unit and cannot be edited."), true);
}
},
allow_appointments: function(frm) {
if(!frm.doc.allow_appointments){
frm.set_value("overlap_appointments", false);
}
},
is_group: function(frm) {
if(frm.doc.is_group){
frm.set_value("allow_appointments", false);
}
}
});

View File

@ -3,11 +3,11 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 1,
"autoname": "field:patient_service_unit_name",
"autoname": "field:healthcare_service_unit_name",
"beta": 1,
"creation": "2016-09-21 13:48:14.731437",
"custom": 0,
"description": "Patinet Service Unit",
"description": "Healthcare Service Unit",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
@ -19,7 +19,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "patient_service_unit_name",
"fieldname": "healthcare_service_unit_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
@ -50,7 +50,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "parent_patient_service_unit",
"fieldname": "parent_healthcare_service_unit",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
@ -62,7 +62,7 @@
"label": "Parent Service Unit",
"length": 0,
"no_copy": 0,
"options": "Patient Service Unit",
"options": "Healthcare Service Unit",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -113,6 +113,39 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_group != 1",
"fieldname": "allow_appointments",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Appointments",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_group != 1 && doc.allow_appointments == 1",
"fieldname": "overlap_appointments",
"fieldtype": "Check",
"hidden": 0,
@ -138,6 +171,39 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_group != 1",
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warehouse",
"length": 0,
"no_copy": 0,
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -250,7 +316,7 @@
"label": "Old Parent",
"length": 0,
"no_copy": 1,
"options": "Patient Service Unit",
"options": "Healthcare Service Unit",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@ -275,16 +341,15 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-03-07 13:25:51.163029",
"modified": "2018-05-04 11:20:16.942603",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Service Unit",
"name": "Healthcare Service Unit",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 1,
"cancel": 0,
"create": 0,
"delete": 0,
@ -300,12 +365,10 @@
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"user_permission_doctypes": "[\"Service Unit\"]",
"write": 0
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@ -325,7 +388,6 @@
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 0,
@ -348,11 +410,11 @@
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Healthcare",
"search_fields": "patient_service_unit_name",
"search_fields": "healthcare_service_unit_name",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "patient_service_unit_name",
"title_field": "healthcare_service_unit_name",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.utils.nestedset import NestedSet
class HealthcareServiceUnit(NestedSet):
nsm_parent_field = 'parent_healthcare_service_unit'
def on_update(self):
super(HealthcareServiceUnit, self).on_update()
self.validate_one_root()
def validate(self):
if self.is_group:
self.allow_appointments = False
self.overlap_appointments = False
elif not self.allow_appointments:
self.overlap_appointments = False

View File

@ -0,0 +1,3 @@
frappe.treeview_settings["Healthcare Service Unit"] = {
ignore_fields:["parent_healthcare_service_unit"]
};

View File

@ -0,0 +1,23 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Healthcare Service Unit", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
frappe.run_serially([
// insert a new Healthcare Service Unit
() => frappe.tests.make('Healthcare Service Unit', [
// values to be set
{key: 'value'}
]),
() => {
assert.equal(cur_frm.doc.key, 'value');
},
() => done()
]);
});

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import unittest
class TestHealthcareServiceUnit(unittest.TestCase):
pass

View File

@ -26,6 +26,7 @@ frappe.ui.form.on('Patient Appointment', {
return {
filters: {
"is_group": false,
"allow_appointments": true
}
};
});
@ -40,9 +41,16 @@ frappe.ui.form.on('Patient Appointment', {
btn_update_status(frm, "Cancelled");
});
frm.add_custom_button(__("Consultation"),function(){
btn_create_consultation(frm);
},"Create");
if(frm.doc.procedure_template){
frm.add_custom_button(__("Procedure"),function(){
btn_create_procedure(frm);
},"Create");
}
else{
frm.add_custom_button(__("Consultation"),function(){
btn_create_consultation(frm);
},"Create");
}
frm.add_custom_button(__('Vital Signs'), function() {
btn_create_vital_signs(frm);
@ -53,9 +61,16 @@ frappe.ui.form.on('Patient Appointment', {
btn_update_status(frm, "Cancelled");
});
frm.add_custom_button(__("Consultation"),function(){
btn_create_consultation(frm);
},"Create");
if(frm.doc.procedure_template){
frm.add_custom_button(__("Procedure"),function(){
btn_create_procedure(frm);
},"Create");
}
else{
frm.add_custom_button(__("Consultation"),function(){
btn_create_consultation(frm);
},"Create");
}
frm.add_custom_button(__('Vital Signs'), function() {
btn_create_vital_signs(frm);
@ -201,8 +216,85 @@ frappe.ui.form.on('Patient Appointment', {
frm.disable_save();
}
},
get_procedure_from_consultation: function(frm) {
get_procedure_prescribed(frm);
}
});
var get_procedure_prescribed = function(frm){
if(frm.doc.patient){
frappe.call({
method:"erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_procedure_prescribed",
args: {patient: frm.doc.patient},
callback: function(r){
show_procedure_templates(frm, r.message);
}
});
}
else{
frappe.msgprint("Please select Patient to get prescribed procedure");
}
};
var show_procedure_templates = function(frm, result){
var d = new frappe.ui.Dialog({
title: __("Prescribed Procedures"),
fields: [
{
fieldtype: "HTML", fieldname: "procedure_template"
}
]
});
var html_field = d.fields_dict.procedure_template.$wrapper;
html_field.empty();
$.each(result, function(x, y){
var row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
<div class="col-xs-5"> %(consultation)s <br> %(consulting_physician)s <br> %(consultation_date)s </div>\
<div class="col-xs-5"> %(procedure_template)s <br>%(physician)s <br> %(date)s</div>\
<div class="col-xs-2">\
<a data-name="%(name)s" data-procedure-template="%(procedure_template)s"\
data-consultation="%(consultation)s" data-physician="%(physician)s"\
data-date="%(date)s" data-department="%(department)s">\
<button class="btn btn-default btn-xs">Add\
</button></a></div></div><div class="col-xs-12"><hr/><div/>', {name:y[0], procedure_template: y[1],
consultation:y[2], consulting_physician:y[3], consultation_date:y[4],
physician:y[5]? y[5]:'', date: y[6]? y[6]:'', department: y[7]? y[7]:''})).appendTo(html_field);
row.find("a").click(function() {
frm.doc.procedure_template = $(this).attr("data-procedure-template");
frm.doc.procedure_prescription = $(this).attr("data-name");
frm.doc.physician = $(this).attr("data-physician");
frm.doc.appointment_date = $(this).attr("data-date");
frm.doc.department = $(this).attr("data-department");
refresh_field("procedure_template");
refresh_field("procedure_prescription");
refresh_field("appointment_date");
refresh_field("physician");
refresh_field("department");
d.hide();
return false;
});
});
if(!result){
var msg = "There are no procedure prescribed for "+frm.doc.patient;
$(repl('<div class="col-xs-12" style="padding-top:20px;" >%(msg)s</div></div>', {msg: msg})).appendTo(html_field);
}
d.show();
};
var btn_create_procedure = function(frm){
var doc = frm.doc;
frappe.call({
method:"erpnext.healthcare.doctype.clinical_procedure.clinical_procedure.create_procedure",
args: {appointment: doc.name},
callback: function(data){
if(!data.exc){
var doclist = frappe.model.sync(data.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
}
}
});
};
var btn_create_consultation = function(frm){
var doc = frm.doc;
frappe.call({

View File

@ -109,6 +109,101 @@
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "get_procedure_from_consultation",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Get prescribed procedures",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "procedure_prescription",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Procedure Prescription",
"length": 0,
"no_copy": 1,
"options": "Procedure Prescription",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "procedure_template",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Procedure",
"length": 0,
"no_copy": 0,
"options": "Clinical Procedure Template",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 1,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -176,16 +271,16 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"columns": 0,
"description": "In Minutes",
"fieldname": "duration",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Duration",
"length": 0,
@ -285,7 +380,7 @@
"label": "Service Unit",
"length": 0,
"no_copy": 0,
"options": "Patient Service Unit",
"options": "Healthcare Service Unit",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -754,7 +849,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-03-13 12:10:00.123456",
"modified": "2018-05-02 03:38:09.442721",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Patient Appointment",
@ -763,7 +858,6 @@
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@ -783,7 +877,6 @@
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@ -803,7 +896,6 @@
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,

View File

@ -24,6 +24,8 @@ class PatientAppointment(Document):
self.reload()
def after_insert(self):
if self.procedure_prescription:
frappe.db.set_value("Procedure Prescription", self.procedure_prescription, "appointment_booked", True)
# Check fee validity exists
appointment = self
validity_exist = validity_exists(appointment.physician, appointment.patient)
@ -122,10 +124,10 @@ def get_availability_data(date, physician):
if available_slots:
appointments = []
if schedule.service_unit:
slot_name = schedule.schedule+" - "+schedule.service_unit
allow_overlap = frappe.get_value('Patient Service Unit', schedule.service_unit, 'overlap_appointments')
allow_overlap = frappe.get_value('Healthcare Service Unit', schedule.service_unit, 'overlap_appointments')
if allow_overlap:
# fetch all appointments to physician by service unit
appointments = frappe.get_all(
@ -164,9 +166,15 @@ def get_availability_data(date, physician):
@frappe.whitelist()
def update_status(appointment_id, status):
frappe.db.set_value("Patient Appointment", appointment_id, "status", status)
appointment_booked = True
if status == "Cancelled":
appointment_booked = False
appointment_cancel(appointment_id)
procedure_prescription = frappe.db.get_value("Patient Appointment", appointment_id, "procedure_prescription")
if procedure_prescription:
frappe.db.set_value("Procedure Prescription", procedure_prescription, "appointment_booked", appointment_booked)
@frappe.whitelist()
def set_open_appointments():
@ -202,7 +210,10 @@ def invoice_appointment(appointment_doc):
sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
fee_validity = get_fee_validity(appointment_doc.physician, appointment_doc.patient, appointment_doc.appointment_date)
create_invoice_items(appointment_doc.physician, appointment_doc.company, sales_invoice)
procedure_template = False
if appointment_doc.procedure_template:
procedure_template = appointment_doc.procedure_template
create_invoice_items(appointment_doc.physician, appointment_doc.company, sales_invoice, procedure_template)
sales_invoice.save(ignore_permissions=True)
frappe.db.sql("""update `tabPatient Appointment` set sales_invoice=%s where name=%s""", (sales_invoice.name, appointment_doc.name))
@ -256,18 +267,26 @@ def create_fee_validity(physician, patient, date):
return fee_validity
def create_invoice_items(physician, company, invoice):
def create_invoice_items(physician, company, invoice, procedure_template):
item_line = invoice.append("items")
item_line.item_name = "Consulting Charges"
item_line.description = "Consulting Charges: " + physician
if procedure_template:
procedure_template_obj = frappe.get_doc("Clinical Procedure Template", procedure_template)
item_line.item_code = procedure_template_obj.item_code
item_line.item_name = procedure_template_obj.template
item_line.description = procedure_template_obj.description
else:
item_line.item_name = "Consulting Charges"
item_line.description = "Consulting Charges: " + physician
item_line.uom = "Nos"
item_line.conversion_factor = 1
item_line.income_account = get_income_account(physician, company)
op_consulting_charge = frappe.db.get_value("Physician", physician, "op_consulting_charge")
if op_consulting_charge:
item_line.rate = op_consulting_charge
item_line.amount = op_consulting_charge
item_line.qty = 1
item_line.uom = "Nos"
item_line.conversion_factor = 1
item_line.income_account = get_income_account(physician, company)
op_consulting_charge = frappe.db.get_value("Physician", physician, "op_consulting_charge")
if op_consulting_charge:
item_line.rate = op_consulting_charge
item_line.amount = op_consulting_charge
return invoice
@ -336,4 +355,12 @@ def get_events(start, end, filters=None):
{"start": start, "end": end}, as_dict=True, update={"allDay": 0})
for item in data:
item.end = item.start + datetime.timedelta(minutes = item.duration)
return data
return data
@frappe.whitelist()
def get_procedure_prescribed(patient):
return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.physician,
ct.consultation_date, pp.physician, pp.date, pp.department
from tabConsultation ct, `tabProcedure Prescription` pp
where ct.patient='{0}' and pp.parent=ct.name and pp.appointment_booked=0
order by ct.creation desc""".format(patient))

View File

@ -1,15 +0,0 @@
// Copyright (c) 2017, earthians and contributors
// For license information, please see license.txt
frappe.ui.form.on('Patient Service Unit', {
});
// get query select patient service unit
cur_frm.fields_dict['parent_patient_service_unit'].get_query = function(doc) {
return{
filters:[
['Patient Service Unit', 'is_group', '=', 1],
['Patient Service Unit', 'name', '!=', doc.patient_service_unit_name]
]
};
};

View File

@ -1,14 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, earthians and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.utils.nestedset import NestedSet
class PatientServiceUnit(NestedSet):
nsm_parent_field = 'parent_patient_service_unit'
def on_update(self):
super(PatientServiceUnit, self).on_update()
self.validate_one_root()

View File

@ -1,3 +0,0 @@
frappe.treeview_settings["Patient Service Unit"] = {
ignore_fields:["parent_patient_service_unit"]
};

View File

@ -23,6 +23,7 @@ frappe.ui.form.on('Physician', {
return {
filters: {
"is_group": false,
"allow_appointments": true
}
};
});

View File

@ -28,6 +28,7 @@ frappe.ui.form.on('Physician Schedule', {
primary_action: () => {
var values = d.get_values();
if(values) {
let slot_added = false;
values.days.split(',').forEach(function(day){
day = $.trim(day);
if(['Sunday', 'Monday', 'Tuesday', 'Wednesday',
@ -35,27 +36,75 @@ frappe.ui.form.on('Physician Schedule', {
add_slots(day);
}
});
function add_slots(week_day){
let cur_time = moment(values.from_time, 'HH:mm:ss');
let end_time = moment(values.to_time, 'HH:mm:ss');
function check_overlap_or_add_slot(week_day, cur_time, end_time, add_slots_to_child){
let overlap = false;
while(cur_time < end_time) {
let add_to_child = true;
let to_time = cur_time.clone().add(values.duration, 'minutes');
if(to_time <= end_time) {
if(frm.doc.time_slots){
frm.doc.time_slots.forEach(function(slot) {
if(slot.day == week_day){
let slot_from_moment = moment(slot.from_time, 'HH:mm:ss');
let slot_to_moment = moment(slot.to_time, 'HH:mm:ss');
if(cur_time.isSame(slot_from_moment) || cur_time.isBetween(slot_from_moment, slot_to_moment) ||
to_time.isSame(slot_to_moment) || to_time.isBetween(slot_from_moment, slot_to_moment)){
overlap = true;
if(add_slots_to_child){
frappe.show_alert({
message:__('Time slot skiped, the slot {0} to {1} overlap exisiting slot {2} to {3}',
[cur_time.format('HH:mm:ss'), to_time.format('HH:mm:ss'), slot.from_time, slot.to_time]),
indicator:'orange'
});
add_to_child = false;
}
}
}
});
}
// add a new timeslot
frm.add_child('time_slots', {
from_time: cur_time.format('HH:mm:ss'),
to_time: to_time.format('HH:mm:ss'),
day: week_day
});
if(add_to_child && add_slots_to_child){
frm.add_child('time_slots', {
from_time: cur_time.format('HH:mm:ss'),
to_time: to_time.format('HH:mm:ss'),
day: week_day
});
slot_added = true;
}
}
cur_time = to_time;
}
return overlap;
}
function add_slots(week_day){
let cur_time = moment(values.from_time, 'HH:mm:ss');
let end_time = moment(values.to_time, 'HH:mm:ss');
if(check_overlap_or_add_slot(week_day, cur_time, end_time, false)){
frappe.confirm(__('Schedules for {0} overlaps, do you want to proceed after skiping overlaped slots ?', [week_day]),
function() {
// if Yes
check_overlap_or_add_slot(week_day, cur_time, end_time, true);
},
function() {
// if No
frappe.show_alert({
message:__('Slots for {0} are not added to the schedule', [week_day]),
indicator:'red'
});
}
);
}
else{
check_overlap_or_add_slot(week_day, cur_time, end_time, true);
}
}
frm.refresh_field('time_slots');
frappe.show_alert({
message:__('Time slots added'),
indicator:'green'
});
if(slot_added){
frappe.show_alert({
message:__('Time slots added'),
indicator:'green'
});
}
}
},
});

View File

@ -41,6 +41,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
@ -61,7 +62,7 @@
"label": "Service Unit",
"length": 0,
"no_copy": 0,
"options": "Patient Service Unit",
"options": "Healthcare Service Unit",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -72,6 +73,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
@ -85,7 +87,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-12-27 10:57:42.301295",
"modified": "2018-05-02 03:38:09.935153",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Physician Service Unit Schedule",

View File

@ -0,0 +1,262 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 1,
"creation": "2017-11-17 15:52:48.324157",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "procedure",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Procedure",
"length": 0,
"no_copy": 0,
"options": "Clinical Procedure Template",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "procedure_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Procedure Name",
"length": 0,
"no_copy": 0,
"options": "procedure.template",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Department",
"length": 0,
"no_copy": 0,
"options": "Medical Department",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "physician",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Physician",
"length": 0,
"no_copy": 0,
"options": "Physician",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "comments",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Comments",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "appointment_booked",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Appointment Booked",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-05-01 23:15:54.775612",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Procedure Prescription",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.model.document import Document
class ProcedurePrescription(Document):
pass

View File

@ -17,6 +17,7 @@ def setup_healthcare():
create_lab_test_items()
create_lab_test_template()
create_sensitivity()
add_healthcare_service_unit_tree_root()
def create_medical_departments():
departments = [
@ -260,3 +261,13 @@ def create_sensitivity():
{"doctype": "Sensitivity", "sensitivity": _("Intermediate")}
]
insert_record(records)
def add_healthcare_service_unit_tree_root():
record = [
{
"doctype": "Healthcare Service Unit",
"healthcare_service_unit_name": "All Healthcare Service Unit",
"is_group": 1
}
]
insert_record(record)

View File

@ -527,6 +527,7 @@ erpnext.patches.v10_1.transfer_subscription_to_auto_repeat
erpnext.patches.v10_1.drop_old_subscription_records
erpnext.patches.v11_0.update_brand_in_item_price
erpnext.patches.v11_0.create_default_success_action
erpnext.patches.v11_0.add_healthcare_service_unit_tree_root
erpnext.patches.v10_0.set_qty_in_transactions_based_on_serial_no_input
erpnext.patches.v10_0.show_leaves_of_all_department_members_in_calendar
erpnext.patches.v11_0.rename_field_max_days_allowed

View File

@ -0,0 +1,13 @@
import frappe
from frappe import _
def execute():
""" assign lft and rgt appropriately """
frappe.reload_doc("healthcare", "doctype", "healthcare_service_unit")
if not frappe.db.exists("Healthcare Service Unit", _('All Healthcare Service Unit')):
frappe.get_doc({
'doctype': 'Healthcare Service Unit',
'healthcare_service_unit_name': _('All Healthcare Service Unit'),
'is_group': 1
}).insert(ignore_permissions=True)