feat(healthcare): Added Treatment Plan Template feature (#26557)
* feat: Added doctypes for treatment plan template * feat: Added child doctype * feat: Added validations for patient age * chore: Clean up treatment plan template * fix: Limit plan items to templates * Added multiselectdialogbox for treatment plan template * Add template name as autoname * Clean up code * Cleanup lint issues * Clean up code * Added tests for tpt filters * Added test records * Fix order of fields * Added tests for care plan template * Added age property for patient * Clean up code * Clean up list view * Clean up code * Fix lint issues * Clean up test records * Code cleanup no-docs * chore: Code cleanup * chore: Use ORM instead of raw sql * fix: Make treatment plan item fields mandatory * fix: Added healthcare roles in permissions rules * fix: Added filters for symptoms, diagnosis * fix: Show applicable treatment plans button only if patient is present * fix: Fix key error issues * fix: Fix issues with filters in plan templates * chore: Fix age filters * refactor: appending treatment plan items * fix: treatment plan test Co-authored-by: Jannat Patel <31363128+pateljannat@users.noreply.github.com> Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
This commit is contained in:
parent
16eed07a0f
commit
f1b77360ee
@ -56,6 +56,7 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_in_quick_entry": 1,
|
||||
"fieldname": "dosage_form",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
@ -109,7 +110,7 @@
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-09-30 23:32:09.495288",
|
||||
"modified": "2021-06-11 11:53:06.343704",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Drug Prescription",
|
||||
|
@ -102,12 +102,19 @@ class Patient(Document):
|
||||
|
||||
return name
|
||||
|
||||
@property
|
||||
def age(self):
|
||||
if not self.dob:
|
||||
return
|
||||
dob = getdate(self.dob)
|
||||
age = dateutil.relativedelta.relativedelta(getdate(), dob)
|
||||
return age
|
||||
|
||||
def get_age(self):
|
||||
age_str = ''
|
||||
if self.dob:
|
||||
dob = getdate(self.dob)
|
||||
age = dateutil.relativedelta.relativedelta(getdate(), dob)
|
||||
age_str = str(age.years) + ' ' + _("Years(s)") + ' ' + str(age.months) + ' ' + _("Month(s)") + ' ' + str(age.days) + ' ' + _("Day(s)")
|
||||
age = self.age
|
||||
if not age:
|
||||
return
|
||||
age_str = str(age.years) + ' ' + _("Years(s)") + ' ' + str(age.months) + ' ' + _("Month(s)") + ' ' + str(age.days) + ' ' + _("Day(s)")
|
||||
return age_str
|
||||
|
||||
@frappe.whitelist()
|
||||
|
@ -185,7 +185,42 @@ frappe.ui.form.on('Patient Encounter', {
|
||||
};
|
||||
frm.set_value(values);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get_applicable_treatment_plans: function(frm) {
|
||||
frappe.call({
|
||||
method: 'get_applicable_treatment_plans',
|
||||
doc: frm.doc,
|
||||
args: {'encounter': frm.doc},
|
||||
freeze: true,
|
||||
freeze_message: __('Fetching Treatment Plans'),
|
||||
callback: function() {
|
||||
new frappe.ui.form.MultiSelectDialog({
|
||||
doctype: "Treatment Plan Template",
|
||||
target: this.cur_frm,
|
||||
setters: {
|
||||
medical_department: "",
|
||||
},
|
||||
action(selections) {
|
||||
frappe.call({
|
||||
method: 'set_treatment_plans',
|
||||
doc: frm.doc,
|
||||
args: selections,
|
||||
}).then(() => {
|
||||
frm.refresh_field('drug_prescription');
|
||||
frm.refresh_field('procedure_prescription');
|
||||
frm.refresh_field('lab_test_prescription');
|
||||
frm.refresh_field('therapies');
|
||||
});
|
||||
cur_dialog.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var schedule_inpatient = function(frm) {
|
||||
|
@ -31,6 +31,7 @@
|
||||
"sb_symptoms",
|
||||
"symptoms",
|
||||
"symptoms_in_print",
|
||||
"get_applicable_treatment_plans",
|
||||
"physical_examination",
|
||||
"diagnosis",
|
||||
"diagnosis_in_print",
|
||||
@ -324,11 +325,17 @@
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.patient",
|
||||
"fieldname": "get_applicable_treatment_plans",
|
||||
"fieldtype": "Button",
|
||||
"label": "Get Applicable Treatment Plans"
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-11-30 10:39:00.783119",
|
||||
"modified": "2021-07-27 11:39:12.347704",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Patient Encounter",
|
||||
|
@ -10,6 +10,7 @@ from frappe.utils import cstr, getdate, add_days
|
||||
from frappe import _
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
|
||||
|
||||
class PatientEncounter(Document):
|
||||
def validate(self):
|
||||
self.set_title()
|
||||
@ -33,6 +34,85 @@ class PatientEncounter(Document):
|
||||
self.title = _('{0} with {1}').format(self.patient_name or self.patient,
|
||||
self.practitioner_name or self.practitioner)[:100]
|
||||
|
||||
@frappe.whitelist()
|
||||
@staticmethod
|
||||
def get_applicable_treatment_plans(encounter):
|
||||
patient = frappe.get_doc('Patient', encounter['patient'])
|
||||
|
||||
plan_filters = {}
|
||||
plan_filters['name'] = ['in', []]
|
||||
|
||||
age = patient.age
|
||||
if age:
|
||||
plan_filters['patient_age_from'] = ['<=', age.years]
|
||||
plan_filters['patient_age_to'] = ['>=', age.years]
|
||||
|
||||
gender = patient.sex
|
||||
if gender:
|
||||
plan_filters['gender'] = ['in', [gender, None]]
|
||||
|
||||
diagnosis = encounter.get('diagnosis')
|
||||
if diagnosis:
|
||||
diagnosis = [_diagnosis['diagnosis'] for _diagnosis in encounter['diagnosis']]
|
||||
filters = [
|
||||
['diagnosis', 'in', diagnosis],
|
||||
['parenttype', '=', 'Treatment Plan Template'],
|
||||
]
|
||||
diagnosis = frappe.get_list('Patient Encounter Diagnosis', filters=filters, fields='*')
|
||||
plan_names = [_diagnosis['parent'] for _diagnosis in diagnosis]
|
||||
plan_filters['name'][1].extend(plan_names)
|
||||
|
||||
symptoms = encounter.get('symptoms')
|
||||
if symptoms:
|
||||
symptoms = [symptom['complaint'] for symptom in encounter['symptoms']]
|
||||
filters = [
|
||||
['complaint', 'in', symptoms],
|
||||
['parenttype', '=', 'Treatment Plan Template'],
|
||||
]
|
||||
symptoms = frappe.get_list('Patient Encounter Symptom', filters=filters, fields='*')
|
||||
plan_names = [symptom['parent'] for symptom in symptoms]
|
||||
plan_filters['name'][1].extend(plan_names)
|
||||
|
||||
if not plan_filters['name'][1]:
|
||||
plan_filters.pop('name')
|
||||
|
||||
plans = frappe.get_list('Treatment Plan Template', fields='*', filters=plan_filters)
|
||||
|
||||
return plans
|
||||
|
||||
@frappe.whitelist()
|
||||
def set_treatment_plans(self, treatment_plans=None):
|
||||
for treatment_plan in treatment_plans:
|
||||
self.set_treatment_plan(treatment_plan)
|
||||
|
||||
def set_treatment_plan(self, plan):
|
||||
plan_items = frappe.get_list('Treatment Plan Template Item', filters={'parent': plan}, fields='*')
|
||||
for plan_item in plan_items:
|
||||
self.set_treatment_plan_item(plan_item)
|
||||
|
||||
drugs = frappe.get_list('Drug Prescription', filters={'parent': plan}, fields='*')
|
||||
for drug in drugs:
|
||||
self.append('drug_prescription', drug)
|
||||
|
||||
self.save()
|
||||
|
||||
def set_treatment_plan_item(self, plan_item):
|
||||
if plan_item.type == 'Clinical Procedure Template':
|
||||
self.append('procedure_prescription', {
|
||||
'procedure': plan_item.template
|
||||
})
|
||||
|
||||
if plan_item.type == 'Lab Test Template':
|
||||
self.append('lab_test_prescription', {
|
||||
'lab_test_code': plan_item.template
|
||||
})
|
||||
|
||||
if plan_item.type == 'Therapy Type':
|
||||
self.append('therapies', {
|
||||
'therapy_type': plan_item.template
|
||||
})
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_ip_medication_order(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
|
@ -4,5 +4,82 @@
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from erpnext.healthcare.doctype.patient_encounter.patient_encounter import PatientEncounter
|
||||
|
||||
|
||||
class TestPatientEncounter(unittest.TestCase):
|
||||
pass
|
||||
def setUp(self):
|
||||
try:
|
||||
gender_m = frappe.get_doc({
|
||||
'doctype': 'Gender',
|
||||
'gender': 'MALE'
|
||||
}).insert()
|
||||
gender_f = frappe.get_doc({
|
||||
'doctype': 'Gender',
|
||||
'gender': 'FEMALE'
|
||||
}).insert()
|
||||
except frappe.exceptions.DuplicateEntryError:
|
||||
gender_m = frappe.get_doc({
|
||||
'doctype': 'Gender',
|
||||
'gender': 'MALE'
|
||||
})
|
||||
gender_f = frappe.get_doc({
|
||||
'doctype': 'Gender',
|
||||
'gender': 'FEMALE'
|
||||
})
|
||||
|
||||
self.patient_male = frappe.get_doc({
|
||||
'doctype': 'Patient',
|
||||
'first_name': 'John',
|
||||
'sex': gender_m.gender,
|
||||
}).insert()
|
||||
self.patient_female = frappe.get_doc({
|
||||
'doctype': 'Patient',
|
||||
'first_name': 'Curie',
|
||||
'sex': gender_f.gender,
|
||||
}).insert()
|
||||
self.practitioner = frappe.get_doc({
|
||||
'doctype': 'Healthcare Practitioner',
|
||||
'first_name': 'Doc',
|
||||
'sex': 'MALE',
|
||||
}).insert()
|
||||
try:
|
||||
self.care_plan_male = frappe.get_doc({
|
||||
'doctype': 'Treatment Plan Template',
|
||||
'template_name': 'test plan - m',
|
||||
'gender': gender_m.gender,
|
||||
}).insert()
|
||||
self.care_plan_female = frappe.get_doc({
|
||||
'doctype': 'Treatment Plan Template',
|
||||
'template_name': 'test plan - f',
|
||||
'gender': gender_f.gender,
|
||||
}).insert()
|
||||
except frappe.exceptions.DuplicateEntryError:
|
||||
self.care_plan_male = frappe.get_doc({
|
||||
'doctype': 'Treatment Plan Template',
|
||||
'template_name': 'test plan - m',
|
||||
'gender': gender_m.gender,
|
||||
})
|
||||
self.care_plan_female = frappe.get_doc({
|
||||
'doctype': 'Treatment Plan Template',
|
||||
'template_name': 'test plan - f',
|
||||
'gender': gender_f.gender,
|
||||
})
|
||||
|
||||
def test_treatment_plan_template_filter(self):
|
||||
encounter = frappe.get_doc({
|
||||
'doctype': 'Patient Encounter',
|
||||
'patient': self.patient_male.name,
|
||||
'practitioner': self.practitioner.name,
|
||||
}).insert()
|
||||
plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict())
|
||||
self.assertEqual(plans[0]['name'], self.care_plan_male.template_name)
|
||||
|
||||
encounter = frappe.get_doc({
|
||||
'doctype': 'Patient Encounter',
|
||||
'patient': self.patient_female.name,
|
||||
'practitioner': self.practitioner.name,
|
||||
}).insert()
|
||||
plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict())
|
||||
self.assertEqual(plans[0]['name'], self.care_plan_female.template_name)
|
||||
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"doctype": "Treatment Plan Template",
|
||||
"template_name": "Chemo",
|
||||
"patient_age_from": 21
|
||||
}
|
||||
]
|
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestTreatmentPlanTemplate(unittest.TestCase):
|
||||
pass
|
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Treatment Plan Template', {
|
||||
refresh: function (frm) {
|
||||
frm.set_query('type', 'items', function () {
|
||||
return {
|
||||
filters: {
|
||||
'name': ['in', ['Lab Test Template', 'Clinical Procedure Template', 'Therapy Type']],
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
@ -0,0 +1,189 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "field:template_name",
|
||||
"creation": "2021-06-10 10:14:17.901273",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"section_break_1",
|
||||
"template_name",
|
||||
"description",
|
||||
"practitioners",
|
||||
"disabled",
|
||||
"column_break_1",
|
||||
"medical_department",
|
||||
"goal",
|
||||
"order_group",
|
||||
"section_break_8",
|
||||
"patient_age_from",
|
||||
"complaints",
|
||||
"gender",
|
||||
"column_break_12",
|
||||
"patient_age_to",
|
||||
"diagnosis",
|
||||
"plan_items_section",
|
||||
"items",
|
||||
"drugs"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "section_break_1",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Plan Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "medical_department",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Medical Department",
|
||||
"options": "Medical Department"
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Description"
|
||||
},
|
||||
{
|
||||
"fieldname": "goal",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Goal"
|
||||
},
|
||||
{
|
||||
"fieldname": "practitioners",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Practitioners",
|
||||
"options": "Treatment Plan Template Practitioner"
|
||||
},
|
||||
{
|
||||
"fieldname": "order_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Order Group",
|
||||
"options": "Patient Encounter",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Plan Conditions"
|
||||
},
|
||||
{
|
||||
"fieldname": "template_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Template Name",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "patient_age_from",
|
||||
"fieldtype": "Int",
|
||||
"label": "Patient Age From",
|
||||
"non_negative": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "patient_age_to",
|
||||
"fieldtype": "Int",
|
||||
"label": "Patient Age To",
|
||||
"non_negative": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "gender",
|
||||
"fieldtype": "Link",
|
||||
"label": "Gender",
|
||||
"options": "Gender"
|
||||
},
|
||||
{
|
||||
"fieldname": "complaints",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Complaints",
|
||||
"options": "Patient Encounter Symptom"
|
||||
},
|
||||
{
|
||||
"fieldname": "diagnosis",
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": "Diagnosis",
|
||||
"options": "Patient Encounter Diagnosis"
|
||||
},
|
||||
{
|
||||
"fieldname": "plan_items_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Plan Items"
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Items",
|
||||
"options": "Treatment Plan Template Item"
|
||||
},
|
||||
{
|
||||
"fieldname": "drugs",
|
||||
"fieldtype": "Table",
|
||||
"label": "Drugs",
|
||||
"options": "Drug Prescription"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disabled"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_1",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-08-18 02:41:58.354296",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Treatment Plan Template",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Physician",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Healthcare Administrator",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "template_name",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
class TreatmentPlanTemplate(Document):
|
||||
def validate(self):
|
||||
self.validate_age()
|
||||
|
||||
def validate_age(self):
|
||||
if self.patient_age_from and self.patient_age_from < 0:
|
||||
frappe.throw(_('Patient Age From cannot be less than 0'))
|
||||
if self.patient_age_to and self.patient_age_to < 0:
|
||||
frappe.throw(_('Patient Age To cannot be less than 0'))
|
||||
if self.patient_age_to and self.patient_age_from and \
|
||||
self.patient_age_to < self.patient_age_from:
|
||||
frappe.throw(_('Patient Age To cannot be less than Patient Age From'))
|
@ -0,0 +1,10 @@
|
||||
frappe.listview_settings['Treatment Plan Template'] = {
|
||||
get_indicator: function(doc) {
|
||||
var colors = {
|
||||
1: 'gray',
|
||||
0: 'blue',
|
||||
};
|
||||
let label = doc.disabled == 1 ? 'Disabled' : 'Enabled';
|
||||
return [__(label), colors[doc.disabled], 'disable,=,' + doc.disabled];
|
||||
}
|
||||
};
|
@ -0,0 +1,55 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-06-10 11:47:29.194795",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"type",
|
||||
"template",
|
||||
"qty",
|
||||
"instructions"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Type",
|
||||
"options": "DocType",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "template",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Template",
|
||||
"options": "type",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Int",
|
||||
"label": "Qty"
|
||||
},
|
||||
{
|
||||
"fieldname": "instructions",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"label": "Instructions"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-08-17 11:19:03.515441",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Treatment Plan Template Item",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class TreatmentPlanTemplateItem(Document):
|
||||
pass
|
@ -0,0 +1,32 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2021-06-10 10:37:56.669416",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"practitioner"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "practitioner",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Practitioner",
|
||||
"options": "Healthcare Practitioner",
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-11 16:05:06.733299",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Treatment Plan Template Practitioner",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class TreatmentPlanTemplatePractitioner(Document):
|
||||
pass
|
Loading…
Reference in New Issue
Block a user