feat: Therapy Plan Template (#23558)
* feat: Therapy Plan Template * feat: Handle billing Therapy Plans created via Templates * feat: add dashboard to Therapy Plan Template * fix: codacy issues * fix: sider * fix: validate Therapy Session overlap * feat: Create Sales Invoice from Therapy Plan * fix: sider * chore: added tests for Therapy Plan Template * fix: test * fix: test Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com> Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
parent
e977bc38a3
commit
434791ed6e
@ -5,9 +5,9 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from frappe.utils import getdate
|
||||
from frappe.utils import getdate, flt
|
||||
from erpnext.healthcare.doctype.therapy_type.test_therapy_type import create_therapy_type
|
||||
from erpnext.healthcare.doctype.therapy_plan.therapy_plan import make_therapy_session
|
||||
from erpnext.healthcare.doctype.therapy_plan.therapy_plan import make_therapy_session, make_sales_invoice
|
||||
from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_healthcare_docs, create_patient
|
||||
|
||||
class TestTherapyPlan(unittest.TestCase):
|
||||
@ -20,25 +20,45 @@ class TestTherapyPlan(unittest.TestCase):
|
||||
plan = create_therapy_plan()
|
||||
self.assertEquals(plan.status, 'Not Started')
|
||||
|
||||
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab')
|
||||
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company')
|
||||
frappe.get_doc(session).submit()
|
||||
self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'In Progress')
|
||||
|
||||
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab')
|
||||
session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab', '_Test Company')
|
||||
frappe.get_doc(session).submit()
|
||||
self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
|
||||
|
||||
def test_therapy_plan_from_template(self):
|
||||
patient = create_patient()
|
||||
template = create_therapy_plan_template()
|
||||
# check linked item
|
||||
self.assertTrue(frappe.db.exists('Therapy Plan Template', {'linked_item': 'Complete Rehab'}))
|
||||
|
||||
def create_therapy_plan():
|
||||
plan = create_therapy_plan(template)
|
||||
# invoice
|
||||
si = make_sales_invoice(plan.name, patient, '_Test Company', template)
|
||||
si.save()
|
||||
|
||||
therapy_plan_template_amt = frappe.db.get_value('Therapy Plan Template', template, 'total_amount')
|
||||
self.assertEquals(si.items[0].amount, therapy_plan_template_amt)
|
||||
|
||||
|
||||
def create_therapy_plan(template=None):
|
||||
patient = create_patient()
|
||||
therapy_type = create_therapy_type()
|
||||
plan = frappe.new_doc('Therapy Plan')
|
||||
plan.patient = patient
|
||||
plan.start_date = getdate()
|
||||
plan.append('therapy_plan_details', {
|
||||
'therapy_type': therapy_type.name,
|
||||
'no_of_sessions': 2
|
||||
})
|
||||
|
||||
if template:
|
||||
plan.therapy_plan_template = template
|
||||
plan = plan.set_therapy_details_from_template()
|
||||
else:
|
||||
plan.append('therapy_plan_details', {
|
||||
'therapy_type': therapy_type.name,
|
||||
'no_of_sessions': 2
|
||||
})
|
||||
|
||||
plan.save()
|
||||
return plan
|
||||
|
||||
@ -55,3 +75,22 @@ def create_encounter(patient, medical_department, practitioner):
|
||||
encounter.save()
|
||||
encounter.submit()
|
||||
return encounter
|
||||
|
||||
def create_therapy_plan_template():
|
||||
template_name = frappe.db.exists('Therapy Plan Template', 'Complete Rehab')
|
||||
if not template_name:
|
||||
therapy_type = create_therapy_type()
|
||||
template = frappe.new_doc('Therapy Plan Template')
|
||||
template.plan_name = template.item_code = template.item_name = 'Complete Rehab'
|
||||
template.item_group = 'Services'
|
||||
rate = frappe.db.get_value('Therapy Type', therapy_type.name, 'rate')
|
||||
template.append('therapy_types', {
|
||||
'therapy_type': therapy_type.name,
|
||||
'no_of_sessions': 2,
|
||||
'rate': rate,
|
||||
'amount': 2 * flt(rate)
|
||||
})
|
||||
template.save()
|
||||
template_name = template.name
|
||||
|
||||
return template_name
|
||||
|
@ -37,7 +37,8 @@ frappe.ui.form.on('Therapy Plan', {
|
||||
args: {
|
||||
therapy_plan: frm.doc.name,
|
||||
patient: frm.doc.patient,
|
||||
therapy_type: data.therapy_type
|
||||
therapy_type: data.therapy_type,
|
||||
company: frm.doc.company
|
||||
},
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
@ -49,13 +50,53 @@ frappe.ui.form.on('Therapy Plan', {
|
||||
});
|
||||
}, __('Select Therapy Type'), __('Create'));
|
||||
}, __('Create'));
|
||||
|
||||
if (frm.doc.therapy_plan_template && !frm.doc.invoiced) {
|
||||
frm.add_custom_button(__('Sales Invoice'), function() {
|
||||
frm.trigger('make_sales_invoice');
|
||||
}, __('Create'));
|
||||
}
|
||||
}
|
||||
|
||||
if (frm.doc.therapy_plan_template) {
|
||||
frappe.meta.get_docfield('Therapy Plan Detail', 'therapy_type', frm.doc.name).read_only = 1;
|
||||
frappe.meta.get_docfield('Therapy Plan Detail', 'no_of_sessions', frm.doc.name).read_only = 1;
|
||||
}
|
||||
},
|
||||
|
||||
make_sales_invoice: function(frm) {
|
||||
frappe.call({
|
||||
args: {
|
||||
'reference_name': frm.doc.name,
|
||||
'patient': frm.doc.patient,
|
||||
'company': frm.doc.company,
|
||||
'therapy_plan_template': frm.doc.therapy_plan_template
|
||||
},
|
||||
method: 'erpnext.healthcare.doctype.therapy_plan.therapy_plan.make_sales_invoice',
|
||||
callback: function(r) {
|
||||
var doclist = frappe.model.sync(r.message);
|
||||
frappe.set_route('Form', doclist[0].doctype, doclist[0].name);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
therapy_plan_template: function(frm) {
|
||||
if (frm.doc.therapy_plan_template) {
|
||||
frappe.call({
|
||||
method: 'set_therapy_details_from_template',
|
||||
doc: frm.doc,
|
||||
freeze: true,
|
||||
freeze_message: __('Fetching Template Details'),
|
||||
callback: function() {
|
||||
refresh_field('therapy_plan_details');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
show_progress_for_therapies: function(frm) {
|
||||
let bars = [];
|
||||
let message = '';
|
||||
let added_min = false;
|
||||
|
||||
// completed sessions
|
||||
let title = __('{0} sessions completed', [frm.doc.total_sessions_completed]);
|
||||
@ -71,7 +112,6 @@ frappe.ui.form.on('Therapy Plan', {
|
||||
});
|
||||
if (bars[0].width == '0%') {
|
||||
bars[0].width = '0.5%';
|
||||
added_min = 0.5;
|
||||
}
|
||||
message = title;
|
||||
frm.dashboard.add_progress(__('Status'), bars, message);
|
||||
|
@ -9,11 +9,13 @@
|
||||
"naming_series",
|
||||
"patient",
|
||||
"patient_name",
|
||||
"invoiced",
|
||||
"column_break_4",
|
||||
"company",
|
||||
"status",
|
||||
"start_date",
|
||||
"section_break_3",
|
||||
"therapy_plan_template",
|
||||
"therapy_plan_details",
|
||||
"title",
|
||||
"section_break_9",
|
||||
@ -46,6 +48,7 @@
|
||||
"fieldtype": "Table",
|
||||
"label": "Therapy Plan Details",
|
||||
"options": "Therapy Plan Detail",
|
||||
"read_only_depends_on": "therapy_plan_template",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
@ -105,11 +108,27 @@
|
||||
"fieldtype": "Link",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Company",
|
||||
"options": "Company"
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "therapy_plan_template",
|
||||
"fieldtype": "Link",
|
||||
"label": "Therapy Plan Template",
|
||||
"options": "Therapy Plan Template"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "invoiced",
|
||||
"fieldtype": "Check",
|
||||
"label": "Invoiced",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-05-25 14:38:53.649315",
|
||||
"modified": "2020-10-23 01:27:42.128855",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Therapy Plan",
|
||||
|
@ -5,7 +5,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import today
|
||||
from frappe.utils import flt, today
|
||||
|
||||
class TherapyPlan(Document):
|
||||
def validate(self):
|
||||
@ -33,13 +33,26 @@ class TherapyPlan(Document):
|
||||
self.db_set('total_sessions', total_sessions)
|
||||
self.db_set('total_sessions_completed', total_sessions_completed)
|
||||
|
||||
def set_therapy_details_from_template(self):
|
||||
# Add therapy types in the child table
|
||||
self.set('therapy_plan_details', [])
|
||||
therapy_plan_template = frappe.get_doc('Therapy Plan Template', self.therapy_plan_template)
|
||||
|
||||
for data in therapy_plan_template.therapy_types:
|
||||
self.append('therapy_plan_details', {
|
||||
'therapy_type': data.therapy_type,
|
||||
'no_of_sessions': data.no_of_sessions
|
||||
})
|
||||
return self
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_therapy_session(therapy_plan, patient, therapy_type):
|
||||
def make_therapy_session(therapy_plan, patient, therapy_type, company):
|
||||
therapy_type = frappe.get_doc('Therapy Type', therapy_type)
|
||||
|
||||
therapy_session = frappe.new_doc('Therapy Session')
|
||||
therapy_session.therapy_plan = therapy_plan
|
||||
therapy_session.company = company
|
||||
therapy_session.patient = patient
|
||||
therapy_session.therapy_type = therapy_type.name
|
||||
therapy_session.duration = therapy_type.default_duration
|
||||
@ -48,4 +61,39 @@ def make_therapy_session(therapy_plan, patient, therapy_type):
|
||||
|
||||
if frappe.flags.in_test:
|
||||
therapy_session.start_date = today()
|
||||
return therapy_session.as_dict()
|
||||
return therapy_session.as_dict()
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_sales_invoice(reference_name, patient, company, therapy_plan_template):
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
si = frappe.new_doc('Sales Invoice')
|
||||
si.company = company
|
||||
si.patient = patient
|
||||
si.customer = frappe.db.get_value('Patient', patient, 'customer')
|
||||
|
||||
item = frappe.db.get_value('Therapy Plan Template', therapy_plan_template, 'linked_item')
|
||||
price_list, price_list_currency = frappe.db.get_values('Price List', {'selling': 1}, ['name', 'currency'])[0]
|
||||
args = {
|
||||
'doctype': 'Sales Invoice',
|
||||
'item_code': item,
|
||||
'company': company,
|
||||
'customer': si.customer,
|
||||
'selling_price_list': price_list,
|
||||
'price_list_currency': price_list_currency,
|
||||
'plc_conversion_rate': 1.0,
|
||||
'conversion_rate': 1.0
|
||||
}
|
||||
|
||||
item_line = si.append('items', {})
|
||||
item_details = get_item_details(args)
|
||||
item_line.item_code = item
|
||||
item_line.qty = 1
|
||||
item_line.rate = item_details.price_list_rate
|
||||
item_line.amount = flt(item_line.rate) * flt(item_line.qty)
|
||||
item_line.reference_dt = 'Therapy Plan'
|
||||
item_line.reference_dn = reference_name
|
||||
item_line.description = item_details.description
|
||||
|
||||
si.set_missing_values(for_validate = True)
|
||||
return si
|
||||
|
@ -4,10 +4,18 @@ from frappe import _
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'therapy_plan',
|
||||
'non_standard_fieldnames': {
|
||||
'Sales Invoice': 'reference_dn'
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Therapy Sessions'),
|
||||
'items': ['Therapy Session']
|
||||
},
|
||||
{
|
||||
'label': _('Billing'),
|
||||
'items': ['Sales Invoice']
|
||||
}
|
||||
]
|
||||
],
|
||||
'disable_create_buttons': ['Sales Invoice']
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-30 22:02:01.740109",
|
||||
"modified": "2020-10-08 01:17:34.778028",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Therapy Plan Detail",
|
||||
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
class TestTherapyPlanTemplate(unittest.TestCase):
|
||||
pass
|
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Therapy Plan Template', {
|
||||
refresh: function(frm) {
|
||||
frm.set_query('therapy_type', 'therapy_types', () => {
|
||||
return {
|
||||
filters: {
|
||||
'is_billable': 1
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
set_totals: function(frm) {
|
||||
let total_sessions = 0;
|
||||
let total_amount = 0.0;
|
||||
frm.doc.therapy_types.forEach((d) => {
|
||||
if (d.no_of_sessions) total_sessions += cint(d.no_of_sessions);
|
||||
if (d.amount) total_amount += flt(d.amount);
|
||||
});
|
||||
frm.set_value('total_sessions', total_sessions);
|
||||
frm.set_value('total_amount', total_amount);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Therapy Plan Template Detail', {
|
||||
therapy_type: function(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
frappe.call('frappe.client.get', {
|
||||
doctype: 'Therapy Type',
|
||||
name: row.therapy_type
|
||||
}).then((res) => {
|
||||
row.rate = res.message.rate;
|
||||
if (!row.no_of_sessions)
|
||||
row.no_of_sessions = 1;
|
||||
row.amount = flt(row.rate) * cint(row.no_of_sessions);
|
||||
frm.refresh_field('therapy_types');
|
||||
frm.trigger('set_totals');
|
||||
});
|
||||
},
|
||||
|
||||
no_of_sessions: function(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
row.amount = flt(row.rate) * cint(row.no_of_sessions);
|
||||
frm.refresh_field('therapy_types');
|
||||
frm.trigger('set_totals');
|
||||
},
|
||||
|
||||
rate: function(frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
row.amount = flt(row.rate) * cint(row.no_of_sessions);
|
||||
frm.refresh_field('therapy_types');
|
||||
frm.trigger('set_totals');
|
||||
}
|
||||
});
|
@ -0,0 +1,132 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "field:plan_name",
|
||||
"creation": "2020-09-22 17:51:38.861055",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"plan_name",
|
||||
"linked_item_details_section",
|
||||
"item_code",
|
||||
"item_name",
|
||||
"item_group",
|
||||
"column_break_6",
|
||||
"description",
|
||||
"linked_item",
|
||||
"therapy_types_section",
|
||||
"therapy_types",
|
||||
"section_break_11",
|
||||
"total_sessions",
|
||||
"column_break_13",
|
||||
"total_amount"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "plan_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Plan Name",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "therapy_types_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Therapy Types"
|
||||
},
|
||||
{
|
||||
"fieldname": "therapy_types",
|
||||
"fieldtype": "Table",
|
||||
"label": "Therapy Types",
|
||||
"options": "Therapy Plan Template Detail",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "linked_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Linked Item",
|
||||
"options": "Item",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "linked_item_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Linked Item Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Code",
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "item_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Item Group",
|
||||
"options": "Item Group",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Item Description"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Amount",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_11",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_sessions",
|
||||
"fieldtype": "Int",
|
||||
"label": "Total Sessions",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-08 00:56:58.062105",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Therapy 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
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint, flt
|
||||
from erpnext.healthcare.doctype.therapy_type.therapy_type import make_item_price
|
||||
|
||||
class TherapyPlanTemplate(Document):
|
||||
def after_insert(self):
|
||||
self.create_item_from_template()
|
||||
|
||||
def validate(self):
|
||||
self.set_totals()
|
||||
|
||||
def on_update(self):
|
||||
doc_before_save = self.get_doc_before_save()
|
||||
if not doc_before_save: return
|
||||
if doc_before_save.item_name != self.item_name or doc_before_save.item_group != self.item_group \
|
||||
or doc_before_save.description != self.description:
|
||||
self.update_item()
|
||||
|
||||
if doc_before_save.therapy_types != self.therapy_types:
|
||||
self.update_item_price()
|
||||
|
||||
def set_totals(self):
|
||||
total_sessions = 0
|
||||
total_amount = 0
|
||||
|
||||
for entry in self.therapy_types:
|
||||
total_sessions += cint(entry.no_of_sessions)
|
||||
total_amount += flt(entry.amount)
|
||||
|
||||
self.total_sessions = total_sessions
|
||||
self.total_amount = total_amount
|
||||
|
||||
def create_item_from_template(self):
|
||||
uom = frappe.db.exists('UOM', 'Nos') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
|
||||
|
||||
item = frappe.get_doc({
|
||||
'doctype': 'Item',
|
||||
'item_code': self.item_code,
|
||||
'item_name': self.item_name,
|
||||
'item_group': self.item_group,
|
||||
'description': self.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,
|
||||
'stock_uom': uom
|
||||
}).insert(ignore_permissions=True, ignore_mandatory=True)
|
||||
|
||||
make_item_price(item.name, self.total_amount)
|
||||
self.db_set('linked_item', item.name)
|
||||
|
||||
def update_item(self):
|
||||
item_doc = frappe.get_doc('Item', {'item_code': self.linked_item})
|
||||
item_doc.item_name = self.item_name
|
||||
item_doc.item_group = self.item_group
|
||||
item_doc.description = self.description
|
||||
item_doc.ignore_mandatory = True
|
||||
item_doc.save(ignore_permissions=True)
|
||||
|
||||
def update_item_price(self):
|
||||
item_price = frappe.get_doc('Item Price', {'item_code': self.linked_item})
|
||||
item_price.item_name = self.item_name
|
||||
item_price.price_list_rate = self.total_amount
|
||||
item_price.ignore_mandatory = True
|
||||
item_price.save(ignore_permissions=True)
|
@ -0,0 +1,13 @@
|
||||
from __future__ import unicode_literals
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'therapy_plan_template',
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Therapy Plans'),
|
||||
'items': ['Therapy Plan']
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2020-10-07 23:04:44.373381",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"therapy_type",
|
||||
"no_of_sessions",
|
||||
"rate",
|
||||
"amount"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "therapy_type",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Therapy Type",
|
||||
"options": "Therapy Type",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "no_of_sessions",
|
||||
"fieldtype": "Int",
|
||||
"in_list_view": 1,
|
||||
"label": "No of Sessions"
|
||||
},
|
||||
{
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Rate"
|
||||
},
|
||||
{
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-07 23:46:54.296322",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Therapy Plan Template Detail",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class TherapyPlanTemplateDetail(Document):
|
||||
pass
|
@ -92,7 +92,8 @@ frappe.ui.form.on('Therapy Session', {
|
||||
'start_date': data.message.appointment_date,
|
||||
'start_time': data.message.appointment_time,
|
||||
'service_unit': data.message.service_unit,
|
||||
'company': data.message.company
|
||||
'company': data.message.company,
|
||||
'duration': data.message.duration
|
||||
};
|
||||
frm.set_value(values);
|
||||
}
|
||||
@ -107,6 +108,7 @@ frappe.ui.form.on('Therapy Session', {
|
||||
'start_date': '',
|
||||
'start_time': '',
|
||||
'service_unit': '',
|
||||
'duration': ''
|
||||
};
|
||||
frm.set_value(values);
|
||||
}
|
||||
|
@ -47,7 +47,8 @@
|
||||
"fieldname": "appointment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Appointment",
|
||||
"options": "Patient Appointment"
|
||||
"options": "Patient Appointment",
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "patient",
|
||||
@ -90,7 +91,8 @@
|
||||
"fetch_from": "therapy_template.default_duration",
|
||||
"fieldname": "duration",
|
||||
"fieldtype": "Int",
|
||||
"label": "Duration"
|
||||
"label": "Duration",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "location",
|
||||
@ -220,7 +222,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-30 10:56:10.354268",
|
||||
"modified": "2020-10-22 23:10:21.178644",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Therapy Session",
|
||||
|
@ -4,16 +4,41 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import datetime
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_time, flt
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe import _
|
||||
from frappe.utils import cstr, getdate
|
||||
from frappe.utils import cstr, getdate, get_link_to_form
|
||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
|
||||
|
||||
class TherapySession(Document):
|
||||
def validate(self):
|
||||
self.validate_duplicate()
|
||||
self.set_total_counts()
|
||||
|
||||
def validate_duplicate(self):
|
||||
end_time = datetime.datetime.combine(getdate(self.start_date), get_time(self.start_time)) \
|
||||
+ datetime.timedelta(minutes=flt(self.duration))
|
||||
|
||||
overlaps = frappe.db.sql("""
|
||||
select
|
||||
name
|
||||
from
|
||||
`tabTherapy Session`
|
||||
where
|
||||
start_date=%s and name!=%s and docstatus!=2
|
||||
and (practitioner=%s or patient=%s) and
|
||||
((start_time<%s and start_time + INTERVAL duration MINUTE>%s) or
|
||||
(start_time>%s and start_time<%s) or
|
||||
(start_time=%s))
|
||||
""", (self.start_date, self.name, self.practitioner, self.patient,
|
||||
self.start_time, end_time.time(), self.start_time, end_time.time(), self.start_time))
|
||||
|
||||
if overlaps:
|
||||
overlapping_details = _('Therapy Session overlaps with {0}').format(get_link_to_form('Therapy Session', overlaps[0][0]))
|
||||
frappe.throw(overlapping_details, title=_('Therapy Sessions Overlapping'))
|
||||
|
||||
def on_submit(self):
|
||||
self.update_sessions_count_in_therapy_plan()
|
||||
insert_session_medical_record(self)
|
||||
|
@ -41,7 +41,7 @@ class TherapyType(Document):
|
||||
if self.rate:
|
||||
item_price = frappe.get_doc('Item Price', {'item_code': self.item})
|
||||
item_price.item_name = self.item_name
|
||||
item_price.price_list_name = self.rate
|
||||
item_price.price_list_rate = self.rate
|
||||
item_price.ignore_mandatory = True
|
||||
item_price.save()
|
||||
|
||||
|
@ -23,9 +23,9 @@ def get_healthcare_services_to_invoice(patient, company):
|
||||
items_to_invoice += get_lab_tests_to_invoice(patient, company)
|
||||
items_to_invoice += get_clinical_procedures_to_invoice(patient, company)
|
||||
items_to_invoice += get_inpatient_services_to_invoice(patient, company)
|
||||
items_to_invoice += get_therapy_plans_to_invoice(patient, company)
|
||||
items_to_invoice += get_therapy_sessions_to_invoice(patient, company)
|
||||
|
||||
|
||||
return items_to_invoice
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ def validate_customer_created(patient):
|
||||
msg += " <b><a href='#Form/Patient/{0}'>{0}</a></b>".format(patient.name)
|
||||
frappe.throw(msg, title=_('Customer Not Found'))
|
||||
|
||||
|
||||
def get_appointments_to_invoice(patient, company):
|
||||
appointments_to_invoice = []
|
||||
patient_appointments = frappe.get_list(
|
||||
@ -246,12 +247,44 @@ def get_inpatient_services_to_invoice(patient, company):
|
||||
return services_to_invoice
|
||||
|
||||
|
||||
def get_therapy_plans_to_invoice(patient, company):
|
||||
therapy_plans_to_invoice = []
|
||||
therapy_plans = frappe.get_list(
|
||||
'Therapy Plan',
|
||||
fields=['therapy_plan_template', 'name'],
|
||||
filters={
|
||||
'patient': patient.name,
|
||||
'invoiced': 0,
|
||||
'company': company,
|
||||
'therapy_plan_template': ('!=', '')
|
||||
}
|
||||
)
|
||||
for plan in therapy_plans:
|
||||
therapy_plans_to_invoice.append({
|
||||
'reference_type': 'Therapy Plan',
|
||||
'reference_name': plan.name,
|
||||
'service': frappe.db.get_value('Therapy Plan Template', plan.therapy_plan_template, 'linked_item')
|
||||
})
|
||||
|
||||
return therapy_plans_to_invoice
|
||||
|
||||
|
||||
def get_therapy_sessions_to_invoice(patient, company):
|
||||
therapy_sessions_to_invoice = []
|
||||
therapy_plans = frappe.db.get_all('Therapy Plan', {'therapy_plan_template': ('!=', '')})
|
||||
therapy_plans_created_from_template = []
|
||||
for entry in therapy_plans:
|
||||
therapy_plans_created_from_template.append(entry.name)
|
||||
|
||||
therapy_sessions = frappe.get_list(
|
||||
'Therapy Session',
|
||||
fields='*',
|
||||
filters={'patient': patient.name, 'invoiced': 0, 'company': company}
|
||||
filters={
|
||||
'patient': patient.name,
|
||||
'invoiced': 0,
|
||||
'company': company,
|
||||
'therapy_plan': ('not in', therapy_plans_created_from_template)
|
||||
}
|
||||
)
|
||||
for therapy in therapy_sessions:
|
||||
if not therapy.appointment:
|
||||
@ -368,8 +401,8 @@ def validate_invoiced_on_submit(item):
|
||||
else:
|
||||
is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, 'invoiced')
|
||||
if is_invoiced:
|
||||
frappe.throw(_('The item referenced by {0} - {1} is already invoiced'\
|
||||
).format(item.reference_dt, item.reference_dn))
|
||||
frappe.throw(_('The item referenced by {0} - {1} is already invoiced').format(
|
||||
item.reference_dt, item.reference_dn))
|
||||
|
||||
|
||||
def manage_prescriptions(invoiced, ref_dt, ref_dn, dt, created_check_field):
|
||||
|
Loading…
x
Reference in New Issue
Block a user