Merge branch 'develop' into sales-analytics
This commit is contained in:
commit
8cb356bf30
@ -55,7 +55,7 @@ class BankStatementTransactionEntry(Document):
|
||||
|
||||
def populate_payment_entries(self):
|
||||
if self.bank_statement is None: return
|
||||
filename = self.bank_statement.split("/")[-1]
|
||||
file_url = self.bank_statement
|
||||
if (len(self.new_transaction_items + self.reconciled_transaction_items) > 0):
|
||||
frappe.throw(_("Transactions already retreived from the statement"))
|
||||
|
||||
@ -65,7 +65,7 @@ class BankStatementTransactionEntry(Document):
|
||||
if self.bank_settings:
|
||||
mapped_items = frappe.get_doc("Bank Statement Settings", self.bank_settings).mapped_items
|
||||
statement_headers = self.get_statement_headers()
|
||||
transactions = get_transaction_entries(filename, statement_headers)
|
||||
transactions = get_transaction_entries(file_url, statement_headers)
|
||||
for entry in transactions:
|
||||
date = entry[statement_headers["Date"]].strip()
|
||||
#print("Processing entry DESC:{0}-W:{1}-D:{2}-DT:{3}".format(entry["Particulars"], entry["Withdrawals"], entry["Deposits"], entry["Date"]))
|
||||
@ -398,20 +398,21 @@ def get_transaction_info(headers, header_index, row):
|
||||
transaction[header] = ""
|
||||
return transaction
|
||||
|
||||
def get_transaction_entries(filename, headers):
|
||||
def get_transaction_entries(file_url, headers):
|
||||
header_index = {}
|
||||
rows, transactions = [], []
|
||||
|
||||
if (filename.lower().endswith("xlsx")):
|
||||
if (file_url.lower().endswith("xlsx")):
|
||||
from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file
|
||||
rows = read_xlsx_file_from_attached_file(file_id=filename)
|
||||
elif (filename.lower().endswith("csv")):
|
||||
rows = read_xlsx_file_from_attached_file(file_url=file_url)
|
||||
elif (file_url.lower().endswith("csv")):
|
||||
from frappe.utils.csvutils import read_csv_content
|
||||
_file = frappe.get_doc("File", {"file_name": filename})
|
||||
_file = frappe.get_doc("File", {"file_url": file_url})
|
||||
filepath = _file.get_full_path()
|
||||
with open(filepath,'rb') as csvfile:
|
||||
rows = read_csv_content(csvfile.read())
|
||||
elif (filename.lower().endswith("xls")):
|
||||
elif (file_url.lower().endswith("xls")):
|
||||
filename = file_url.split("/")[-1]
|
||||
rows = get_rows_from_xls_file(filename)
|
||||
else:
|
||||
frappe.throw(_("Only .csv and .xlsx files are supported currently"))
|
||||
|
@ -7,6 +7,7 @@ import json
|
||||
from frappe import _, throw
|
||||
from frappe.utils import (today, flt, cint, fmt_money, formatdate,
|
||||
getdate, add_days, add_months, get_last_day, nowdate, get_link_to_form)
|
||||
from frappe.model.workflow import get_workflow_name, is_transition_condition_satisfied, WorkflowPermissionError
|
||||
from erpnext.stock.get_item_details import get_conversion_factor, get_item_details
|
||||
from erpnext.setup.utils import get_exchange_rate
|
||||
from erpnext.accounts.utils import get_fiscal_years, validate_fiscal_year, get_account_currency
|
||||
@ -1194,7 +1195,7 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna
|
||||
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
||||
return child_item
|
||||
|
||||
def check_and_delete_children(parent, data):
|
||||
def validate_and_delete_children(parent, data):
|
||||
deleted_children = []
|
||||
updated_item_names = [d.get("docname") for d in data]
|
||||
for item in parent.items:
|
||||
@ -1221,18 +1222,37 @@ def check_and_delete_children(parent, data):
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
||||
def check_permissions(doc, perm_type='create'):
|
||||
def check_doc_permissions(doc, perm_type='create'):
|
||||
try:
|
||||
doc.check_permission(perm_type)
|
||||
except:
|
||||
action = "add" if perm_type == 'create' else "update"
|
||||
frappe.throw(_("You do not have permissions to {} items in a Sales Order.").format(action), title=_("Insufficient Permissions"))
|
||||
except frappe.PermissionError:
|
||||
actions = { 'create': 'add', 'write': 'update', 'cancel': 'remove' }
|
||||
|
||||
frappe.throw(_("You do not have permissions to {} items in a {}.")
|
||||
.format(actions[perm_type], parent_doctype), title=_("Insufficient Permissions"))
|
||||
|
||||
def validate_workflow_conditions(doc):
|
||||
workflow = get_workflow_name(doc.doctype)
|
||||
if not workflow:
|
||||
return
|
||||
|
||||
workflow_doc = frappe.get_doc("Workflow", workflow)
|
||||
current_state = doc.get(workflow_doc.workflow_state_field)
|
||||
roles = frappe.get_roles()
|
||||
|
||||
transitions = []
|
||||
for transition in workflow_doc.transitions:
|
||||
if transition.next_state == current_state and transition.allowed in roles:
|
||||
if not is_transition_condition_satisfied(transition, doc):
|
||||
continue
|
||||
transitions.append(transition.as_dict())
|
||||
|
||||
if not transitions:
|
||||
frappe.throw(_("You do not have workflow access to update this document."), title=_("Insufficient Workflow Permissions"))
|
||||
|
||||
def get_new_child_item(item_row):
|
||||
if parent_doctype == "Sales Order":
|
||||
return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||
if parent_doctype == "Purchase Order":
|
||||
return set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||
new_child_function = set_sales_order_defaults if parent_doctype == "Sales Order" else set_purchase_order_defaults
|
||||
return new_child_function(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||
|
||||
def validate_quantity(child_item, d):
|
||||
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
|
||||
@ -1245,17 +1265,18 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
|
||||
sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
|
||||
parent = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||
|
||||
check_and_delete_children(parent, data)
|
||||
|
||||
check_doc_permissions(parent, 'cancel')
|
||||
validate_and_delete_children(parent, data)
|
||||
|
||||
for d in data:
|
||||
new_child_flag = False
|
||||
if not d.get("docname"):
|
||||
new_child_flag = True
|
||||
check_permissions(parent, 'create')
|
||||
check_doc_permissions(parent, 'create')
|
||||
child_item = get_new_child_item(d)
|
||||
else:
|
||||
check_permissions(parent, 'write')
|
||||
check_doc_permissions(parent, 'write')
|
||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||
|
||||
prev_rate, new_rate = flt(child_item.get("rate")), flt(d.get("rate"))
|
||||
@ -1362,6 +1383,9 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
parent.update_prevdoc_status('submit')
|
||||
parent.update_delivery_status()
|
||||
|
||||
parent.reload()
|
||||
validate_workflow_conditions(parent)
|
||||
|
||||
parent.update_blanket_order()
|
||||
parent.update_billing_percentage()
|
||||
parent.set_status()
|
||||
|
@ -3,15 +3,15 @@
|
||||
|
||||
frappe.ui.form.on('Student', {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("guardian", "guardian_name", "guardian_name");
|
||||
frm.add_fetch("student", "title", "full_name");
|
||||
frm.add_fetch("student", "gender", "gender");
|
||||
frm.add_fetch("student", "date_of_birth", "date_of_birth");
|
||||
frm.add_fetch('guardian', 'guardian_name', 'guardian_name');
|
||||
frm.add_fetch('student', 'title', 'full_name');
|
||||
frm.add_fetch('student', 'gender', 'gender');
|
||||
frm.add_fetch('student', 'date_of_birth', 'date_of_birth');
|
||||
|
||||
frm.set_query("student", "siblings", function(doc, cdt, cdn) {
|
||||
frm.set_query('student', 'siblings', function(doc) {
|
||||
return {
|
||||
"filters": {
|
||||
"name": ["!=", doc.name]
|
||||
'filters': {
|
||||
'name': ['!=', doc.name]
|
||||
}
|
||||
};
|
||||
})
|
||||
@ -25,6 +25,12 @@ frappe.ui.form.on('Student', {
|
||||
{party_type:'Student', party:frm.doc.name});
|
||||
});
|
||||
}
|
||||
|
||||
frappe.db.get_value('Education Settings', {name: 'Education Settings'}, 'user_creation_skip', (r) => {
|
||||
if (cint(r.user_creation_skip) !== 1) {
|
||||
frm.set_df_property('student_email_id', 'reqd', 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -102,7 +102,6 @@
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"label": "Student Email Address",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
@ -255,7 +254,7 @@
|
||||
],
|
||||
"image_field": "image",
|
||||
"links": [],
|
||||
"modified": "2020-07-23 18:14:06.366442",
|
||||
"modified": "2020-09-07 19:28:08.914568",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student",
|
||||
|
@ -7,7 +7,7 @@ frappe.ui.form.on("Student Applicant", {
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.application_status== "Applied" && frm.doc.docstatus== 1 ) {
|
||||
if (frm.doc.application_status==="Applied" && frm.doc.docstatus===1 ) {
|
||||
frm.add_custom_button(__("Approve"), function() {
|
||||
frm.set_value("application_status", "Approved");
|
||||
frm.save_or_update();
|
||||
@ -20,10 +20,11 @@ frappe.ui.form.on("Student Applicant", {
|
||||
}, 'Actions');
|
||||
}
|
||||
|
||||
if(frm.doc.application_status== "Approved" && frm.doc.docstatus== 1 ) {
|
||||
if (frm.doc.application_status === "Approved" && frm.doc.docstatus === 1) {
|
||||
frm.add_custom_button(__("Enroll"), function() {
|
||||
frm.events.enroll(frm)
|
||||
}).addClass("btn-primary");
|
||||
|
||||
frm.add_custom_button(__("Reject"), function() {
|
||||
frm.set_value("application_status", "Rejected");
|
||||
frm.save_or_update();
|
||||
@ -35,7 +36,13 @@ frappe.ui.form.on("Student Applicant", {
|
||||
frappe.hide_msgprint(true);
|
||||
frappe.show_progress(__("Enrolling student"), data.progress[0],data.progress[1]);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
frappe.db.get_value("Education Settings", {name: "Education Settings"}, "user_creation_skip", (r) => {
|
||||
if (cint(r.user_creation_skip) !== 1) {
|
||||
frm.set_df_property("student_email_id", "reqd", 1);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
enroll: function(frm) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,10 +34,10 @@ frappe.ui.form.on('Lab Test', {
|
||||
if (frm.doc.docstatus === 1 && frm.doc.status !== 'Approved' && frm.doc.status !== 'Rejected') {
|
||||
frm.add_custom_button(__('Approve'), function () {
|
||||
status_update(1, frm);
|
||||
});
|
||||
}, __('Actions'));
|
||||
frm.add_custom_button(__('Reject'), function () {
|
||||
status_update(0, frm);
|
||||
});
|
||||
}, __('Actions'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,23 +179,6 @@ var show_lab_tests = function (frm, lab_test_list) {
|
||||
d.show();
|
||||
};
|
||||
|
||||
cur_frm.cscript.custom_before_submit = function (doc) {
|
||||
if (doc.normal_test_items) {
|
||||
for (let result in doc.normal_test_items) {
|
||||
if (!doc.normal_test_items[result].result_value && !doc.normal_test_items[result].allow_blank && doc.normal_test_items[result].require_result_value) {
|
||||
frappe.throw(__('Please input all required result values'));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doc.descriptive_test_items) {
|
||||
for (let result in doc.descriptive_test_items) {
|
||||
if (!doc.descriptive_test_items[result].result_value && !doc.descriptive_test_items[result].allow_blank && doc.descriptive_test_items[result].require_result_value) {
|
||||
frappe.throw(__('Please input all required result values'));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var make_dialog = function (frm, emailed, printed) {
|
||||
var number = frm.doc.mobile;
|
||||
|
||||
@ -203,7 +186,7 @@ var make_dialog = function (frm, emailed, printed) {
|
||||
title: 'Send SMS',
|
||||
width: 400,
|
||||
fields: [
|
||||
{ fieldname: 'sms_type', fieldtype: 'Select', label: 'Type', options: ['Emailed', 'Printed'] },
|
||||
{ fieldname: 'result_format', fieldtype: 'Select', label: 'Result Format', options: ['Emailed', 'Printed'] },
|
||||
{ fieldname: 'number', fieldtype: 'Data', label: 'Mobile Number', reqd: 1 },
|
||||
{ fieldname: 'message', fieldtype: 'Small Text', label: 'Message', reqd: 1 }
|
||||
],
|
||||
@ -217,22 +200,22 @@ var make_dialog = function (frm, emailed, printed) {
|
||||
dialog.hide();
|
||||
}
|
||||
});
|
||||
if (frm.doc.report_preference == 'Print') {
|
||||
if (frm.doc.report_preference === 'Print') {
|
||||
dialog.set_values({
|
||||
'sms_type': 'Printed',
|
||||
'result_format': 'Printed',
|
||||
'number': number,
|
||||
'message': printed
|
||||
});
|
||||
} else {
|
||||
dialog.set_values({
|
||||
'sms_type': 'Emailed',
|
||||
'result_format': 'Emailed',
|
||||
'number': number,
|
||||
'message': emailed
|
||||
});
|
||||
}
|
||||
var fd = dialog.fields_dict;
|
||||
$(fd.sms_type.input).change(function () {
|
||||
if (dialog.get_value('sms_type') == 'Emailed') {
|
||||
$(fd.result_format.input).change(function () {
|
||||
if (dialog.get_value('result_format') === 'Emailed') {
|
||||
dialog.set_values({
|
||||
'number': number,
|
||||
'message': emailed
|
||||
|
@ -84,7 +84,7 @@
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "LP-",
|
||||
"options": "HLC-LAB-.YYYY.-",
|
||||
"print_hide": 1,
|
||||
"report_hide": 1,
|
||||
"reqd": 1
|
||||
@ -197,11 +197,10 @@
|
||||
{
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Status",
|
||||
"options": "Draft\nCompleted\nApproved\nRejected\nCancelled",
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"report_hide": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
@ -249,8 +248,8 @@
|
||||
{
|
||||
"fieldname": "result_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 1,
|
||||
"label": "Result Date",
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
@ -354,7 +353,8 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "sb_normal",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Compound Test Result"
|
||||
},
|
||||
{
|
||||
"fieldname": "normal_test_items",
|
||||
@ -369,11 +369,13 @@
|
||||
{
|
||||
"depends_on": "descriptive_toggle",
|
||||
"fieldname": "organisms_section",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Organism Test Result"
|
||||
},
|
||||
{
|
||||
"fieldname": "sb_sensitivity",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Sensitivity Test Result"
|
||||
},
|
||||
{
|
||||
"fieldname": "sensitivity_test_items",
|
||||
@ -383,8 +385,10 @@
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "sb_comments",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Comments"
|
||||
},
|
||||
{
|
||||
"fieldname": "lab_test_comment",
|
||||
@ -531,7 +535,8 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "sb_descriptive",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Descriptive Test Result"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@ -550,7 +555,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-16 13:35:24.811062",
|
||||
"modified": "2020-07-30 18:18:38.516215",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Lab Test",
|
||||
|
@ -6,23 +6,24 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import getdate, cstr
|
||||
from frappe.utils import getdate, cstr, get_link_to_form
|
||||
|
||||
class LabTest(Document):
|
||||
def validate(self):
|
||||
if not self.is_new():
|
||||
self.set_secondary_uom_result()
|
||||
|
||||
def on_submit(self):
|
||||
self.validate_result_values()
|
||||
self.db_set('submitted_date', getdate())
|
||||
self.db_set('status', 'Completed')
|
||||
insert_lab_test_to_medical_record(self)
|
||||
|
||||
def on_cancel(self):
|
||||
delete_lab_test_from_medical_record(self)
|
||||
self.db_set('status', 'Cancelled')
|
||||
delete_lab_test_from_medical_record(self)
|
||||
self.reload()
|
||||
|
||||
def validate(self):
|
||||
if not self.is_new():
|
||||
self.set_secondary_uom_result()
|
||||
|
||||
def on_update(self):
|
||||
if self.sensitivity_test_items:
|
||||
sensitivity = sorted(self.sensitivity_test_items, key=lambda x: x.antibiotic_sensitivity)
|
||||
@ -51,7 +52,20 @@ class LabTest(Document):
|
||||
item.secondary_uom_result = float(item.result_value) * float(item.conversion_factor)
|
||||
except:
|
||||
item.secondary_uom_result = ''
|
||||
frappe.msgprint(_('Result for Secondary UOM not calculated for row #{0}'.format(item.idx)), title = _('Warning'))
|
||||
frappe.msgprint(_('Row #{0}: Result for Secondary UOM not calculated'.format(item.idx)), title = _('Warning'))
|
||||
|
||||
def validate_result_values(self):
|
||||
if self.normal_test_items:
|
||||
for item in self.normal_test_items:
|
||||
if not item.result_value and not item.allow_blank and item.require_result_value:
|
||||
frappe.throw(_('Row #{0}: Please enter the result value for {1}').format(
|
||||
item.idx, frappe.bold(item.lab_test_name)), title=_('Mandatory Results'))
|
||||
|
||||
if self.descriptive_test_items:
|
||||
for item in self.descriptive_test_items:
|
||||
if not item.result_value and not item.allow_blank and item.require_result_value:
|
||||
frappe.throw(_('Row #{0}: Please enter the result value for {1}').format(
|
||||
item.idx, frappe.bold(item.lab_test_particulars)), title=_('Mandatory Results'))
|
||||
|
||||
|
||||
def create_test_from_template(lab_test):
|
||||
@ -89,7 +103,7 @@ def create_multiple(doctype, docname):
|
||||
lab_test_created = create_lab_test_from_encounter(docname)
|
||||
|
||||
if lab_test_created:
|
||||
frappe.msgprint(_('Lab Test(s) {0} created'.format(lab_test_created)))
|
||||
frappe.msgprint(_('Lab Test(s) {0} created successfully').format(lab_test_created), indicator='green')
|
||||
else:
|
||||
frappe.msgprint(_('No Lab Tests created'))
|
||||
|
||||
@ -211,8 +225,9 @@ def create_sample_doc(template, patient, invoice, company = None):
|
||||
'docstatus': 0,
|
||||
'sample': template.sample
|
||||
})
|
||||
|
||||
if sample_exists:
|
||||
# Update Sample Collection by adding quantity
|
||||
# update sample collection by adding quantity
|
||||
sample_collection = frappe.get_doc('Sample Collection', sample_exists[0][0])
|
||||
quantity = int(sample_collection.sample_qty) + int(template.sample_qty)
|
||||
if template.sample_details:
|
||||
@ -238,7 +253,7 @@ def create_sample_doc(template, patient, invoice, company = None):
|
||||
sample_collection.company = company
|
||||
|
||||
if template.sample_details:
|
||||
sample_collection.sample_details = 'Test :' + (template.get('lab_test_name') or template.get('template')) + '\n' + 'Collection Detials:\n\t' + template.sample_details
|
||||
sample_collection.sample_details = _('Test :') + (template.get('lab_test_name') or template.get('template')) + '\n' + 'Collection Detials:\n\t' + template.sample_details
|
||||
sample_collection.save(ignore_permissions=True)
|
||||
|
||||
return sample_collection
|
||||
@ -248,26 +263,31 @@ def create_sample_collection(lab_test, template, patient, invoice):
|
||||
sample_collection = create_sample_doc(template, patient, invoice, lab_test.company)
|
||||
if sample_collection:
|
||||
lab_test.sample = sample_collection.name
|
||||
|
||||
sample_collection_doc = get_link_to_form('Sample Collection', sample_collection.name)
|
||||
frappe.msgprint(_('Sample Collection {0} has been created').format(sample_collection_doc),
|
||||
title=_('Sample Collection'), indicator='green')
|
||||
return lab_test
|
||||
|
||||
def load_result_format(lab_test, template, prescription, invoice):
|
||||
if template.lab_test_template_type == 'Single':
|
||||
create_normals(template, lab_test)
|
||||
|
||||
elif template.lab_test_template_type == 'Compound':
|
||||
create_compounds(template, lab_test, False)
|
||||
|
||||
elif template.lab_test_template_type == 'Descriptive':
|
||||
create_descriptives(template, lab_test)
|
||||
|
||||
elif template.lab_test_template_type == 'Grouped':
|
||||
# Iterate for each template in the group and create one result for all.
|
||||
for lab_test_group in template.lab_test_groups:
|
||||
# Template_in_group = None
|
||||
if lab_test_group.lab_test_template:
|
||||
template_in_group = frappe.get_doc('Lab Test Template',
|
||||
lab_test_group.lab_test_template)
|
||||
template_in_group = frappe.get_doc('Lab Test Template', lab_test_group.lab_test_template)
|
||||
if template_in_group:
|
||||
if template_in_group.lab_test_template_type == 'Single':
|
||||
create_normals(template_in_group, lab_test)
|
||||
|
||||
elif template_in_group.lab_test_template_type == 'Compound':
|
||||
normal_heading = lab_test.append('normal_test_items')
|
||||
normal_heading.lab_test_name = template_in_group.lab_test_name
|
||||
@ -275,6 +295,7 @@ def load_result_format(lab_test, template, prescription, invoice):
|
||||
normal_heading.allow_blank = 1
|
||||
normal_heading.template = template_in_group.name
|
||||
create_compounds(template_in_group, lab_test, True)
|
||||
|
||||
elif template_in_group.lab_test_template_type == 'Descriptive':
|
||||
descriptive_heading = lab_test.append('descriptive_test_items')
|
||||
descriptive_heading.lab_test_name = template_in_group.lab_test_name
|
||||
@ -282,6 +303,7 @@ def load_result_format(lab_test, template, prescription, invoice):
|
||||
descriptive_heading.allow_blank = 1
|
||||
descriptive_heading.template = template_in_group.name
|
||||
create_descriptives(template_in_group, lab_test)
|
||||
|
||||
else: # Lab Test Group - Add New Line
|
||||
normal = lab_test.append('normal_test_items')
|
||||
normal.lab_test_name = lab_test_group.group_event
|
||||
@ -292,6 +314,7 @@ def load_result_format(lab_test, template, prescription, invoice):
|
||||
normal.allow_blank = lab_test_group.allow_blank
|
||||
normal.require_result_value = 1
|
||||
normal.template = template.name
|
||||
|
||||
if template.lab_test_template_type != 'No Result':
|
||||
if prescription:
|
||||
lab_test.prescription = prescription
|
||||
@ -302,9 +325,10 @@ def load_result_format(lab_test, template, prescription, invoice):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_employee_by_user_id(user_id):
|
||||
emp_id = frappe.db.get_value('Employee', { 'user_id': user_id })
|
||||
employee = frappe.get_doc('Employee', emp_id)
|
||||
return employee
|
||||
emp_id = frappe.db.exists('Employee', { 'user_id': user_id })
|
||||
if emp_id:
|
||||
return frappe.get_doc('Employee', emp_id)
|
||||
return None
|
||||
|
||||
def insert_lab_test_to_medical_record(doc):
|
||||
table_row = False
|
||||
@ -325,7 +349,7 @@ def insert_lab_test_to_medical_record(doc):
|
||||
table_row += ' ' + frappe.bold(_('Lab Test Result: ')) + item.result_value
|
||||
|
||||
if item.normal_range:
|
||||
table_row += ' ' + _('Normal Range:') + item.normal_range
|
||||
table_row += ' ' + _('Normal Range: ') + item.normal_range
|
||||
table_row += ' ' + comment
|
||||
|
||||
elif doc.descriptive_test_items:
|
||||
@ -356,7 +380,7 @@ def insert_lab_test_to_medical_record(doc):
|
||||
medical_record.save(ignore_permissions = True)
|
||||
|
||||
def delete_lab_test_from_medical_record(self):
|
||||
medical_record_id = frappe.db.sql('select name from `tabPatient Medical Record` where reference_name= %s', (self.name))
|
||||
medical_record_id = frappe.db.sql('select name from `tabPatient Medical Record` where reference_name=%s', (self.name))
|
||||
|
||||
if medical_record_id and medical_record_id[0][0]:
|
||||
frappe.delete_doc('Patient Medical Record', medical_record_id[0][0])
|
||||
|
@ -3,13 +3,16 @@
|
||||
*/
|
||||
frappe.listview_settings['Lab Test'] = {
|
||||
add_fields: ['name', 'status', 'invoiced'],
|
||||
filters: [['docstatus', '=', '0']],
|
||||
filters: [['docstatus', '=', '1']],
|
||||
get_indicator: function (doc) {
|
||||
if (doc.status == 'Approved') {
|
||||
return [__('Approved'), 'green', 'status, = ,Approved'];
|
||||
}
|
||||
if (doc.status == 'Rejected') {
|
||||
if (doc.status === 'Approved') {
|
||||
return [__('Approved'), 'green', 'status, =, Approved'];
|
||||
} else if (doc.status === 'Rejected') {
|
||||
return [__('Rejected'), 'orange', 'status, =, Rejected'];
|
||||
} else if (doc.status === 'Completed') {
|
||||
return [__('Completed'), 'green', 'status, =, Completed'];
|
||||
} else if (doc.status === 'Cancelled') {
|
||||
return [__('Cancelled'), 'red', 'status, =, Cancelled'];
|
||||
}
|
||||
},
|
||||
onload: function (listview) {
|
||||
@ -21,7 +24,7 @@ frappe.listview_settings['Lab Test'] = {
|
||||
|
||||
var create_multiple_dialog = function (listview) {
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
title: 'Create Multiple Lab Test',
|
||||
title: 'Create Multiple Lab Tests',
|
||||
width: 100,
|
||||
fields: [
|
||||
{ fieldtype: 'Link', label: 'Patient', fieldname: 'patient', options: 'Patient', reqd: 1 },
|
||||
@ -41,7 +44,7 @@ var create_multiple_dialog = function (listview) {
|
||||
}
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Create Lab Test'),
|
||||
primary_action_label: __('Create'),
|
||||
primary_action: function () {
|
||||
frappe.call({
|
||||
method: 'erpnext.healthcare.doctype.lab_test.lab_test.create_multiple',
|
||||
|
@ -3,8 +3,204 @@
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Lab Test')
|
||||
import frappe
|
||||
from frappe.utils import getdate, nowtime
|
||||
from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_patient
|
||||
from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple
|
||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account, get_income_account
|
||||
from erpnext.healthcare.doctype.patient_medical_record.test_patient_medical_record import create_lab_test_template as create_blood_test_template
|
||||
|
||||
class TestLabTest(unittest.TestCase):
|
||||
pass
|
||||
def test_lab_test_item(self):
|
||||
lab_template = create_lab_test_template()
|
||||
self.assertTrue(frappe.db.exists('Item', lab_template.item))
|
||||
self.assertEqual(frappe.db.get_value('Item Price', {'item_code':lab_template.item}, 'price_list_rate'), lab_template.lab_test_rate)
|
||||
|
||||
lab_template.disabled = 1
|
||||
lab_template.save()
|
||||
self.assertEquals(frappe.db.get_value('Item', lab_template.item, 'disabled'), 1)
|
||||
|
||||
lab_template.reload()
|
||||
|
||||
lab_template.disabled = 0
|
||||
lab_template.save()
|
||||
|
||||
def test_descriptive_lab_test(self):
|
||||
lab_template = create_lab_test_template()
|
||||
|
||||
# blank result value not allowed as per template
|
||||
lab_test = create_lab_test(lab_template)
|
||||
lab_test.descriptive_test_items[0].result_value = 12
|
||||
lab_test.descriptive_test_items[2].result_value = 1
|
||||
lab_test.save()
|
||||
self.assertRaises(frappe.ValidationError, lab_test.submit)
|
||||
|
||||
def test_sample_collection(self):
|
||||
frappe.db.set_value('Healthcare Settings', 'Healthcare Settings', 'create_sample_collection_for_lab_test', 1)
|
||||
lab_template = create_lab_test_template()
|
||||
|
||||
lab_test = create_lab_test(lab_template)
|
||||
lab_test.descriptive_test_items[0].result_value = 12
|
||||
lab_test.descriptive_test_items[1].result_value = 1
|
||||
lab_test.descriptive_test_items[2].result_value = 2.3
|
||||
lab_test.save()
|
||||
|
||||
# check sample collection created
|
||||
self.assertTrue(frappe.db.exists('Sample Collection', {'sample': lab_template.sample}))
|
||||
|
||||
frappe.db.set_value('Healthcare Settings', 'Healthcare Settings', 'create_sample_collection_for_lab_test', 0)
|
||||
lab_test = create_lab_test(lab_template)
|
||||
lab_test.descriptive_test_items[0].result_value = 12
|
||||
lab_test.descriptive_test_items[1].result_value = 1
|
||||
lab_test.descriptive_test_items[2].result_value = 2.3
|
||||
lab_test.save()
|
||||
|
||||
# sample collection should not be created
|
||||
lab_test.reload()
|
||||
self.assertEquals(lab_test.sample, None)
|
||||
|
||||
def test_create_lab_tests_from_sales_invoice(self):
|
||||
sales_invoice = create_sales_invoice()
|
||||
create_multiple('Sales Invoice', sales_invoice.name)
|
||||
sales_invoice.reload()
|
||||
self.assertIsNotNone(sales_invoice.items[0].reference_dn)
|
||||
self.assertIsNotNone(sales_invoice.items[1].reference_dn)
|
||||
|
||||
def test_create_lab_tests_from_patient_encounter(self):
|
||||
patient_encounter = create_patient_encounter()
|
||||
create_multiple('Patient Encounter', patient_encounter.name)
|
||||
patient_encounter.reload()
|
||||
self.assertTrue(patient_encounter.lab_test_prescription[0].lab_test_created)
|
||||
self.assertTrue(patient_encounter.lab_test_prescription[0].lab_test_created)
|
||||
|
||||
|
||||
def create_lab_test_template(test_sensitivity=0, sample_collection=1):
|
||||
medical_department = create_medical_department()
|
||||
if frappe.db.exists('Lab Test Template', 'Insulin Resistance'):
|
||||
return frappe.get_doc('Lab Test Template', 'Insulin Resistance')
|
||||
template = frappe.new_doc('Lab Test Template')
|
||||
template.lab_test_name = 'Insulin Resistance'
|
||||
template.lab_test_template_type = 'Descriptive'
|
||||
template.lab_test_code = 'Insulin Resistance'
|
||||
template.lab_test_group = 'Services'
|
||||
template.department = medical_department
|
||||
template.is_billable = 1
|
||||
template.lab_test_description = 'Insulin Resistance'
|
||||
template.lab_test_rate = 2000
|
||||
|
||||
for entry in ['FBS', 'Insulin', 'IR']:
|
||||
template.append('descriptive_test_templates', {
|
||||
'particulars': entry,
|
||||
'allow_blank': 1 if entry=='IR' else 0
|
||||
})
|
||||
|
||||
if test_sensitivity:
|
||||
template.sensitivity = 1
|
||||
|
||||
if sample_collection:
|
||||
template.sample = create_lab_test_sample()
|
||||
template.sample_qty = 5.0
|
||||
|
||||
template.save()
|
||||
return template
|
||||
|
||||
def create_medical_department():
|
||||
medical_department = frappe.db.exists('Medical Department', '_Test Medical Department')
|
||||
if not medical_department:
|
||||
medical_department = frappe.new_doc('Medical Department')
|
||||
medical_department.department = '_Test Medical Department'
|
||||
medical_department.save()
|
||||
medical_department = medical_department.name
|
||||
|
||||
return medical_department
|
||||
|
||||
def create_lab_test(lab_template):
|
||||
patient = create_patient()
|
||||
lab_test = frappe.new_doc('Lab Test')
|
||||
lab_test.template = lab_template.name
|
||||
lab_test.patient = patient
|
||||
lab_test.patient_sex = 'Female'
|
||||
lab_test.save()
|
||||
|
||||
return lab_test
|
||||
|
||||
def create_lab_test_sample():
|
||||
blood_sample = frappe.db.exists('Lab Test Sample', 'Blood Sample')
|
||||
if blood_sample:
|
||||
return blood_sample
|
||||
|
||||
sample = frappe.new_doc('Lab Test Sample')
|
||||
sample.sample = 'Blood Sample'
|
||||
sample.sample_uom = 'U/ml'
|
||||
sample.save()
|
||||
|
||||
return sample.name
|
||||
|
||||
def create_sales_invoice():
|
||||
patient = create_patient()
|
||||
medical_department = create_medical_department()
|
||||
insulin_resistance_template = create_lab_test_template()
|
||||
blood_test_template = create_blood_test_template(medical_department)
|
||||
|
||||
sales_invoice = frappe.new_doc('Sales Invoice')
|
||||
sales_invoice.patient = patient
|
||||
sales_invoice.customer = frappe.db.get_value('Patient', patient, 'customer')
|
||||
sales_invoice.due_date = getdate()
|
||||
sales_invoice.company = '_Test Company'
|
||||
sales_invoice.debit_to = get_receivable_account('_Test Company')
|
||||
|
||||
tests = [insulin_resistance_template, blood_test_template]
|
||||
for entry in tests:
|
||||
sales_invoice.append('items', {
|
||||
'item_code': entry.item,
|
||||
'item_name': entry.lab_test_name,
|
||||
'description': entry.lab_test_description,
|
||||
'qty': 1,
|
||||
'uom': 'Nos',
|
||||
'conversion_factor': 1,
|
||||
'income_account': get_income_account(None, '_Test Company'),
|
||||
'rate': entry.lab_test_rate,
|
||||
'amount': entry.lab_test_rate
|
||||
})
|
||||
|
||||
sales_invoice.set_missing_values()
|
||||
|
||||
sales_invoice.submit()
|
||||
return sales_invoice
|
||||
|
||||
def create_patient_encounter():
|
||||
patient = create_patient()
|
||||
medical_department = create_medical_department()
|
||||
insulin_resistance_template = create_lab_test_template()
|
||||
blood_test_template = create_blood_test_template(medical_department)
|
||||
|
||||
patient_encounter = frappe.new_doc('Patient Encounter')
|
||||
patient_encounter.patient = patient
|
||||
patient_encounter.practitioner = create_practitioner()
|
||||
patient_encounter.encounter_date = getdate()
|
||||
patient_encounter.encounter_time = nowtime()
|
||||
|
||||
tests = [insulin_resistance_template, blood_test_template]
|
||||
for entry in tests:
|
||||
patient_encounter.append('lab_test_prescription', {
|
||||
'lab_test_code': entry.item,
|
||||
'lab_test_name': entry.lab_test_name
|
||||
})
|
||||
|
||||
patient_encounter.submit()
|
||||
return patient_encounter
|
||||
|
||||
|
||||
def create_practitioner():
|
||||
practitioner = frappe.db.exists('Healthcare Practitioner', '_Test Healthcare Practitioner')
|
||||
|
||||
if not practitioner:
|
||||
practitioner = frappe.new_doc('Healthcare Practitioner')
|
||||
practitioner.first_name = '_Test Healthcare Practitioner'
|
||||
practitioner.gender = 'Female'
|
||||
practitioner.op_consulting_charge = 500
|
||||
practitioner.inpatient_visit_charge = 500
|
||||
practitioner.save(ignore_permissions=True)
|
||||
practitioner = practitioner.name
|
||||
|
||||
return practitioner
|
||||
|
@ -93,7 +93,8 @@
|
||||
"depends_on": "secondary_uom",
|
||||
"fieldname": "conversion_factor",
|
||||
"fieldtype": "Float",
|
||||
"label": "Conversion Factor"
|
||||
"label": "Conversion Factor",
|
||||
"mandatory_depends_on": "secondary_uom"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@ -106,7 +107,7 @@
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-06-24 10:59:01.921924",
|
||||
"modified": "2020-07-30 12:36:03.082391",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Lab Test Group Template",
|
||||
|
@ -34,14 +34,15 @@
|
||||
"descriptive_test_templates",
|
||||
"section_break_group",
|
||||
"lab_test_groups",
|
||||
"medical_coding_section",
|
||||
"medical_code_standard",
|
||||
"medical_code",
|
||||
"sb_sample_collection",
|
||||
"sample",
|
||||
"sample_uom",
|
||||
"sample_qty",
|
||||
"column_break_33",
|
||||
"sample_details",
|
||||
"medical_coding_section",
|
||||
"medical_code",
|
||||
"medical_code_standard",
|
||||
"worksheet_section",
|
||||
"worksheet_instructions",
|
||||
"result_legend_section",
|
||||
@ -112,7 +113,7 @@
|
||||
{
|
||||
"default": "1",
|
||||
"depends_on": "eval:doc.lab_test_template_type != 'Grouped'",
|
||||
"description": "If unchecked, the item wont be appear in Sales Invoice, but can be used in group test creation. ",
|
||||
"description": "If unchecked, the item will not be available in Sales Invoices for billing but can be used in group test creation. ",
|
||||
"fieldname": "is_billable",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Billable",
|
||||
@ -128,6 +129,7 @@
|
||||
"mandatory_depends_on": "eval:doc.is_billable == 1"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "medical_coding_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Medical Coding"
|
||||
@ -184,7 +186,7 @@
|
||||
"depends_on": "eval:doc.lab_test_template_type == 'Descriptive'",
|
||||
"fieldname": "section_break_special",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Descriptive"
|
||||
"label": "Descriptive Test"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
@ -196,7 +198,7 @@
|
||||
"depends_on": "eval:doc.lab_test_template_type == 'Grouped'",
|
||||
"fieldname": "section_break_group",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Group"
|
||||
"label": "Group Tests"
|
||||
},
|
||||
{
|
||||
"fieldname": "lab_test_groups",
|
||||
@ -217,7 +219,6 @@
|
||||
"no_copy": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "sb_sample_collection",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Sample Collection"
|
||||
@ -311,10 +312,14 @@
|
||||
"fieldname": "descriptive_test_templates",
|
||||
"fieldtype": "Table",
|
||||
"options": "Descriptive Test Template"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_33",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-07-13 12:57:09.925436",
|
||||
"modified": "2020-07-30 14:32:40.449818",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Lab Test Template",
|
||||
|
@ -15,7 +15,8 @@ class LabTestTemplate(Document):
|
||||
|
||||
def validate(self):
|
||||
if self.is_billable and (not self.lab_test_rate or self.lab_test_rate <= 0.0):
|
||||
frappe.throw(_("Standard Selling Rate should be greater than zero."))
|
||||
frappe.throw(_('Standard Selling Rate should be greater than zero.'))
|
||||
|
||||
self.validate_conversion_factor()
|
||||
self.enable_disable_item()
|
||||
|
||||
@ -42,7 +43,9 @@ class LabTestTemplate(Document):
|
||||
# Remove template reference from item and disable item
|
||||
if self.item:
|
||||
try:
|
||||
frappe.delete_doc('Item', self.item)
|
||||
item = self.item
|
||||
self.db_set('item', '')
|
||||
frappe.delete_doc('Item', item)
|
||||
except Exception:
|
||||
frappe.throw(_('Not permitted. Please disable the Lab Test Template'))
|
||||
|
||||
@ -63,26 +66,26 @@ class LabTestTemplate(Document):
|
||||
'standard_rate': self.lab_test_rate,
|
||||
'description': self.lab_test_description
|
||||
})
|
||||
item.save()
|
||||
item.flags.ignore_mandatory = True
|
||||
item.save(ignore_permissions=True)
|
||||
|
||||
def item_price_exists(self):
|
||||
item_price = frappe.db.exists({'doctype': 'Item Price', 'item_code': self.lab_test_code})
|
||||
if item_price:
|
||||
return item_price[0][0]
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
|
||||
def validate_conversion_factor(self):
|
||||
if self.lab_test_template_type == "Single" and self.secondary_uom and not self.conversion_factor:
|
||||
frappe.throw(_("Conversion Factor is mandatory"))
|
||||
if self.lab_test_template_type == "Compound":
|
||||
if self.lab_test_template_type == 'Single' and self.secondary_uom and not self.conversion_factor:
|
||||
frappe.throw(_('Conversion Factor is mandatory'))
|
||||
if self.lab_test_template_type == 'Compound':
|
||||
for item in self.normal_test_templates:
|
||||
if item.secondary_uom and not item.conversion_factor:
|
||||
frappe.throw(_("Conversion Factor is mandatory"))
|
||||
if self.lab_test_template_type == "Grouped":
|
||||
frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(item.idx))
|
||||
if self.lab_test_template_type == 'Grouped':
|
||||
for group in self.lab_test_groups:
|
||||
if group.template_or_new_line == "Add New Line" and group.secondary_uom and not group.conversion_factor:
|
||||
frappe.throw(_("Conversion Factor is mandatory"))
|
||||
if group.template_or_new_line == 'Add New Line' and group.secondary_uom and not group.conversion_factor:
|
||||
frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(group.idx))
|
||||
|
||||
|
||||
def create_item_from_template(doc):
|
||||
@ -101,9 +104,9 @@ def create_item_from_template(doc):
|
||||
'include_item_in_manufacturing': 0,
|
||||
'show_in_website': 0,
|
||||
'is_pro_applicable': 0,
|
||||
'disabled': 0 if doc.is_billable and not doc.disabled else doc.disabled,
|
||||
'disabled': 0 if doc.is_billable and not doc.disabled else doc.disabled,
|
||||
'stock_uom': uom
|
||||
}).insert(ignore_permissions = True, ignore_mandatory = True)
|
||||
}).insert(ignore_permissions=True, ignore_mandatory=True)
|
||||
|
||||
# Insert item price
|
||||
if doc.is_billable and doc.lab_test_rate != 0.0:
|
||||
@ -123,7 +126,7 @@ def make_item_price(item, price_list_name, item_price):
|
||||
'price_list': price_list_name,
|
||||
'item_code': item,
|
||||
'price_list_rate': item_price
|
||||
}).insert(ignore_permissions = True, ignore_mandatory = True)
|
||||
}).insert(ignore_permissions=True, ignore_mandatory=True)
|
||||
|
||||
@frappe.whitelist()
|
||||
def change_test_code_from_template(lab_test_code, doc):
|
||||
@ -132,8 +135,8 @@ def change_test_code_from_template(lab_test_code, doc):
|
||||
if frappe.db.exists({'doctype': 'Item', 'item_code': lab_test_code}):
|
||||
frappe.throw(_('Lab Test Item {0} already exist').format(lab_test_code))
|
||||
else:
|
||||
rename_doc('Item', doc.name, lab_test_code, ignore_permissions = True)
|
||||
rename_doc('Item', doc.name, lab_test_code, ignore_permissions=True)
|
||||
frappe.db.set_value('Lab Test Template', doc.name, 'lab_test_code', lab_test_code)
|
||||
frappe.db.set_value('Lab Test Template', doc.name, 'lab_test_name', lab_test_code)
|
||||
rename_doc('Lab Test Template', doc.name, lab_test_code, ignore_permissions = True)
|
||||
rename_doc('Lab Test Template', doc.name, lab_test_code, ignore_permissions=True)
|
||||
return lab_test_code
|
||||
|
@ -0,0 +1,13 @@
|
||||
from __future__ import unicode_literals
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'template',
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Lab Tests'),
|
||||
'items': ['Lab Test']
|
||||
}
|
||||
]
|
||||
}
|
@ -3,5 +3,5 @@
|
||||
*/
|
||||
frappe.listview_settings['Lab Test Template'] = {
|
||||
add_fields: ['lab_test_name', 'lab_test_code', 'lab_test_rate'],
|
||||
filters: [['disabled', '=', 0]]
|
||||
filters: [['disabled', '=', 'No']]
|
||||
};
|
||||
|
@ -34,7 +34,7 @@ class TestPatientMedicalRecord(unittest.TestCase):
|
||||
self.assertTrue(medical_rec)
|
||||
|
||||
template = create_lab_test_template(medical_department)
|
||||
lab_test = create_lab_test(template, patient)
|
||||
lab_test = create_lab_test(template.name, patient)
|
||||
# check for lab test
|
||||
medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': lab_test.name})
|
||||
self.assertTrue(medical_rec)
|
||||
@ -66,7 +66,7 @@ def create_vital_signs(appointment):
|
||||
|
||||
def create_lab_test_template(medical_department):
|
||||
if frappe.db.exists('Lab Test Template', 'Blood Test'):
|
||||
return 'Blood Test'
|
||||
return frappe.get_doc('Lab Test Template', 'Blood Test')
|
||||
|
||||
template = frappe.new_doc('Lab Test Template')
|
||||
template.lab_test_name = 'Blood Test'
|
||||
@ -76,7 +76,7 @@ def create_lab_test_template(medical_department):
|
||||
template.is_billable = 1
|
||||
template.lab_test_rate = 2000
|
||||
template.save()
|
||||
return template.name
|
||||
return template
|
||||
|
||||
def create_lab_test(template, patient):
|
||||
lab_test = frappe.new_doc('Lab Test')
|
||||
|
@ -3,29 +3,29 @@
|
||||
|
||||
frappe.ui.form.on('Sample Collection', {
|
||||
refresh: function(frm) {
|
||||
if(frappe.defaults.get_default("create_sample_collection_for_lab_test")){
|
||||
frm.add_custom_button(__("View Lab Tests"), function() {
|
||||
frappe.route_options = {"sample": frm.doc.name};
|
||||
frappe.set_route("List", "Lab Test");
|
||||
if (frappe.defaults.get_default('create_sample_collection_for_lab_test')) {
|
||||
frm.add_custom_button(__('View Lab Tests'), function() {
|
||||
frappe.route_options = {'sample': frm.doc.name};
|
||||
frappe.set_route('List', 'Lab Test');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Sample Collection", "patient", function(frm) {
|
||||
frappe.ui.form.on('Sample Collection', 'patient', function(frm) {
|
||||
if(frm.doc.patient){
|
||||
frappe.call({
|
||||
"method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail",
|
||||
'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
|
||||
args: {
|
||||
patient: frm.doc.patient
|
||||
},
|
||||
callback: function (data) {
|
||||
var age = null;
|
||||
if(data.message.dob){
|
||||
if (data.message.dob){
|
||||
age = calculate_age(data.message.dob);
|
||||
}
|
||||
frappe.model.set_value(frm.doctype,frm.docname, "patient_age", age);
|
||||
frappe.model.set_value(frm.doctype,frm.docname, "patient_sex", data.message.sex);
|
||||
frappe.model.set_value(frm.doctype,frm.docname, 'patient_age', age);
|
||||
frappe.model.set_value(frm.doctype,frm.docname, 'patient_sex', data.message.sex);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -36,5 +36,5 @@ var calculate_age = function(birth) {
|
||||
var age = new Date();
|
||||
age.setTime(ageMS);
|
||||
var years = age.getFullYear() - 1970;
|
||||
return years + " Year(s) " + age.getMonth() + " Month(s) " + age.getDate() + " Day(s)";
|
||||
return years + ' Year(s) ' + age.getMonth() + ' Month(s) ' + age.getDate() + ' Day(s)';
|
||||
};
|
||||
|
@ -9,8 +9,10 @@
|
||||
"document_type": "Document",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"patient_details_section",
|
||||
"naming_series",
|
||||
"patient",
|
||||
"patient_name",
|
||||
"patient_age",
|
||||
"patient_sex",
|
||||
"column_break_4",
|
||||
@ -25,15 +27,17 @@
|
||||
"collected_by",
|
||||
"collected_time",
|
||||
"num_print",
|
||||
"amended_from",
|
||||
"section_break_15",
|
||||
"sample_details"
|
||||
"sample_details",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fetch_from": "patient.inpatient_record",
|
||||
"fieldname": "inpatient_record",
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Inpatient Record",
|
||||
"options": "Inpatient Record",
|
||||
"read_only": 1
|
||||
@ -42,6 +46,8 @@
|
||||
"bold": 1,
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Series",
|
||||
"no_copy": 1,
|
||||
"options": "HLC-SC-.YYYY.-",
|
||||
@ -52,6 +58,8 @@
|
||||
"default": "0",
|
||||
"fieldname": "invoiced",
|
||||
"fieldtype": "Check",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Invoiced",
|
||||
"no_copy": 1,
|
||||
"read_only": 1,
|
||||
@ -61,41 +69,60 @@
|
||||
"fetch_from": "inpatient_record.patient",
|
||||
"fieldname": "patient",
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Patient",
|
||||
"options": "Patient",
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "patient_age",
|
||||
"fieldtype": "Data",
|
||||
"label": "Age"
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Age",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "patient.sex",
|
||||
"fieldname": "patient_sex",
|
||||
"fieldtype": "Data",
|
||||
"label": "Gender"
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Gender",
|
||||
"options": "Gender",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Company",
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Sample Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "sample",
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
@ -108,16 +135,23 @@
|
||||
"fetch_from": "sample.sample_uom",
|
||||
"fieldname": "sample_uom",
|
||||
"fieldtype": "Data",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "UOM"
|
||||
"label": "UOM",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_10",
|
||||
"fieldtype": "Column Break"
|
||||
"fieldtype": "Column Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "collected_by",
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Collected By",
|
||||
"options": "User"
|
||||
@ -125,20 +159,27 @@
|
||||
{
|
||||
"fieldname": "collected_time",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Collected Time"
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Collected On"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"default": "1",
|
||||
"description": "Number of prints required for labelling the samples",
|
||||
"fieldname": "num_print",
|
||||
"fieldtype": "Int",
|
||||
"label": "No. of print",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "No. of prints",
|
||||
"print_hide": 1,
|
||||
"report_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Sample Collection",
|
||||
@ -147,25 +188,43 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_15",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "sample_qty",
|
||||
"fieldtype": "Float",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Quantity"
|
||||
},
|
||||
{
|
||||
"fieldname": "sample_details",
|
||||
"fieldtype": "Long Text",
|
||||
"hide_days": 1,
|
||||
"hide_seconds": 1,
|
||||
"ignore_xss_filter": 1,
|
||||
"label": "Collection Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "patient_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Patient Details"
|
||||
},
|
||||
{
|
||||
"fetch_from": "patient.patient_name",
|
||||
"fieldname": "patient_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Patient Name",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-05-25 14:36:46.990469",
|
||||
"modified": "2020-07-30 16:53:13.076104",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Sample Collection",
|
||||
|
@ -3,7 +3,12 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import flt
|
||||
from frappe import _
|
||||
|
||||
class SampleCollection(Document):
|
||||
pass
|
||||
def validate(self):
|
||||
if flt(self.sample_qty) <= 0:
|
||||
frappe.throw(_('Sample Quantity cannot be negative or 0'), title=_('Invalid Quantity'))
|
||||
|
@ -4,29 +4,54 @@
|
||||
frappe.query_reports["Lab Test Report"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
"fieldname": "from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.datetime.now_date(),
|
||||
"width": "80"
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname":"to_date",
|
||||
"fieldname": "to_date",
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.datetime.now_date()
|
||||
"default": frappe.datetime.now_date(),
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname":"patient",
|
||||
"fieldname": "company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"default": frappe.defaults.get_default("Company"),
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"fieldname": "template",
|
||||
"label": __("Lab Test Template"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Lab Test Template"
|
||||
},
|
||||
{
|
||||
"fieldname": "patient",
|
||||
"label": __("Patient"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Patient"
|
||||
},
|
||||
{
|
||||
"fieldname":"department",
|
||||
"fieldname": "department",
|
||||
"label": __("Medical Department"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Medical Department"
|
||||
},
|
||||
{
|
||||
"fieldname": "status",
|
||||
"label": __("Status"),
|
||||
"fieldtype": "Select",
|
||||
"options": "\nCompleted\nApproved\nRejected"
|
||||
},
|
||||
{
|
||||
"fieldname": "invoiced",
|
||||
"label": __("Invoiced"),
|
||||
"fieldtype": "Check"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -1,30 +1,31 @@
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"creation": "2013-04-23 18:15:29",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 1,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2018-08-06 11:41:50.218737",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Lab Test Report",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"ref_doctype": "Lab Test",
|
||||
"report_name": "Lab Test Report",
|
||||
"report_type": "Script Report",
|
||||
"add_total_row": 0,
|
||||
"creation": "2013-04-23 18:15:29",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 1,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2020-07-30 18:53:20.102873",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Healthcare",
|
||||
"name": "Lab Test Report",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"ref_doctype": "Lab Test",
|
||||
"report_name": "Lab Test Report",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Laboratory User"
|
||||
},
|
||||
},
|
||||
{
|
||||
"role": "Nursing User"
|
||||
},
|
||||
},
|
||||
{
|
||||
"role": "LabTest Approver"
|
||||
},
|
||||
},
|
||||
{
|
||||
"role": "Healthcare Administrator"
|
||||
}
|
||||
|
@ -8,51 +8,204 @@ from frappe import msgprint, _
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
lab_test_list = get_lab_test(filters)
|
||||
data, columns = [], []
|
||||
|
||||
columns = get_columns()
|
||||
lab_test_list = get_lab_tests(filters)
|
||||
|
||||
if not lab_test_list:
|
||||
msgprint(_("No record found"))
|
||||
msgprint(_('No records found'))
|
||||
return columns, lab_test_list
|
||||
|
||||
data = []
|
||||
for lab_test in lab_test_list:
|
||||
row = [ lab_test.lab_test_name, lab_test.patient, lab_test.practitioner, lab_test.invoiced, lab_test.status, lab_test.result_date, lab_test.department]
|
||||
row = frappe._dict({
|
||||
'test': lab_test.name,
|
||||
'template': lab_test.template,
|
||||
'company': lab_test.company,
|
||||
'patient': lab_test.patient,
|
||||
'patient_name': lab_test.patient_name,
|
||||
'practitioner': lab_test.practitioner,
|
||||
'employee': lab_test.employee,
|
||||
'status': lab_test.status,
|
||||
'invoiced': lab_test.invoiced,
|
||||
'result_date': lab_test.result_date,
|
||||
'department': lab_test.department
|
||||
})
|
||||
data.append(row)
|
||||
|
||||
return columns, data
|
||||
chart = get_chart_data(data)
|
||||
report_summary = get_report_summary(data)
|
||||
return columns, data, None, chart, report_summary
|
||||
|
||||
|
||||
def get_columns():
|
||||
columns = [
|
||||
_("Test") + ":Data:120",
|
||||
_("Patient") + ":Link/Patient:180",
|
||||
_("Healthcare Practitioner") + ":Link/Healthcare Practitioner:120",
|
||||
_("Invoiced") + ":Check:100",
|
||||
_("Status") + ":Data:120",
|
||||
_("Result Date") + ":Date:120",
|
||||
_("Department") + ":Data:120",
|
||||
return [
|
||||
{
|
||||
'fieldname': 'test',
|
||||
'label': _('Lab Test'),
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Lab Test',
|
||||
'width': '120'
|
||||
},
|
||||
{
|
||||
'fieldname': 'template',
|
||||
'label': _('Lab Test Template'),
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Lab Test Template',
|
||||
'width': '120'
|
||||
},
|
||||
{
|
||||
'fieldname': 'company',
|
||||
'label': _('Company'),
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Company',
|
||||
'width': '120'
|
||||
},
|
||||
{
|
||||
'fieldname': 'patient',
|
||||
'label': _('Patient'),
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Patient',
|
||||
'width': '120'
|
||||
},
|
||||
{
|
||||
'fieldname': 'patient_name',
|
||||
'label': _('Patient Name'),
|
||||
'fieldtype': 'Data',
|
||||
'width': '120'
|
||||
},
|
||||
{
|
||||
'fieldname': 'employee',
|
||||
'label': _('Lab Technician'),
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Employee',
|
||||
'width': '120'
|
||||
},
|
||||
{
|
||||
'fieldname': 'status',
|
||||
'label': _('Status'),
|
||||
'fieldtype': 'Data',
|
||||
'width': '100'
|
||||
},
|
||||
{
|
||||
'fieldname': 'invoiced',
|
||||
'label': _('Invoiced'),
|
||||
'fieldtype': 'Check',
|
||||
'width': '100'
|
||||
},
|
||||
{
|
||||
'fieldname': 'result_date',
|
||||
'label': _('Result Date'),
|
||||
'fieldtype': 'Date',
|
||||
'width': '100'
|
||||
},
|
||||
{
|
||||
'fieldname': 'practitioner',
|
||||
'label': _('Requesting Practitioner'),
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Healthcare Practitioner',
|
||||
'width': '120'
|
||||
},
|
||||
{
|
||||
'fieldname': 'department',
|
||||
'label': _('Medical Department'),
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Medical Department',
|
||||
'width': '100'
|
||||
}
|
||||
]
|
||||
|
||||
return columns
|
||||
def get_lab_tests(filters):
|
||||
conditions = get_conditions(filters)
|
||||
data = frappe.get_all(
|
||||
doctype='Lab Test',
|
||||
fields=['name', 'template', 'company', 'patient', 'patient_name', 'practitioner', 'employee', 'status', 'invoiced', 'result_date', 'department'],
|
||||
filters=conditions,
|
||||
order_by='submitted_date desc'
|
||||
)
|
||||
return data
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
conditions = {
|
||||
'docstatus': ('=', 1)
|
||||
}
|
||||
|
||||
if filters.get("patient"):
|
||||
conditions += "and patient = %(patient)s"
|
||||
if filters.get("from_date"):
|
||||
conditions += "and result_date >= %(from_date)s"
|
||||
if filters.get("to_date"):
|
||||
conditions += " and result_date <= %(to_date)s"
|
||||
if filters.get("department"):
|
||||
conditions += " and department = %(department)s"
|
||||
if filters.get('from_date') and filters.get('to_date'):
|
||||
conditions['result_date'] = ('between', (filters.get('from_date'), filters.get('to_date')))
|
||||
filters.pop('from_date')
|
||||
filters.pop('to_date')
|
||||
|
||||
for key, value in filters.items():
|
||||
if filters.get(key):
|
||||
conditions[key] = value
|
||||
|
||||
return conditions
|
||||
|
||||
def get_lab_test(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""select name, patient, lab_test_name, patient_name, status, result_date, practitioner, invoiced, department
|
||||
from `tabLab Test`
|
||||
where docstatus<2 %s order by submitted_date desc, name desc""" %
|
||||
conditions, filters, as_dict=1)
|
||||
def get_chart_data(data):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
labels = ['Completed', 'Approved', 'Rejected']
|
||||
|
||||
status_wise_data = {
|
||||
'Completed': 0,
|
||||
'Approved': 0,
|
||||
'Rejected': 0
|
||||
}
|
||||
|
||||
datasets = []
|
||||
|
||||
for entry in data:
|
||||
status_wise_data[entry.status] += 1
|
||||
|
||||
datasets.append({
|
||||
'name': 'Lab Test Status',
|
||||
'values': [status_wise_data.get('Completed'), status_wise_data.get('Approved'), status_wise_data.get('Rejected')]
|
||||
})
|
||||
|
||||
chart = {
|
||||
'data': {
|
||||
'labels': labels,
|
||||
'datasets': datasets
|
||||
},
|
||||
'type': 'donut',
|
||||
'height': 300,
|
||||
}
|
||||
|
||||
return chart
|
||||
|
||||
|
||||
def get_report_summary(data):
|
||||
if not data:
|
||||
return None
|
||||
|
||||
total_lab_tests = len(data)
|
||||
invoiced_lab_tests, unbilled_lab_tests = 0, 0
|
||||
|
||||
for entry in data:
|
||||
if entry.invoiced:
|
||||
invoiced_lab_tests += 1
|
||||
else:
|
||||
unbilled_lab_tests += 1
|
||||
|
||||
return [
|
||||
{
|
||||
'value': total_lab_tests,
|
||||
'indicator': 'Blue',
|
||||
'label': 'Total Lab Tests',
|
||||
'datatype': 'Int',
|
||||
},
|
||||
{
|
||||
'value': invoiced_lab_tests,
|
||||
'indicator': 'Green',
|
||||
'label': 'Invoiced Lab Tests',
|
||||
'datatype': 'Int',
|
||||
},
|
||||
{
|
||||
'value': unbilled_lab_tests,
|
||||
'indicator': 'Red',
|
||||
'label': 'Unbilled Lab Tests',
|
||||
'datatype': 'Int',
|
||||
}
|
||||
]
|
||||
|
@ -417,7 +417,42 @@ class TestSalesOrder(unittest.TestCase):
|
||||
# add new item
|
||||
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 100, 'qty' : 2}])
|
||||
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Sales Order', trans_item, so.name)
|
||||
test_user.remove_roles("Accounts User")
|
||||
frappe.set_user("Administrator")
|
||||
|
||||
def test_update_child_qty_rate_with_workflow(self):
|
||||
from frappe.model.workflow import apply_workflow
|
||||
|
||||
workflow = make_sales_order_workflow()
|
||||
so = make_sales_order(item_code= "_Test Item", qty=1, rate=150, do_not_submit=1)
|
||||
apply_workflow(so, 'Approve')
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
user = 'test@example.com'
|
||||
test_user = frappe.get_doc('User', user)
|
||||
test_user.add_roles("Sales User", "Test Junior Approver")
|
||||
frappe.set_user(user)
|
||||
|
||||
# user shouldn't be able to edit since grand_total will become > 200 if qty is doubled
|
||||
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 150, 'qty' : 2, 'docname': so.items[0].name}])
|
||||
self.assertRaises(frappe.ValidationError, update_child_qty_rate, 'Sales Order', trans_item, so.name)
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
user2 = 'test2@example.com'
|
||||
test_user2 = frappe.get_doc('User', user2)
|
||||
test_user2.add_roles("Sales User", "Test Approver")
|
||||
frappe.set_user(user2)
|
||||
|
||||
# Test Approver is allowed to edit with grand_total > 200
|
||||
update_child_qty_rate("Sales Order", trans_item, so.name)
|
||||
so.reload()
|
||||
self.assertEqual(so.items[0].qty, 2)
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
test_user.remove_roles("Sales User", "Test Junior Approver", "Test Approver")
|
||||
test_user2.remove_roles("Sales User", "Test Junior Approver", "Test Approver")
|
||||
workflow.is_active = 0
|
||||
workflow.save()
|
||||
|
||||
def test_update_child_qty_rate_product_bundle(self):
|
||||
# test Update Items with product bundle
|
||||
@ -973,3 +1008,37 @@ def get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"):
|
||||
"reserved_qty"))
|
||||
|
||||
test_dependencies = ["Currency Exchange"]
|
||||
|
||||
def make_sales_order_workflow():
|
||||
if frappe.db.exists('Workflow', 'SO Test Workflow'):
|
||||
doc = frappe.get_doc("Workflow", "SO Test Workflow")
|
||||
doc.set("is_active", 1)
|
||||
doc.save()
|
||||
return doc
|
||||
|
||||
frappe.get_doc(dict(doctype='Role', role_name='Test Junior Approver')).insert(ignore_if_duplicate=True)
|
||||
frappe.get_doc(dict(doctype='Role', role_name='Test Approver')).insert(ignore_if_duplicate=True)
|
||||
frappe.db.commit()
|
||||
frappe.cache().hdel('roles', frappe.session.user)
|
||||
|
||||
workflow = frappe.get_doc({
|
||||
"doctype": "Workflow",
|
||||
"workflow_name": "SO Test Workflow",
|
||||
"document_type": "Sales Order",
|
||||
"workflow_state_field": "workflow_state",
|
||||
"is_active": 1,
|
||||
"send_email_alert": 0,
|
||||
})
|
||||
workflow.append('states', dict( state = 'Pending', allow_edit = 'All' ))
|
||||
workflow.append('states', dict( state = 'Approved', allow_edit = 'Test Approver', doc_status = 1 ))
|
||||
workflow.append('transitions', dict(
|
||||
state = 'Pending', action = 'Approve', next_state = 'Approved', allowed = 'Test Junior Approver', allow_self_approval = 1,
|
||||
condition = 'doc.grand_total < 200'
|
||||
))
|
||||
workflow.append('transitions', dict(
|
||||
state = 'Pending', action = 'Approve', next_state = 'Approved', allowed = 'Test Approver', allow_self_approval = 1,
|
||||
condition = 'doc.grand_total > 200'
|
||||
))
|
||||
workflow.insert(ignore_permissions=True)
|
||||
|
||||
return workflow
|
@ -130,12 +130,18 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
||||
if (this.frm.doc.docstatus===0) {
|
||||
this.frm.add_custom_button(__('Sales Order'),
|
||||
function() {
|
||||
if (!me.frm.doc.customer) {
|
||||
frappe.throw({
|
||||
title: __("Mandatory"),
|
||||
message: __("Please Select a Customer")
|
||||
});
|
||||
}
|
||||
erpnext.utils.map_current_doc({
|
||||
method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
|
||||
source_doctype: "Sales Order",
|
||||
target: me.frm,
|
||||
setters: {
|
||||
customer: me.frm.doc.customer || undefined,
|
||||
customer: me.frm.doc.customer,
|
||||
},
|
||||
get_query_filters: {
|
||||
docstatus: 1,
|
||||
|
@ -116,12 +116,18 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
|
||||
if (this.frm.doc.docstatus == 0) {
|
||||
this.frm.add_custom_button(__('Purchase Order'),
|
||||
function () {
|
||||
if (!me.frm.doc.supplier) {
|
||||
frappe.throw({
|
||||
title: __("Mandatory"),
|
||||
message: __("Please Select a Supplier")
|
||||
});
|
||||
}
|
||||
erpnext.utils.map_current_doc({
|
||||
method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
|
||||
source_doctype: "Purchase Order",
|
||||
target: me.frm,
|
||||
setters: {
|
||||
supplier: me.frm.doc.supplier || undefined,
|
||||
supplier: me.frm.doc.supplier,
|
||||
},
|
||||
get_query_filters: {
|
||||
docstatus: 1,
|
||||
|
@ -73,7 +73,8 @@
|
||||
"fieldname": "reference_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Reference Type",
|
||||
"options": "\nPurchase Receipt\nPurchase Invoice\nDelivery Note\nSales Invoice\nStock Entry"
|
||||
"options": "\nPurchase Receipt\nPurchase Invoice\nDelivery Note\nSales Invoice\nStock Entry",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "reference_name",
|
||||
@ -84,7 +85,8 @@
|
||||
"label": "Reference Name",
|
||||
"oldfieldname": "purchase_receipt_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "reference_type"
|
||||
"options": "reference_type",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_7",
|
||||
@ -231,9 +233,10 @@
|
||||
],
|
||||
"icon": "fa fa-search",
|
||||
"idx": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-04-26 17:50:25.068222",
|
||||
"modified": "2020-09-12 16:11:31.910508",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Quality Inspection",
|
||||
|
Loading…
Reference in New Issue
Block a user