Healthcare - Patient Appointment - Service unit based scheduling and booking (#13211)
* New Document - Patient Service Unit * Physician - schedule based on patient service unit * Consultation - Remove validation on submit * Consultation - Label changed from Drug Prescription to Medication * Availability check and book appointment based on service unit, appointment invoice creation optimized * patch fixes * Patient Service Unit - field - overlap_appointments * Patient Appointment - Service Unit based scheduling and booking * Patient Appointment - issue fixed #13016 Healthcare Patient Appointment Save Button Issue - remove validation on save and enable save on book appointment * Codacy fixes on PR #13211 * Codacy fixes on PR #13211 * Fee validity test -fixes * Fee Validity - test - fixes
This commit is contained in:
parent
11241044b2
commit
665b48773f
@ -86,6 +86,11 @@ def get_data():
|
|||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Medical Code",
|
"name": "Medical Code",
|
||||||
"label": _("Medical Code"),
|
"label": _("Medical Code"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Patient Service Unit",
|
||||||
|
"label": _("Patient Service Unit")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -767,7 +767,7 @@
|
|||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Drug Prescription",
|
"label": "Medication",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
@ -797,7 +797,7 @@
|
|||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
"label": "Drug Prescription",
|
"label": "Medication",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Drug Prescription",
|
"options": "Drug Prescription",
|
||||||
@ -945,7 +945,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-28 11:25:35.256848",
|
"modified": "2018-02-19 11:35:13.826577",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Healthcare",
|
"module": "Healthcare",
|
||||||
"name": "Consultation",
|
"name": "Consultation",
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
import json
|
import json
|
||||||
@ -19,10 +18,6 @@ class Consultation(Document):
|
|||||||
def after_insert(self):
|
def after_insert(self):
|
||||||
insert_consultation_to_medical_record(self)
|
insert_consultation_to_medical_record(self)
|
||||||
|
|
||||||
def on_submit(self):
|
|
||||||
if not self.diagnosis or not self.symptoms:
|
|
||||||
frappe.throw(_("Diagnosis and Complaints cannot be left blank"))
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
if(self.appointment):
|
if(self.appointment):
|
||||||
frappe.db.set_value("Patient Appointment", self.appointment, "status", "Open")
|
frappe.db.set_value("Patient Appointment", self.appointment, "status", "Open")
|
||||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
from erpnext.healthcare.doctype.patient_appointment.patient_appointment import create_invoice
|
from erpnext.healthcare.doctype.patient_appointment.patient_appointment import invoice_appointment
|
||||||
from frappe.utils.make_random import get_random
|
from frappe.utils.make_random import get_random
|
||||||
from frappe.utils import nowdate, add_days
|
from frappe.utils import nowdate, add_days
|
||||||
# test_records = frappe.get_test_records('Fee Validity')
|
# test_records = frappe.get_test_records('Fee Validity')
|
||||||
@ -14,6 +14,7 @@ class TestFeeValidity(unittest.TestCase):
|
|||||||
def test_fee_validity(self):
|
def test_fee_validity(self):
|
||||||
patient = get_random("Patient")
|
patient = get_random("Patient")
|
||||||
physician = get_random("Physician")
|
physician = get_random("Physician")
|
||||||
|
department = get_random("Medical Department")
|
||||||
|
|
||||||
if not patient:
|
if not patient:
|
||||||
patient = frappe.new_doc("Patient")
|
patient = frappe.new_doc("Patient")
|
||||||
@ -22,33 +23,43 @@ class TestFeeValidity(unittest.TestCase):
|
|||||||
patient.save(ignore_permissions=True)
|
patient.save(ignore_permissions=True)
|
||||||
patient = patient.name
|
patient = patient.name
|
||||||
|
|
||||||
|
if not department:
|
||||||
|
medical_department = frappe.new_doc("Medical Department")
|
||||||
|
medical_department.department = "Test Medical Department"
|
||||||
|
medical_department.save(ignore_permissions=True)
|
||||||
|
department = medical_department.name
|
||||||
|
|
||||||
if not physician:
|
if not physician:
|
||||||
physician = frappe.new_doc("Physician")
|
physician = frappe.new_doc("Physician")
|
||||||
physician.first_name = "Amit Jain"
|
physician.first_name = "Amit Jain"
|
||||||
|
physician.department = department
|
||||||
physician.save(ignore_permissions=True)
|
physician.save(ignore_permissions=True)
|
||||||
physician = physician.name
|
physician = physician.name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
frappe.db.set_value("Healthcare Settings", None, "max_visit", 2)
|
frappe.db.set_value("Healthcare Settings", None, "max_visit", 2)
|
||||||
frappe.db.set_value("Healthcare Settings", None, "valid_days", 7)
|
frappe.db.set_value("Healthcare Settings", None, "valid_days", 7)
|
||||||
|
|
||||||
appointment = create_appointment(patient, physician, nowdate())
|
appointment = create_appointment(patient, physician, nowdate(), department)
|
||||||
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
||||||
self.assertEqual(invoice, None)
|
self.assertEqual(invoice, None)
|
||||||
create_invoice(frappe.defaults.get_global_default("company"), physician, patient, appointment.name, appointment.appointment_date)
|
invoice_appointment(appointment)
|
||||||
appointment = create_appointment(patient, physician, add_days(nowdate(), 4))
|
appointment = create_appointment(patient, physician, add_days(nowdate(), 4), department)
|
||||||
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
||||||
self.assertTrue(invoice)
|
self.assertTrue(invoice)
|
||||||
appointment = create_appointment(patient, physician, add_days(nowdate(), 5))
|
appointment = create_appointment(patient, physician, add_days(nowdate(), 5), department)
|
||||||
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
||||||
self.assertEqual(invoice, None)
|
self.assertEqual(invoice, None)
|
||||||
appointment = create_appointment(patient, physician, add_days(nowdate(), 10))
|
appointment = create_appointment(patient, physician, add_days(nowdate(), 10), department)
|
||||||
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
invoice = frappe.db.get_value("Patient Appointment", appointment.name, "sales_invoice")
|
||||||
self.assertEqual(invoice, None)
|
self.assertEqual(invoice, None)
|
||||||
|
|
||||||
def create_appointment(patient, physician, appointment_date):
|
def create_appointment(patient, physician, appointment_date, department):
|
||||||
appointment = frappe.new_doc("Patient Appointment")
|
appointment = frappe.new_doc("Patient Appointment")
|
||||||
appointment.patient = patient
|
appointment.patient = patient
|
||||||
appointment.physician = physician
|
appointment.physician = physician
|
||||||
|
appointment.department = department
|
||||||
appointment.appointment_date = appointment_date
|
appointment.appointment_date = appointment_date
|
||||||
appointment.save(ignore_permissions=True)
|
appointment.save(ignore_permissions=True)
|
||||||
return appointment
|
return appointment
|
||||||
|
@ -15,6 +15,20 @@ frappe.ui.form.on('Patient Appointment', {
|
|||||||
filters: {"disabled": 0}
|
filters: {"disabled": 0}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
frm.set_query("physician", function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'department': frm.doc.department
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
frm.set_query("service_unit", function(){
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"is_group": false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
if(frm.doc.patient){
|
if(frm.doc.patient){
|
||||||
frm.add_custom_button(__('Medical Record'), function() {
|
frm.add_custom_button(__('Medical Record'), function() {
|
||||||
frappe.route_options = {"patient": frm.doc.patient};
|
frappe.route_options = {"patient": frm.doc.patient};
|
||||||
@ -83,11 +97,10 @@ frappe.ui.form.on('Patient Appointment', {
|
|||||||
date: appointment_date
|
date: appointment_date
|
||||||
},
|
},
|
||||||
callback: (r) => {
|
callback: (r) => {
|
||||||
// console.log(r);
|
|
||||||
var data = r.message;
|
var data = r.message;
|
||||||
if(data.available_slots.length > 0) {
|
if(data.slot_details.length > 0){
|
||||||
show_availability(data);
|
show_availability(data);
|
||||||
} else {
|
}else{
|
||||||
show_empty_state();
|
show_empty_state();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,48 +121,71 @@ frappe.ui.form.on('Patient Appointment', {
|
|||||||
primary_action_label: __("Book"),
|
primary_action_label: __("Book"),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
// book slot
|
// book slot
|
||||||
frm.set_value('appointment_time', selected_slot);
|
var btn_selected = $wrapper.find('button.btn-selected-slot');
|
||||||
frm.set_value('duration', data.time_per_appointment);
|
frm.set_value('appointment_time', btn_selected.attr('data-name'));
|
||||||
|
frm.set_value('service_unit', btn_selected.attr('data-service-unit') || '');
|
||||||
|
frm.set_value('duration', btn_selected.attr('data-duration'));
|
||||||
d.hide();
|
d.hide();
|
||||||
frm.save();
|
frm.save();
|
||||||
|
frm.enable_save();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var $wrapper = d.fields_dict.available_slots.$wrapper;
|
var $wrapper = d.fields_dict.available_slots.$wrapper;
|
||||||
var selected_slot = null;
|
|
||||||
|
|
||||||
// disable dialog action initially
|
// disable dialog action initially
|
||||||
d.get_primary_btn().attr('disabled', true);
|
d.get_primary_btn().attr('disabled', true);
|
||||||
|
|
||||||
// make buttons for each slot
|
var slot_details = data.slot_details;
|
||||||
var slot_html = data.available_slots.map(slot => {
|
var slot_html = "";
|
||||||
return `<button class="btn btn-default"
|
$.each(slot_details, function(i, slot_detail){
|
||||||
data-name=${slot.from_time}
|
slot_html = slot_html + `<label>${slot_detail['slot_name']}</label>`;
|
||||||
style="margin: 0 10px 10px 0; width: 72px">
|
slot_html = slot_html + `<br/>` + slot_detail['avail_slot'].map(slot => {
|
||||||
${slot.from_time.substring(0, slot.from_time.length - 3)}
|
let disabled = '';
|
||||||
</button>`;
|
let start_str = slot.from_time;
|
||||||
}).join("");
|
let start_time = moment(slot.from_time, 'HH:mm:ss');
|
||||||
|
let to_time = moment(slot.to_time, 'HH:mm:ss');
|
||||||
|
let interval = (to_time - start_time)/60000 | 0;
|
||||||
|
// iterate in all booked appointments, update the start time and duration
|
||||||
|
slot_detail['appointments'].forEach(function(booked) {
|
||||||
|
let booked_moment = moment(booked.appointment_time, 'HH:mm:ss');
|
||||||
|
if(booked_moment.isSame(start_time) || booked_moment.isBetween(start_time, to_time)){
|
||||||
|
if(booked.duration == 0){
|
||||||
|
disabled = 'disabled="disabled"';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
start_time = booked_moment;
|
||||||
|
let end_time = booked_moment.add(booked.duration, 'minutes');
|
||||||
|
if(end_time.isSameOrAfter(to_time)){
|
||||||
|
disabled = 'disabled="disabled"';
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
start_str = end_time.format('HH:mm:ss');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return `<button class="btn btn-default"
|
||||||
|
data-name=${start_str}
|
||||||
|
data-duration=${interval}
|
||||||
|
data-service-unit="${slot_detail['service_unit'] || ''}"
|
||||||
|
style="margin: 0 10px 10px 0; width: 72px;" ${disabled}>
|
||||||
|
${start_str.substring(0, start_str.length - 3)}
|
||||||
|
</button>`;
|
||||||
|
}).join("");
|
||||||
|
slot_html = slot_html + `<br/>`;
|
||||||
|
});
|
||||||
|
|
||||||
$wrapper
|
$wrapper
|
||||||
.css('margin-bottom', 0)
|
.css('margin-bottom', 0)
|
||||||
.addClass('text-center')
|
.addClass('text-center')
|
||||||
.html(slot_html);
|
.html(slot_html);
|
||||||
|
|
||||||
// disable buttons for which appointments are booked
|
|
||||||
data.appointments.map(slot => {
|
|
||||||
if(slot.status == "Scheduled" || slot.status == "Open" || slot.status == "Closed"){
|
|
||||||
$wrapper
|
|
||||||
.find(`button[data-name="${slot.appointment_time}"]`)
|
|
||||||
.attr('disabled', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// blue button when clicked
|
// blue button when clicked
|
||||||
$wrapper.on('click', 'button', function() {
|
$wrapper.on('click', 'button', function() {
|
||||||
var $btn = $(this);
|
var $btn = $(this);
|
||||||
$wrapper.find('button').removeClass('btn-primary');
|
$wrapper.find('button').removeClass('btn-primary');
|
||||||
|
$wrapper.find('button').removeClass('btn-selected-slot');
|
||||||
$btn.addClass('btn-primary');
|
$btn.addClass('btn-primary');
|
||||||
selected_slot = $btn.attr('data-name');
|
$btn.addClass('btn-selected-slot');
|
||||||
|
|
||||||
// enable dialog action
|
// enable dialog action
|
||||||
d.get_primary_btn().attr('disabled', null);
|
d.get_primary_btn().attr('disabled', null);
|
||||||
});
|
});
|
||||||
@ -209,12 +245,9 @@ var btn_update_status = function(frm, status){
|
|||||||
};
|
};
|
||||||
|
|
||||||
var btn_invoice_consultation = function(frm){
|
var btn_invoice_consultation = function(frm){
|
||||||
var doc = frm.doc;
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method:
|
doc: frm.doc,
|
||||||
"erpnext.healthcare.doctype.patient_appointment.patient_appointment.create_invoice",
|
method:"create_invoice",
|
||||||
args: {company: doc.company, physician:doc.physician, patient: doc.patient,
|
|
||||||
appointment_id: doc.name, appointment_date:doc.appointment_date },
|
|
||||||
callback: function(data){
|
callback: function(data){
|
||||||
if(!data.exc){
|
if(!data.exc){
|
||||||
if(data.message){
|
if(data.message){
|
||||||
|
@ -42,6 +42,39 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 1,
|
"set_only_once": 1,
|
||||||
|
"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": 1,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"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": 1,
|
||||||
|
"search_index": 1,
|
||||||
|
"set_only_once": 1,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -73,6 +106,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 1,
|
"set_only_once": 1,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -103,6 +137,71 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 1,
|
"set_only_once": 1,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "appointment_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,
|
||||||
|
"depends_on": "eval:!doc.__islocal",
|
||||||
|
"description": "In Minutes",
|
||||||
|
"fieldname": "duration",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"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": "Duration",
|
||||||
|
"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
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -134,6 +233,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -151,8 +251,42 @@
|
|||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
|
"label": "",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
|
"options": "",
|
||||||
|
"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": "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": "Patient Service Unit",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -162,7 +296,8 @@
|
|||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 1,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -195,6 +330,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -226,6 +362,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -257,6 +394,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -271,7 +409,7 @@
|
|||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 1,
|
||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
@ -289,6 +427,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -319,7 +458,8 @@
|
|||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 1,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -349,68 +489,8 @@
|
|||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 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": "appointment_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": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 1,
|
"set_only_once": 1,
|
||||||
"unique": 0
|
"translatable": 0,
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "In Minutes",
|
|
||||||
"fieldname": "duration",
|
|
||||||
"fieldtype": "Int",
|
|
||||||
"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": "Duration",
|
|
||||||
"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
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -441,6 +521,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -470,37 +551,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"translatable": 0,
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "department",
|
|
||||||
"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": "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": 1,
|
|
||||||
"set_only_once": 1,
|
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -532,6 +583,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -563,6 +615,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -593,6 +646,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -623,6 +677,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -654,6 +709,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 1,
|
"set_only_once": 1,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -685,6 +741,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -698,7 +755,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-12-28 11:26:20.262978",
|
"modified": "2018-02-26 12:44:33.756124",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Healthcare",
|
"module": "Healthcare",
|
||||||
"name": "Patient Appointment",
|
"name": "Patient Appointment",
|
||||||
@ -744,6 +801,26 @@
|
|||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
"submit": 0,
|
||||||
"write": 1
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "Nursing User",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"quick_entry": 0,
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
import json
|
import json
|
||||||
from frappe.utils import getdate, cint
|
from frappe.utils import getdate
|
||||||
from frappe import _
|
from frappe import _
|
||||||
import datetime
|
import datetime
|
||||||
from frappe.core.doctype.sms_settings.sms_settings import send_sms
|
from frappe.core.doctype.sms_settings.sms_settings import send_sms
|
||||||
@ -40,13 +40,8 @@ class PatientAppointment(Document):
|
|||||||
frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
|
frappe.msgprint(_("{0} has fee validity till {1}").format(appointment.patient, fee_validity.valid_till))
|
||||||
confirm_sms(self)
|
confirm_sms(self)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def create_invoice(self):
|
||||||
# duration is the only changeable field in the document
|
return invoice_appointment(self)
|
||||||
if not self.is_new():
|
|
||||||
self.db_set('duration', cint(self.duration))
|
|
||||||
else:
|
|
||||||
super(PatientAppointment, self).save(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def appointment_cancel(appointment_id):
|
def appointment_cancel(appointment_id):
|
||||||
appointment = frappe.get_doc("Patient Appointment", appointment_id)
|
appointment = frappe.get_doc("Patient Appointment", appointment_id)
|
||||||
@ -79,9 +74,9 @@ def get_availability_data(date, physician):
|
|||||||
weekday = date.strftime("%A")
|
weekday = date.strftime("%A")
|
||||||
|
|
||||||
available_slots = []
|
available_slots = []
|
||||||
physician_schedule_name = None
|
slot_details = []
|
||||||
physician_schedule = None
|
physician_schedule = None
|
||||||
time_per_appointment = None
|
|
||||||
employee = None
|
employee = None
|
||||||
|
|
||||||
physician_obj = frappe.get_doc("Physician", physician)
|
physician_obj = frappe.get_doc("Physician", physician)
|
||||||
@ -112,43 +107,56 @@ def get_availability_data(date, physician):
|
|||||||
frappe.throw(_("Dr {0} on Leave on {1}").format(physician, date))
|
frappe.throw(_("Dr {0} on Leave on {1}").format(physician, date))
|
||||||
|
|
||||||
# get physicians schedule
|
# get physicians schedule
|
||||||
physician_schedule_name = frappe.db.get_value("Physician", physician, "physician_schedule")
|
if physician_obj.physician_schedules:
|
||||||
if physician_schedule_name:
|
for schedule in physician_obj.physician_schedules:
|
||||||
physician_schedule = frappe.get_doc("Physician Schedule", physician_schedule_name)
|
if schedule.schedule:
|
||||||
time_per_appointment = frappe.db.get_value("Physician", physician, "time_per_appointment")
|
physician_schedule = frappe.get_doc("Physician Schedule", schedule.schedule)
|
||||||
|
else:
|
||||||
|
frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician)))
|
||||||
|
|
||||||
|
if physician_schedule:
|
||||||
|
available_slots = []
|
||||||
|
for t in physician_schedule.time_slots:
|
||||||
|
if weekday == t.day:
|
||||||
|
available_slots.append(t)
|
||||||
|
|
||||||
|
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')
|
||||||
|
if allow_overlap:
|
||||||
|
# fetch all appointments to physician by service unit
|
||||||
|
appointments = frappe.get_all(
|
||||||
|
"Patient Appointment",
|
||||||
|
filters={"physician": physician, "service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]},
|
||||||
|
fields=["name", "appointment_time", "duration", "status"])
|
||||||
|
else:
|
||||||
|
# fetch all appointments to service unit
|
||||||
|
appointments = frappe.get_all(
|
||||||
|
"Patient Appointment",
|
||||||
|
filters={"service_unit": schedule.service_unit, "appointment_date": date, "status": ["not in",["Cancelled"]]},
|
||||||
|
fields=["name", "appointment_time", "duration", "status"])
|
||||||
|
else:
|
||||||
|
slot_name = schedule.schedule
|
||||||
|
# fetch all appointments to physician without service unit
|
||||||
|
appointments = frappe.get_all(
|
||||||
|
"Patient Appointment",
|
||||||
|
filters={"physician": physician, "service_unit": '', "appointment_date": date, "status": ["not in",["Cancelled"]]},
|
||||||
|
fields=["name", "appointment_time", "duration", "status"])
|
||||||
|
|
||||||
|
slot_details.append({"slot_name":slot_name, "service_unit":schedule.service_unit,
|
||||||
|
"avail_slot":available_slots, 'appointments': appointments})
|
||||||
|
|
||||||
else:
|
else:
|
||||||
frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician)))
|
frappe.throw(_("Dr {0} does not have a Physician Schedule. Add it in Physician master".format(physician)))
|
||||||
|
|
||||||
if physician_schedule:
|
if not available_slots and not slot_details:
|
||||||
for t in physician_schedule.time_slots:
|
|
||||||
if weekday == t.day:
|
|
||||||
available_slots.append(t)
|
|
||||||
|
|
||||||
# `time_per_appointment` should never be None since validation in `Patient` is supposed to prevent
|
|
||||||
# that. However, it isn't impossible so we'll prepare for that.
|
|
||||||
if not time_per_appointment:
|
|
||||||
frappe.throw(_('"Time Per Appointment" hasn"t been set for Dr {0}. Add it in Physician master.').format(physician))
|
|
||||||
|
|
||||||
# if physician not available return
|
|
||||||
if not available_slots:
|
|
||||||
# TODO: return available slots in nearby dates
|
# TODO: return available slots in nearby dates
|
||||||
frappe.throw(_("Physician not available on {0}").format(weekday))
|
frappe.throw(_("Physician not available on {0}").format(weekday))
|
||||||
|
|
||||||
# if physician on leave return
|
|
||||||
|
|
||||||
# if holiday return
|
|
||||||
# if is_holiday(weekday):
|
|
||||||
|
|
||||||
# get appointments on that day for physician
|
|
||||||
appointments = frappe.get_all(
|
|
||||||
"Patient Appointment",
|
|
||||||
filters={"physician": physician, "appointment_date": date},
|
|
||||||
fields=["name", "appointment_time", "duration", "status"])
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"available_slots": available_slots,
|
"slot_details": slot_details
|
||||||
"appointments": appointments,
|
|
||||||
"time_per_appointment": time_per_appointment
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -182,25 +190,25 @@ def confirm_sms(doc):
|
|||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_invoice(company, physician, patient, appointment_id, appointment_date):
|
def invoice_appointment(appointment_doc):
|
||||||
if not appointment_id:
|
if not appointment_doc.name:
|
||||||
return False
|
return False
|
||||||
sales_invoice = frappe.new_doc("Sales Invoice")
|
sales_invoice = frappe.new_doc("Sales Invoice")
|
||||||
sales_invoice.customer = frappe.get_value("Patient", patient, "customer")
|
sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
|
||||||
sales_invoice.appointment = appointment_id
|
sales_invoice.appointment = appointment_doc.name
|
||||||
sales_invoice.due_date = getdate()
|
sales_invoice.due_date = getdate()
|
||||||
sales_invoice.is_pos = '0'
|
sales_invoice.is_pos = '0'
|
||||||
sales_invoice.debit_to = get_receivable_account(company)
|
sales_invoice.debit_to = get_receivable_account(appointment_doc.company)
|
||||||
|
|
||||||
fee_validity = get_fee_validity(physician, patient, appointment_date)
|
fee_validity = get_fee_validity(appointment_doc.physician, appointment_doc.patient, appointment_doc.appointment_date)
|
||||||
create_invoice_items(appointment_id, physician, company, sales_invoice)
|
create_invoice_items(appointment_doc.physician, appointment_doc.company, sales_invoice)
|
||||||
|
|
||||||
sales_invoice.save(ignore_permissions=True)
|
sales_invoice.save(ignore_permissions=True)
|
||||||
frappe.db.sql("""update `tabPatient Appointment` set sales_invoice=%s where name=%s""", (sales_invoice.name, appointment_id))
|
frappe.db.sql("""update `tabPatient Appointment` set sales_invoice=%s where name=%s""", (sales_invoice.name, appointment_doc.name))
|
||||||
frappe.db.set_value("Fee Validity", fee_validity.name, "ref_invoice", sales_invoice.name)
|
frappe.db.set_value("Fee Validity", fee_validity.name, "ref_invoice", sales_invoice.name)
|
||||||
consultation = frappe.db.exists({
|
consultation = frappe.db.exists({
|
||||||
"doctype": "Consultation",
|
"doctype": "Consultation",
|
||||||
"appointment": appointment_id})
|
"appointment": appointment_doc.name})
|
||||||
if consultation:
|
if consultation:
|
||||||
frappe.db.set_value("Consultation", consultation[0][0], "invoice", sales_invoice.name)
|
frappe.db.set_value("Consultation", consultation[0][0], "invoice", sales_invoice.name)
|
||||||
return sales_invoice.name
|
return sales_invoice.name
|
||||||
@ -247,7 +255,7 @@ def create_fee_validity(physician, patient, date):
|
|||||||
return fee_validity
|
return fee_validity
|
||||||
|
|
||||||
|
|
||||||
def create_invoice_items(appointment_id, physician, company, invoice):
|
def create_invoice_items(physician, company, invoice):
|
||||||
item_line = invoice.append("items")
|
item_line = invoice.append("items")
|
||||||
item_line.item_name = "Consulting Charges"
|
item_line.item_name = "Consulting Charges"
|
||||||
item_line.description = "Consulting Charges: " + physician
|
item_line.description = "Consulting Charges: " + physician
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
// 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]
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,358 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:patient_service_unit_name",
|
||||||
|
"beta": 1,
|
||||||
|
"creation": "2016-09-21 13:48:14.731437",
|
||||||
|
"custom": 0,
|
||||||
|
"description": "Patinet Service Unit",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "Setup",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "patient_service_unit_name",
|
||||||
|
"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": "Service Unit",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 1,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "parent_patient_service_unit",
|
||||||
|
"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",
|
||||||
|
"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,
|
||||||
|
"fieldname": "overlap_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 Overlap",
|
||||||
|
"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": "company",
|
||||||
|
"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": "Company",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Company",
|
||||||
|
"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": "lft",
|
||||||
|
"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": "lft",
|
||||||
|
"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": "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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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-03-07 13:25:51.163029",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Healthcare",
|
||||||
|
"name": "Patient Service Unit",
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
# -*- 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()
|
@ -0,0 +1,3 @@
|
|||||||
|
frappe.treeview_settings["Patient Service Unit"] = {
|
||||||
|
ignore_fields:["parent_patient_service_unit"]
|
||||||
|
};
|
@ -0,0 +1,23 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
|
// and remove above this line
|
||||||
|
|
||||||
|
QUnit.test("test: Patient 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', [
|
||||||
|
// values to be set
|
||||||
|
{key: 'value'}
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,8 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2017, earthians and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestPatientServiceUnit(unittest.TestCase):
|
||||||
|
pass
|
@ -19,6 +19,13 @@ frappe.ui.form.on('Physician', {
|
|||||||
if(!frm.is_new()) {
|
if(!frm.is_new()) {
|
||||||
frappe.contacts.render_address_and_contact(frm);
|
frappe.contacts.render_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
|
frm.set_query("service_unit", "physician_schedules", function(){
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"is_group": false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -435,45 +435,14 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 1,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "physician_schedule",
|
|
||||||
"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": "Physician Schedule",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Physician Schedule",
|
|
||||||
"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_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "column_break_17",
|
"fieldname": "physician_schedules",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Table",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
@ -481,39 +450,10 @@
|
|||||||
"in_global_search": 0,
|
"in_global_search": 0,
|
||||||
"in_list_view": 0,
|
"in_list_view": 0,
|
||||||
"in_standard_filter": 0,
|
"in_standard_filter": 0,
|
||||||
|
"label": "Physician Schedules",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"options": "Physician Service Unit Schedule",
|
||||||
"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,
|
|
||||||
"description": "In minutes",
|
|
||||||
"fieldname": "time_per_appointment",
|
|
||||||
"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": "Time per Appointment",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": "",
|
"precision": "",
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
@ -811,7 +751,7 @@
|
|||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-01-19 15:25:43.166877",
|
"modified": "2018-01-19 15:25:43.166877",
|
||||||
"modified_by": "jams@hcf.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Healthcare",
|
"module": "Healthcare",
|
||||||
"name": "Physician",
|
"name": "Physician",
|
||||||
"name_case": "",
|
"name_case": "",
|
||||||
|
@ -20,7 +20,6 @@ class Physician(Document):
|
|||||||
[cstr(self.get(f)).strip() for f in ["first_name","middle_name","last_name"]]))
|
[cstr(self.get(f)).strip() for f in ["first_name","middle_name","last_name"]]))
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_schedule_and_time()
|
|
||||||
validate_party_accounts(self)
|
validate_party_accounts(self)
|
||||||
|
|
||||||
if self.user_id:
|
if self.user_id:
|
||||||
@ -37,15 +36,6 @@ class Physician(Document):
|
|||||||
frappe.permissions.remove_user_permission(
|
frappe.permissions.remove_user_permission(
|
||||||
"Physician", self.name, existing_user_id)
|
"Physician", self.name, existing_user_id)
|
||||||
|
|
||||||
def validate_schedule_and_time(self):
|
|
||||||
if (self.physician_schedule or self.time_per_appointment) and \
|
|
||||||
not (self.physician_schedule and self.time_per_appointment):
|
|
||||||
frappe.msgprint(
|
|
||||||
_('Both "Physician Schedule" and Time Per Appointment" must be set for Dr {0}').format(
|
|
||||||
self.first_name),
|
|
||||||
title='Error', raise_exception=1, indicator='red'
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
if self.user_id:
|
if self.user_id:
|
||||||
frappe.permissions.add_user_permission("Physician", self.name, self.user_id)
|
frappe.permissions.add_user_permission("Physician", self.name, self.user_id)
|
||||||
|
@ -12,23 +12,6 @@ class TestPhysician(unittest.TestCase):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.delete_doc_if_exists('Physician', '_Testdoctor2', force=1)
|
frappe.delete_doc_if_exists('Physician', '_Testdoctor2', force=1)
|
||||||
|
|
||||||
def test_schedule_and_time(self):
|
|
||||||
physician = frappe.new_doc('Physician')
|
|
||||||
physician.first_name = '_Testdoctor2'
|
|
||||||
physician.physician_schedule = '_Testdoctor2 Schedule'
|
|
||||||
|
|
||||||
self.assertRaises(frappe.ValidationError, physician.insert)
|
|
||||||
|
|
||||||
physician.physician_schedule = ''
|
|
||||||
physician.time_per_appointment = 15
|
|
||||||
|
|
||||||
self.assertRaises(frappe.ValidationError, physician.insert)
|
|
||||||
|
|
||||||
physician.physician_schedule = '_Testdoctor2 Schedule'
|
|
||||||
physician.time_per_appointment = 15
|
|
||||||
|
|
||||||
physician.insert()
|
|
||||||
|
|
||||||
def test_new_physician_without_schedule(self):
|
def test_new_physician_without_schedule(self):
|
||||||
physician = frappe.new_doc('Physician')
|
physician = frappe.new_doc('Physician')
|
||||||
physician.first_name = '_Testdoctor2'
|
physician.first_name = '_Testdoctor2'
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"beta": 1,
|
||||||
|
"creation": "2017-11-16 12:19:17.163786",
|
||||||
|
"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": "schedule",
|
||||||
|
"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": "Schedule",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Physician Schedule",
|
||||||
|
"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,
|
||||||
|
"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": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "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,
|
||||||
|
"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": "2017-12-27 10:57:42.301295",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Healthcare",
|
||||||
|
"name": "Physician Service Unit Schedule",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
@ -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 PhysicianServiceUnitSchedule(Document):
|
||||||
|
pass
|
@ -504,6 +504,7 @@ execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=
|
|||||||
erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group
|
erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group
|
||||||
erpnext.patches.v10_0.add_default_cash_flow_mappers
|
erpnext.patches.v10_0.add_default_cash_flow_mappers
|
||||||
erpnext.patches.v11_0.make_quality_inspection_template
|
erpnext.patches.v11_0.make_quality_inspection_template
|
||||||
|
erpnext.patches.v10_0.remove_and_copy_fields_in_physician
|
||||||
erpnext.patches.v10_0.update_status_for_multiple_source_in_po
|
erpnext.patches.v10_0.update_status_for_multiple_source_in_po
|
||||||
erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry
|
erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry
|
||||||
erpnext.patches.v10_0.update_territory_and_customer_group
|
erpnext.patches.v10_0.update_territory_and_customer_group
|
||||||
|
12
erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
Normal file
12
erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
if frappe.db.exists("DocType", "Physician"):
|
||||||
|
frappe.reload_doc("healthcare", "doctype", "physician")
|
||||||
|
frappe.reload_doc("healthcare", "doctype", "physician_service_unit_schedule")
|
||||||
|
if frappe.db.has_column('Physician', 'physician_schedule'):
|
||||||
|
for doc in frappe.get_all('Physician'):
|
||||||
|
_doc = frappe.get_doc('Physician', doc.name)
|
||||||
|
if _doc.physician_schedule:
|
||||||
|
_doc.append('physician_schedules', {'schedule': _doc.physician_schedule})
|
||||||
|
_doc.save()
|
Loading…
x
Reference in New Issue
Block a user