Merge branch 'develop' into sales-analytics

This commit is contained in:
Anupam Kumar
2020-09-14 11:21:58 -07:00
committed by GitHub
27 changed files with 1055 additions and 1399 deletions

View File

@@ -55,7 +55,7 @@ class BankStatementTransactionEntry(Document):
def populate_payment_entries(self): def populate_payment_entries(self):
if self.bank_statement is None: return 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): if (len(self.new_transaction_items + self.reconciled_transaction_items) > 0):
frappe.throw(_("Transactions already retreived from the statement")) frappe.throw(_("Transactions already retreived from the statement"))
@@ -65,7 +65,7 @@ class BankStatementTransactionEntry(Document):
if self.bank_settings: if self.bank_settings:
mapped_items = frappe.get_doc("Bank Statement Settings", self.bank_settings).mapped_items mapped_items = frappe.get_doc("Bank Statement Settings", self.bank_settings).mapped_items
statement_headers = self.get_statement_headers() 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: for entry in transactions:
date = entry[statement_headers["Date"]].strip() 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"])) #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] = "" transaction[header] = ""
return transaction return transaction
def get_transaction_entries(filename, headers): def get_transaction_entries(file_url, headers):
header_index = {} header_index = {}
rows, transactions = [], [] rows, transactions = [], []
if (filename.lower().endswith("xlsx")): if (file_url.lower().endswith("xlsx")):
from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file
rows = read_xlsx_file_from_attached_file(file_id=filename) rows = read_xlsx_file_from_attached_file(file_url=file_url)
elif (filename.lower().endswith("csv")): elif (file_url.lower().endswith("csv")):
from frappe.utils.csvutils import read_csv_content 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() filepath = _file.get_full_path()
with open(filepath,'rb') as csvfile: with open(filepath,'rb') as csvfile:
rows = read_csv_content(csvfile.read()) 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) rows = get_rows_from_xls_file(filename)
else: else:
frappe.throw(_("Only .csv and .xlsx files are supported currently")) frappe.throw(_("Only .csv and .xlsx files are supported currently"))

View File

@@ -7,6 +7,7 @@ import json
from frappe import _, throw from frappe import _, throw
from frappe.utils import (today, flt, cint, fmt_money, formatdate, from frappe.utils import (today, flt, cint, fmt_money, formatdate,
getdate, add_days, add_months, get_last_day, nowdate, get_link_to_form) 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.stock.get_item_details import get_conversion_factor, get_item_details
from erpnext.setup.utils import get_exchange_rate from erpnext.setup.utils import get_exchange_rate
from erpnext.accounts.utils import get_fiscal_years, validate_fiscal_year, get_account_currency 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 child_item.base_amount = 1 # Initiallize value will update in parent validation
return child_item return child_item
def check_and_delete_children(parent, data): def validate_and_delete_children(parent, data):
deleted_children = [] deleted_children = []
updated_item_names = [d.get("docname") for d in data] updated_item_names = [d.get("docname") for d in data]
for item in parent.items: for item in parent.items:
@@ -1221,18 +1222,37 @@ def check_and_delete_children(parent, data):
@frappe.whitelist() @frappe.whitelist()
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"): 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: try:
doc.check_permission(perm_type) doc.check_permission(perm_type)
except: except frappe.PermissionError:
action = "add" if perm_type == 'create' else "update" actions = { 'create': 'add', 'write': 'update', 'cancel': 'remove' }
frappe.throw(_("You do not have permissions to {} items in a Sales Order.").format(action), title=_("Insufficient Permissions"))
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): def get_new_child_item(item_row):
if parent_doctype == "Sales Order": new_child_function = set_sales_order_defaults if parent_doctype == "Sales Order" else set_purchase_order_defaults
return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row) return new_child_function(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)
def validate_quantity(child_item, d): def validate_quantity(child_item, d):
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty): 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'] sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation']
parent = frappe.get_doc(parent_doctype, parent_doctype_name) 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: for d in data:
new_child_flag = False new_child_flag = False
if not d.get("docname"): if not d.get("docname"):
new_child_flag = True new_child_flag = True
check_permissions(parent, 'create') check_doc_permissions(parent, 'create')
child_item = get_new_child_item(d) child_item = get_new_child_item(d)
else: else:
check_permissions(parent, 'write') check_doc_permissions(parent, 'write')
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname")) child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
prev_rate, new_rate = flt(child_item.get("rate")), flt(d.get("rate")) 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_prevdoc_status('submit')
parent.update_delivery_status() parent.update_delivery_status()
parent.reload()
validate_workflow_conditions(parent)
parent.update_blanket_order() parent.update_blanket_order()
parent.update_billing_percentage() parent.update_billing_percentage()
parent.set_status() parent.set_status()

View File

@@ -3,15 +3,15 @@
frappe.ui.form.on('Student', { frappe.ui.form.on('Student', {
setup: function(frm) { setup: function(frm) {
frm.add_fetch("guardian", "guardian_name", "guardian_name"); frm.add_fetch('guardian', 'guardian_name', 'guardian_name');
frm.add_fetch("student", "title", "full_name"); frm.add_fetch('student', 'title', 'full_name');
frm.add_fetch("student", "gender", "gender"); frm.add_fetch('student', 'gender', 'gender');
frm.add_fetch("student", "date_of_birth", "date_of_birth"); 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 { return {
"filters": { 'filters': {
"name": ["!=", doc.name] 'name': ['!=', doc.name]
} }
}; };
}) })
@@ -25,6 +25,12 @@ frappe.ui.form.on('Student', {
{party_type:'Student', party:frm.doc.name}); {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);
}
});
} }
}); });

View File

@@ -102,7 +102,6 @@
"fieldtype": "Data", "fieldtype": "Data",
"in_global_search": 1, "in_global_search": 1,
"label": "Student Email Address", "label": "Student Email Address",
"reqd": 1,
"unique": 1 "unique": 1
}, },
{ {
@@ -255,7 +254,7 @@
], ],
"image_field": "image", "image_field": "image",
"links": [], "links": [],
"modified": "2020-07-23 18:14:06.366442", "modified": "2020-09-07 19:28:08.914568",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Education", "module": "Education",
"name": "Student", "name": "Student",

View File

@@ -7,7 +7,7 @@ frappe.ui.form.on("Student Applicant", {
}, },
refresh: function(frm) { 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.add_custom_button(__("Approve"), function() {
frm.set_value("application_status", "Approved"); frm.set_value("application_status", "Approved");
frm.save_or_update(); frm.save_or_update();
@@ -20,10 +20,11 @@ frappe.ui.form.on("Student Applicant", {
}, 'Actions'); }, '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.add_custom_button(__("Enroll"), function() {
frm.events.enroll(frm) frm.events.enroll(frm)
}).addClass("btn-primary"); }).addClass("btn-primary");
frm.add_custom_button(__("Reject"), function() { frm.add_custom_button(__("Reject"), function() {
frm.set_value("application_status", "Rejected"); frm.set_value("application_status", "Rejected");
frm.save_or_update(); frm.save_or_update();
@@ -35,7 +36,13 @@ frappe.ui.form.on("Student Applicant", {
frappe.hide_msgprint(true); frappe.hide_msgprint(true);
frappe.show_progress(__("Enrolling student"), data.progress[0],data.progress[1]); 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) { enroll: function(frm) {

View File

@@ -34,10 +34,10 @@ frappe.ui.form.on('Lab Test', {
if (frm.doc.docstatus === 1 && frm.doc.status !== 'Approved' && frm.doc.status !== 'Rejected') { if (frm.doc.docstatus === 1 && frm.doc.status !== 'Approved' && frm.doc.status !== 'Rejected') {
frm.add_custom_button(__('Approve'), function () { frm.add_custom_button(__('Approve'), function () {
status_update(1, frm); status_update(1, frm);
}); }, __('Actions'));
frm.add_custom_button(__('Reject'), function () { frm.add_custom_button(__('Reject'), function () {
status_update(0, frm); status_update(0, frm);
}); }, __('Actions'));
} }
} }
@@ -179,23 +179,6 @@ var show_lab_tests = function (frm, lab_test_list) {
d.show(); 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 make_dialog = function (frm, emailed, printed) {
var number = frm.doc.mobile; var number = frm.doc.mobile;
@@ -203,7 +186,7 @@ var make_dialog = function (frm, emailed, printed) {
title: 'Send SMS', title: 'Send SMS',
width: 400, width: 400,
fields: [ 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: 'number', fieldtype: 'Data', label: 'Mobile Number', reqd: 1 },
{ fieldname: 'message', fieldtype: 'Small Text', label: 'Message', reqd: 1 } { fieldname: 'message', fieldtype: 'Small Text', label: 'Message', reqd: 1 }
], ],
@@ -217,22 +200,22 @@ var make_dialog = function (frm, emailed, printed) {
dialog.hide(); dialog.hide();
} }
}); });
if (frm.doc.report_preference == 'Print') { if (frm.doc.report_preference === 'Print') {
dialog.set_values({ dialog.set_values({
'sms_type': 'Printed', 'result_format': 'Printed',
'number': number, 'number': number,
'message': printed 'message': printed
}); });
} else { } else {
dialog.set_values({ dialog.set_values({
'sms_type': 'Emailed', 'result_format': 'Emailed',
'number': number, 'number': number,
'message': emailed 'message': emailed
}); });
} }
var fd = dialog.fields_dict; var fd = dialog.fields_dict;
$(fd.sms_type.input).change(function () { $(fd.result_format.input).change(function () {
if (dialog.get_value('sms_type') == 'Emailed') { if (dialog.get_value('result_format') === 'Emailed') {
dialog.set_values({ dialog.set_values({
'number': number, 'number': number,
'message': emailed 'message': emailed

View File

@@ -84,7 +84,7 @@
"fieldname": "naming_series", "fieldname": "naming_series",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Series", "label": "Series",
"options": "LP-", "options": "HLC-LAB-.YYYY.-",
"print_hide": 1, "print_hide": 1,
"report_hide": 1, "report_hide": 1,
"reqd": 1 "reqd": 1
@@ -197,11 +197,10 @@
{ {
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"in_list_view": 1,
"label": "Status", "label": "Status",
"options": "Draft\nCompleted\nApproved\nRejected\nCancelled", "options": "Draft\nCompleted\nApproved\nRejected\nCancelled",
"print_hide": 1,
"read_only": 1, "read_only": 1,
"report_hide": 1,
"search_index": 1 "search_index": 1
}, },
{ {
@@ -249,8 +248,8 @@
{ {
"fieldname": "result_date", "fieldname": "result_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 1,
"label": "Result Date", "label": "Result Date",
"read_only": 1,
"search_index": 1 "search_index": 1
}, },
{ {
@@ -354,7 +353,8 @@
}, },
{ {
"fieldname": "sb_normal", "fieldname": "sb_normal",
"fieldtype": "Section Break" "fieldtype": "Section Break",
"label": "Compound Test Result"
}, },
{ {
"fieldname": "normal_test_items", "fieldname": "normal_test_items",
@@ -369,11 +369,13 @@
{ {
"depends_on": "descriptive_toggle", "depends_on": "descriptive_toggle",
"fieldname": "organisms_section", "fieldname": "organisms_section",
"fieldtype": "Section Break" "fieldtype": "Section Break",
"label": "Organism Test Result"
}, },
{ {
"fieldname": "sb_sensitivity", "fieldname": "sb_sensitivity",
"fieldtype": "Section Break" "fieldtype": "Section Break",
"label": "Sensitivity Test Result"
}, },
{ {
"fieldname": "sensitivity_test_items", "fieldname": "sensitivity_test_items",
@@ -383,8 +385,10 @@
"report_hide": 1 "report_hide": 1
}, },
{ {
"collapsible": 1,
"fieldname": "sb_comments", "fieldname": "sb_comments",
"fieldtype": "Section Break" "fieldtype": "Section Break",
"label": "Comments"
}, },
{ {
"fieldname": "lab_test_comment", "fieldname": "lab_test_comment",
@@ -531,7 +535,8 @@
}, },
{ {
"fieldname": "sb_descriptive", "fieldname": "sb_descriptive",
"fieldtype": "Section Break" "fieldtype": "Section Break",
"label": "Descriptive Test Result"
}, },
{ {
"default": "0", "default": "0",
@@ -550,7 +555,7 @@
], ],
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-07-16 13:35:24.811062", "modified": "2020-07-30 18:18:38.516215",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Healthcare", "module": "Healthcare",
"name": "Lab Test", "name": "Lab Test",

View File

@@ -6,23 +6,24 @@ from __future__ import unicode_literals
import frappe import frappe
from frappe import _ from frappe import _
from frappe.model.document import Document 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): class LabTest(Document):
def validate(self):
if not self.is_new():
self.set_secondary_uom_result()
def on_submit(self): def on_submit(self):
self.validate_result_values()
self.db_set('submitted_date', getdate()) self.db_set('submitted_date', getdate())
self.db_set('status', 'Completed') self.db_set('status', 'Completed')
insert_lab_test_to_medical_record(self) insert_lab_test_to_medical_record(self)
def on_cancel(self): def on_cancel(self):
delete_lab_test_from_medical_record(self)
self.db_set('status', 'Cancelled') self.db_set('status', 'Cancelled')
delete_lab_test_from_medical_record(self)
self.reload() self.reload()
def validate(self):
if not self.is_new():
self.set_secondary_uom_result()
def on_update(self): def on_update(self):
if self.sensitivity_test_items: if self.sensitivity_test_items:
sensitivity = sorted(self.sensitivity_test_items, key=lambda x: x.antibiotic_sensitivity) 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) item.secondary_uom_result = float(item.result_value) * float(item.conversion_factor)
except: except:
item.secondary_uom_result = '' 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): 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) lab_test_created = create_lab_test_from_encounter(docname)
if lab_test_created: 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: else:
frappe.msgprint(_('No Lab Tests created')) frappe.msgprint(_('No Lab Tests created'))
@@ -211,8 +225,9 @@ def create_sample_doc(template, patient, invoice, company = None):
'docstatus': 0, 'docstatus': 0,
'sample': template.sample 'sample': template.sample
}) })
if sample_exists: 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]) sample_collection = frappe.get_doc('Sample Collection', sample_exists[0][0])
quantity = int(sample_collection.sample_qty) + int(template.sample_qty) quantity = int(sample_collection.sample_qty) + int(template.sample_qty)
if template.sample_details: if template.sample_details:
@@ -238,7 +253,7 @@ def create_sample_doc(template, patient, invoice, company = None):
sample_collection.company = company sample_collection.company = company
if template.sample_details: 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) sample_collection.save(ignore_permissions=True)
return sample_collection 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) sample_collection = create_sample_doc(template, patient, invoice, lab_test.company)
if sample_collection: if sample_collection:
lab_test.sample = sample_collection.name 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 return lab_test
def load_result_format(lab_test, template, prescription, invoice): def load_result_format(lab_test, template, prescription, invoice):
if template.lab_test_template_type == 'Single': if template.lab_test_template_type == 'Single':
create_normals(template, lab_test) create_normals(template, lab_test)
elif template.lab_test_template_type == 'Compound': elif template.lab_test_template_type == 'Compound':
create_compounds(template, lab_test, False) create_compounds(template, lab_test, False)
elif template.lab_test_template_type == 'Descriptive': elif template.lab_test_template_type == 'Descriptive':
create_descriptives(template, lab_test) create_descriptives(template, lab_test)
elif template.lab_test_template_type == 'Grouped': elif template.lab_test_template_type == 'Grouped':
# Iterate for each template in the group and create one result for all. # Iterate for each template in the group and create one result for all.
for lab_test_group in template.lab_test_groups: for lab_test_group in template.lab_test_groups:
# Template_in_group = None # Template_in_group = None
if lab_test_group.lab_test_template: if lab_test_group.lab_test_template:
template_in_group = frappe.get_doc('Lab Test Template', template_in_group = frappe.get_doc('Lab Test Template', lab_test_group.lab_test_template)
lab_test_group.lab_test_template)
if template_in_group: if template_in_group:
if template_in_group.lab_test_template_type == 'Single': if template_in_group.lab_test_template_type == 'Single':
create_normals(template_in_group, lab_test) create_normals(template_in_group, lab_test)
elif template_in_group.lab_test_template_type == 'Compound': elif template_in_group.lab_test_template_type == 'Compound':
normal_heading = lab_test.append('normal_test_items') normal_heading = lab_test.append('normal_test_items')
normal_heading.lab_test_name = template_in_group.lab_test_name 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.allow_blank = 1
normal_heading.template = template_in_group.name normal_heading.template = template_in_group.name
create_compounds(template_in_group, lab_test, True) create_compounds(template_in_group, lab_test, True)
elif template_in_group.lab_test_template_type == 'Descriptive': elif template_in_group.lab_test_template_type == 'Descriptive':
descriptive_heading = lab_test.append('descriptive_test_items') descriptive_heading = lab_test.append('descriptive_test_items')
descriptive_heading.lab_test_name = template_in_group.lab_test_name 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.allow_blank = 1
descriptive_heading.template = template_in_group.name descriptive_heading.template = template_in_group.name
create_descriptives(template_in_group, lab_test) create_descriptives(template_in_group, lab_test)
else: # Lab Test Group - Add New Line else: # Lab Test Group - Add New Line
normal = lab_test.append('normal_test_items') normal = lab_test.append('normal_test_items')
normal.lab_test_name = lab_test_group.group_event 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.allow_blank = lab_test_group.allow_blank
normal.require_result_value = 1 normal.require_result_value = 1
normal.template = template.name normal.template = template.name
if template.lab_test_template_type != 'No Result': if template.lab_test_template_type != 'No Result':
if prescription: if prescription:
lab_test.prescription = prescription lab_test.prescription = prescription
@@ -302,9 +325,10 @@ def load_result_format(lab_test, template, prescription, invoice):
@frappe.whitelist() @frappe.whitelist()
def get_employee_by_user_id(user_id): def get_employee_by_user_id(user_id):
emp_id = frappe.db.get_value('Employee', { 'user_id': user_id }) emp_id = frappe.db.exists('Employee', { 'user_id': user_id })
employee = frappe.get_doc('Employee', emp_id) if emp_id:
return employee return frappe.get_doc('Employee', emp_id)
return None
def insert_lab_test_to_medical_record(doc): def insert_lab_test_to_medical_record(doc):
table_row = False 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 table_row += ' ' + frappe.bold(_('Lab Test Result: ')) + item.result_value
if item.normal_range: if item.normal_range:
table_row += ' ' + _('Normal Range:') + item.normal_range table_row += ' ' + _('Normal Range: ') + item.normal_range
table_row += ' ' + comment table_row += ' ' + comment
elif doc.descriptive_test_items: elif doc.descriptive_test_items:
@@ -356,7 +380,7 @@ def insert_lab_test_to_medical_record(doc):
medical_record.save(ignore_permissions = True) medical_record.save(ignore_permissions = True)
def delete_lab_test_from_medical_record(self): 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]: if medical_record_id and medical_record_id[0][0]:
frappe.delete_doc('Patient Medical Record', medical_record_id[0][0]) frappe.delete_doc('Patient Medical Record', medical_record_id[0][0])

View File

@@ -3,13 +3,16 @@
*/ */
frappe.listview_settings['Lab Test'] = { frappe.listview_settings['Lab Test'] = {
add_fields: ['name', 'status', 'invoiced'], add_fields: ['name', 'status', 'invoiced'],
filters: [['docstatus', '=', '0']], filters: [['docstatus', '=', '1']],
get_indicator: function (doc) { get_indicator: function (doc) {
if (doc.status == 'Approved') { if (doc.status === 'Approved') {
return [__('Approved'), 'green', 'status, = ,Approved']; return [__('Approved'), 'green', 'status, =, Approved'];
} } else if (doc.status === 'Rejected') {
if (doc.status == 'Rejected') {
return [__('Rejected'), 'orange', '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) { onload: function (listview) {
@@ -21,7 +24,7 @@ frappe.listview_settings['Lab Test'] = {
var create_multiple_dialog = function (listview) { var create_multiple_dialog = function (listview) {
var dialog = new frappe.ui.Dialog({ var dialog = new frappe.ui.Dialog({
title: 'Create Multiple Lab Test', title: 'Create Multiple Lab Tests',
width: 100, width: 100,
fields: [ fields: [
{ fieldtype: 'Link', label: 'Patient', fieldname: 'patient', options: 'Patient', reqd: 1 }, { 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 () { primary_action: function () {
frappe.call({ frappe.call({
method: 'erpnext.healthcare.doctype.lab_test.lab_test.create_multiple', method: 'erpnext.healthcare.doctype.lab_test.lab_test.create_multiple',

View File

@@ -3,8 +3,204 @@
# See license.txt # See license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import unittest import unittest
import frappe
# test_records = frappe.get_test_records('Lab Test') 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): 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

View File

@@ -93,7 +93,8 @@
"depends_on": "secondary_uom", "depends_on": "secondary_uom",
"fieldname": "conversion_factor", "fieldname": "conversion_factor",
"fieldtype": "Float", "fieldtype": "Float",
"label": "Conversion Factor" "label": "Conversion Factor",
"mandatory_depends_on": "secondary_uom"
}, },
{ {
"default": "0", "default": "0",
@@ -106,7 +107,7 @@
], ],
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2020-06-24 10:59:01.921924", "modified": "2020-07-30 12:36:03.082391",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Healthcare", "module": "Healthcare",
"name": "Lab Test Group Template", "name": "Lab Test Group Template",

View File

@@ -34,14 +34,15 @@
"descriptive_test_templates", "descriptive_test_templates",
"section_break_group", "section_break_group",
"lab_test_groups", "lab_test_groups",
"medical_coding_section",
"medical_code_standard",
"medical_code",
"sb_sample_collection", "sb_sample_collection",
"sample", "sample",
"sample_uom", "sample_uom",
"sample_qty", "sample_qty",
"column_break_33",
"sample_details", "sample_details",
"medical_coding_section",
"medical_code",
"medical_code_standard",
"worksheet_section", "worksheet_section",
"worksheet_instructions", "worksheet_instructions",
"result_legend_section", "result_legend_section",
@@ -112,7 +113,7 @@
{ {
"default": "1", "default": "1",
"depends_on": "eval:doc.lab_test_template_type != 'Grouped'", "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", "fieldname": "is_billable",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Is Billable", "label": "Is Billable",
@@ -128,6 +129,7 @@
"mandatory_depends_on": "eval:doc.is_billable == 1" "mandatory_depends_on": "eval:doc.is_billable == 1"
}, },
{ {
"collapsible": 1,
"fieldname": "medical_coding_section", "fieldname": "medical_coding_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Medical Coding" "label": "Medical Coding"
@@ -184,7 +186,7 @@
"depends_on": "eval:doc.lab_test_template_type == 'Descriptive'", "depends_on": "eval:doc.lab_test_template_type == 'Descriptive'",
"fieldname": "section_break_special", "fieldname": "section_break_special",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Descriptive" "label": "Descriptive Test"
}, },
{ {
"default": "0", "default": "0",
@@ -196,7 +198,7 @@
"depends_on": "eval:doc.lab_test_template_type == 'Grouped'", "depends_on": "eval:doc.lab_test_template_type == 'Grouped'",
"fieldname": "section_break_group", "fieldname": "section_break_group",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Group" "label": "Group Tests"
}, },
{ {
"fieldname": "lab_test_groups", "fieldname": "lab_test_groups",
@@ -217,7 +219,6 @@
"no_copy": 1 "no_copy": 1
}, },
{ {
"collapsible": 1,
"fieldname": "sb_sample_collection", "fieldname": "sb_sample_collection",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Sample Collection" "label": "Sample Collection"
@@ -311,10 +312,14 @@
"fieldname": "descriptive_test_templates", "fieldname": "descriptive_test_templates",
"fieldtype": "Table", "fieldtype": "Table",
"options": "Descriptive Test Template" "options": "Descriptive Test Template"
},
{
"fieldname": "column_break_33",
"fieldtype": "Column Break"
} }
], ],
"links": [], "links": [],
"modified": "2020-07-13 12:57:09.925436", "modified": "2020-07-30 14:32:40.449818",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Healthcare", "module": "Healthcare",
"name": "Lab Test Template", "name": "Lab Test Template",

View File

@@ -15,7 +15,8 @@ class LabTestTemplate(Document):
def validate(self): def validate(self):
if self.is_billable and (not self.lab_test_rate or self.lab_test_rate <= 0.0): 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.validate_conversion_factor()
self.enable_disable_item() self.enable_disable_item()
@@ -42,7 +43,9 @@ class LabTestTemplate(Document):
# Remove template reference from item and disable item # Remove template reference from item and disable item
if self.item: if self.item:
try: try:
frappe.delete_doc('Item', self.item) item = self.item
self.db_set('item', '')
frappe.delete_doc('Item', item)
except Exception: except Exception:
frappe.throw(_('Not permitted. Please disable the Lab Test Template')) frappe.throw(_('Not permitted. Please disable the Lab Test Template'))
@@ -63,26 +66,26 @@ class LabTestTemplate(Document):
'standard_rate': self.lab_test_rate, 'standard_rate': self.lab_test_rate,
'description': self.lab_test_description 'description': self.lab_test_description
}) })
item.save() item.flags.ignore_mandatory = True
item.save(ignore_permissions=True)
def item_price_exists(self): def item_price_exists(self):
item_price = frappe.db.exists({'doctype': 'Item Price', 'item_code': self.lab_test_code}) item_price = frappe.db.exists({'doctype': 'Item Price', 'item_code': self.lab_test_code})
if item_price: if item_price:
return item_price[0][0] return item_price[0][0]
else: return False
return False
def validate_conversion_factor(self): def validate_conversion_factor(self):
if self.lab_test_template_type == "Single" and self.secondary_uom and not self.conversion_factor: if self.lab_test_template_type == 'Single' and self.secondary_uom and not self.conversion_factor:
frappe.throw(_("Conversion Factor is mandatory")) frappe.throw(_('Conversion Factor is mandatory'))
if self.lab_test_template_type == "Compound": if self.lab_test_template_type == 'Compound':
for item in self.normal_test_templates: for item in self.normal_test_templates:
if item.secondary_uom and not item.conversion_factor: if item.secondary_uom and not item.conversion_factor:
frappe.throw(_("Conversion Factor is mandatory")) frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(item.idx))
if self.lab_test_template_type == "Grouped": if self.lab_test_template_type == 'Grouped':
for group in self.lab_test_groups: 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: if group.template_or_new_line == 'Add New Line' and group.secondary_uom and not group.conversion_factor:
frappe.throw(_("Conversion Factor is mandatory")) frappe.throw(_('Row #{0}: Conversion Factor is mandatory').format(group.idx))
def create_item_from_template(doc): def create_item_from_template(doc):
@@ -101,9 +104,9 @@ def create_item_from_template(doc):
'include_item_in_manufacturing': 0, 'include_item_in_manufacturing': 0,
'show_in_website': 0, 'show_in_website': 0,
'is_pro_applicable': 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 'stock_uom': uom
}).insert(ignore_permissions = True, ignore_mandatory = True) }).insert(ignore_permissions=True, ignore_mandatory=True)
# Insert item price # Insert item price
if doc.is_billable and doc.lab_test_rate != 0.0: 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, 'price_list': price_list_name,
'item_code': item, 'item_code': item,
'price_list_rate': item_price 'price_list_rate': item_price
}).insert(ignore_permissions = True, ignore_mandatory = True) }).insert(ignore_permissions=True, ignore_mandatory=True)
@frappe.whitelist() @frappe.whitelist()
def change_test_code_from_template(lab_test_code, doc): 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}): if frappe.db.exists({'doctype': 'Item', 'item_code': lab_test_code}):
frappe.throw(_('Lab Test Item {0} already exist').format(lab_test_code)) frappe.throw(_('Lab Test Item {0} already exist').format(lab_test_code))
else: 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_code', lab_test_code)
frappe.db.set_value('Lab Test Template', doc.name, 'lab_test_name', 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 return lab_test_code

View File

@@ -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']
}
]
}

View File

@@ -3,5 +3,5 @@
*/ */
frappe.listview_settings['Lab Test Template'] = { frappe.listview_settings['Lab Test Template'] = {
add_fields: ['lab_test_name', 'lab_test_code', 'lab_test_rate'], add_fields: ['lab_test_name', 'lab_test_code', 'lab_test_rate'],
filters: [['disabled', '=', 0]] filters: [['disabled', '=', 'No']]
}; };

View File

@@ -34,7 +34,7 @@ class TestPatientMedicalRecord(unittest.TestCase):
self.assertTrue(medical_rec) self.assertTrue(medical_rec)
template = create_lab_test_template(medical_department) 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 # check for lab test
medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': lab_test.name}) medical_rec = frappe.db.exists('Patient Medical Record', {'status': 'Open', 'reference_name': lab_test.name})
self.assertTrue(medical_rec) self.assertTrue(medical_rec)
@@ -66,7 +66,7 @@ def create_vital_signs(appointment):
def create_lab_test_template(medical_department): def create_lab_test_template(medical_department):
if frappe.db.exists('Lab Test Template', 'Blood Test'): 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 = frappe.new_doc('Lab Test Template')
template.lab_test_name = 'Blood Test' template.lab_test_name = 'Blood Test'
@@ -76,7 +76,7 @@ def create_lab_test_template(medical_department):
template.is_billable = 1 template.is_billable = 1
template.lab_test_rate = 2000 template.lab_test_rate = 2000
template.save() template.save()
return template.name return template
def create_lab_test(template, patient): def create_lab_test(template, patient):
lab_test = frappe.new_doc('Lab Test') lab_test = frappe.new_doc('Lab Test')

View File

@@ -3,29 +3,29 @@
frappe.ui.form.on('Sample Collection', { frappe.ui.form.on('Sample Collection', {
refresh: function(frm) { refresh: function(frm) {
if(frappe.defaults.get_default("create_sample_collection_for_lab_test")){ if (frappe.defaults.get_default('create_sample_collection_for_lab_test')) {
frm.add_custom_button(__("View Lab Tests"), function() { frm.add_custom_button(__('View Lab Tests'), function() {
frappe.route_options = {"sample": frm.doc.name}; frappe.route_options = {'sample': frm.doc.name};
frappe.set_route("List", "Lab Test"); 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){ if(frm.doc.patient){
frappe.call({ frappe.call({
"method": "erpnext.healthcare.doctype.patient.patient.get_patient_detail", 'method': 'erpnext.healthcare.doctype.patient.patient.get_patient_detail',
args: { args: {
patient: frm.doc.patient patient: frm.doc.patient
}, },
callback: function (data) { callback: function (data) {
var age = null; var age = null;
if(data.message.dob){ if (data.message.dob){
age = calculate_age(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_age', age);
frappe.model.set_value(frm.doctype,frm.docname, "patient_sex", data.message.sex); 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(); var age = new Date();
age.setTime(ageMS); age.setTime(ageMS);
var years = age.getFullYear() - 1970; 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)';
}; };

View File

@@ -9,8 +9,10 @@
"document_type": "Document", "document_type": "Document",
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [ "field_order": [
"patient_details_section",
"naming_series", "naming_series",
"patient", "patient",
"patient_name",
"patient_age", "patient_age",
"patient_sex", "patient_sex",
"column_break_4", "column_break_4",
@@ -25,15 +27,17 @@
"collected_by", "collected_by",
"collected_time", "collected_time",
"num_print", "num_print",
"amended_from",
"section_break_15", "section_break_15",
"sample_details" "sample_details",
"amended_from"
], ],
"fields": [ "fields": [
{ {
"fetch_from": "patient.inpatient_record", "fetch_from": "patient.inpatient_record",
"fieldname": "inpatient_record", "fieldname": "inpatient_record",
"fieldtype": "Link", "fieldtype": "Link",
"hide_days": 1,
"hide_seconds": 1,
"label": "Inpatient Record", "label": "Inpatient Record",
"options": "Inpatient Record", "options": "Inpatient Record",
"read_only": 1 "read_only": 1
@@ -42,6 +46,8 @@
"bold": 1, "bold": 1,
"fieldname": "naming_series", "fieldname": "naming_series",
"fieldtype": "Select", "fieldtype": "Select",
"hide_days": 1,
"hide_seconds": 1,
"label": "Series", "label": "Series",
"no_copy": 1, "no_copy": 1,
"options": "HLC-SC-.YYYY.-", "options": "HLC-SC-.YYYY.-",
@@ -52,6 +58,8 @@
"default": "0", "default": "0",
"fieldname": "invoiced", "fieldname": "invoiced",
"fieldtype": "Check", "fieldtype": "Check",
"hide_days": 1,
"hide_seconds": 1,
"label": "Invoiced", "label": "Invoiced",
"no_copy": 1, "no_copy": 1,
"read_only": 1, "read_only": 1,
@@ -61,41 +69,60 @@
"fetch_from": "inpatient_record.patient", "fetch_from": "inpatient_record.patient",
"fieldname": "patient", "fieldname": "patient",
"fieldtype": "Link", "fieldtype": "Link",
"hide_days": 1,
"hide_seconds": 1,
"ignore_user_permissions": 1, "ignore_user_permissions": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Patient", "label": "Patient",
"options": "Patient", "options": "Patient",
"reqd": 1,
"search_index": 1 "search_index": 1
}, },
{ {
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break" "fieldtype": "Column Break",
"hide_days": 1,
"hide_seconds": 1
}, },
{ {
"fieldname": "patient_age", "fieldname": "patient_age",
"fieldtype": "Data", "fieldtype": "Data",
"label": "Age" "hide_days": 1,
"hide_seconds": 1,
"label": "Age",
"read_only": 1
}, },
{ {
"fetch_from": "patient.sex", "fetch_from": "patient.sex",
"fieldname": "patient_sex", "fieldname": "patient_sex",
"fieldtype": "Data", "fieldtype": "Link",
"label": "Gender" "hide_days": 1,
"hide_seconds": 1,
"label": "Gender",
"options": "Gender",
"read_only": 1
}, },
{ {
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"hide_days": 1,
"hide_seconds": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Company", "label": "Company",
"options": "Company" "options": "Company"
}, },
{ {
"fieldname": "section_break_6", "fieldname": "section_break_6",
"fieldtype": "Section Break" "fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Sample Details"
}, },
{ {
"fieldname": "sample", "fieldname": "sample",
"fieldtype": "Link", "fieldtype": "Link",
"hide_days": 1,
"hide_seconds": 1,
"ignore_user_permissions": 1, "ignore_user_permissions": 1,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
@@ -108,16 +135,23 @@
"fetch_from": "sample.sample_uom", "fetch_from": "sample.sample_uom",
"fieldname": "sample_uom", "fieldname": "sample_uom",
"fieldtype": "Data", "fieldtype": "Data",
"hide_days": 1,
"hide_seconds": 1,
"in_list_view": 1, "in_list_view": 1,
"label": "UOM" "label": "UOM",
"read_only": 1
}, },
{ {
"fieldname": "column_break_10", "fieldname": "column_break_10",
"fieldtype": "Column Break" "fieldtype": "Column Break",
"hide_days": 1,
"hide_seconds": 1
}, },
{ {
"fieldname": "collected_by", "fieldname": "collected_by",
"fieldtype": "Link", "fieldtype": "Link",
"hide_days": 1,
"hide_seconds": 1,
"ignore_user_permissions": 1, "ignore_user_permissions": 1,
"label": "Collected By", "label": "Collected By",
"options": "User" "options": "User"
@@ -125,20 +159,27 @@
{ {
"fieldname": "collected_time", "fieldname": "collected_time",
"fieldtype": "Datetime", "fieldtype": "Datetime",
"label": "Collected Time" "hide_days": 1,
"hide_seconds": 1,
"label": "Collected On"
}, },
{ {
"allow_on_submit": 1, "allow_on_submit": 1,
"default": "1", "default": "1",
"description": "Number of prints required for labelling the samples",
"fieldname": "num_print", "fieldname": "num_print",
"fieldtype": "Int", "fieldtype": "Int",
"label": "No. of print", "hide_days": 1,
"hide_seconds": 1,
"label": "No. of prints",
"print_hide": 1, "print_hide": 1,
"report_hide": 1 "report_hide": 1
}, },
{ {
"fieldname": "amended_from", "fieldname": "amended_from",
"fieldtype": "Link", "fieldtype": "Link",
"hide_days": 1,
"hide_seconds": 1,
"label": "Amended From", "label": "Amended From",
"no_copy": 1, "no_copy": 1,
"options": "Sample Collection", "options": "Sample Collection",
@@ -147,25 +188,43 @@
}, },
{ {
"fieldname": "section_break_15", "fieldname": "section_break_15",
"fieldtype": "Section Break" "fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1
}, },
{ {
"default": "0", "default": "0",
"fieldname": "sample_qty", "fieldname": "sample_qty",
"fieldtype": "Float", "fieldtype": "Float",
"hide_days": 1,
"hide_seconds": 1,
"in_list_view": 1, "in_list_view": 1,
"label": "Quantity" "label": "Quantity"
}, },
{ {
"fieldname": "sample_details", "fieldname": "sample_details",
"fieldtype": "Long Text", "fieldtype": "Long Text",
"hide_days": 1,
"hide_seconds": 1,
"ignore_xss_filter": 1, "ignore_xss_filter": 1,
"label": "Collection Details" "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, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-05-25 14:36:46.990469", "modified": "2020-07-30 16:53:13.076104",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Healthcare", "module": "Healthcare",
"name": "Sample Collection", "name": "Sample Collection",

View File

@@ -3,7 +3,12 @@
# For license information, please see license.txt # For license information, please see license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe
from frappe.model.document import Document from frappe.model.document import Document
from frappe.utils import flt
from frappe import _
class SampleCollection(Document): 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'))

View File

@@ -4,29 +4,54 @@
frappe.query_reports["Lab Test Report"] = { frappe.query_reports["Lab Test Report"] = {
"filters": [ "filters": [
{ {
"fieldname":"from_date", "fieldname": "from_date",
"label": __("From Date"), "label": __("From Date"),
"fieldtype": "Date", "fieldtype": "Date",
"default": frappe.datetime.now_date(), "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
"width": "80" "reqd": 1
}, },
{ {
"fieldname":"to_date", "fieldname": "to_date",
"label": __("To Date"), "label": __("To Date"),
"fieldtype": "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"), "label": __("Patient"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Patient" "options": "Patient"
}, },
{ {
"fieldname":"department", "fieldname": "department",
"label": __("Medical Department"), "label": __("Medical Department"),
"fieldtype": "Link", "fieldtype": "Link",
"options": "Medical Department" "options": "Medical Department"
},
{
"fieldname": "status",
"label": __("Status"),
"fieldtype": "Select",
"options": "\nCompleted\nApproved\nRejected"
},
{
"fieldname": "invoiced",
"label": __("Invoiced"),
"fieldtype": "Check"
} }
] ]
}; };

View File

@@ -1,30 +1,31 @@
{ {
"add_total_row": 1, "add_total_row": 0,
"creation": "2013-04-23 18:15:29", "creation": "2013-04-23 18:15:29",
"disabled": 0, "disable_prepared_report": 0,
"docstatus": 0, "disabled": 0,
"doctype": "Report", "docstatus": 0,
"idx": 1, "doctype": "Report",
"is_standard": "Yes", "idx": 1,
"modified": "2018-08-06 11:41:50.218737", "is_standard": "Yes",
"modified_by": "Administrator", "modified": "2020-07-30 18:53:20.102873",
"module": "Healthcare", "modified_by": "Administrator",
"name": "Lab Test Report", "module": "Healthcare",
"owner": "Administrator", "name": "Lab Test Report",
"prepared_report": 0, "owner": "Administrator",
"ref_doctype": "Lab Test", "prepared_report": 0,
"report_name": "Lab Test Report", "ref_doctype": "Lab Test",
"report_type": "Script Report", "report_name": "Lab Test Report",
"report_type": "Script Report",
"roles": [ "roles": [
{ {
"role": "Laboratory User" "role": "Laboratory User"
}, },
{ {
"role": "Nursing User" "role": "Nursing User"
}, },
{ {
"role": "LabTest Approver" "role": "LabTest Approver"
}, },
{ {
"role": "Healthcare Administrator" "role": "Healthcare Administrator"
} }

View File

@@ -8,51 +8,204 @@ from frappe import msgprint, _
def execute(filters=None): def execute(filters=None):
if not filters: filters = {} if not filters: filters = {}
lab_test_list = get_lab_test(filters) data, columns = [], []
columns = get_columns() columns = get_columns()
lab_test_list = get_lab_tests(filters)
if not lab_test_list: if not lab_test_list:
msgprint(_("No record found")) msgprint(_('No records found'))
return columns, lab_test_list return columns, lab_test_list
data = [] data = []
for lab_test in lab_test_list: 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) 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(): def get_columns():
columns = [ return [
_("Test") + ":Data:120", {
_("Patient") + ":Link/Patient:180", 'fieldname': 'test',
_("Healthcare Practitioner") + ":Link/Healthcare Practitioner:120", 'label': _('Lab Test'),
_("Invoiced") + ":Check:100", 'fieldtype': 'Link',
_("Status") + ":Data:120", 'options': 'Lab Test',
_("Result Date") + ":Date:120", 'width': '120'
_("Department") + ":Data: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): def get_conditions(filters):
conditions = "" conditions = {
'docstatus': ('=', 1)
}
if filters.get("patient"): if filters.get('from_date') and filters.get('to_date'):
conditions += "and patient = %(patient)s" conditions['result_date'] = ('between', (filters.get('from_date'), filters.get('to_date')))
if filters.get("from_date"): filters.pop('from_date')
conditions += "and result_date >= %(from_date)s" filters.pop('to_date')
if filters.get("to_date"):
conditions += " and result_date <= %(to_date)s" for key, value in filters.items():
if filters.get("department"): if filters.get(key):
conditions += " and department = %(department)s" conditions[key] = value
return conditions return conditions
def get_lab_test(filters): def get_chart_data(data):
conditions = get_conditions(filters) if not data:
return frappe.db.sql("""select name, patient, lab_test_name, patient_name, status, result_date, practitioner, invoiced, department return None
from `tabLab Test`
where docstatus<2 %s order by submitted_date desc, name desc""" % labels = ['Completed', 'Approved', 'Rejected']
conditions, filters, as_dict=1)
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',
}
]

View File

@@ -417,7 +417,42 @@ class TestSalesOrder(unittest.TestCase):
# add new item # add new item
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 100, 'qty' : 2}]) 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) self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Sales Order', trans_item, so.name)
test_user.remove_roles("Accounts User")
frappe.set_user("Administrator") 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): def test_update_child_qty_rate_product_bundle(self):
# test Update Items with product bundle # test Update Items with product bundle
@@ -973,3 +1008,37 @@ def get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"):
"reserved_qty")) "reserved_qty"))
test_dependencies = ["Currency Exchange"] 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

View File

@@ -130,12 +130,18 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
if (this.frm.doc.docstatus===0) { if (this.frm.doc.docstatus===0) {
this.frm.add_custom_button(__('Sales Order'), this.frm.add_custom_button(__('Sales Order'),
function() { function() {
if (!me.frm.doc.customer) {
frappe.throw({
title: __("Mandatory"),
message: __("Please Select a Customer")
});
}
erpnext.utils.map_current_doc({ erpnext.utils.map_current_doc({
method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note", method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
source_doctype: "Sales Order", source_doctype: "Sales Order",
target: me.frm, target: me.frm,
setters: { setters: {
customer: me.frm.doc.customer || undefined, customer: me.frm.doc.customer,
}, },
get_query_filters: { get_query_filters: {
docstatus: 1, docstatus: 1,

View File

@@ -116,12 +116,18 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
if (this.frm.doc.docstatus == 0) { if (this.frm.doc.docstatus == 0) {
this.frm.add_custom_button(__('Purchase Order'), this.frm.add_custom_button(__('Purchase Order'),
function () { function () {
if (!me.frm.doc.supplier) {
frappe.throw({
title: __("Mandatory"),
message: __("Please Select a Supplier")
});
}
erpnext.utils.map_current_doc({ erpnext.utils.map_current_doc({
method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt", method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_receipt",
source_doctype: "Purchase Order", source_doctype: "Purchase Order",
target: me.frm, target: me.frm,
setters: { setters: {
supplier: me.frm.doc.supplier || undefined, supplier: me.frm.doc.supplier,
}, },
get_query_filters: { get_query_filters: {
docstatus: 1, docstatus: 1,

View File

@@ -73,7 +73,8 @@
"fieldname": "reference_type", "fieldname": "reference_type",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Reference Type", "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", "fieldname": "reference_name",
@@ -84,7 +85,8 @@
"label": "Reference Name", "label": "Reference Name",
"oldfieldname": "purchase_receipt_no", "oldfieldname": "purchase_receipt_no",
"oldfieldtype": "Link", "oldfieldtype": "Link",
"options": "reference_type" "options": "reference_type",
"reqd": 1
}, },
{ {
"fieldname": "section_break_7", "fieldname": "section_break_7",
@@ -231,9 +233,10 @@
], ],
"icon": "fa fa-search", "icon": "fa fa-search",
"idx": 1, "idx": 1,
"index_web_pages_for_search": 1,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-04-26 17:50:25.068222", "modified": "2020-09-12 16:11:31.910508",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Quality Inspection", "name": "Quality Inspection",