diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index 1407d5f5fe3..0a72d4fa4e6 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -102,15 +102,15 @@ class Account(NestedSet): if not frappe.db.get_value("Account", {'account_name': self.account_name, 'company': ancestors[0]}, 'name'): frappe.throw(_("Please add the account to root level Company - %s" % ancestors[0])) - else: + elif self.parent_account: descendants = get_descendants_of('Company', self.company) if not descendants: return parent_acc_name_map = {} parent_acc_name, parent_acc_number = frappe.db.get_value('Account', self.parent_account, \ ["account_name", "account_number"]) - filters = { + filters = { "company": ["in", descendants], - "account_name": parent_acc_name, + "account_name": parent_acc_name, } if parent_acc_number: filters["account_number"] = parent_acc_number diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json index e64bc9e0c78..2214811d8b3 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.json +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json @@ -114,13 +114,13 @@ "fieldname": "debit_in_account_currency", "fieldtype": "Currency", "label": "Debit Amount in Account Currency", - "options": "currency" + "options": "account_currency" }, { "fieldname": "credit_in_account_currency", "fieldtype": "Currency", "label": "Credit Amount in Account Currency", - "options": "currency" + "options": "account_currency" }, { "fieldname": "against", @@ -250,7 +250,7 @@ "icon": "fa fa-list", "idx": 1, "in_create": 1, - "modified": "2020-02-10 04:54:57.777905", + "modified": "2020-03-28 16:22:33.766994", "modified_by": "Administrator", "module": "Accounts", "name": "GL Entry", diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 6b74f477f2b..34132e9a915 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -317,13 +317,13 @@ def make_payment_request(**args): "payment_request_type": args.get("payment_request_type"), "currency": ref_doc.currency, "grand_total": grand_total, - "email_to": args.recipient_id or "", + "email_to": args.recipient_id or ref_doc.owner, "subject": _("Payment Request for {0}").format(args.dn), "message": gateway_account.get("message") or get_dummy_message(ref_doc), "reference_doctype": args.dt, "reference_name": args.dn, - "party_type": args.get("party_type"), - "party": args.get("party"), + "party_type": args.get("party_type") or "Customer", + "party": args.get("party") or ref_doc.customer, "bank_account": bank_account }) diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 36bb2be3dc5..296c7049ce4 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -760,7 +760,7 @@ "depends_on": "is_fixed_asset", "fetch_from": "item_code.asset_category", "fieldname": "asset_category", - "fieldtype": "Data", + "fieldtype": "Link", "in_preview": 1, "label": "Asset Category", "options": "Asset Category", @@ -770,7 +770,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2020-03-05 14:20:17.297284", + "modified": "2020-04-01 14:20:17.297284", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index fcddab40b8f..eda80246cdb 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -429,13 +429,17 @@ class SalesInvoice(SellingController): if (not for_validate) or (for_validate and not self.get(fieldname)): self.set(fieldname, pos.get(fieldname)) - customer_price_list = frappe.get_value("Customer", self.customer, 'default_price_list') - if pos.get("company_address"): self.company_address = pos.get("company_address") - if not customer_price_list: - self.set('selling_price_list', pos.get('selling_price_list')) + customer_price_list, customer_group = frappe.get_value("Customer", self.customer, ['default_price_list', 'customer_group']) + + customer_group_price_list = frappe.get_value("Customer Group", customer_group, 'default_price_list') + + selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list') + + if selling_price_list: + self.set('selling_price_list', selling_price_list) if not for_validate: self.update_stock = cint(pos.get("update_stock")) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index 791f3f8008b..bb0d0a132a5 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -218,15 +218,15 @@ {%= __("Total") %} - {%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %} + {%= format_currency(data[i]["invoiced"], data[0]["currency"] ) %} {% if(!filters.show_future_payments) { %} - {%= format_currency(data[i]["paid"], data[i]["currency"]) %} - {%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} + {%= format_currency(data[i]["paid"], data[0]["currency"]) %} + {%= format_currency(data[i]["credit_note"], data[0]["currency"]) %} {% } %} - {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} + {%= format_currency(data[i]["outstanding"], data[0]["currency"]) %} {% if(filters.show_future_payments) { %} {% if(report.report_name === "Accounts Receivable") { %} @@ -234,8 +234,8 @@ {%= data[i]["po_no"] %} {% } %} {%= data[i]["future_ref"] %} - {%= format_currency(data[i]["future_amount"], data[i]["currency"]) %} - {%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %} + {%= format_currency(data[i]["future_amount"], data[0]["currency"]) %} + {%= format_currency(data[i]["remaining_balance"], data[0]["currency"]) %} {% } %} {% } %} {% } else { %} @@ -256,10 +256,10 @@ {% } else { %} {%= __("Total") %} {% } %} - {%= format_currency(data[i]["invoiced"], data[i]["currency"]) %} - {%= format_currency(data[i]["paid"], data[i]["currency"]) %} - {%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} - {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} + {%= format_currency(data[i]["invoiced"], data[0]["currency"]) %} + {%= format_currency(data[i]["paid"], data[0]["currency"]) %} + {%= format_currency(data[i]["credit_note"], data[0]["currency"]) %} + {%= format_currency(data[i]["outstanding"], data[0]["currency"]) %} {% } %} {% } %} diff --git a/erpnext/buying/doctype/supplier/supplier_dashboard.py b/erpnext/buying/doctype/supplier/supplier_dashboard.py index 887a0937369..b3b294d5701 100644 --- a/erpnext/buying/doctype/supplier/supplier_dashboard.py +++ b/erpnext/buying/doctype/supplier/supplier_dashboard.py @@ -9,7 +9,8 @@ def get_data(): 'heatmap_message': _('This is based on transactions against this Supplier. See timeline below for details'), 'fieldname': 'supplier', 'non_standard_fieldnames': { - 'Payment Entry': 'party_name' + 'Payment Entry': 'party_name', + 'Bank Account': 'party' }, 'transactions': [ { @@ -24,6 +25,10 @@ def get_data(): 'label': _('Payments'), 'items': ['Payment Entry'] }, + { + 'label': _('Bank'), + 'items': ['Bank Account'] + }, { 'label': _('Pricing'), 'items': ['Pricing Rule'] diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js index 39042b8b068..16061c61ba0 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js @@ -4,15 +4,17 @@ // attach required files {% include 'erpnext/public/js/controllers/buying.js' %}; -frappe.ui.form.on('Suppier Quotation', { - setup: function(frm) { - frm.custom_make_buttons = { - 'Purchase Order': 'Purchase Order' - } - } -}); - erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({ + setup: function() { + this.frm.custom_make_buttons = { + 'Purchase Order': 'Purchase Order', + 'Quotation': 'Quotation', + 'Subscription': 'Subscription' + } + + this._super(); + }, + refresh: function() { var me = this; this._super(); diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index a47507eaf7b..ff07b59bd9b 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -658,19 +658,32 @@ class BuyingController(StockController): # If asset has to be auto created # Check for asset naming series if item_data.get('asset_naming_series'): + created_assets = [] + for qty in range(cint(d.qty)): - self.make_asset(d) - is_plural = 's' if cint(d.qty) != 1 else '' - messages.append(_('{0} Asset{2} Created for {1}').format(cint(d.qty), d.item_code, is_plural)) + asset = self.make_asset(d) + created_assets.append(asset) + + if len(created_assets) > 5: + # dont show asset form links if more than 5 assets are created + messages.append(_('{} Asset{} created for {}').format(len(created_assets), is_plural, frappe.bold(d.item_code))) + else: + assets_link = list(map(lambda d: frappe.utils.get_link_to_form('Asset', d), created_assets)) + assets_link = frappe.bold(','.join(assets_link)) + + is_plural = 's' if len(created_assets) != 1 else '' + messages.append( + _('Asset{} {assets_link} created for {}').format(is_plural, frappe.bold(d.item_code), assets_link=assets_link) + ) else: - frappe.throw(_("Row {1}: Asset Naming Series is mandatory for the auto creation for item {0}") - .format(d.item_code, d.idx)) + frappe.throw(_("Row {}: Asset Naming Series is mandatory for the auto creation for item {}") + .format(d.idx, frappe.bold(d.item_code))) else: - messages.append(_("Assets not created for {0}. You will have to create asset manually.") - .format(d.item_code)) + messages.append(_("Assets not created for {0}. You will have to create asset manually.") + .format(frappe.bold(d.item_code))) for message in messages: - frappe.msgprint(message, title="Success") + frappe.msgprint(message, title="Success", indicator="green") def make_asset(self, row): if not row.asset_location: @@ -702,6 +715,8 @@ class BuyingController(StockController): asset.set_missing_values() asset.insert() + return asset.name + def update_fixed_asset(self, field, delete_asset = False): for d in self.get("items"): if d.is_fixed_asset: @@ -731,7 +746,7 @@ class BuyingController(StockController): asset.supplier = None if asset.docstatus == 1 and delete_asset: frappe.throw(_('Cannot cancel this document as it is linked with submitted asset {0}.\ - Please cancel the it to continue.').format(asset.name)) + Please cancel the it to continue.').format(frappe.utils.get_link_to_form('Asset', asset.name))) asset.flags.ignore_validate_update_after_submit = True asset.flags.ignore_mandatory = True @@ -1012,4 +1027,4 @@ def get_batches_with_qty(item_code, fg_item, required_qty, transferred_batch_qty available_batches.append({'batch': batch, 'qty': available_qty}) required_qty -= available_qty - return available_batches \ No newline at end of file + return available_batches diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index d18f8e54d8f..163ef72ee10 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import frappe +import erpnext from frappe.desk.reportview import get_match_cond, get_filters_cond from frappe.utils import nowdate, getdate from collections import defaultdict @@ -129,23 +130,26 @@ def supplier_query(doctype, txt, searchfield, start, page_len, filters): }) def tax_account_query(doctype, txt, searchfield, start, page_len, filters): + company_currency = erpnext.get_company_currency(filters.get('company')) + tax_accounts = frappe.db.sql("""select name, parent_account from tabAccount where tabAccount.docstatus!=2 and account_type in (%s) and is_group = 0 and company = %s + and account_currency = %s and `%s` LIKE %s order by idx desc, name limit %s, %s""" % - (", ".join(['%s']*len(filters.get("account_type"))), "%s", searchfield, "%s", "%s", "%s"), - tuple(filters.get("account_type") + [filters.get("company"), "%%%s%%" % txt, + (", ".join(['%s']*len(filters.get("account_type"))), "%s", "%s", searchfield, "%s", "%s", "%s"), + tuple(filters.get("account_type") + [filters.get("company"), company_currency, "%%%s%%" % txt, start, page_len])) if not tax_accounts: tax_accounts = frappe.db.sql("""select name, parent_account from tabAccount where tabAccount.docstatus!=2 and is_group = 0 - and company = %s and `%s` LIKE %s limit %s, %s""" - % ("%s", searchfield, "%s", "%s", "%s"), - (filters.get("company"), "%%%s%%" % txt, start, page_len)) + and company = %s and account_currency = %s and `%s` LIKE %s limit %s, %s""" #nosec + % ("%s", "%s", searchfield, "%s", "%s", "%s"), + (filters.get("company"), company_currency, "%%%s%%" % txt, start, page_len)) return tax_accounts diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json index 68426c36be1..da10db1857a 100644 --- a/erpnext/education/doctype/course/course.json +++ b/erpnext/education/doctype/course/course.json @@ -74,7 +74,7 @@ } ], "image_field": "hero_image", - "modified": "2019-06-12 12:34:23.748157", + "modified": "2020-03-29 12:50:27.677589", "modified_by": "Administrator", "module": "Education", "name": "Course", @@ -103,6 +103,30 @@ "role": "Instructor", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Administrator", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Education Manager", + "share": 1, + "write": 1 } ], "restrict_to_domain": "Education", diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js index fa9188449e3..cf8c9b9ca35 100644 --- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js +++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js @@ -5,20 +5,16 @@ frappe.ui.form.on('Clinical Procedure', { setup: function(frm) { frm.set_query('batch_no', 'items', function(doc, cdt, cdn) { var item = locals[cdt][cdn]; - if(!item.item_code) { - frappe.throw(__("Please enter Item Code to get Batch Number")); + if (!item.item_code) { + frappe.throw(__('Please enter Item Code to get Batch Number')); } else { + let filters = {'item_code': item.item_code}; + if (frm.doc.status == 'In Progress') { - var filters = { - 'item_code': item.item_code, - 'posting_date': frm.doc.start_date || frappe.datetime.nowdate() - }; - if(frm.doc.warehouse) filters["warehouse"] = frm.doc.warehouse; - } else { - filters = { - 'item_code': item.item_code - }; + filters['posting_date'] = frm.doc.start_date || frappe.datetime.nowdate(); + if (frm.doc.warehouse) filters['warehouse'] = frm.doc.warehouse; } + return { query : "erpnext.controllers.queries.get_batch_no", filters: filters @@ -29,7 +25,7 @@ frappe.ui.form.on('Clinical Procedure', { refresh: function(frm) { frm.set_query("patient", function () { return { - filters: {"disabled": 0} + filters: {"status": "Active"} }; }); frm.set_query("appointment", function () { diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js index 583728dd185..de0f9c43003 100644 --- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js +++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.js @@ -31,17 +31,7 @@ frappe.ui.form.on('Clinical Procedure Template', { if(!frm.doc.__islocal) { cur_frm.add_custom_button(__('Change Item Code'), function() { change_template_code(frm.doc); - } ); - if(frm.doc.disabled == 1){ - cur_frm.add_custom_button(__('Enable Template'), function() { - enable_template(frm.doc); - } ); - } - else{ - cur_frm.add_custom_button(__('Disable Template'), function() { - disable_template(frm.doc); - } ); - } + }); } } }); @@ -52,27 +42,6 @@ var mark_change_in_item = function(frm) { } }; -var disable_template = function(doc){ - frappe.call({ - method: "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.disable_enable_template", - args: {status: 1, name: doc.name, item_code: doc.item_code, is_billable: doc.is_billable}, - callback: function(){ - cur_frm.reload_doc(); - } - }); -}; - -var enable_template = function(doc){ - frappe.call({ - method: "erpnext.healthcare.doctype.clinical_procedure_template.clinical_procedure_template.disable_enable_template", - args: {status: 0, name: doc.name, item_code: doc.item_code, is_billable: doc.is_billable}, - callback: function(){ - cur_frm.reload_doc(); - } - }); -}; - - var change_template_code = function(doc){ var d = new frappe.ui.Dialog({ title:__("Change Template Code"), diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json index 26564a34ce4..7ae4be84a28 100644 --- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json +++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.json @@ -1,807 +1,230 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:template", - "beta": 1, - "creation": "2017-10-05 14:59:55.438359", - "custom": 0, - "description": "Procedure Template", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 1, - "engine": "InnoDB", + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:template", + "beta": 1, + "creation": "2017-10-05 14:59:55.438359", + "description": "Procedure Template", + "doctype": "DocType", + "document_type": "Setup", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "template", + "item", + "item_code", + "item_group", + "description", + "column_break_5", + "disabled", + "is_billable", + "rate", + "medical_department", + "consumables", + "consume_stock", + "items", + "sample_collection", + "sample", + "sample_uom", + "sample_qty", + "column_break_21", + "sample_details", + "change_in_item" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "template", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Template Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "fieldname": "template", + "fieldtype": "Data", + "in_global_search": 1, + "in_list_view": 1, + "label": "Template Name", + "reqd": 1, "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "item_code", + "fieldname": "item_code", + "fieldtype": "Data", + "label": "Item Code", + "options": "Item", + "reqd": 1 + }, + { + "fieldname": "item_group", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Item Code", - "length": 0, - "no_copy": 1, - "options": "Item", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "ignore_user_permissions": 1, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Item Group", + "options": "Item Group", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "item_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Item Group", - "length": 0, - "no_copy": 0, - "options": "Item Group", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "medical_department", + "fieldtype": "Link", + "label": "Medical Department", + "options": "Medical Department" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "medical_department", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Medical Department", - "length": 0, - "no_copy": 0, - "options": "Medical Department", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_5", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_5", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "0", + "fieldname": "is_billable", + "fieldtype": "Check", + "label": "Is Billable" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_billable", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Is Billable", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "is_billable", + "fieldname": "rate", + "fieldtype": "Float", + "label": "Rate", + "mandatory_depends_on": "is_billable" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_billable", - "fieldname": "rate", - "fieldtype": "Float", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Rate", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "description", + "fieldtype": "Small Text", + "ignore_xss_filter": 1, + "label": "Description", + "no_copy": 1, + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "description", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 1, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Description", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "0", + "fieldname": "consume_stock", + "fieldtype": "Check", + "label": "Allow Stock Consumption", + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fieldname": "section_break_9", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "consumables", + "fieldtype": "Section Break", + "label": "Consumables" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "consume_stock", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Allow Stock Consumption", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "depends_on": "eval:doc.consume_stock == 1", + "fieldname": "items", + "fieldtype": "Table", + "ignore_user_permissions": 1, + "label": "Items", + "options": "Clinical Procedure Item" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.consume_stock == 1", - "fieldname": "consumables", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Consumables", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "collapsible": 1, + "fieldname": "sample_collection", + "fieldtype": "Section Break", + "label": "Sample Collection" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "items", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Items", - "length": 0, - "no_copy": 0, - "options": "Clinical Procedure Item", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "sample", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Sample", + "options": "Lab Test Sample" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "depends_on": "", - "fieldname": "sample_collection", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Sample Collection", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fetch_from": "sample.sample_uom", + "fieldname": "sample_uom", + "fieldtype": "Data", + "label": "UOM" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sample", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Sample", - "length": 0, - "no_copy": 0, - "options": "Lab Test Sample", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "sample_qty", + "fieldtype": "Float", + "label": "Quantity" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "sample.sample_uom", - "fieldname": "sample_uom", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "UOM", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_21", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sample_qty", - "fieldtype": "Float", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Quantity", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "sample_details", + "fieldtype": "Small Text", + "ignore_xss_filter": 1, + "label": "Collection Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_21", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "0", + "fieldname": "change_in_item", + "fieldtype": "Check", + "hidden": 1, + "label": "Change In Item", + "no_copy": 1, + "print_hide": 1, + "report_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sample_details", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 1, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Collection Details", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "0", + "fieldname": "disabled", + "fieldtype": "Check", + "label": "Disabled" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "change_in_item", - "fieldtype": "Check", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Change In Item", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "disabled", - "fieldtype": "Check", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Disabled", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "item", - "fieldtype": "Link", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Item", - "length": 0, - "no_copy": 1, - "options": "Item", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fieldname": "item", + "fieldtype": "Link", + "label": "Item", + "no_copy": 1, + "options": "Item", + "read_only": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-02-12 11:37:18.713344", - "modified_by": "Administrator", - "module": "Healthcare", - "name": "Clinical Procedure Template", - "name_case": "", - "owner": "Administrator", + ], + "links": [], + "modified": "2020-02-27 16:32:55.780893", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Clinical Procedure Template", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Healthcare Administrator", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Healthcare Administrator", + "share": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Nursing User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 0 - }, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Nursing User", + "share": 1 + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Physician", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Physician", + "share": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Healthcare", - "search_fields": "template", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "template", - "track_changes": 1, - "track_seen": 1, - "track_views": 0 + ], + "restrict_to_domain": "Healthcare", + "search_fields": "template", + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "template", + "track_changes": 1, + "track_seen": 1 } \ No newline at end of file diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py index 141329b3db1..00fad910a4f 100644 --- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py +++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py @@ -9,26 +9,36 @@ from frappe.model.document import Document from frappe.utils import nowdate class ClinicalProcedureTemplate(Document): - def on_update(self): - #Item and Price List update --> if (change_in_item) - if(self.change_in_item and self.is_billable == 1 and self.item): - updating_item(self) - if(self.rate != 0.0): - updating_rate(self) - elif(self.is_billable == 0 and self.item): - frappe.db.set_value("Item",self.item,"disabled",1) - - frappe.db.set_value(self.doctype,self.name,"change_in_item",0) - self.reload() + def validate(self): + self.enable_disable_item() def after_insert(self): create_item_from_template(self) + def on_update(self): + #Item and Price List update --> if (change_in_item) + if self.change_in_item and self.is_billable == 1 and self.item: + updating_item(self) + if self.rate != 0.0: + updating_rate(self) + elif self.is_billable == 0 and self.item: + frappe.db.set_value('Item',self.item,'disabled',1) + + frappe.db.set_value(self.doctype,self.name,'change_in_item',0) + self.reload() + + def enable_disable_item(self): + if self.is_billable: + if self.disabled: + frappe.db.set_value('Item', self.item, 'disabled', 1) + else: + frappe.db.set_value('Item', self.item, 'disabled', 0) + #Call before delete the template def on_trash(self): if(self.item): try: - frappe.delete_doc("Item",self.item) + frappe.delete_doc('Item',self.item) except Exception: frappe.throw(_("""Not permitted. Please disable the Procedure Template""")) @@ -40,7 +50,7 @@ class ClinicalProcedureTemplate(Document): and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)""", (args.get('item_code'), nowdate()), as_dict = 1) if not item: - frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get('item_code'))) + frappe.throw(_('Item {0} is not active or end of life has been reached').format(args.get('item_code'))) item = item[0] @@ -63,46 +73,47 @@ def updating_rate(self): item_code=%s""",(self.template, self.rate, self.item)) def create_item_from_template(doc): - if(doc.is_billable == 1): + disabled = 1 + + if doc.is_billable: disabled = 0 - else: - disabled = 1 + #insert item item = frappe.get_doc({ - "doctype": "Item", - "item_code": doc.template, - "item_name":doc.template, - "item_group": doc.item_group, - "description":doc.description, - "is_sales_item": 1, - "is_service_item": 1, - "is_purchase_item": 0, - "is_stock_item": 0, - "show_in_website": 0, - "is_pro_applicable": 0, - "disabled": disabled, - "stock_uom": "Unit" + 'doctype': 'Item', + 'item_code': doc.template, + 'item_name':doc.template, + 'item_group': doc.item_group, + 'description':doc.description, + 'is_sales_item': 1, + 'is_service_item': 1, + 'is_purchase_item': 0, + 'is_stock_item': 0, + 'show_in_website': 0, + 'is_pro_applicable': 0, + 'disabled': disabled, + 'stock_uom': 'Unit' }).insert(ignore_permissions=True) #insert item price #get item price list to insert item price if(doc.rate != 0.0): - price_list_name = frappe.db.get_value("Price List", {"selling": 1}) + price_list_name = frappe.db.get_value('Price List', {'selling': 1}) if(doc.rate): make_item_price(item.name, price_list_name, doc.rate) else: make_item_price(item.name, price_list_name, 0.0) #Set item to the template - frappe.db.set_value("Clinical Procedure Template", doc.name, "item", item.name) + frappe.db.set_value('Clinical Procedure Template', doc.name, 'item', item.name) doc.reload() #refresh the doc after insert. def make_item_price(item, price_list_name, item_price): frappe.get_doc({ - "doctype": "Item Price", - "price_list": price_list_name, - "item_code": item, - "price_list_rate": item_price + 'doctype': 'Item Price', + 'price_list': price_list_name, + 'item_code': item, + 'price_list_rate': item_price }).insert(ignore_permissions=True) @frappe.whitelist() @@ -111,20 +122,11 @@ def change_item_code_from_template(item_code, doc): doc = frappe._dict(args) if(frappe.db.exists({ - "doctype": "Item", - "item_code": item_code})): - frappe.throw(_("Code {0} already exist").format(item_code)) + 'doctype': 'Item', + 'item_code': item_code})): + frappe.throw(_('Code {0} already exist').format(item_code)) else: - frappe.rename_doc("Item", doc.item_code, item_code, ignore_permissions = True) - frappe.db.set_value("Clinical Procedure Template", doc.name, "item_code", item_code) + frappe.rename_doc('Item', doc.item_code, item_code, ignore_permissions=True) + frappe.db.set_value('Clinical Procedure Template', doc.name, 'item_code', item_code) return -@frappe.whitelist() -def disable_enable_template(status, name, item_code): - frappe.db.set_value("Clinical Procedure Template", name, "disabled", status) - if (frappe.db.exists({ #set Item's disabled field to status - "doctype": "Item", - "item_code": item_code})): - frappe.db.set_value("Item", item_code, "disabled", status) - - return diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json index f6521183097..6fdc21d388f 100644 --- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json +++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json @@ -78,6 +78,7 @@ }, { "default": "0", + "description": "Checking this will create new Patients with a Disabled status by default and will only be enabled after invoicing the Registration Fee.", "fieldname": "collect_registration_fee", "fieldtype": "Check", "label": "Collect Fee for Patient Registration" diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py index 86094896154..85db0dbabb6 100644 --- a/erpnext/healthcare/doctype/lab_test/lab_test.py +++ b/erpnext/healthcare/doctype/lab_test/lab_test.py @@ -290,19 +290,23 @@ def insert_lab_test_to_medical_record(doc): comment = "" if item.lab_test_comment: comment = str(item.lab_test_comment) - event = "" + table_row = item.lab_test_name + if item.lab_test_event: - event = item.lab_test_event - table_row = item.lab_test_name +" "+ event +" "+ item.result_value + table_row += " " + item.lab_test_event + + if item.result_value: + table_row += " " + item.result_value + if item.normal_range: table_row += " normal_range("+item.normal_range+")" - table_row += " "+comment + table_row += " " + comment elif doc.special_test_items: item = doc.special_test_items[0] if item.lab_test_particulars and item.result_value: - table_row = item.lab_test_particulars +" "+ item.result_value + table_row = item.lab_test_particulars + " " + item.result_value elif doc.sensitivity_test_items: item = doc.sensitivity_test_items[0] diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py index 89f2defb14b..5c9e7524c1a 100644 --- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py +++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe, json from frappe.model.document import Document +from frappe.model.rename_doc import rename_doc from frappe import _ class LabTestTemplate(Document): @@ -98,13 +99,11 @@ def create_item_from_template(doc): # get item price list to insert item price if doc.lab_test_rate != 0.0: price_list_name = frappe.db.get_value("Price List", {"selling": 1}) - if(doc.lab_test_rate): + if doc.lab_test_rate: make_item_price(item.name, price_list_name, doc.lab_test_rate) - item.standard_rate = doc.lab_test_rate else: make_item_price(item.name, price_list_name, 0.0) - item.standard_rate = 0.0 - item.save(ignore_permissions = True) + # Set item in the template frappe.db.set_value("Lab Test Template", doc.name, "item", item.name) diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js index 1a34fe8076f..9984b0ae9c9 100644 --- a/erpnext/healthcare/doctype/patient/patient.js +++ b/erpnext/healthcare/doctype/patient/patient.js @@ -15,7 +15,7 @@ frappe.ui.form.on('Patient', { } else { erpnext.toggle_naming_series(); } - if (frappe.defaults.get_default("collect_registration_fee") && frm.doc.disabled == 1) { + if (frappe.defaults.get_default("collect_registration_fee") && frm.doc.status == 'Disabled') { frm.add_custom_button(__('Invoice Patient Registration'), function () { btn_invoice_registration(frm); }); diff --git a/erpnext/healthcare/doctype/patient/patient.json b/erpnext/healthcare/doctype/patient/patient.json index 0136f72f5be..7f97e17934f 100644 --- a/erpnext/healthcare/doctype/patient/patient.json +++ b/erpnext/healthcare/doctype/patient/patient.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_copy": 1, "allow_import": 1, "allow_rename": 1, @@ -19,15 +20,14 @@ "blood_group", "dob", "age_html", - "status", "image", "column_break_14", + "status", "customer", "report_preference", "mobile", "email", "phone", - "disabled", "sb_relation", "patient_relation", "allergy_medical_and_surgical_history", @@ -125,15 +125,15 @@ "report_hide": 1 }, { - "default": "Active", "fieldname": "status", "fieldtype": "Select", - "hidden": 1, + "in_filter": 1, + "in_list_view": 1, "label": "Status", "no_copy": 1, - "options": "Active\nDormant\nOpen", + "options": "Active\nDisabled", "print_hide": 1, - "report_hide": 1 + "read_only": 1 }, { "fieldname": "image", @@ -183,19 +183,8 @@ "fieldname": "phone", "fieldtype": "Data", "in_filter": 1, - "in_list_view": 1, "label": "Phone" }, - { - "default": "0", - "fieldname": "disabled", - "fieldtype": "Check", - "hidden": 1, - "label": "Disabled", - "no_copy": 1, - "print_hide": 1, - "report_hide": 1 - }, { "collapsible": 1, "fieldname": "sb_relation", @@ -346,8 +335,9 @@ ], "icon": "fa fa-user", "image_field": "image", + "links": [], "max_attachments": 50, - "modified": "2019-09-25 23:30:49.905893", + "modified": "2020-01-29 11:22:40.698125", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient", diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py index e3eea96f859..420416809dd 100644 --- a/erpnext/healthcare/doctype/patient/patient.py +++ b/erpnext/healthcare/doctype/patient/patient.py @@ -15,8 +15,8 @@ class Patient(Document): def after_insert(self): if(frappe.db.get_value("Healthcare Settings", None, "manage_customer") == '1' and not self.customer): create_customer(self) - if(frappe.db.get_value("Healthcare Settings", None, "collect_registration_fee") == '1'): - frappe.db.set_value("Patient", self.name, "disabled", 1) + if frappe.db.get_single_value('Healthcare Settings', 'collect_registration_fee'): + frappe.db.set_value('Patient', self.name, 'status', 'Disabled') else: send_registration_sms(self) self.reload() @@ -62,7 +62,7 @@ class Patient(Document): return age_str def invoice_patient_registration(self): - frappe.db.set_value("Patient", self.name, "disabled", 0) + frappe.db.set_value("Patient", self.name, "status", "Active") send_registration_sms(self) if(flt(frappe.get_value("Healthcare Settings", None, "registration_fee"))>0): company = frappe.defaults.get_user_default('company') diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js index 858145eef3c..087f1628404 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js @@ -11,7 +11,7 @@ frappe.ui.form.on('Patient Appointment', { refresh: function(frm) { frm.set_query("patient", function () { return { - filters: {"disabled": 0} + filters: {"status": "Active"} }; }); frm.set_query("practitioner", function() { @@ -288,12 +288,19 @@ var check_and_set_availability = function(frm) { }; var get_procedure_prescribed = function(frm){ - if(frm.doc.patient){ + if (frm.doc.patient) { frappe.call({ method:"erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_procedure_prescribed", args: {patient: frm.doc.patient}, - callback: function(r){ - show_procedure_templates(frm, r.message); + callback: function(r) { + if (r.message && r.message.length) { + show_procedure_templates(frm, r.message); + } else { + frappe.msgprint({ + title: __('Not Found'), + message: __('No Prescribed Procedures found for the selected Patient') + }); + } } }); } diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json index ee9f013084b..93124b4de56 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json @@ -1,1177 +1,333 @@ { "allow_copy": 1, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, "allow_import": 1, - "allow_rename": 0, "autoname": "OP-.######", "beta": 1, "creation": "2017-05-04 11:52:40.941507", - "custom": 0, - "docstatus": 0, "doctype": "DocType", "document_type": "Document", - "editable_grid": 0, "engine": "InnoDB", + "field_order": [ + "inpatient_record", + "patient", + "appointment_type", + "duration", + "column_break_1", + "status", + "procedure_template", + "get_procedure_from_encounter", + "procedure_prescription", + "service_unit", + "check_availability", + "section_break_12", + "practitioner", + "department", + "column_break_17", + "appointment_date", + "appointment_time", + "section_break_16", + "patient_name", + "patient_sex", + "column_break_21", + "patient_age", + "section_break_1", + "appointment_datetime", + "mode_of_payment", + "paid_amount", + "column_break_2", + "invoiced", + "company", + "section_break_3", + "notes", + "referring_practitioner", + "reminded" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fetch_from": "patient.inpatient_record", "fieldname": "inpatient_record", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Inpatient Record", - "length": 0, - "no_copy": 0, "options": "Inpatient Record", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "read_only": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fetch_from": "inpatient_record.patient", "fieldname": "patient", "fieldtype": "Link", - "hidden": 0, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 1, "label": "Patient", - "length": 0, - "no_copy": 0, "options": "Patient", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, "reqd": 1, "search_index": 1, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "appointment_type", "fieldtype": "Link", - "hidden": 0, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Appointment Type", - "length": 0, - "no_copy": 0, "options": "Appointment Type", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "description": "In Minutes", "fieldname": "duration", "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, "in_filter": 1, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Duration", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "label": "Duration" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_1", "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "read_only": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "Scheduled", "depends_on": "eval:!doc.__islocal", "fieldname": "status", "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, "in_filter": 1, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Status", - "length": 0, - "no_copy": 0, "options": "\nScheduled\nOpen\nClosed\nPending\nCancelled", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "search_index": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "procedure_template", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Procedure", - "length": 0, - "no_copy": 0, "options": "Clinical Procedure Template", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "get_procedure_from_encounter", "fieldtype": "Button", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Get prescribed procedures", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "label": "Get prescribed procedures" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "procedure_prescription", "fieldtype": "Link", "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Procedure Prescription", - "length": 0, "no_copy": 1, "options": "Procedure Prescription", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "print_hide": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "service_unit", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Service Unit", - "length": 0, - "no_copy": 0, "options": "Healthcare Service Unit", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "depends_on": "eval:doc.__islocal", "fieldname": "check_availability", "fieldtype": "Button", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Check availability", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "label": "Check availability" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "section_break_12", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fieldtype": "Section Break" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "practitioner", "fieldtype": "Link", - "hidden": 0, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, "in_standard_filter": 1, "label": "Healthcare Practitioner", - "length": 0, - "no_copy": 0, "options": "Healthcare Practitioner", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, "reqd": 1, "search_index": 1, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "department", "fieldtype": "Link", - "hidden": 0, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 1, "label": "Department", - "length": 0, - "no_copy": 0, "options": "Medical Department", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, "search_index": 1, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_17", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fieldtype": "Column Break" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "appointment_date", "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 1, "label": "Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, "reqd": 1, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "search_index": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "appointment_time", "fieldtype": "Time", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, "in_list_view": 1, - "in_standard_filter": 0, "label": "Time", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "read_only": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "section_break_16", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fieldtype": "Section Break" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", "fetch_from": "patient.patient_name", "fieldname": "patient_name", "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Patient Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "read_only": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fetch_from": "patient.sex", "fieldname": "patient_sex", "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Gender", - "length": 0, "no_copy": 1, - "options": "", - "permlevel": 0, - "precision": "", "print_hide": 1, - "print_hide_if_no_value": 0, "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "report_hide": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_21", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fieldtype": "Column Break" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "patient_age", "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Patient Age", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "read_only": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", "fieldname": "section_break_1", "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "appointment_datetime", "fieldtype": "Datetime", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Date TIme", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", + "label": "Appointment Datetime", "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "read_only": 1, + "search_index": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "mode_of_payment", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Mode of Payment", - "length": 0, - "no_copy": 0, - "options": "Mode of Payment", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "options": "Mode of Payment" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "paid_amount", "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Paid Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "label": "Paid Amount" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_2", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fieldtype": "Column Break" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "0", "fieldname": "invoiced", "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Invoiced", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "search_index": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "company", "fieldtype": "Link", "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Company", - "length": 0, "no_copy": 1, "options": "Company", - "permlevel": 0, - "precision": "", "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "report_hide": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "fieldname": "section_break_3", "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "More Info", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "label": "More Info" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "notes", "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, "ignore_xss_filter": 1, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Notes", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "label": "Notes" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "referring_practitioner", "fieldtype": "Link", - "hidden": 0, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Referring Practitioner", - "length": 0, - "no_copy": 0, "options": "Healthcare Practitioner", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 0 + "set_only_once": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "0", "fieldname": "reminded", "fieldtype": "Check", "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Reminded", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "report_hide": 1 } ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-14 13:24:01.529536", - "modified_by": "Administrator", + "modified": "2020-03-27 15:55:24.344945", + "modified_by": "ruchamahabal2@gmail.com", "module": "Healthcare", "name": "Patient Appointment", - "name_case": "", "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, "print": 1, "read": 1, "report": 1, "role": "Healthcare Administrator", - "set_user_permissions": 0, "share": 1, - "submit": 0, "write": 1 }, { - "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, "print": 1, "read": 1, "report": 1, "role": "Physician", - "set_user_permissions": 0, "share": 1, - "submit": 0, "write": 1 }, { - "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, "print": 1, "read": 1, "report": 1, "role": "Nursing User", - "set_user_permissions": 0, "share": 1, - "submit": 0, "write": 1 } ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, "restrict_to_domain": "Healthcare", "search_fields": "patient, practitioner, department, appointment_date, appointment_time", "show_name_in_global_search": 1, @@ -1179,6 +335,5 @@ "sort_order": "DESC", "title_field": "patient", "track_changes": 1, - "track_seen": 1, - "track_views": 0 -} + "track_seen": 1 +} \ No newline at end of file diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py index 12248fcdce3..8f3602af67e 100755 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py @@ -25,6 +25,7 @@ class PatientAppointment(Document): self.reload() def validate(self): + self.set_appointment_datetime() end_time = datetime.datetime.combine(getdate(self.appointment_date), get_time(self.appointment_time)) + datetime.timedelta(minutes=float(self.duration)) overlaps = frappe.db.sql(""" select @@ -44,6 +45,9 @@ class PatientAppointment(Document): frappe.throw(_("""Appointment overlaps with {0}.
{1} has appointment scheduled with {2} at {3} having {4} minute(s) duration.""").format(overlaps[0][0], overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4])) + def set_appointment_datetime(self): + self.appointment_datetime = "%s %s" % (self.appointment_date, self.appointment_time or "00:00:00") + def after_insert(self): if self.procedure_prescription: frappe.db.set_value("Procedure Prescription", self.procedure_prescription, "appointment_booked", True) @@ -319,27 +323,29 @@ def create_encounter(appointment): return encounter.as_dict() -def remind_appointment(): - if frappe.db.get_value("Healthcare Settings", None, "app_rem") == '1': - rem_before = datetime.datetime.strptime(frappe.get_value("Healthcare Settings", None, "rem_before"), "%H:%M:%S") - rem_dt = datetime.datetime.now() + datetime.timedelta( - hours=rem_before.hour, minutes=rem_before.minute, seconds=rem_before.second) +def set_appointment_reminder(): + if frappe.db.get_single_value("Healthcare Settings", "app_rem"): + remind_before = datetime.datetime.strptime(frappe.db.get_single_value("Healthcare Settings", "rem_before"), '%H:%M:%S') - appointment_list = frappe.db.sql( - "select name from `tabPatient Appointment` where start_dt between %s and %s and reminded = 0 ", - (datetime.datetime.now(), rem_dt) - ) + reminder_dt = datetime.datetime.now() + datetime.timedelta( + hours=remind_before.hour, minutes=remind_before.minute, seconds=remind_before.second) - for i in range(0, len(appointment_list)): - doc = frappe.get_doc("Patient Appointment", appointment_list[i][0]) - message = frappe.db.get_value("Healthcare Settings", None, "app_rem_msg") + appointment_list = frappe.db.get_all("Patient Appointment", { + "appointment_datetime": ["between", (datetime.datetime.now(), reminder_dt)], + "reminded": 0, + "status": ["!=", "Cancelled"] + }) + + for appointment in appointment_list: + doc = frappe.get_doc('Patient Appointment', appointment.name) + message = frappe.db.get_single_value("Healthcare Settings", "app_rem_msg") send_message(doc, message) - frappe.db.set_value("Patient Appointment", doc.name, "reminded",1) + frappe.db.set_value('Patient Appointment', doc.name, 'reminded', 1) def send_message(doc, message): - patient = frappe.get_doc("Patient", doc.patient) - if patient.mobile: + patient_mobile = frappe.db.get_value("Patient", doc.patient, "mobile") + if patient_mobile: context = {"doc": doc, "alert": doc, "comments": None} if doc.get("_comments"): context["comments"] = json.loads(doc.get("_comments")) diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js index 088bc8161b1..c1b0b18dba4 100644 --- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js +++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js @@ -62,7 +62,7 @@ frappe.ui.form.on('Patient Encounter', { frm.set_query("patient", function () { return { - filters: {"disabled": 0} + filters: {"status": "Active"} }; }); frm.set_query("drug_code", "drug_prescription", function() { diff --git a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json index 08a1b86969c..cff100cc704 100644 --- a/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json +++ b/erpnext/healthcare/doctype/practitioner_schedule/practitioner_schedule.json @@ -1,160 +1,71 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:schedule_name", - "beta": 1, - "creation": "2017-05-03 17:28:03.926787", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:schedule_name", + "beta": 1, + "creation": "2017-05-03 17:28:03.926787", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "disabled", + "schedule_details_section", + "schedule_name", + "time_slots" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "schedule_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 1, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Schedule Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "schedule_name", + "fieldtype": "Data", + "ignore_xss_filter": 1, + "in_list_view": 1, + "label": "Schedule Name", + "reqd": 1, + "unique": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "time_slots", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Time Slots", - "length": 0, - "no_copy": 0, - "options": "Healthcare Schedule Time Slot", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "time_slots", + "fieldtype": "Table", + "label": "Time Slots", + "options": "Healthcare Schedule Time Slot" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "disabled", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Disabled", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "default": "0", + "fieldname": "disabled", + "fieldtype": "Check", + "label": "Disabled", + "print_hide": 1 + }, + { + "fieldname": "schedule_details_section", + "fieldtype": "Section Break", + "label": "Schedule Details" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-06-29 14:55:34.795995", - "modified_by": "Administrator", - "module": "Healthcare", - "name": "Practitioner Schedule", - "name_case": "", - "owner": "rmehta@gmail.com", + ], + "links": [], + "modified": "2020-01-31 12:21:45.975488", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Practitioner Schedule", + "owner": "rmehta@gmail.com", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Healthcare Administrator", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Healthcare Administrator", + "share": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Healthcare", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 + ], + "restrict_to_domain": "Healthcare", + "show_name_in_global_search": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 7f268d6ba14..81fb40506b6 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -268,7 +268,9 @@ doc_events = { scheduler_events = { "all": [ - "erpnext.projects.doctype.project.project.project_status_update_reminder" + "erpnext.projects.doctype.project.project.project_status_update_reminder", + "erpnext.healthcare_healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder" + ], "hourly": [ 'erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails', diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index 3acaee4ffbd..4f08bbc3fc7 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -135,6 +135,7 @@ frappe.ui.form.on("BOM", { frappe.call({ method: "erpnext.manufacturing.doctype.work_order.work_order.make_work_order", args: { + bom_no: frm.doc.name, item: frm.doc.item, qty: data.qty || 0.0, project: frm.doc.project diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js index 6db8f2f5b38..9ee5e80f88d 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.js +++ b/erpnext/manufacturing/doctype/job_card/job_card.js @@ -24,7 +24,7 @@ frappe.ui.form.on('Job Card', { } } - if (frm.doc.docstatus == 0 && frm.doc.for_quantity > frm.doc.total_completed_qty + if (frm.doc.docstatus == 0 && (frm.doc.for_quantity > frm.doc.total_completed_qty || !frm.doc.for_quantity) && (!frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) { frm.trigger("prepare_timer_buttons"); } @@ -63,10 +63,14 @@ frappe.ui.form.on('Job Card', { let completed_time = frappe.datetime.now_datetime(); frm.trigger("hide_timer"); - frappe.prompt({fieldtype: 'Float', label: __('Completed Quantity'), - fieldname: 'qty', reqd: 1, default: frm.doc.for_quantity}, data => { - frm.events.complete_job(frm, completed_time, data.qty); - }, __("Enter Value"), __("Complete")); + if (frm.doc.for_quantity) { + frappe.prompt({fieldtype: 'Float', label: __('Completed Quantity'), + fieldname: 'qty', reqd: 1, default: frm.doc.for_quantity}, data => { + frm.events.complete_job(frm, completed_time, data.qty); + }, __("Enter Value"), __("Complete")); + } else { + frm.events.complete_job(frm, completed_time, 0); + } }).addClass("btn-primary"); } }, diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json index fd39af1faad..7661fffa864 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.json +++ b/erpnext/manufacturing/doctype/job_card/job_card.json @@ -99,8 +99,7 @@ "fieldname": "for_quantity", "fieldtype": "Float", "in_list_view": 1, - "label": "Qty To Manufacture", - "reqd": 1 + "label": "Qty To Manufacture" }, { "fieldname": "wip_warehouse", @@ -122,6 +121,7 @@ "options": "Employee" }, { + "allow_bulk_edit": 1, "fieldname": "time_logs", "fieldtype": "Table", "label": "Time Logs", @@ -290,78 +290,61 @@ } ], "is_submittable": 1, - "modified": "2020-03-24 13:08:57.926201", + "modified": "2020-03-27 13:36:35.417502", "modified_by": "Administrator", "module": "Manufacturing", "name": "Job Card", "owner": "Administrator", "permissions": [ { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Manufacturing User", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Manufacturing User", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Manufacturing Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Manufacturing Manager", + "share": 1, + "submit": 1, "write": 1 } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "operation", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "operation", + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index eec7d242871..7c648c79014 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -92,10 +92,7 @@ class JobCard(Document): if not self.time_logs: frappe.throw(_("Time logs are required for job card {0}").format(self.name)) - if self.total_completed_qty <= 0.0: - frappe.throw(_("Total completed qty must be greater than zero")) - - if self.total_completed_qty != self.for_quantity: + if self.for_quantity and self.total_completed_qty != self.for_quantity: frappe.throw(_("The total completed qty({0}) must be equal to qty to manufacture({1})" .format(frappe.bold(self.total_completed_qty),frappe.bold(self.for_quantity)))) @@ -106,27 +103,34 @@ class JobCard(Document): for_quantity, time_in_mins = 0, 0 from_time_list, to_time_list = [], [] - for d in frappe.get_all('Job Card', - filters = {'docstatus': 1, 'operation_id': self.operation_id}): - doc = frappe.get_doc('Job Card', d.name) - for_quantity += doc.total_completed_qty - time_in_mins += doc.total_time_in_mins - for time_log in doc.time_logs: - if time_log.from_time: - from_time_list.append(time_log.from_time) - if time_log.to_time: - to_time_list.append(time_log.to_time) + data = frappe.get_all('Job Card', + fields = ["sum(total_time_in_mins) as time_in_mins", "sum(total_completed_qty) as completed_qty"], + filters = {"docstatus": 1, "work_order": self.work_order, + "workstation": self.workstation, "operation": self.operation}) + + if data and len(data) > 0: + for_quantity = data[0].completed_qty + time_in_mins = data[0].time_in_mins if for_quantity: + time_data = frappe.db.sql(""" + SELECT + min(from_time) as start_time, max(to_time) as end_time + FROM `tabJob Card` jc, `tabJob Card Time Log` jctl + WHERE + jctl.parent = jc.name and jc.work_order = %s + and jc.workstation = %s and jc.operation = %s and jc.docstatus = 1 + """, (self.work_order, self.workstation, self.operation), as_dict=1) + wo = frappe.get_doc('Work Order', self.work_order) for data in wo.operations: - if data.name == self.operation_id: + if data.workstation == self.workstation and data.operation == self.operation: data.completed_qty = for_quantity data.actual_operation_time = time_in_mins - data.actual_start_time = min(from_time_list) if from_time_list else None - data.actual_end_time = max(to_time_list) if to_time_list else None + data.actual_start_time = time_data[0].start_time if time_data else None + data.actual_end_time = time_data[0].end_time if time_data else None wo.flags.ignore_validate_update_after_submit = True wo.update_operation_status() diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 76202e5a6f3..61b4ca838b3 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -144,7 +144,7 @@ class ProductionPlan(Document): item_condition = " and mr_item.item_code ={0}".format(frappe.db.escape(self.item_code)) items = frappe.db.sql("""select distinct parent, name, item_code, warehouse, description, - (qty - ordered_qty) as pending_qty + (qty - ordered_qty) * conversion_factor as pending_qty from `tabMaterial Request Item` mr_item where parent in (%s) and docstatus = 1 and qty > ordered_qty and exists (select name from `tabBOM` bom where bom.item=mr_item.item_code diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 83579414812..8a39f7420e9 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -274,7 +274,7 @@ class WorkOrder(Document): stock_entry = frappe.db.sql("""select name from `tabStock Entry` where work_order = %s and docstatus = 1""", self.name) if stock_entry: - frappe.throw(_("Cannot cancel because submitted Stock Entry {0} exists").format(stock_entry[0][0])) + frappe.throw(_("Cannot cancel because submitted Stock Entry {0} exists").format(frappe.utils.get_link_to_form('Stock Entry', stock_entry[0][0]))) def update_planned_qty(self): update_bin_qty(self.production_item, self.fg_warehouse, { @@ -609,7 +609,7 @@ def get_item_details(item, project = None): return res @frappe.whitelist() -def make_work_order(item, qty=0, project=None): +def make_work_order(bom_no, item, qty=0, project=None): if not frappe.has_permission("Work Order", "write"): frappe.throw(_("Not permitted"), frappe.PermissionError) @@ -618,6 +618,7 @@ def make_work_order(item, qty=0, project=None): wo_doc = frappe.new_doc("Work Order") wo_doc.production_item = item wo_doc.update(item_details) + wo_doc.bom_no = bom_no if flt(qty) > 0: wo_doc.qty = flt(qty) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index ee8ca0d5662..e1c38a91297 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -362,12 +362,17 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ ['serial_no', 'batch_no', 'barcode'].forEach(field => { if (data[field] && frappe.meta.has_field(row_to_modify.doctype, field)) { + + let value = (row_to_modify[field] && field === "serial_no") + ? row_to_modify[field] + '\n' + data[field] : data[field]; + frappe.model.set_value(row_to_modify.doctype, - row_to_modify.name, field, data[field]); + row_to_modify.name, field, value); } }); scan_barcode_field.set_value(''); + refresh_field("items"); }); } return false; diff --git a/erpnext/public/js/utils/item_quick_entry.js b/erpnext/public/js/utils/item_quick_entry.js index 2947d5b98eb..27ef107acef 100644 --- a/erpnext/public/js/utils/item_quick_entry.js +++ b/erpnext/public/js/utils/item_quick_entry.js @@ -8,12 +8,19 @@ frappe.ui.form.ItemQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({ render_dialog: function() { this.mandatory = this.get_variant_fields().concat(this.mandatory); this.mandatory = this.mandatory.concat(this.get_attributes_fields()); + this.check_naming_series_based_on(); this._super(); this.init_post_render_dialog_operations(); this.preset_fields_for_template(); this.dialog.$wrapper.find('.edit-full').text(__('Edit in full page for more options like assets, serial nos, batches etc.')) }, + check_naming_series_based_on: function() { + if (frappe.defaults.get_default("item_naming_by") === "Naming Series") { + this.mandatory = this.mandatory.filter(d => d.fieldname !== "item_code"); + } + }, + init_post_render_dialog_operations: function() { this.dialog.fields_dict.attribute_html.$wrapper.append(frappe.render_template("item_quick_entry")); this.init_for_create_variant_trigger(); diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 9e4a71d60e5..19cf65dee86 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -500,7 +500,7 @@ def close_or_unclose_sales_orders(names, status): def get_requested_item_qty(sales_order): return frappe._dict(frappe.db.sql(""" - select sales_order_item, sum(stock_qty) + select sales_order_item, sum(qty) from `tabMaterial Request Item` where docstatus = 1 and sales_order = %s @@ -511,16 +511,12 @@ def get_requested_item_qty(sales_order): def make_material_request(source_name, target_doc=None): requested_item_qty = get_requested_item_qty(source_name) - def postprocess(source, doc): - doc.material_request_type = "Purchase" - def update_item(source, target, source_parent): # qty is for packed items, because packed items don't have stock_qty field - qty = source.get("stock_qty") or source.get("qty") + qty = source.get("qty") target.project = source_parent.project target.qty = qty - requested_item_qty.get(source.name, 0) - target.conversion_factor = 1 - target.stock_qty = qty - requested_item_qty.get(source.name, 0) + target.stock_qty = flt(target.qty) * flt(target.conversion_factor) doc = get_mapped_doc("Sales Order", source_name, { "Sales Order": { @@ -541,14 +537,12 @@ def make_material_request(source_name, target_doc=None): "doctype": "Material Request Item", "field_map": { "name": "sales_order_item", - "parent": "sales_order", - "stock_uom": "uom", - "stock_qty": "qty" + "parent": "sales_order" }, "condition": lambda doc: not frappe.db.exists('Product Bundle', doc.item_code) and doc.stock_qty > requested_item_qty.get(doc.name, 0), "postprocess": update_item } - }, target_doc, postprocess) + }, target_doc) return doc diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py index a9d2be5fffc..bef2c53d6d4 100644 --- a/erpnext/selling/page/point_of_sale/point_of_sale.py +++ b/erpnext/selling/page/point_of_sale/point_of_sale.py @@ -64,30 +64,40 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p for d in item_prices_data: item_prices[d.item_code] = d - + # prepare filter for bin query + bin_filters = {'item_code': ['in', items]} + if warehouse: + bin_filters['warehouse'] = warehouse if display_items_in_stock: - filters = {'actual_qty': [">", 0], 'item_code': ['in', items]} + bin_filters['actual_qty'] = [">", 0] - if warehouse: - filters['warehouse'] = warehouse + # query item bin + bin_data = frappe.get_all( + 'Bin', fields=['item_code', 'sum(actual_qty) as actual_qty'], + filters=bin_filters, group_by='item_code' + ) - bin_data = frappe._dict( - frappe.get_all("Bin", fields = ["item_code", "sum(actual_qty) as actual_qty"], - filters = filters, group_by = "item_code") - ) + # convert list of dict into dict as {item_code: actual_qty} + bin_dict = {} + for b in bin_data: + bin_dict[b.get('item_code')] = b.get('actual_qty') for item in items_data: - row = {} + item_code = item.item_code + item_price = item_prices.get(item_code) or {} + item_stock_qty = bin_dict.get(item_code) - row.update(item) - item_price = item_prices.get(item.item_code) or {} - row.update({ - 'price_list_rate': item_price.get('price_list_rate'), - 'currency': item_price.get('currency'), - 'actual_qty': bin_data.get('actual_qty') - }) - - result.append(row) + if display_items_in_stock and not item_stock_qty: + pass + else: + row = {} + row.update(item) + row.update({ + 'price_list_rate': item_price.get('price_list_rate'), + 'currency': item_price.get('currency'), + 'actual_qty': item_stock_qty, + }) + result.append(row) res = { 'items': result diff --git a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py index 4509904249f..28dd0564075 100644 --- a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py +++ b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import getdate, cint +from frappe.utils import getdate, cint, cstr import calendar def execute(filters=None): @@ -48,7 +48,7 @@ def execute(filters=None): new = new_customers_in.get(key, [0,0.0]) repeat = repeat_customers_in.get(key, [0,0.0]) - out.append([year, calendar.month_name[month], + out.append([cstr(year), calendar.month_name[month], new[0], repeat[0], new[0] + repeat[0], new[1], repeat[1], new[1] + repeat[1]]) diff --git a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py index 1fc3663bed7..405004ece54 100644 --- a/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py +++ b/erpnext/selling/report/item_wise_sales_history/item_wise_sales_history.py @@ -121,8 +121,8 @@ def get_columns(filters): }, { "label": _("Billed Amount"), - "fieldname": "rate", - "options": "billed_amount", + "fieldtype": "currency", + "fieldname": "billed_amount", "width": 120 }, { diff --git a/erpnext/stock/__init__.py b/erpnext/stock/__init__.py index a4d4cbd8ef8..8d64efe41dd 100644 --- a/erpnext/stock/__init__.py +++ b/erpnext/stock/__init__.py @@ -13,12 +13,16 @@ install_docs = [ ] def get_warehouse_account_map(company=None): - if not frappe.flags.warehouse_account_map or frappe.flags.in_test: + company_warehouse_account_map = company and frappe.flags.setdefault('warehouse_account_map', {}).get(company) + warehouse_account_map = frappe.flags.warehouse_account_map + + if not warehouse_account_map or not company_warehouse_account_map or frappe.flags.in_test: warehouse_account = frappe._dict() filters = {} if company: filters['company'] = company + frappe.flags.setdefault('warehouse_account_map', {}).setdefault(company, {}) for d in frappe.get_all('Warehouse', fields = ["name", "account", "parent_warehouse", "company", "is_group"], @@ -30,10 +34,12 @@ def get_warehouse_account_map(company=None): if d.account: d.account_currency = frappe.db.get_value('Account', d.account, 'account_currency', cache=True) warehouse_account.setdefault(d.name, d) - - frappe.flags.warehouse_account_map = warehouse_account - - return frappe.flags.warehouse_account_map + if company: + frappe.flags.warehouse_account_map[company] = warehouse_account + else: + frappe.flags.warehouse_account_map = warehouse_account + + return frappe.flags.warehouse_account_map.get(company) or frappe.flags.warehouse_account_map def get_warehouse_account(warehouse, warehouse_account=None): account = warehouse.account diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index cb0eb406df6..24896f09da1 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -741,14 +741,12 @@ class Item(WebsiteGenerator): defaults = frappe.defaults.get_defaults() or {} # To check default warehouse is belong to the default company - if defaults.get("default_warehouse") and frappe.db.exists("Warehouse", + if defaults.get("default_warehouse") and defaults.company and frappe.db.exists("Warehouse", {'name': defaults.default_warehouse, 'company': defaults.company}): - warehouse = defaults.default_warehouse - - self.append("item_defaults", { - "company": defaults.get("company"), - "default_warehouse": warehouse - }) + self.append("item_defaults", { + "company": defaults.get("company"), + "default_warehouse": defaults.default_warehouse + }) def update_variants(self): if self.flags.dont_update_variants or \ diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index d97b699a0f3..5ad0e13db9a 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -8,6 +8,7 @@ from frappe.utils import flt from frappe.model.meta import get_field_precision from frappe.model.document import Document from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos +from erpnext.accounts.doctype.account.account import get_account_currency class LandedCostVoucher(Document): def get_items_from_purchase_receipts(self): @@ -43,6 +44,7 @@ class LandedCostVoucher(Document): else: self.validate_applicable_charges_for_item() self.validate_purchase_receipts() + self.validate_expense_accounts() self.set_total_taxes_and_charges() def check_mandatory(self): @@ -71,6 +73,14 @@ class LandedCostVoucher(Document): frappe.throw(_("Row {0}: Cost center is required for an item {1}") .format(item.idx, item.item_code)) + def validate_expense_accounts(self): + company_currency = erpnext.get_company_currency(self.company) + for account in self.taxes: + if get_account_currency(account.expense_account) != company_currency: + frappe.throw(msg=_(""" Row {0}: Expense account currency should be same as company's default currency. + Please select expense account with account currency as {1}""") + .format(account.idx, frappe.bold(company_currency)), title=_("Invalid Account Currency")) + def set_total_taxes_and_charges(self): self.total_taxes_and_charges = sum([flt(d.amount) for d in self.get("taxes")]) diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 6531e095b84..78383e05a6f 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -484,7 +484,7 @@ def raise_work_orders(material_request): wo_order = frappe.new_doc("Work Order") wo_order.update({ "production_item": d.item_code, - "qty": d.qty - d.ordered_qty, + "qty": d.stock_qty - d.ordered_qty, "fg_warehouse": d.warehouse, "wip_warehouse": default_wip_warehouse, "description": d.description, diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 23ee9f472b8..b54233f4585 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -303,12 +303,12 @@ frappe.ui.form.on('Stock Entry', { method: "erpnext.stock.get_item_details.get_serial_no", args: {"args": args}, callback: function(r) { - if (!r.exe){ + if (!r.exe && r.message){ frappe.model.set_value(cdt, cdn, "serial_no", r.message); - } - if (callback) { - callback(); + if (callback) { + callback(); + } } } }); @@ -537,10 +537,15 @@ frappe.ui.form.on('Stock Entry Detail', { if(r.message) { var d = locals[cdt][cdn]; $.each(r.message, function(k, v) { - frappe.model.set_value(cdt, cdn, k, v); // qty and it's subsequent fields weren't triggered + if (v) { + frappe.model.set_value(cdt, cdn, k, v); // qty and it's subsequent fields weren't triggered + } }); refresh_field("items"); - erpnext.stock.select_batch_and_serial_no(frm, d); + + if (!d.serial_no) { + erpnext.stock.select_batch_and_serial_no(frm, d); + } } } }); diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index a6da3d306b4..b2384f1b4e9 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -298,13 +298,8 @@ class StockEntry(StockController): if validate_for_manufacture: if d.bom_no: d.s_warehouse = None - if not d.t_warehouse: frappe.throw(_("Target warehouse is mandatory for row {0}").format(d.idx)) - - elif self.pro_doc and (cstr(d.t_warehouse) != self.pro_doc.fg_warehouse and cstr(d.t_warehouse) != self.pro_doc.scrap_warehouse): - frappe.throw(_("Target warehouse in row {0} must be same as Work Order").format(d.idx)) - else: d.t_warehouse = None if not d.s_warehouse: diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.js b/erpnext/stock/report/stock_ledger/stock_ledger.js index 3fab3273b9e..1813c2b5bd7 100644 --- a/erpnext/stock/report/stock_ledger/stock_ledger.js +++ b/erpnext/stock/report/stock_ledger/stock_ledger.js @@ -29,7 +29,13 @@ frappe.query_reports["Stock Ledger"] = { "fieldname":"warehouse", "label": __("Warehouse"), "fieldtype": "Link", - "options": "Warehouse" + "options": "Warehouse", + "get_query": function() { + const company = frappe.query_report.get_filter_value('company'); + return { + filters: { 'company': company } + } + } }, { "fieldname":"item_code", diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index b100f453273..7567a1ae758 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -428,7 +428,7 @@ class update_entries_after(object): frappe.get_desk_link(self.exceptions[0]["voucher_type"], self.exceptions[0]["voucher_no"])) if self.verbose: - frappe.throw(msg, NegativeStockError, title='Insufficent Stock') + frappe.throw(msg, NegativeStockError, title='Insufficient Stock') else: raise NegativeStockError(msg) diff --git a/erpnext/support/web_form/issues/issues.json b/erpnext/support/web_form/issues/issues.json index 652114f7382..0f15e4737fd 100644 --- a/erpnext/support/web_form/issues/issues.json +++ b/erpnext/support/web_form/issues/issues.json @@ -18,7 +18,7 @@ "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2019-06-27 22:58:49.609672", + "modified": "2020-03-06 05:24:05.749664", "modified_by": "Administrator", "module": "Support", "name": "issues", @@ -58,7 +58,7 @@ "options": "Open\nReplied\nHold\nClosed", "read_only": 1, "reqd": 0, - "show_in_filter": 0 + "show_in_filter": 1 }, { "allow_read_on_all_link_options": 0,