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
diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py
index 4e8bb48..f1339a7 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -33,6 +33,11 @@
"type": "page",
"name": "appointment-analytic",
"label": _("Appointment Analytics"),
+ },
+ {
+ "type": "doctype",
+ "name": "Clinical Procedure",
+ "label": _("Clinical Procedure"),
}
]
},
@@ -89,8 +94,8 @@
},
{
"type": "doctype",
- "name": "Patient Service Unit",
- "label": _("Patient Service Unit")
+ "name": "Healthcare Service Unit",
+ "label": _("Healthcare Service Unit")
}
]
},
@@ -157,6 +162,11 @@
"type": "doctype",
"name": "Lab Test Template",
"label": _("Lab Test Template")
+ },
+ {
+ "type": "doctype",
+ "name": "Clinical Procedure Template",
+ "label": _("Clinical Procedure Template"),
}
]
}
diff --git a/erpnext/healthcare/doctype/patient_service_unit/__init__.py b/erpnext/healthcare/doctype/clinical_procedure/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/patient_service_unit/__init__.py
copy to erpnext/healthcare/doctype/clinical_procedure/__init__.py
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
new file mode 100644
index 0000000..9fc5b37
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
@@ -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
+ }
+ };
+});
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
new file mode 100644
index 0000000..c687393
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.json
@@ -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
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
new file mode 100644
index 0000000..6346f1f
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -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()
diff --git a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.js
similarity index 68%
rename from erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js
rename to erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.js
index 320388a..80ef3d5 100644
--- a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js
+++ b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.js
@@ -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'}
]),
diff --git a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
new file mode 100644
index 0000000..09059e1
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
@@ -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
diff --git a/erpnext/healthcare/doctype/patient_service_unit/__init__.py b/erpnext/healthcare/doctype/clinical_procedure_item/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/patient_service_unit/__init__.py
copy to erpnext/healthcare/doctype/clinical_procedure_item/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.json b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
similarity index 62%
copy from erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.json
copy to erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
index 0ca1a53..c0a3247 100644
--- a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.json
+++ b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.json
@@ -2,33 +2,126 @@
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
- "allow_rename": 1,
- "autoname": "field:patient_service_unit_name",
+ "allow_rename": 0,
"beta": 1,
- "creation": "2016-09-21 13:48:14.731437",
+ "creation": "2017-10-05 16:15:10.876952",
"custom": 0,
- "description": "Patinet Service Unit",
"docstatus": 0,
"doctype": "DocType",
- "document_type": "Setup",
+ "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": "patient_service_unit_name",
+ "fieldname": "barcode",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
- "in_global_search": 1,
+ "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": "Service Unit",
+ "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,
@@ -47,53 +140,22 @@
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
- "bold": 1,
+ "bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "parent_patient_service_unit",
+ "fieldname": "uom",
"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": 0,
- "label": "Parent Service Unit",
- "length": 0,
- "no_copy": 0,
- "options": "Patient 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": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_group",
- "fieldtype": "Check",
- "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": "Is Group",
+ "label": "UOM",
"length": 0,
"no_copy": 0,
+ "options": "UOM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -101,7 +163,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -110,11 +172,11 @@
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
- "bold": 1,
+ "bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "overlap_appointments",
- "fieldtype": "Check",
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -122,7 +184,6 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Allow Overlap",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -144,26 +205,26 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "company",
+ "fieldname": "batch_no",
"fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 1,
+ "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": "Company",
+ "label": "Batch",
"length": 0,
- "no_copy": 1,
- "options": "Company",
+ "no_copy": 0,
+ "options": "Batch",
"permlevel": 0,
"precision": "",
- "print_hide": 1,
+ "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
- "report_hide": 1,
+ "report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
@@ -176,93 +237,124 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "lft",
- "fieldtype": "Int",
- "hidden": 1,
+ "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": "lft",
+ "label": "Conversion Factor",
"length": 0,
- "no_copy": 1,
+ "no_copy": 0,
"permlevel": 0,
"precision": "",
- "print_hide": 1,
+ "print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 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
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "rgt",
- "fieldtype": "Int",
- "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": "rgt",
- "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": 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,
- "fieldname": "old_parent",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Old Parent",
- "length": 0,
- "no_copy": 1,
- "options": "Patient Service Unit",
- "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": "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,
@@ -273,86 +365,21 @@
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
- "istable": 0,
+ "istable": 1,
"max_attachments": 0,
- "modified": "2018-03-07 13:25:51.163029",
+ "modified": "2018-03-28 14:34:03.796229",
"modified_by": "Administrator",
"module": "Healthcare",
- "name": "Patient Service Unit",
+ "name": "Clinical Procedure Item",
"name_case": "",
"owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "apply_user_permissions": 1,
- "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,
- "user_permission_doctypes": "[\"Service Unit\"]",
- "write": 0
- },
- {
- "amend": 0,
- "apply_user_permissions": 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,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "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
- }
- ],
+ "permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
- "restrict_to_domain": "Healthcare",
- "search_fields": "patient_service_unit_name",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
- "title_field": "patient_service_unit_name",
"track_changes": 1,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py
new file mode 100644
index 0000000..d59e517
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure_item/clinical_procedure_item.py
@@ -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
diff --git a/erpnext/healthcare/doctype/patient_service_unit/__init__.py b/erpnext/healthcare/doctype/clinical_procedure_template/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/patient_service_unit/__init__.py
copy to erpnext/healthcare/doctype/clinical_procedure_template/__init__.py
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
new file mode 100644
index 0000000..583728d
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js
@@ -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
+ }
+ };
+});
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
new file mode 100644
index 0000000..af430da
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json
@@ -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
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
new file mode 100644
index 0000000..565fe90
--- /dev/null
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
@@ -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
diff --git a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js b/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.js
similarity index 65%
copy from erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js
copy to erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.js
index 320388a..1dde8b5 100644
--- a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.js
@@ -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 Template", 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 Template
+ () => frappe.tests.make('Clinical Procedure Template', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.py b/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py
similarity index 72%
rename from erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.py
rename to erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py
index ceb49fd..62e138b 100644
--- a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.py
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.py
@@ -4,5 +4,5 @@
from __future__ import unicode_literals
import unittest
-class TestPatientServiceUnit(unittest.TestCase):
+class TestClinicalProcedureTemplate(unittest.TestCase):
pass
diff --git a/erpnext/healthcare/doctype/consultation/consultation.js b/erpnext/healthcare/doctype/consultation/consultation.js
index dc4870f..727d175 100644
--- a/erpnext/healthcare/doctype/consultation/consultation.js
+++ b/erpnext/healthcare/doctype/consultation/consultation.js
@@ -35,6 +35,10 @@
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 @@
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("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);
diff --git a/erpnext/healthcare/doctype/consultation/consultation.json b/erpnext/healthcare/doctype/consultation/consultation.json
index c1bd37a..2f6de0c 100644
--- a/erpnext/healthcare/doctype/consultation/consultation.json
+++ b/erpnext/healthcare/doctype/consultation/consultation.json
@@ -880,6 +880,67 @@
"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,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "consultation_comment",
"fieldtype": "Small Text",
"hidden": 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",
diff --git a/erpnext/healthcare/doctype/consultation/consultation.py b/erpnext/healthcare/doctype/consultation/consultation.py
index 472a2f2..b647c2e 100755
--- a/erpnext/healthcare/doctype/consultation/consultation.py
+++ b/erpnext/healthcare/doctype/consultation/consultation.py
@@ -125,5 +125,7 @@
subject +="\nDrug(s) Prescribed. "
if(consultation.test_prescription):
subject += "\nTest(s) Prescribed."
+ if(consultation.procedure_prescription):
+ subject += "\nProcedure(s) Prescribed."
return subject
diff --git a/erpnext/healthcare/doctype/patient_service_unit/__init__.py b/erpnext/healthcare/doctype/healthcare_service_unit/__init__.py
similarity index 100%
rename from erpnext/healthcare/doctype/patient_service_unit/__init__.py
rename to erpnext/healthcare/doctype/healthcare_service_unit/__init__.py
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
new file mode 100644
index 0000000..e966515
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.js
@@ -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);
+ }
+ }
+});
diff --git a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.json b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
similarity index 77%
rename from erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.json
rename to erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
index 0ca1a53..d11ecdc 100644
--- a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.json
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json
@@ -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,
@@ -141,6 +174,39 @@
{
"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,
"bold": 0,
"collapsible": 0,
"columns": 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
}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
new file mode 100644
index 0000000..21b0e6e
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.py
@@ -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
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
new file mode 100644
index 0000000..4eb9475
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
@@ -0,0 +1,3 @@
+frappe.treeview_settings["Healthcare Service Unit"] = {
+ ignore_fields:["parent_healthcare_service_unit"]
+};
diff --git a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js b/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.js
similarity index 67%
copy from erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js
copy to erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.js
index 320388a..a67a411 100644
--- a/erpnext/healthcare/doctype/patient_service_unit/test_patient_service_unit.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.js
@@ -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: Healthcare Service Unit", 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 Healthcare Service Unit
+ () => frappe.tests.make('Healthcare Service Unit', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.py b/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.py
new file mode 100644
index 0000000..bced2fe
--- /dev/null
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.py
@@ -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
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index 41974a6..7d5ed8d 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -26,6 +26,7 @@
return {
filters: {
"is_group": false,
+ "allow_appointments": true
}
};
});
@@ -40,9 +41,16 @@
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 @@
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 @@
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({
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index 1cdf393..b865be8 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -115,6 +115,101 @@
"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,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "appointment_date",
"fieldtype": "Date",
"hidden": 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,
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index 861f7c4..536ab00 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -24,6 +24,8 @@
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 @@
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 @@
@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 @@
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 @@
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 @@
{"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
\ No newline at end of file
+ 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))
diff --git a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.js b/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.js
deleted file mode 100644
index 197b4e5..0000000
--- a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.js
+++ /dev/null
@@ -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]
- ]
- };
-};
diff --git a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.py b/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.py
deleted file mode 100644
index 6c177d8..0000000
--- a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit.py
+++ /dev/null
@@ -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()
diff --git a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit_tree.js b/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit_tree.js
deleted file mode 100644
index 0b03f2d..0000000
--- a/erpnext/healthcare/doctype/patient_service_unit/patient_service_unit_tree.js
+++ /dev/null
@@ -1,3 +0,0 @@
-frappe.treeview_settings["Patient Service Unit"] = {
- ignore_fields:["parent_patient_service_unit"]
-};
diff --git a/erpnext/healthcare/doctype/physician/physician.js b/erpnext/healthcare/doctype/physician/physician.js
index 6ce0199..0b1a077 100755
--- a/erpnext/healthcare/doctype/physician/physician.js
+++ b/erpnext/healthcare/doctype/physician/physician.js
@@ -23,6 +23,7 @@
return {
filters: {
"is_group": false,
+ "allow_appointments": true
}
};
});
diff --git a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js b/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
index 5b0b57f..c1b5581 100644
--- a/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
+++ b/erpnext/healthcare/doctype/physician_schedule/physician_schedule.js
@@ -28,6 +28,7 @@
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 @@
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'
+ });
+ }
}
},
});
diff --git a/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.json b/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.json
index 69fe7b3..7fff2be 100644
--- a/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.json
+++ b/erpnext/healthcare/doctype/physician_service_unit_schedule/physician_service_unit_schedule.json
@@ -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",
diff --git a/erpnext/healthcare/doctype/patient_service_unit/__init__.py b/erpnext/healthcare/doctype/procedure_prescription/__init__.py
similarity index 100%
copy from erpnext/healthcare/doctype/patient_service_unit/__init__.py
copy to erpnext/healthcare/doctype/procedure_prescription/__init__.py
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
new file mode 100644
index 0000000..cbe4200
--- /dev/null
+++ b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.json
@@ -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
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.py b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.py
new file mode 100644
index 0000000..62ea9f1
--- /dev/null
+++ b/erpnext/healthcare/doctype/procedure_prescription/procedure_prescription.py
@@ -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
diff --git a/erpnext/healthcare/setup.py b/erpnext/healthcare/setup.py
index fca1270..f30f42c 100644
--- a/erpnext/healthcare/setup.py
+++ b/erpnext/healthcare/setup.py
@@ -17,6 +17,7 @@
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 @@
{"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)
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index fa2251f..abee28f 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -527,6 +527,7 @@
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
diff --git a/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py b/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py
new file mode 100644
index 0000000..17368bf
--- /dev/null
+++ b/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py
@@ -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)