From d9ab412032602f40cc6f78a1c355c0a85c3989f5 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 6 Mar 2020 19:04:41 +0530 Subject: [PATCH 001/104] feat: Allow PI creation without PO --- .../purchase_invoice/purchase_invoice.py | 16 +- erpnext/buying/doctype/supplier/supplier.json | 2002 ++++------------- 2 files changed, 396 insertions(+), 1622 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 737c18a8a98..19edd060a8e 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe, erpnext -from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate +from frappe.utils import cint, cstr, formatdate, flt, getdate, nowdate, get_link_to_form from frappe import _, throw import frappe.defaults @@ -255,16 +255,26 @@ class PurchaseInvoice(BuyingController): def po_required(self): if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes': + + if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_order'): + return + for d in self.get('items'): if not d.purchase_order: - throw(_("As per the Buying Settings if Purchase Order Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Order first for item {0}").format(d.item_code)) + throw(_("""Purchase Order Required for item {0} + To submit the invoice without purchase order please set + {1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold('Purchase Order Required'), + frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings'))) def pr_required(self): stock_items = self.get_stock_items() if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes': for d in self.get('items'): if not d.purchase_receipt and d.item_code in stock_items: - throw(_("As per the Buying Settings if Purchase Reciept Required == 'YES', then for creating Purchase Invoice, user need to create Purchase Receipt first for item {0}").format(d.item_code)) + throw(_("""Purchase Receipt Required for item {0} + To submit the invoice without purchase receipt please set + {1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold('Purchase Receipt Required'), + frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings'))) def validate_write_off_account(self): if self.write_off_amount and not self.write_off_account: diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index b5f0366c8e4..6ad238d2b38 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -1,1683 +1,447 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 1, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "naming_series:", - "beta": 0, - "creation": "2013-01-10 16:34:11", - "custom": 0, - "description": "Supplier of Goods or Services.", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, - "engine": "InnoDB", + "actions": [], + "allow_events_in_timeline": 1, + "allow_import": 1, + "allow_rename": 1, + "autoname": "naming_series:", + "creation": "2013-01-10 16:34:11", + "description": "Supplier of Goods or Services.", + "doctype": "DocType", + "document_type": "Setup", + "engine": "InnoDB", + "field_order": [ + "basic_info", + "naming_series", + "supplier_name", + "country", + "default_bank_account", + "tax_id", + "tax_category", + "tax_withholding_category", + "is_transporter", + "is_internal_supplier", + "represents_company", + "image", + "column_break0", + "supplier_group", + "supplier_type", + "pan", + "language", + "allow_purchase_invoice_creation_without_purchase_order", + "disabled", + "warn_rfqs", + "warn_pos", + "prevent_rfqs", + "prevent_pos", + "allowed_to_transact_section", + "companies", + "section_break_7", + "default_currency", + "column_break_10", + "default_price_list", + "section_credit_limit", + "payment_terms", + "cb_21", + "on_hold", + "hold_type", + "release_date", + "address_contacts", + "address_html", + "column_break1", + "contact_html", + "default_payable_accounts", + "accounts", + "default_tax_withholding_config", + "column_break2", + "website", + "supplier_details", + "column_break_30", + "is_frozen" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "basic_info", - "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": "Name and Type", - "length": 0, - "no_copy": 0, - "oldfieldtype": "Section Break", - "options": "fa fa-user", - "permlevel": 0, - "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": "basic_info", + "fieldtype": "Section Break", + "label": "Name and Type", + "oldfieldtype": "Section Break", + "options": "fa fa-user" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "naming_series", - "fieldtype": "Select", - "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": "Series", - "length": 0, - "no_copy": 1, - "oldfieldname": "naming_series", - "oldfieldtype": "Select", - "options": "SUP-.YYYY.-", - "permlevel": 0, - "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 - }, + "fieldname": "naming_series", + "fieldtype": "Select", + "label": "Series", + "no_copy": 1, + "oldfieldname": "naming_series", + "oldfieldtype": "Select", + "options": "SUP-.YYYY.-", + "set_only_once": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "fieldname": "supplier_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Supplier Name", - "length": 0, - "no_copy": 1, - "oldfieldname": "supplier_name", - "oldfieldtype": "Data", - "permlevel": 0, - "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 - }, + "bold": 1, + "fieldname": "supplier_name", + "fieldtype": "Data", + "in_global_search": 1, + "label": "Supplier Name", + "no_copy": 1, + "oldfieldname": "supplier_name", + "oldfieldtype": "Data", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "country", - "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": "Country", - "length": 0, - "no_copy": 0, - "options": "Country", - "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": "country", + "fieldtype": "Link", + "label": "Country", + "options": "Country" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "default_bank_account", - "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": "Default Bank Account", - "length": 0, - "no_copy": 0, - "options": "Bank Account", - "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": "default_bank_account", + "fieldtype": "Link", + "label": "Default Bank Account", + "options": "Bank Account" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "tax_id", - "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": "Tax ID", - "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": "tax_id", + "fieldtype": "Data", + "label": "Tax ID" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "tax_category", - "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": "Tax Category", - "length": 0, - "no_copy": 0, - "options": "Tax Category", - "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": "tax_category", + "fieldtype": "Link", + "label": "Tax Category", + "options": "Tax Category" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "tax_withholding_category", - "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": "Tax Withholding Category", - "length": 0, - "no_copy": 0, - "options": "Tax Withholding Category", - "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": "tax_withholding_category", + "fieldtype": "Link", + "label": "Tax Withholding Category", + "options": "Tax Withholding Category" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_transporter", - "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 Transporter", - "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_transporter", + "fieldtype": "Check", + "label": "Is Transporter" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fieldname": "is_internal_supplier", - "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 Internal Supplier", - "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_internal_supplier", + "fieldtype": "Check", + "label": "Is Internal Supplier" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "is_internal_supplier", - "fieldname": "represents_company", - "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": "Represents Company", - "length": 0, - "no_copy": 0, - "options": "Company", - "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, + "depends_on": "is_internal_supplier", + "fieldname": "represents_company", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Represents Company", + "options": "Company", "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "image", - "fieldtype": "Attach Image", - "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": "Image", - "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": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "image", + "fieldtype": "Attach Image", + "hidden": 1, + "label": "Image", + "no_copy": 1, + "print_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break0", - "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, - "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_break0", + "fieldtype": "Column Break", "width": "50%" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "supplier_group", - "fieldtype": "Link", - "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": "Supplier Group", - "length": 0, - "no_copy": 0, - "oldfieldname": "supplier_type", - "oldfieldtype": "Link", - "options": "Supplier Group", - "permlevel": 0, - "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": "supplier_group", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Supplier Group", + "oldfieldname": "supplier_type", + "oldfieldtype": "Link", + "options": "Supplier Group", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Company", - "fieldname": "supplier_type", - "fieldtype": "Select", - "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": "Supplier Type", - "length": 0, - "no_copy": 0, - "options": "Company\nIndividual", - "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": "Company", + "fieldname": "supplier_type", + "fieldtype": "Select", + "label": "Supplier Type", + "options": "Company\nIndividual", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "pan", - "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": "PAN", - "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": "pan", + "fieldtype": "Data", + "label": "PAN" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "language", - "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": "Print Language", - "length": 0, - "no_copy": 0, - "options": "Language", - "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": "language", + "fieldtype": "Link", + "label": "Print Language", + "options": "Language" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "default": "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": 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 - }, + "bold": 1, + "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": "warn_rfqs", - "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": "Warn RFQs", - "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 - }, + "default": "0", + "fieldname": "warn_rfqs", + "fieldtype": "Check", + "label": "Warn RFQs", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "warn_pos", - "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": "Warn POs", - "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 - }, + "default": "0", + "fieldname": "warn_pos", + "fieldtype": "Check", + "label": "Warn POs", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "prevent_rfqs", - "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": "Prevent RFQs", - "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 - }, + "default": "0", + "fieldname": "prevent_rfqs", + "fieldtype": "Check", + "label": "Prevent RFQs", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "prevent_pos", - "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": "Prevent POs", - "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 - }, + "default": "0", + "fieldname": "prevent_pos", + "fieldtype": "Check", + "label": "Prevent POs", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "represents_company", - "fieldname": "allowed_to_transact_section", - "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": "Allowed To Transact With", - "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": "represents_company", + "fieldname": "allowed_to_transact_section", + "fieldtype": "Section Break", + "label": "Allowed To Transact With" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "represents_company", - "fieldname": "companies", - "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": "Allowed To Transact With", - "length": 0, - "no_copy": 0, - "options": "Allowed To Transact With", - "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": "represents_company", + "fieldname": "companies", + "fieldtype": "Table", + "label": "Allowed To Transact With", + "options": "Allowed To Transact With" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "section_break_7", - "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": "Currency and Price List", - "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": "section_break_7", + "fieldtype": "Section Break", + "label": "Currency and Price List" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "default_currency", - "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": "Billing Currency", - "length": 0, - "no_copy": 1, - "options": "Currency", - "permlevel": 0, - "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": "default_currency", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Billing Currency", + "no_copy": 1, + "options": "Currency" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_10", - "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 - }, + "fieldname": "column_break_10", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "default_price_list", - "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": "Price List", - "length": 0, - "no_copy": 0, - "options": "Price List", - "permlevel": 0, - "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": "default_price_list", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Price List", + "options": "Price List" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "section_credit_limit", - "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": "Credit Limit", - "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": "section_credit_limit", + "fieldtype": "Section Break", + "label": "Credit Limit" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fieldname": "payment_terms", - "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": "Default Payment Terms Template", - "length": 0, - "no_copy": 0, - "options": "Payment Terms 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": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "payment_terms", + "fieldtype": "Link", + "label": "Default Payment Terms Template", + "options": "Payment Terms Template" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "cb_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 - }, + "fieldname": "cb_21", + "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": "on_hold", - "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": "Block Supplier", - "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": "on_hold", + "fieldtype": "Check", + "label": "Block Supplier" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.on_hold", - "fieldname": "hold_type", - "fieldtype": "Select", - "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": "Hold Type", - "length": 0, - "no_copy": 0, - "options": "\nAll\nInvoices\nPayments", - "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": "eval:doc.on_hold", + "fieldname": "hold_type", + "fieldtype": "Select", + "label": "Hold Type", + "options": "\nAll\nInvoices\nPayments" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.on_hold", - "description": "Leave blank if the Supplier is blocked indefinitely", - "fieldname": "release_date", - "fieldtype": "Date", - "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": "Release Date", - "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": "eval:doc.on_hold", + "description": "Leave blank if the Supplier is blocked indefinitely", + "fieldname": "release_date", + "fieldtype": "Date", + "label": "Release Date" + }, { - "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": "address_contacts", - "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": "Address and Contacts", - "length": 0, - "no_copy": 0, - "oldfieldtype": "Column Break", - "options": "fa fa-map-marker", - "permlevel": 0, - "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": "eval:!doc.__islocal", + "fieldname": "address_contacts", + "fieldtype": "Section Break", + "label": "Address and Contacts", + "oldfieldtype": "Column Break", + "options": "fa fa-map-marker" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "address_html", - "fieldtype": "HTML", - "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": "Address HTML", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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 - }, + "fieldname": "address_html", + "fieldtype": "HTML", + "label": "Address HTML", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break1", - "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, - "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_break1", + "fieldtype": "Column Break", "width": "50%" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "contact_html", - "fieldtype": "HTML", - "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": "Contact HTML", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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 - }, + "fieldname": "contact_html", + "fieldtype": "HTML", + "label": "Contact HTML", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "accounts", - "columns": 0, - "fieldname": "default_payable_accounts", - "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": "Default Payable Accounts", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "collapsible_depends_on": "accounts", + "fieldname": "default_payable_accounts", + "fieldtype": "Section Break", + "label": "Default Payable Accounts" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "description": "Mention if non-standard payable account", - "fieldname": "accounts", - "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": "Accounts", - "length": 0, - "no_copy": 0, - "options": "Party Account", - "permlevel": 0, - "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 - }, + "description": "Mention if non-standard payable account", + "fieldname": "accounts", + "fieldtype": "Table", + "label": "Accounts", + "options": "Party Account" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "default_tax_withholding_config", - "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": "Default Tax Withholding Config", - "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": "default_tax_withholding_config", + "fieldtype": "Section Break", + "label": "Default Tax Withholding Config" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "supplier_details", - "columns": 0, - "fieldname": "column_break2", - "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 Information", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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, + "collapsible_depends_on": "supplier_details", + "fieldname": "column_break2", + "fieldtype": "Section Break", + "label": "More Information", "width": "50%" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "website", - "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": "Website", - "length": 0, - "no_copy": 0, - "oldfieldname": "website", - "oldfieldtype": "Data", - "permlevel": 0, - "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": "website", + "fieldtype": "Data", + "label": "Website", + "oldfieldname": "website", + "oldfieldtype": "Data" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Statutory info and other general information about your Supplier", - "fieldname": "supplier_details", - "fieldtype": "Text", - "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": "Supplier Details", - "length": 0, - "no_copy": 0, - "oldfieldname": "supplier_details", - "oldfieldtype": "Code", - "permlevel": 0, - "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 - }, + "description": "Statutory info and other general information about your Supplier", + "fieldname": "supplier_details", + "fieldtype": "Text", + "label": "Supplier Details", + "oldfieldname": "supplier_details", + "oldfieldtype": "Code" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_30", - "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 - }, + "fieldname": "column_break_30", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_frozen", - "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 Frozen", - "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_frozen", + "fieldtype": "Check", + "label": "Is Frozen" + }, + { + "default": "0", + "fieldname": "allow_purchase_invoice_creation_without_purchase_order", + "fieldtype": "Check", + "label": "Allow Purchase Invoice creation without Purchase Order" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-user", - "idx": 370, - "image_field": "image", - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-01-17 13:58:08.597793", - "modified_by": "Administrator", - "module": "Buying", - "name": "Supplier", - "name_case": "Title Case", - "owner": "Administrator", + ], + "icon": "fa fa-user", + "idx": 370, + "image_field": "image", + "links": [], + "modified": "2020-03-06 19:04:06.097092", + "modified_by": "Administrator", + "module": "Buying", + "name": "Supplier", + "name_case": "Title Case", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase User" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase Manager", "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Purchase Master Manager", - "set_user_permissions": 1, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "import": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Purchase Master Manager", + "set_user_permissions": 1, + "share": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Stock User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "read": 1, + "role": "Stock User" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Stock Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Stock Manager" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Accounts User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "read": 1, + "role": "Accounts User" + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Accounts Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager" } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "search_fields": "supplier_name, supplier_group", - "show_name_in_global_search": 1, - "sort_order": "ASC", - "title_field": "supplier_name", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 -} + ], + "quick_entry": 1, + "search_fields": "supplier_name, supplier_group", + "show_name_in_global_search": 1, + "sort_field": "modified", + "sort_order": "ASC", + "title_field": "supplier_name", + "track_changes": 1 +} \ No newline at end of file From 0f807bf7ee2038d4868996ded1eb3025cd36274b Mon Sep 17 00:00:00 2001 From: Myuddin khatri Date: Thu, 12 Mar 2020 14:30:28 +0530 Subject: [PATCH 002/104] fix(shopping-cart): address is made mandatory to place order --- erpnext/shopping_cart/cart.py | 24 +++++++++---------- erpnext/templates/includes/cart.js | 5 ++-- .../templates/includes/cart/cart_address.html | 18 ++++++++++---- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py index 813d0dd196f..f85abdba04d 100644 --- a/erpnext/shopping_cart/cart.py +++ b/erpnext/shopping_cart/cart.py @@ -38,14 +38,14 @@ def get_cart_quotation(doc=None): addresses = get_address_docs(party=party) if not doc.customer_address and addresses: - update_cart_address("customer_address", addresses[0].name) + update_cart_address("billing", addresses[0].name) return { "doc": decorate_quotation_doc(doc), "shipping_addresses": [{"name": address.name, "display": address.display} - for address in addresses], + for address in addresses if address.address_type == "Shipping"], "billing_addresses": [{"name": address.name, "display": address.display} - for address in addresses], + for address in addresses if address.address_type == "Billing"], "shipping_rules": get_applicable_shipping_rules(party), "cart_settings": frappe.get_cached_doc("Shopping Cart Settings") } @@ -64,6 +64,9 @@ def place_order(): # company used to create customer accounts frappe.defaults.set_user_default("company", quotation.company) + if not (quotation.shipping_address_name or quotation.customer_address): + frappe.throw(_("Set Shipping Address or Billing Address")) + from erpnext.selling.doctype.quotation.quotation import _make_sales_order sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True)) sales_order.payment_schedule = [] @@ -194,21 +197,16 @@ def get_terms_and_conditions(terms_name): return frappe.db.get_value('Terms and Conditions', terms_name, 'terms') @frappe.whitelist() -def update_cart_address(address_fieldname, address_name): +def update_cart_address(address_type, address_name): quotation = _get_cart_quotation() address_display = get_address_display(frappe.get_doc("Address", address_name).as_dict()) - if address_fieldname == "shipping_address_name": - quotation.shipping_address_name = address_name - quotation.shipping_address = address_display - - if not quotation.customer_address: - address_fieldname == "customer_address" - - if address_fieldname == "customer_address": + if address_type.lower() == "billing": quotation.customer_address = address_name quotation.address_display = address_display - + elif address_type.lower() == "shipping": + quotation.shipping_address_name = address_name + quotation.shipping_address = address_display apply_cart_settings(quotation=quotation) diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js index 456bc7e4136..c6dfd35e29e 100644 --- a/erpnext/templates/includes/cart.js +++ b/erpnext/templates/includes/cart.js @@ -26,15 +26,14 @@ $.extend(shopping_cart, { bind_address_select: function() { $(".cart-addresses").on('click', '.address-card', function(e) { const $card = $(e.currentTarget); - const address_fieldname = $card.closest('[data-fieldname]').attr('data-fieldname'); + const address_type = $card.closest('[data-address-type]').attr('data-address-type'); const address_name = $card.closest('[data-address-name]').attr('data-address-name'); - return frappe.call({ type: "POST", method: "erpnext.shopping_cart.cart.update_cart_address", freeze: true, args: { - address_fieldname, + address_type, address_name }, callback: function(r) { diff --git a/erpnext/templates/includes/cart/cart_address.html b/erpnext/templates/includes/cart/cart_address.html index f7f35483208..60de3af17bf 100644 --- a/erpnext/templates/includes/cart/cart_address.html +++ b/erpnext/templates/includes/cart/cart_address.html @@ -18,7 +18,7 @@
{{ _("Shipping Address") }}
{% for address in shipping_addresses %} -
+
{% include "templates/includes/cart/address_card.html" %}
{% endfor %} @@ -28,7 +28,7 @@
{{ _("Billing Address") }}
{% for address in billing_addresses %} -
+
{% include "templates/includes/cart/address_card.html" %}
{% endfor %} @@ -123,9 +123,19 @@ frappe.ready(() => { primary_action: (values) => { frappe.call('erpnext.shopping_cart.cart.add_new_address', { doc: values }) .then(r => { - d.hide(); - window.location.reload(); + frappe.call({ + method: "erpnext.shopping_cart.cart.update_cart_address", + args: { + address_type: r.message.address_type, + address_name: r.message.name + }, + callback: function (r) { + d.hide(); + window.location.reload(); + } + }); }); + } }) From 9c63b1d2c9e3d44e3df5c3b8e03f6fe745735320 Mon Sep 17 00:00:00 2001 From: Myuddin khatri Date: Thu, 12 Mar 2020 16:04:22 +0530 Subject: [PATCH 003/104] fix(shopping-cart): setting billing and shipping address setting billing and shipping address --- erpnext/shopping_cart/cart.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py index f85abdba04d..4c3ac100d5b 100644 --- a/erpnext/shopping_cart/cart.py +++ b/erpnext/shopping_cart/cart.py @@ -65,7 +65,7 @@ def place_order(): frappe.defaults.set_user_default("company", quotation.company) if not (quotation.shipping_address_name or quotation.customer_address): - frappe.throw(_("Set Shipping Address or Billing Address")) + frappe.throw(_("Set Shipping Address or Billing Address")) from erpnext.selling.doctype.quotation.quotation import _make_sales_order sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True)) @@ -204,9 +204,11 @@ def update_cart_address(address_type, address_name): if address_type.lower() == "billing": quotation.customer_address = address_name quotation.address_display = address_display + quotation.shipping_address_name == quotation.shipping_address_name or address_name elif address_type.lower() == "shipping": quotation.shipping_address_name = address_name quotation.shipping_address = address_display + quotation.customer_address == quotation.customer_address or address_name apply_cart_settings(quotation=quotation) From 22a069d4b0b642fcd06ed4858731c30905930df9 Mon Sep 17 00:00:00 2001 From: Anurag Mishra Date: Mon, 16 Mar 2020 18:24:28 +0530 Subject: [PATCH 004/104] fix: Wrong status --- erpnext/hr/doctype/expense_claim/expense_claim.json | 4 +++- erpnext/hr/doctype/expense_claim/expense_claim.py | 2 +- erpnext/patches.txt | 1 + .../patches/v12_0/set_correct_status_for_expense_claim.py | 7 +++++++ 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 erpnext/patches/v12_0/set_correct_status_for_expense_claim.py diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json index 5c2f4901713..770b47709dd 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.json +++ b/erpnext/hr/doctype/expense_claim/expense_claim.json @@ -278,6 +278,7 @@ "label": "More Details" }, { + "allow_on_submit": 1, "default": "Draft", "fieldname": "status", "fieldtype": "Select", @@ -366,7 +367,8 @@ "icon": "fa fa-money", "idx": 1, "is_submittable": 1, - "modified": "2019-11-08 14:13:08.964547", + "links": [], + "modified": "2020-03-16 18:11:07.861985", "modified_by": "Administrator", "module": "HR", "name": "Expense Claim", diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index d29b3f75879..e9f15cdfb9a 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -45,7 +45,7 @@ class ExpenseClaim(AccountsController): paid_amount = flt(self.total_amount_reimbursed) + flt(self.total_advance_amount) precision = self.precision("grand_total") if (self.is_paid or (flt(self.total_sanctioned_amount) > 0 - and flt(self.grand_total, precision) == flt(paid_amount, precision))) \ + and flt(self.total_sanctioned_amount, precision) == flt(paid_amount, precision))) \ and self.docstatus == 1 and self.approval_status == 'Approved': self.status = "Paid" elif flt(self.total_sanctioned_amount) > 0 and self.docstatus == 1 and self.approval_status == 'Approved': diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 4e72d5ecd6b..ed14ecd4897 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -650,3 +650,4 @@ erpnext.patches.v12_0.update_price_or_product_discount erpnext.patches.v12_0.add_export_type_field_in_party_master erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22 erpnext.patches.v12_0.create_irs_1099_field_united_states +erpnext.patches.v12_0.set_correct_status_for_expense_claim diff --git a/erpnext/patches/v12_0/set_correct_status_for_expense_claim.py b/erpnext/patches/v12_0/set_correct_status_for_expense_claim.py new file mode 100644 index 00000000000..3d3980743e6 --- /dev/null +++ b/erpnext/patches/v12_0/set_correct_status_for_expense_claim.py @@ -0,0 +1,7 @@ +# Copyright (c) 2020, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +import frappe + +def execute(): + frappe.db.sql("update `tabExpense Claim` set status = 'Paid' where (total_advance_amount + total_amount_reimbursed ) = total_sanctioned_amount") \ No newline at end of file From 6c148ef314b6b89983f3f16efd6af912c64abfc6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 17 Mar 2020 11:43:34 +0530 Subject: [PATCH 005/104] fix: Add check to skip SO and DN in customer master --- .../doctype/sales_invoice/sales_invoice.py | 18 +++++++++++------- erpnext/selling/doctype/customer/customer.json | 16 +++++++++++++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index d0fe4f4832a..9c87f1e82d4 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -412,7 +412,7 @@ class SalesInvoice(SellingController): if pos: self.allow_print_before_pay = pos.allow_print_before_pay - + if not for_validate: self.tax_category = pos.get("tax_category") @@ -534,14 +534,18 @@ class SalesInvoice(SellingController): """check in manage account if sales order / delivery note required or not.""" if self.is_return: return - dic = {'Sales Order':['so_required', 'is_pos'],'Delivery Note':['dn_required', 'update_stock']} - for i in dic: - if frappe.db.get_single_value('Selling Settings', dic[i][0]) == 'Yes': + + prev_doc_field_map = {'Sales Order': ['so_required', 'is_pos'],'Delivery Note': ['dn_required', 'update_stock']} + for key, value in iteritems(prev_doc_field_map): + if frappe.db.get_single_value('Selling Settings', value[0]) == 'Yes': + + if frappe.get_value('Customer', self.customer, value[0]): + continue + for d in self.get('items'): is_stock_item = frappe.get_cached_value('Item', d.item_code, 'is_stock_item') - if (d.item_code and is_stock_item == 1\ - and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1])): - msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1) + if (d.item_code and is_stock_item ==1 and not d.get(key.lower().replace(' ', '_')) and not self.get(value[1])): + msgprint(_("{0} is mandatory for Item {1}").format(key, d.item_code), raise_exception=1) def validate_proj_cust(self): diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index 89ce325a847..a93ab50639d 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -25,6 +25,8 @@ "territory", "tax_id", "tax_category", + "so_required", + "dn_required", "disabled", "is_internal_customer", "represents_company", @@ -466,13 +468,25 @@ "fieldtype": "Table", "label": "Credit Limit", "options": "Customer Credit Limit" + }, + { + "default": "0", + "fieldname": "so_required", + "fieldtype": "Check", + "label": "Allow Sales Invoice Creation Without Sales Order" + }, + { + "default": "0", + "fieldname": "dn_required", + "fieldtype": "Check", + "label": "Allow Sales Invoice Creation Without Delivery Note" } ], "icon": "fa fa-user", "idx": 363, "image_field": "image", "links": [], - "modified": "2020-01-29 20:36:37.879581", + "modified": "2020-03-17 11:03:42.706907", "modified_by": "Administrator", "module": "Selling", "name": "Customer", From 3528149329f610f8c26e64d84ee3449e5efc724f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 17 Mar 2020 11:44:02 +0530 Subject: [PATCH 006/104] fix: Add check to skip PR in supplier master --- .../doctype/purchase_invoice/purchase_invoice.py | 8 ++++++-- erpnext/buying/doctype/supplier/supplier.json | 11 +++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 19edd060a8e..d8e0f21155a 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -263,17 +263,21 @@ class PurchaseInvoice(BuyingController): if not d.purchase_order: throw(_("""Purchase Order Required for item {0} To submit the invoice without purchase order please set - {1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold('Purchase Order Required'), + {1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Order Required')), frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings'))) def pr_required(self): stock_items = self.get_stock_items() if frappe.db.get_value("Buying Settings", None, "pr_required") == 'Yes': + + if frappe.get_value('Supplier', self.supplier, 'allow_purchase_invoice_creation_without_purchase_receipt'): + return + for d in self.get('items'): if not d.purchase_receipt and d.item_code in stock_items: throw(_("""Purchase Receipt Required for item {0} To submit the invoice without purchase receipt please set - {1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold('Purchase Receipt Required'), + {1} as {2} in {3}""").format(frappe.bold(d.item_code), frappe.bold(_('Purchase Receipt Required')), frappe.bold('No'), get_link_to_form('Buying Settings', 'Buying Settings', 'Buying Settings'))) def validate_write_off_account(self): diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index 6ad238d2b38..e78abd62615 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -28,6 +28,7 @@ "pan", "language", "allow_purchase_invoice_creation_without_purchase_order", + "allow_purchase_invoice_creation_without_purchase_receipt", "disabled", "warn_rfqs", "warn_pos", @@ -371,14 +372,20 @@ "default": "0", "fieldname": "allow_purchase_invoice_creation_without_purchase_order", "fieldtype": "Check", - "label": "Allow Purchase Invoice creation without Purchase Order" + "label": "Allow Purchase Invoice Creation Without Purchase Order" + }, + { + "default": "0", + "fieldname": "allow_purchase_invoice_creation_without_purchase_receipt", + "fieldtype": "Check", + "label": "Allow Purchase Invoice Creation Without Purchase Receipt" } ], "icon": "fa fa-user", "idx": 370, "image_field": "image", "links": [], - "modified": "2020-03-06 19:04:06.097092", + "modified": "2020-03-17 09:48:30.578242", "modified_by": "Administrator", "module": "Buying", "name": "Supplier", From da7c6b0d99b6d8bf52cb14978e5bb8b862d631fa Mon Sep 17 00:00:00 2001 From: Marica Date: Wed, 18 Mar 2020 11:29:02 +0530 Subject: [PATCH 007/104] fix: Missing if condition in Customer Default Bank Account Validation. (#20970) --- erpnext/selling/doctype/customer/customer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 3248c998b60..791a3e1536a 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -76,7 +76,8 @@ class Customer(TransactionBase): def validate_default_bank_account(self): if self.default_bank_account: is_company_account = frappe.db.get_value('Bank Account', self.default_bank_account, 'is_company_account') - frappe.throw(_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account))) + if not is_company_account: + frappe.throw(_("{0} is not a company bank account").format(frappe.bold(self.default_bank_account))) def on_update(self): self.validate_name_with_customer_group() From 1ed5993ff6f188201aa7c05440d56c479ad2e618 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 18 Mar 2020 13:33:55 +0530 Subject: [PATCH 008/104] fix: shortage qty in stock projected qty report --- .../stock/report/stock_projected_qty/stock_projected_qty.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py index 913d7d848ed..c8efb1637f9 100644 --- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py +++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py @@ -44,7 +44,9 @@ def execute(filters=None): re_order_level = d.warehouse_reorder_level re_order_qty = d.warehouse_reorder_qty - shortage_qty = re_order_level - flt(bin.projected_qty) if (re_order_level or re_order_qty) else 0 + shortage_qty = 0 + if (re_order_level or re_order_qty) and re_order_level > bin.projected_qty: + shortage_qty = re_order_level - flt(bin.projected_qty) data.append([item.name, item.item_name, item.description, item.item_group, item.brand, bin.warehouse, item.stock_uom, bin.actual_qty, bin.planned_qty, bin.indented_qty, bin.ordered_qty, From 210a718a0420ad88f28b2cc2679a8ce92ff2bd95 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 19 Mar 2020 10:03:06 +0530 Subject: [PATCH 009/104] fix: bom comparison issue --- erpnext/manufacturing/doctype/bom/bom.py | 4 ++++ .../bom_comparison_tool/bom_comparison_tool.js | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index b2a0b18db5e..19d36f6e8c4 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -823,6 +823,10 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None): def get_bom_diff(bom1, bom2): from frappe.model import table_fields + if bom1 == bom2: + frappe.throw(_("BOM 1 {0} and BOM 2 {1} should not be same") + .format(frappe.bold(bom1), frappe.bold(bom2))) + doc1 = frappe.get_doc('BOM', bom1) doc2 = frappe.get_doc('BOM', bom2) diff --git a/erpnext/manufacturing/page/bom_comparison_tool/bom_comparison_tool.js b/erpnext/manufacturing/page/bom_comparison_tool/bom_comparison_tool.js index 7152d3dff61..1bcb1efdaad 100644 --- a/erpnext/manufacturing/page/bom_comparison_tool/bom_comparison_tool.js +++ b/erpnext/manufacturing/page/bom_comparison_tool/bom_comparison_tool.js @@ -22,7 +22,14 @@ erpnext.BOMComparisonTool = class BOMComparisonTool { fieldname: 'name1', fieldtype: 'Link', options: 'BOM', - change: () => this.fetch_and_render() + change: () => this.fetch_and_render(), + get_query: () => { + return { + filters: { + "name": ["not in", [this.form.get_value("name2") || ""]] + } + } + } }, { fieldtype: 'Column Break' @@ -32,7 +39,14 @@ erpnext.BOMComparisonTool = class BOMComparisonTool { fieldname: 'name2', fieldtype: 'Link', options: 'BOM', - change: () => this.fetch_and_render() + change: () => this.fetch_and_render(), + get_query: () => { + return { + filters: { + "name": ["not in", [this.form.get_value("name1") || ""]] + } + } + } }, { fieldtype: 'Section Break' From 7b45ae1f2dbc76db0fc5d72c8791161879ce5640 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 19 Mar 2020 10:58:41 +0530 Subject: [PATCH 010/104] fix: Multiple fixes during pre-release testing (#20985) --- .../doctype/journal_entry/journal_entry.py | 8 +- .../doctype/vehicle_log/test_vehicle_log.py | 7 +- erpnext/hr/doctype/vehicle_log/vehicle_log.js | 26 --- .../hr/doctype/vehicle_log/vehicle_log.json | 9 +- erpnext/hr/doctype/vehicle_log/vehicle_log.py | 54 ++--- .../vehicle_service/vehicle_service.json | 194 +++++------------- .../bom_stock_calculated.py | 4 +- 7 files changed, 84 insertions(+), 218 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 04c5c9ec679..1a530c75395 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -456,8 +456,10 @@ class JournalEntry(AccountsController): def set_print_format_fields(self): bank_amount = party_amount = total_amount = 0.0 currency = bank_account_currency = party_account_currency = pay_to_recd_from= None + party_type = None for d in self.get('accounts'): if d.party_type in ['Customer', 'Supplier'] and d.party: + party_type = d.party_type if not pay_to_recd_from: pay_to_recd_from = d.party @@ -469,9 +471,9 @@ class JournalEntry(AccountsController): bank_amount += (d.debit_in_account_currency or d.credit_in_account_currency) bank_account_currency = d.account_currency - if pay_to_recd_from: - self.pay_to_recd_from = frappe.db.get_value(d.party_type, pay_to_recd_from, - "customer_name" if d.party_type=="Customer" else "supplier_name") + if party_type and pay_to_recd_from: + self.pay_to_recd_from = frappe.db.get_value(party_type, pay_to_recd_from, + "customer_name" if party_type=="Customer" else "supplier_name") if bank_amount: total_amount = bank_amount currency = bank_account_currency diff --git a/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py b/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py index 3770da73fcf..e9dc7764f7b 100644 --- a/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py +++ b/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py @@ -6,11 +6,14 @@ from __future__ import unicode_literals import frappe import unittest from frappe.utils import nowdate,flt, cstr,random_string -# test_records = frappe.get_test_records('Vehicle Log') + class TestVehicleLog(unittest.TestCase): def test_make_vehicle_log_and_syncing_of_odometer_value(self): - employee_id=frappe.db.sql("""select name from `tabEmployee` order by modified desc limit 1""")[0][0] + employee_id = frappe.db.sql("""select name from `tabEmployee` where status='Active' order by modified desc limit 1""") + employee_id = employee_id[0][0] if employee_id else None + license_plate = get_vehicle(employee_id) + vehicle_log = frappe.get_doc({ "doctype": "Vehicle Log", "license_plate": cstr(license_plate), diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.js b/erpnext/hr/doctype/vehicle_log/vehicle_log.js index bdb37d2b734..6f3a0dc40eb 100644 --- a/erpnext/hr/doctype/vehicle_log/vehicle_log.js +++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.js @@ -3,11 +3,6 @@ frappe.ui.form.on("Vehicle Log", { refresh: function(frm) { - - if(frm.doc.license_plate && frm.doc.__islocal){ - frm.events.set_vehicle_details(frm); - } - if(frm.doc.docstatus == 1) { frm.add_custom_button(__('Expense Claim'), function() { frm.events.expense_claim(frm); @@ -16,27 +11,6 @@ frappe.ui.form.on("Vehicle Log", { } }, - license_plate: function(frm) { - if(frm.doc.license_plate){ - frm.events.set_vehicle_details(frm); - } - }, - - set_vehicle_details: function(frm) { - frappe.call({ - method: "erpnext.hr.doctype.vehicle_log.vehicle_log.get_make_model", - args: { - license_plate: frm.doc.license_plate - }, - callback: function(r) { - frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "make", r.message[0]); - frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "model", r.message[1]); - frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "last_odometer", r.message[2]); - frappe.model.set_value(cur_frm.doctype, cur_frm.docname, "employee", r.message[3]); - } - }); - }, - expense_claim: function(frm){ frappe.call({ method: "erpnext.hr.doctype.vehicle_log.vehicle_log.make_expense_claim", diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.json b/erpnext/hr/doctype/vehicle_log/vehicle_log.json index 52effffc064..619e295ebe8 100644 --- a/erpnext/hr/doctype/vehicle_log/vehicle_log.json +++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.json @@ -1,5 +1,4 @@ { - "actions": [], "autoname": "naming_series:", "creation": "2016-09-03 14:14:51.788550", "doctype": "DocType", @@ -56,6 +55,8 @@ "reqd": 1 }, { + "fetch_from": "license_plate.employee", + "fetch_if_empty": 1, "fieldname": "employee", "fieldtype": "Link", "in_list_view": 1, @@ -73,11 +74,13 @@ "fieldtype": "Column Break" }, { + "fetch_from": "license_plate.model", "fieldname": "model", "fieldtype": "Read Only", "label": "Model" }, { + "fetch_from": "license_plate.make", "fieldname": "make", "fieldtype": "Read Only", "label": "Make" @@ -152,6 +155,7 @@ "read_only": 1 }, { + "fetch_from": "license_plate.last_odometer", "fieldname": "last_odometer", "fieldtype": "Int", "label": "last Odometer Value ", @@ -164,8 +168,7 @@ } ], "is_submittable": 1, - "links": [], - "modified": "2020-01-28 12:43:34.419647", + "modified": "2020-03-18 16:45:45.060761", "modified_by": "Administrator", "module": "HR", "name": "Vehicle Log", diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.py b/erpnext/hr/doctype/vehicle_log/vehicle_log.py index 12cc1dd03a6..8affab2a18d 100644 --- a/erpnext/hr/doctype/vehicle_log/vehicle_log.py +++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.py @@ -12,18 +12,7 @@ from frappe.model.document import Document class VehicleLog(Document): def validate(self): if flt(self.odometer) < flt(self.last_odometer): - frappe.throw(_("Current Odometer reading entered should be greater than initial Vehicle Odometer {0}").format(self.last_odometer)) - for service_detail in self.service_detail: - if (service_detail.service_item or service_detail.type or service_detail.frequency or service_detail.expense_amount): - if not (service_detail.service_item and service_detail.type and service_detail.frequency and service_detail.expense_amount): - frappe.throw(_("Service Item,Type,frequency and expense amount are required")) - - def before_insert(self): - model_details = get_make_model(self.license_plate) - self.make = model_details[0] - self.model = model_details[1] - self.last_odometer = model_details[2] - self.employee = model_details[3] + frappe.throw(_("Current Odometer Value should be greater than Last Odometer Value {0}").format(self.last_odometer)) def on_submit(self): frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", self.odometer) @@ -34,35 +23,26 @@ class VehicleLog(Document): updated_odometer_value = int(frappe.db.get_value("Vehicle", self.license_plate, "last_odometer")) - distance_travelled frappe.db.set_value("Vehicle", self.license_plate, "last_odometer", updated_odometer_value) -@frappe.whitelist() -def get_make_model(license_plate): - vehicle=frappe.get_doc("Vehicle",license_plate) - return (vehicle.make, vehicle.model, vehicle.last_odometer, vehicle.employee) - @frappe.whitelist() def make_expense_claim(docname): - def check_exp_claim_exists(): - exp_claim = frappe.db.sql("""select name from `tabExpense Claim` where vehicle_log=%s""",vehicle_log.name) - return exp_claim[0][0] if exp_claim else "" - def calc_service_exp(): - total_exp_amt=0 - exp_claim = check_exp_claim_exists() - if exp_claim: - frappe.throw(_("Expense Claim {0} already exists for the Vehicle Log").format(exp_claim)) - for serdetail in vehicle_log.service_detail: - total_exp_amt = total_exp_amt + serdetail.expense_amount - return total_exp_amt + expense_claim = frappe.db.exists("Expense Claim", {"vehicle_log": docname}) + if expense_claim: + frappe.throw(_("Expense Claim {0} already exists for the Vehicle Log").format(expense_claim)) vehicle_log = frappe.get_doc("Vehicle Log", docname) + service_expense = sum([flt(d.expense_amount) for d in vehicle_log.service_detail]) + + claim_amount = service_expense + flt(vehicle_log.price) + if not claim_amount: + frappe.throw(_("No additional expenses has been added")) + exp_claim = frappe.new_doc("Expense Claim") - exp_claim.employee=vehicle_log.employee - exp_claim.vehicle_log=vehicle_log.name - exp_claim.remark=_("Expense Claim for Vehicle Log {0}").format(vehicle_log.name) - fuel_price=vehicle_log.price - total_claim_amt=calc_service_exp() + fuel_price - exp_claim.append("expenses",{ - "expense_date":vehicle_log.date, - "description":_("Vehicle Expenses"), - "amount":total_claim_amt + exp_claim.employee = vehicle_log.employee + exp_claim.vehicle_log = vehicle_log.name + exp_claim.remark = _("Expense Claim for Vehicle Log {0}").format(vehicle_log.name) + exp_claim.append("expenses", { + "expense_date": vehicle_log.date, + "description": _("Vehicle Expenses"), + "amount": claim_amount }) return exp_claim.as_dict() diff --git a/erpnext/hr/doctype/vehicle_service/vehicle_service.json b/erpnext/hr/doctype/vehicle_service/vehicle_service.json index 7d9d0df44cc..e0bce2b6eec 100644 --- a/erpnext/hr/doctype/vehicle_service/vehicle_service.json +++ b/erpnext/hr/doctype/vehicle_service/vehicle_service.json @@ -1,153 +1,57 @@ { - "allow_copy": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2016-09-03 19:20:14.561962", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 1, + "creation": "2016-09-03 19:20:14.561962", + "doctype": "DocType", + "document_type": "Document", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "service_item", + "type", + "frequency", + "expense_amount" + ], "fields": [ { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "service_item", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Service Item", - "length": 0, - "no_copy": 0, - "options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels", - "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, - "unique": 0 - }, + "fieldname": "service_item", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Service Item", + "options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels", + "reqd": 1 + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Type", - "length": 0, - "no_copy": 0, - "options": "\nInspection\nService\nChange", - "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, - "unique": 0 - }, + "fieldname": "type", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Type", + "options": "\nInspection\nService\nChange", + "reqd": 1 + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "frequency", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Frequency", - "length": 0, - "no_copy": 0, - "options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly", - "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, - "unique": 0 - }, + "fieldname": "frequency", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Frequency", + "options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly", + "reqd": 1 + }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "expense_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Expense", - "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, - "unique": 0 + "fieldname": "expense_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Expense", + "reqd": 1 } - ], - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - - "is_submittable": 0, - "issingle": 0, - "istable": 1, - "max_attachments": 0, - "modified": "2017-01-09 11:10:29.476907", - "modified_by": "Administrator", - "module": "HR", - "name": "Vehicle Service", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0 + ], + "istable": 1, + "modified": "2020-03-18 16:49:46.645004", + "modified_by": "Administrator", + "module": "HR", + "name": "Vehicle Service", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py index f7b407b7922..c1204d36152 100644 --- a/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py +++ b/erpnext/manufacturing/report/bom_stock_calculated/bom_stock_calculated.py @@ -26,8 +26,8 @@ def get_report_data(last_pur_price, reqd_qty, row, manufacture_details): to_build = row.to_build if row.to_build > 0 else 0 diff_qty = to_build - reqd_qty return [row.item_code, row.description, - comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer', []), add_quotes=False), - comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer_part', []), add_quotes=False), + comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer', [])), + comma_and(manufacture_details.get(row.item_code, {}).get('manufacturer_part', [])), row.actual_qty, str(to_build), reqd_qty, diff_qty, last_pur_price] From 71e9f23d7755c0a4243be13a5932c1d7c2e26fde Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 19 Mar 2020 11:00:55 +0530 Subject: [PATCH 011/104] fix: Update is_tree field in Tree doctypes (#20982) --- erpnext/accounts/doctype/account/account.json | 6 +- .../doctype/cost_center/cost_center.json | 4 +- erpnext/assets/doctype/location/location.json | 4 +- .../assessment_group/assessment_group.json | 335 +++---------- .../healthcare_service_unit.json | 406 ++------------- erpnext/hr/doctype/department/department.json | 472 ++---------------- erpnext/projects/doctype/task/task.json | 6 +- .../quality_procedure/quality_procedure.json | 6 +- erpnext/setup/doctype/company/company.json | 6 +- .../customer_group/customer_group.json | 4 +- .../setup/doctype/item_group/item_group.json | 4 +- .../doctype/sales_person/sales_person.json | 4 +- .../supplier_group/supplier_group.json | 384 ++------------ .../setup/doctype/territory/territory.json | 4 +- .../stock/doctype/warehouse/warehouse.json | 4 +- 15 files changed, 226 insertions(+), 1423 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.json b/erpnext/accounts/doctype/account/account.json index 64efc2775a6..6a1183546f3 100644 --- a/erpnext/accounts/doctype/account/account.json +++ b/erpnext/accounts/doctype/account/account.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_copy": 1, "allow_import": 1, "creation": "2013-01-30 12:49:46", @@ -196,10 +197,13 @@ ], "icon": "fa fa-money", "idx": 1, - "modified": "2019-10-10 19:10:02.967554", + "is_tree": 1, + "links": [], + "modified": "2020-03-18 18:26:03.992861", "modified_by": "Administrator", "module": "Accounts", "name": "Account", + "nsm_parent_field": "parent_account", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/accounts/doctype/cost_center/cost_center.json b/erpnext/accounts/doctype/cost_center/cost_center.json index 976f05ad637..126aa543185 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.json +++ b/erpnext/accounts/doctype/cost_center/cost_center.json @@ -124,11 +124,13 @@ ], "icon": "fa fa-money", "idx": 1, + "is_tree": 1, "links": [], - "modified": "2020-01-28 13:50:23.430434", + "modified": "2020-03-18 18:26:01.540170", "modified_by": "Administrator", "module": "Accounts", "name": "Cost Center", + "nsm_parent_field": "parent_cost_center", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/assets/doctype/location/location.json b/erpnext/assets/doctype/location/location.json index 5ecc72ab913..58f59701960 100644 --- a/erpnext/assets/doctype/location/location.json +++ b/erpnext/assets/doctype/location/location.json @@ -139,12 +139,14 @@ "read_only": 1 } ], + "is_tree": 1, "links": [], - "modified": "2020-01-28 13:52:22.513425", + "modified": "2020-03-18 18:25:59.283057", "modified_by": "Administrator", "module": "Assets", "name": "Location", "name_case": "Title Case", + "nsm_parent_field": "parent_location", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/education/doctype/assessment_group/assessment_group.json b/erpnext/education/doctype/assessment_group/assessment_group.json index 56917d20526..a341938a101 100644 --- a/erpnext/education/doctype/assessment_group/assessment_group.json +++ b/erpnext/education/doctype/assessment_group/assessment_group.json @@ -1,274 +1,91 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:assessment_group_name", - "beta": 0, - "creation": "2016-08-04 04:42:48.319388", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:assessment_group_name", + "creation": "2016-08-04 04:42:48.319388", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "assessment_group_name", + "is_group", + "section_break_2", + "parent_assessment_group", + "lft", + "rgt", + "old_parent" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_group_name", - "fieldtype": "Data", - "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": "Assessment Group 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, - "unique": 0 - }, + "fieldname": "assessment_group_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Assessment Group Name", + "reqd": 1, + "unique": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_group", - "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 Group", - "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, - "unique": 0 - }, + "default": "0", + "fieldname": "is_group", + "fieldtype": "Check", + "label": "Is Group" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_2", - "fieldtype": "Section Break", - "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, - "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, - "unique": 0 - }, + "fieldname": "section_break_2", + "fieldtype": "Section Break", + "hidden": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "parent_assessment_group", - "fieldtype": "Link", - "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": "Parent Assessment Group", - "length": 0, - "no_copy": 0, - "options": "Assessment 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, - "unique": 0 - }, + "fieldname": "parent_assessment_group", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Parent Assessment Group", + "options": "Assessment Group", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "lft", - "fieldtype": "Int", - "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": "lft", - "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, - "unique": 0 - }, + "fieldname": "lft", + "fieldtype": "Int", + "label": "lft" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "rgt", - "fieldtype": "Int", - "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": "rgt", - "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, - "unique": 0 - }, + "fieldname": "rgt", + "fieldtype": "Int", + "label": "rgt" + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "old_parent", - "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": "old_parent", - "length": 0, - "no_copy": 0, - "options": "Assessment 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": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 + "fieldname": "old_parent", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "old_parent", + "options": "Assessment Group" } - ], - "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": "2017-11-10 19:09:25.366400", - "modified_by": "Administrator", - "module": "Education", - "name": "Assessment Group", - "name_case": "", - "owner": "Administrator", + ], + "is_tree": 1, + "links": [], + "modified": "2020-03-18 18:26:07.834596", + "modified_by": "Administrator", + "module": "Education", + "name": "Assessment Group", + "nsm_parent_field": "parent_assessment_group", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "apply_user_permissions": 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": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Academics User", + "share": 1, "write": 1 } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Education", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0 + ], + "quick_entry": 1, + "restrict_to_domain": "Education", + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json index 6e92455404f..15d976530b2 100644 --- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json +++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit.json @@ -1,542 +1,206 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "field:healthcare_service_unit_name", "beta": 1, "creation": "2016-09-21 13:48:14.731437", - "custom": 0, "description": "Healthcare Service Unit", - "docstatus": 0, "doctype": "DocType", "document_type": "Setup", "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "healthcare_service_unit_name", + "parent_healthcare_service_unit", + "is_group", + "service_unit_type", + "allow_appointments", + "overlap_appointments", + "inpatient_occupancy", + "occupancy_status", + "warehouse", + "company", + "lft", + "rgt", + "old_parent" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "healthcare_service_unit_name", "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": "Service Unit", - "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": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, "bold": 1, - "collapsible": 0, - "columns": 0, "fieldname": "parent_healthcare_service_unit", "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": 0, "label": "Parent 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": 0, - "translatable": 0, - "unique": 0 + "options": "Healthcare Service Unit" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, "bold": 1, - "collapsible": 0, - "columns": 0, "default": "0", "depends_on": "eval:doc.inpatient_occupancy != 1 && doc.allow_appointments != 1", "fieldname": "is_group", "fieldtype": "Check", - "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": "Is Group", - "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": "Is Group" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, "bold": 1, - "collapsible": 0, - "columns": 0, "depends_on": "eval:doc.is_group != 1", "fieldname": "service_unit_type", "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 Type", - "length": 0, - "no_copy": 0, - "options": "Healthcare Service Unit 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": 0, - "translatable": 0, - "unique": 0 + "options": "Healthcare Service Unit Type" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, "bold": 1, - "collapsible": 0, - "columns": 0, "default": "0", "depends_on": "eval:doc.is_group != 1 && doc.inpatient_occupancy != 1", "fetch_from": "service_unit_type.allow_appointments", "fieldname": "allow_appointments", "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 Appointments", - "length": 0, "no_copy": 1, - "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": "0", "depends_on": "eval:doc.is_group != 1 && doc.allow_appointments == 1 && doc.inpatient_occupany != 1", "fetch_from": "service_unit_type.overlap_appointments", "fieldname": "overlap_appointments", "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 Overlap", - "length": 0, "no_copy": 1, - "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": 1, - "collapsible": 0, - "columns": 0, "default": "0", "depends_on": "eval:doc.allow_appointments != 1 && doc.is_group != 1", "fetch_from": "service_unit_type.inpatient_occupancy", "fieldname": "inpatient_occupancy", "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": "Inpatient Occupancy", - "length": 0, "no_copy": 1, - "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, - "default": "", "depends_on": "eval:doc.inpatient_occupancy == 1", "fieldname": "occupancy_status", "fieldtype": "Select", - "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": "Occupancy Status", - "length": 0, "no_copy": 1, "options": "Vacant\nOccupied", - "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": 1, - "collapsible": 0, - "columns": 0, "depends_on": "eval:doc.is_group != 1", "fieldname": "warehouse", "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": "Warehouse", - "length": 0, "no_copy": 1, - "options": "Warehouse", - "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": "Warehouse" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "company", "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": "Company", - "length": 0, - "no_copy": 0, "options": "Company", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, "remember_last_selected_value": 1, - "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": "lft", "fieldtype": "Int", "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": "lft", - "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": 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": "rgt", "fieldtype": "Int", "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": "rgt", - "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": 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": "old_parent", "fieldtype": "Link", "hidden": 1, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Old Parent", - "length": 0, "no_copy": 1, "options": "Healthcare Service Unit", - "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-10-04 21:09:52.261882", + "is_tree": 1, + "links": [], + "modified": "2020-03-18 18:26:06.360941", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare Service Unit", - "name_case": "", + "nsm_parent_field": "parent_healthcare_service_unit", "owner": "Administrator", "permissions": [ { - "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 + "share": 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, "write": 1 }, { - "amend": 0, - "cancel": 0, "create": 1, - "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, "write": 1 } ], "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, "restrict_to_domain": "Healthcare", "search_fields": "healthcare_service_unit_name", - "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", "title_field": "healthcare_service_unit_name", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/hr/doctype/department/department.json b/erpnext/hr/doctype/department/department.json index 3b400ce8d76..2de391efaaa 100644 --- a/erpnext/hr/doctype/department/department.json +++ b/erpnext/hr/doctype/department/department.json @@ -1,569 +1,177 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, + "actions": [], "allow_import": 1, "allow_rename": 1, - "autoname": "", - "beta": 0, "creation": "2013-02-05 11:48:26", - "custom": 0, - "docstatus": 0, "doctype": "DocType", "document_type": "Setup", - "editable_grid": 0, + "engine": "InnoDB", + "field_order": [ + "department_name", + "parent_department", + "company", + "is_group", + "disabled", + "section_break_4", + "leave_block_list", + "leave_section", + "leave_approvers", + "expense_section", + "expense_approvers", + "lft", + "rgt", + "old_parent" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "department_name", "fieldtype": "Data", - "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": "Department", - "length": 0, - "no_copy": 0, "oldfieldname": "department_name", "oldfieldtype": "Data", - "permlevel": 0, - "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 + "reqd": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "parent_department", "fieldtype": "Link", - "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": "Parent Department", - "length": 0, - "no_copy": 0, - "options": "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 + "options": "Department" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "company", "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": 1, "label": "Company", - "length": 0, - "no_copy": 0, "options": "Company", - "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 + "reqd": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, "bold": 1, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, + "default": "0", "fieldname": "is_group", "fieldtype": "Check", - "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": "Is Group", - "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": "Is Group" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, + "default": "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": 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": "Disabled" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "section_break_4", - "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, "description": "Days for which Holidays are blocked for this department.", - "fetch_if_empty": 0, "fieldname": "leave_block_list", "fieldtype": "Link", - "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": "Leave Block List", - "length": 0, - "no_copy": 0, - "options": "Leave Block List", - "permlevel": 0, - "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": "Leave Block List" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "leave_section", "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": "Leave Approvers", - "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": "Leave Approvers" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "description": "The first Leave Approver in the list will be set as the default Leave Approver.", - "fetch_if_empty": 0, "fieldname": "leave_approvers", "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": "Leave Approver", - "length": 0, - "no_copy": 0, - "options": "Department Approver", - "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": "Department Approver" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "expense_section", "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": "Expense Approvers", - "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": "Expense Approvers" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "description": "The first Expense Approver in the list will be set as the default Expense Approver.", - "fetch_if_empty": 0, "fieldname": "expense_approvers", "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": "Expense Approver", - "length": 0, - "no_copy": 0, - "options": "Department Approver", - "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": "Department Approver" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "lft", "fieldtype": "Int", "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": "lft", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", "print_hide": 1, - "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_if_empty": 0, "fieldname": "rgt", "fieldtype": "Int", "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": "rgt", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", "print_hide": 1, - "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_if_empty": 0, "fieldname": "old_parent", "fieldtype": "Data", "hidden": 1, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Old Parent", - "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": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "print_hide": 1 } ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, "icon": "fa fa-sitemap", "idx": 1, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-06-25 18:43:05.550387", + "is_tree": 1, + "links": [], + "modified": "2020-03-18 18:26:05.966022", "modified_by": "Administrator", "module": "HR", "name": "Department", + "nsm_parent_field": "parent_department", "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, "print": 1, "read": 1, "report": 1, "role": "HR User", - "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": "Academics User", - "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": 1, - "permlevel": 0, "print": 1, "read": 1, "report": 1, "role": "HR Manager", "set_user_permissions": 1, "share": 1, - "submit": 0, "write": 1 } ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, "show_name_in_global_search": 1, - "sort_order": "ASC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + "sort_field": "modified", + "sort_order": "ASC" } \ No newline at end of file diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json index 794d8161d2f..ce0dbd179ce 100644 --- a/erpnext/projects/doctype/task/task.json +++ b/erpnext/projects/doctype/task/task.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "autoname": "TASK-.YYYY.-.#####", "creation": "2013-01-29 19:25:50", @@ -361,11 +362,14 @@ ], "icon": "fa fa-check", "idx": 1, + "is_tree": 1, + "links": [], "max_attachments": 5, - "modified": "2019-09-10 13:46:24.631754", + "modified": "2020-03-18 18:26:04.788061", "modified_by": "Administrator", "module": "Projects", "name": "Task", + "nsm_parent_field": "parent_task", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json index 472b75103cc..e44e0733967 100644 --- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json +++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "format:PRC-{quality_procedure_name}", "creation": "2018-10-06 00:06:29.756804", "doctype": "DocType", @@ -69,10 +70,13 @@ "reqd": 1 } ], - "modified": "2019-08-05 13:09:29.945082", + "is_tree": 1, + "links": [], + "modified": "2020-03-18 18:26:05.511984", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality Procedure", + "nsm_parent_field": "parent_quality_procedure", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index dd602eca103..5ce51a6e8d9 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "field:company_name", @@ -725,10 +726,13 @@ "icon": "fa fa-building", "idx": 1, "image_field": "company_logo", - "modified": "2019-11-22 13:04:47.470768", + "is_tree": 1, + "links": [], + "modified": "2020-03-18 18:26:03.145312", "modified_by": "Administrator", "module": "Setup", "name": "Company", + "nsm_parent_field": "parent_company", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/setup/doctype/customer_group/customer_group.json b/erpnext/setup/doctype/customer_group/customer_group.json index 7fa242ae19d..82d5f7a3f73 100644 --- a/erpnext/setup/doctype/customer_group/customer_group.json +++ b/erpnext/setup/doctype/customer_group/customer_group.json @@ -137,11 +137,13 @@ ], "icon": "fa fa-sitemap", "idx": 1, + "is_tree": 1, "links": [], - "modified": "2020-01-28 13:49:23.961708", + "modified": "2020-03-18 18:26:02.536305", "modified_by": "Administrator", "module": "Setup", "name": "Customer Group", + "nsm_parent_field": "parent_customer_group", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json index 36e3e68ef43..849fb6fd911 100644 --- a/erpnext/setup/doctype/item_group/item_group.json +++ b/erpnext/setup/doctype/item_group/item_group.json @@ -185,13 +185,15 @@ "icon": "fa fa-sitemap", "idx": 1, "image_field": "image", + "is_tree": 1, "links": [], "max_attachments": 3, - "modified": "2020-01-28 13:51:05.456014", + "modified": "2020-03-18 18:25:59.979083", "modified_by": "Administrator", "module": "Setup", "name": "Item Group", "name_case": "Title Case", + "nsm_parent_field": "parent_item_group", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/setup/doctype/sales_person/sales_person.json b/erpnext/setup/doctype/sales_person/sales_person.json index b05365d2ca9..d7a9d5dfba1 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.json +++ b/erpnext/setup/doctype/sales_person/sales_person.json @@ -143,11 +143,13 @@ ], "icon": "icon-user", "idx": 1, + "is_tree": 1, "links": [], - "modified": "2020-01-28 13:50:31.891050", + "modified": "2020-03-18 18:26:01.076203", "modified_by": "Administrator", "module": "Setup", "name": "Sales Person", + "nsm_parent_field": "parent_sales_person", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/setup/doctype/supplier_group/supplier_group.json b/erpnext/setup/doctype/supplier_group/supplier_group.json index 5c413341935..b7989d4ffad 100644 --- a/erpnext/setup/doctype/supplier_group/supplier_group.json +++ b/erpnext/setup/doctype/supplier_group/supplier_group.json @@ -1,481 +1,165 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "field:supplier_group_name", - "beta": 0, "creation": "2013-01-10 16:34:24", - "custom": 0, - "docstatus": 0, "doctype": "DocType", "document_type": "Setup", - "editable_grid": 0, + "engine": "InnoDB", + "field_order": [ + "supplier_group_name", + "parent_supplier_group", + "is_group", + "section_credit_limit", + "payment_terms", + "default_payable_account", + "accounts", + "lft", + "rgt", + "old_parent" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "supplier_group_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": "Supplier Group Name", - "length": 0, - "no_copy": 0, "oldfieldname": "supplier_type", "oldfieldtype": "Data", - "permlevel": 0, - "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": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, "bold": 1, - "collapsible": 0, - "columns": 0, "fieldname": "parent_supplier_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": 0, "label": "Parent Supplier Group", - "length": 0, - "no_copy": 0, - "options": "Supplier 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": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "options": "Supplier Group" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, "bold": 1, - "collapsible": 0, - "columns": 0, + "default": "0", "fieldname": "is_group", "fieldtype": "Check", - "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": "Is Group", - "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": "Is Group" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "fieldname": "section_credit_limit", "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": "Credit Limit", - "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": "Credit Limit" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "payment_terms", "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": "Default Payment Terms Template", - "length": 0, - "no_copy": 0, - "options": "Payment Terms 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": 0, - "translatable": 0, - "unique": 0 + "options": "Payment Terms Template" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "default_payable_account", "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": "Default Payable Account", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "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": "Default Payable Account" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "depends_on": "eval:!doc.__islocal", "description": "Mention if non-standard receivable account applicable", "fieldname": "accounts", "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": "Accounts", - "length": 0, - "no_copy": 0, - "options": "Party Account", - "permlevel": 0, - "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": "Party Account" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "lft", "fieldtype": "Int", "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": "lft", - "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": 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": "rgt", "fieldtype": "Int", "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": "rgt", - "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": 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": "old_parent", "fieldtype": "Link", "hidden": 1, "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Old Parent", - "length": 0, "no_copy": 1, "options": "Supplier Group", - "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, "icon": "fa fa-flag", "idx": 1, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-29 06:25:57.589824", + "is_tree": 1, + "links": [], + "modified": "2020-03-18 18:26:07.179330", "modified_by": "Administrator", "module": "Setup", "name": "Supplier Group", + "nsm_parent_field": "parent_supplier_group", "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, "print": 1, "read": 1, "report": 1, - "role": "Purchase Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Purchase Manager" }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, "print": 1, "read": 1, "report": 1, - "role": "Purchase User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Purchase User" }, { - "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "email": 1, "export": 1, - "if_owner": 0, "import": 1, - "permlevel": 0, "print": 1, "read": 1, "report": 1, "role": "Purchase Master Manager", "set_user_permissions": 1, "share": 1, - "submit": 0, "write": 1 }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, "permlevel": 1, - "print": 0, "read": 1, - "report": 0, "role": "Purchase Master Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, "write": 1 }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, "permlevel": 1, - "print": 0, "read": 1, - "report": 0, - "role": "Purchase Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Purchase Manager" }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, - "export": 0, - "if_owner": 0, - "import": 0, "permlevel": 1, - "print": 0, "read": 1, - "report": 0, - "role": "Purchase User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Purchase User" } ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, "show_name_in_global_search": 1, - "sort_order": "ASC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + "sort_field": "modified", + "sort_order": "ASC" } \ No newline at end of file diff --git a/erpnext/setup/doctype/territory/territory.json b/erpnext/setup/doctype/territory/territory.json index 91a3dda2bb0..4277fe75ec4 100644 --- a/erpnext/setup/doctype/territory/territory.json +++ b/erpnext/setup/doctype/territory/territory.json @@ -121,12 +121,14 @@ ], "icon": "fa fa-map-marker", "idx": 1, + "is_tree": 1, "links": [], - "modified": "2020-01-28 13:49:31.905800", + "modified": "2020-03-18 18:26:02.055750", "modified_by": "Administrator", "module": "Setup", "name": "Territory", "name_case": "Title Case", + "nsm_parent_field": "parent_territory", "owner": "Administrator", "permissions": [ { diff --git a/erpnext/stock/doctype/warehouse/warehouse.json b/erpnext/stock/doctype/warehouse/warehouse.json index 2bf1ed89838..0606d0bdc64 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.json +++ b/erpnext/stock/doctype/warehouse/warehouse.json @@ -228,11 +228,13 @@ ], "icon": "fa fa-building", "idx": 1, + "is_tree": 1, "links": [], - "modified": "2020-01-28 13:50:59.368846", + "modified": "2020-03-18 18:26:00.479541", "modified_by": "Administrator", "module": "Stock", "name": "Warehouse", + "nsm_parent_field": "parent_warehouse", "owner": "Administrator", "permissions": [ { From 8c56f8595e21e96a82f574bca46bd252f351e4af Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 19 Mar 2020 11:03:14 +0530 Subject: [PATCH 012/104] fix: Unable to submit landed cost voucher (#20978) --- .../stock/doctype/landed_cost_voucher/landed_cost_voucher.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 7df40fb02cd..d97b699a0f3 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -104,7 +104,6 @@ class LandedCostVoucher(Document): def update_landed_cost(self): for d in self.get("purchase_receipts"): doc = frappe.get_doc(d.receipt_document_type, d.receipt_document) - # check if there are {qty} assets created and linked to this receipt document self.validate_asset_qty_and_status(d.receipt_document_type, doc) @@ -123,6 +122,8 @@ class LandedCostVoucher(Document): # update latest valuation rate in serial no self.update_rate_in_serial_no_for_non_asset_items(doc) + for d in self.get("purchase_receipts"): + doc = frappe.get_doc(d.receipt_document_type, d.receipt_document) # update stock & gl entries for cancelled state of PR doc.docstatus = 2 doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True) From 4c4a1aa56da55c6bc435c60795b60a12d5c0fb49 Mon Sep 17 00:00:00 2001 From: Rohan Date: Thu, 19 Mar 2020 13:10:26 +0530 Subject: [PATCH 013/104] fix: allow target warehouses to be changed for work order stock entries --- erpnext/stock/doctype/stock_entry/stock_entry.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 56cb3f06b94..0710e551049 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -294,13 +294,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: From 794064db9fb135d354aa06d3eeaa7235fb5d9271 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 19 Mar 2020 14:44:16 +0530 Subject: [PATCH 014/104] fix: stock entry qty must be positive --- erpnext/stock/doctype/stock_entry/stock_entry.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 56cb3f06b94..a6da3d306b4 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -177,6 +177,10 @@ class StockEntry(StockController): stock_items = self.get_stock_items() serialized_items = self.get_serialized_items() for item in self.get("items"): + if item.qty and item.qty < 0: + frappe.throw(_("Row {0}: The item {1}, quantity must be positive number") + .format(item.idx, frappe.bold(item.item_code))) + if item.item_code not in stock_items: frappe.throw(_("{0} is not a stock Item").format(item.item_code)) From e53e96f01bcb033b511bf9a2c7ee15fd8c0d878f Mon Sep 17 00:00:00 2001 From: "Chinmay D. Pai" Date: Fri, 20 Mar 2020 13:57:30 +0530 Subject: [PATCH 015/104] chore: pass traceback and error message as kwargs fixes issue where the system tries to generate an error log but fails with the following error: Traceback (most recent call last): File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 421, in install_country_fixtures frappe.get_attr(module_name)(company_doc, False) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 17, in setup make_fixtures(company) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 523, in make_fixtures set_tax_withholding_category(company) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 543, in set_tax_withholding_category fiscal_year = get_fiscal_year(today(), company=company)[0] File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 24, in get_fiscal_year return get_fiscal_years(date, fiscal_year, label, verbose, company, as_dict=as_dict)[0] File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 80, in get_fiscal_years raise FiscalYearError(error_msg) erpnext.accounts.utils.FiscalYearError: Date 20-03-2020 not in any active Fiscal Year. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/app.py", line 62, in application response = frappe.api.handle() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/api.py", line 55, in handle return frappe.handler.handle() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/handler.py", line 22, in handle data = execute_cmd(cmd) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/handler.py", line 61, in execute_cmd return frappe.call(method, **frappe.form_dict) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 1054, in call return fn(*args, **newargs) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs doc.save() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 273, in save return self._save(*args, **kwargs) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 296, in _save self.insert() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 260, in insert self.run_post_save_methods() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 926, in run_post_save_methods self.run_method("on_update") File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 794, in run_method out = Document.hook(fn)(self, *args, **kwargs) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 1065, in composer return composed(self, method, *args, **kwargs) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 1048, in runner add_to_return_value(self, fn(self, *args, **kwargs)) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 788, in fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 107, in on_update install_country_fixtures(self.name) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 423, in install_country_fixtures frappe.log_error(str(e), frappe.get_traceback()) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 1524, in log_error method=title)).insert(ignore_permissions=True) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 231, in insert self._validate() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/document.py", line 463, in _validate self._validate_length() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/base_document.py", line 583, in _validate_length self.throw_length_exceeded_error(df, max_length, value) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/model/base_document.py", line 599, in throw_length_exceeded_error .format(reference, _(df.label), max_length, value), frappe.CharacterLengthExceededError, title=_('Value too big')) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 377, in throw msgprint(msg, raise_exception=exc, title=title, indicator='red', is_minimizable=is_minimizable) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 356, in msgprint _raise_exception() File "/home/frappe/benches/bench-version-12-2020-03-19/apps/frappe/frappe/__init__.py", line 316, in _raise_exception raise raise_exception(msg) frappe.exceptions.CharacterLengthExceededError: Error Log f2cbb8c0f2: 'Title' (Traceback (most recent call last): File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/setup/doctype/company/company.py", line 421, in install_country_fixtures frappe.get_attr(module_name)(company_doc, False) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 17, in setup make_fixtures(company) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 523, in make_fixtures set_tax_withholding_category(company) File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/regional/india/setup.py", line 543, in set_tax_withholding_category fiscal_year = get_fiscal_year(today(), company=company)[0] File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 24, in get_fiscal_year return get_fiscal_years(date, fiscal_year, label, verbose, company, as_dict=as_dict)[0] File "/home/frappe/benches/bench-version-12-2020-03-19/apps/erpnext/erpnext/accounts/utils.py", line 80, in get_fiscal_years raise FiscalYearError(error_msg) erpnext.accounts.utils.FiscalYearError: Date 20-03-2020 not in any active Fiscal Year. ) will get truncated, as max characters allowed is 140 Signed-off-by: Chinmay D. Pai --- erpnext/setup/doctype/company/company.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index c3fd3566578..bc27f40f560 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -420,7 +420,7 @@ def install_country_fixtures(company): module_name = "erpnext.regional.{0}.setup.setup".format(frappe.scrub(company_doc.country)) frappe.get_attr(module_name)(company_doc, False) except Exception as e: - frappe.log_error(str(e), frappe.get_traceback()) + frappe.log_error(title=str(e), message=frappe.get_traceback()) frappe.throw(_("Failed to setup defaults for country {0}. Please contact support@erpnext.com").format(frappe.bold(company_doc.country))) @@ -590,4 +590,4 @@ def get_default_company_address(name, sort_key='is_primary_address', existing_ad if out: return sorted(out, key = functools.cmp_to_key(lambda x,y: cmp(y[1], x[1])))[0][0] else: - return None \ No newline at end of file + return None From e2bb2593db815aaa78558f7830cb288910d9ae4c Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Mar 2020 12:51:16 +0530 Subject: [PATCH 016/104] fix: Add currency in options of Opportunity Amount - To show currect symbol in list view --- erpnext/crm/doctype/opportunity/opportunity.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json index 66e3ca48dd2..979e4c7a67f 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.json +++ b/erpnext/crm/doctype/opportunity/opportunity.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "naming_series:", @@ -208,7 +209,8 @@ { "fieldname": "opportunity_amount", "fieldtype": "Currency", - "label": "Opportunity Amount" + "label": "Opportunity Amount", + "options": "currency" }, { "default": "0", @@ -412,7 +414,8 @@ ], "icon": "fa fa-info-sign", "idx": 195, - "modified": "2019-09-30 12:58:37.385400", + "links": [], + "modified": "2020-03-20 12:28:45.228994", "modified_by": "Administrator", "module": "CRM", "name": "Opportunity", From 93e72fdd219d6d35198f1771feb84d7e64c8b780 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 20 Mar 2020 17:49:59 +0530 Subject: [PATCH 017/104] fix: UOM fixes in Sales Order,Material Request & Production Plan --- .../doctype/production_plan/production_plan.py | 2 +- .../selling/doctype/sales_order/sales_order.py | 16 +++++----------- .../doctype/material_request/material_request.py | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) 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/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/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, From 20ab2c1e20a48a08bf32de9324ae45af008c148d Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 22 Mar 2020 21:50:22 +0530 Subject: [PATCH 018/104] fix: Remove quick entry from accouting dimensions --- .../accounting_dimension.js | 6 ------ .../accounting_dimension.json | 17 +++++++++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js index a36f4214d7c..3c12f85f938 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js @@ -48,12 +48,6 @@ frappe.ui.form.on('Accounting Dimension', { frm.set_value('label', frm.doc.document_type); frm.set_value('fieldname', frappe.model.scrub(frm.doc.document_type)); - if (frm.is_new()){ - let row = frappe.model.add_child(frm.doc, "Accounting Dimension Detail", "dimension_defaults"); - row.reference_document = frm.doc.document_type; - frm.refresh_fields("dimension_defaults"); - } - frappe.db.get_value('Accounting Dimension', {'document_type': frm.doc.document_type}, 'document_type', (r) => { if (r && r.document_type) { frm.set_df_property('document_type', 'description', "Document type is already set as dimension"); diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json index cf6dc7a8fa5..cf55d554fb3 100644 --- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json +++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "field:label", "creation": "2019-05-04 18:13:37.002352", "doctype": "DocType", @@ -46,7 +47,8 @@ "options": "Accounting Dimension Detail" } ], - "modified": "2019-07-17 16:49:31.134385", + "links": [], + "modified": "2020-03-22 20:34:39.805728", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting Dimension", @@ -63,9 +65,20 @@ "role": "System Manager", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 } ], - "quick_entry": 1, "sort_field": "modified", "sort_order": "ASC", "track_changes": 1 From b05922026d6da9fa1bc6b421809641730400da89 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 23 Mar 2020 16:31:39 +0530 Subject: [PATCH 019/104] feat: import supplier invoices --- erpnext/patches.txt | 1 + .../v12_0/set_permission_einvoicing.py | 15 + .../import_supplier_invoice/__init__.py | 0 .../import_supplier_invoice.js | 46 ++ .../import_supplier_invoice.json | 105 +++++ .../import_supplier_invoice.py | 402 ++++++++++++++++++ .../test_import_supplier_invoice.py | 10 + erpnext/regional/italy/setup.py | 25 ++ erpnext/regional/italy/utils.py | 2 + .../purchase_einvoice/__init__.py | 0 .../purchase_einvoice/purchase_einvoice.json | 23 + 11 files changed, 629 insertions(+) create mode 100644 erpnext/patches/v12_0/set_permission_einvoicing.py create mode 100644 erpnext/regional/doctype/import_supplier_invoice/__init__.py create mode 100644 erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js create mode 100644 erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json create mode 100644 erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py create mode 100644 erpnext/regional/doctype/import_supplier_invoice/test_import_supplier_invoice.py create mode 100644 erpnext/regional/print_format/purchase_einvoice/__init__.py create mode 100644 erpnext/regional/print_format/purchase_einvoice/purchase_einvoice.json diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 4e72d5ecd6b..de4c89c5ace 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -650,3 +650,4 @@ erpnext.patches.v12_0.update_price_or_product_discount erpnext.patches.v12_0.add_export_type_field_in_party_master erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22 erpnext.patches.v12_0.create_irs_1099_field_united_states +erpnext.patches.v12_0.set_permission_einvoicing diff --git a/erpnext/patches/v12_0/set_permission_einvoicing.py b/erpnext/patches/v12_0/set_permission_einvoicing.py new file mode 100644 index 00000000000..1095c8c43e7 --- /dev/null +++ b/erpnext/patches/v12_0/set_permission_einvoicing.py @@ -0,0 +1,15 @@ +import frappe +from erpnext.regional.italy.setup import make_custom_fields +from frappe.permissions import add_permission, update_permission_property + +def execute(): + company = frappe.get_all('Company', filters = {'country': 'Italy'}) + + if not company: + return + + make_custom_fields() + + add_permission('Import Supplier Invoice', 'Accounts Manager', 0) + update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'write', 1) + update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'create', 1) \ No newline at end of file diff --git a/erpnext/regional/doctype/import_supplier_invoice/__init__.py b/erpnext/regional/doctype/import_supplier_invoice/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js new file mode 100644 index 00000000000..c2d6edfc773 --- /dev/null +++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.js @@ -0,0 +1,46 @@ +// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +frappe.ui.form.on('Import Supplier Invoice', { + onload: function(frm) { + frappe.realtime.on("import_invoice_update", function (data) { + frm.dashboard.show_progress(data.title, (data.count / data.total) * 100, data.message); + if (data.count == data.total) { + window.setTimeout(title => frm.dashboard.hide_progress(title), 1500, data.title); + } + }); + }, + setup: function(frm) { + frm.set_query("tax_account", function(doc) { + return { + filters: { + account_type: 'Tax', + company: doc.company + } + }; + }); + + frm.set_query("default_buying_price_list", function(doc) { + return { + filters: { + currency: frappe.get_doc(":Company", doc.company).default_currency + } + }; + }); + }, + + refresh: function(frm) { + frm.trigger("toggle_read_only_fields"); + }, + + toggle_read_only_fields: function(frm) { + if (in_list(["File Import Completed", "Processing File Data"], frm.doc.status)) { + cur_frm.set_read_only(); + cur_frm.refresh_fields(); + frm.set_df_property("import_invoices", "hidden", 1); + } else { + frm.set_df_property("import_invoices", "hidden", 0); + } + } + +}); \ No newline at end of file diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json new file mode 100644 index 00000000000..59e955c23f4 --- /dev/null +++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json @@ -0,0 +1,105 @@ +{ + "actions": [], + "creation": "2019-10-15 12:33:21.845329", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "invoice_series", + "company", + "item_code", + "column_break_5", + "supplier_group", + "tax_account", + "default_buying_price_list", + "upload_xml_invoices_section", + "zip_file", + "import_invoices", + "status" + ], + "fields": [ + { + "fieldname": "company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company", + "reqd": 1 + }, + { + "fieldname": "item_code", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item Code", + "options": "Item", + "reqd": 1 + }, + { + "fieldname": "supplier_group", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Supplier Group", + "options": "Supplier Group", + "reqd": 1 + }, + { + "fieldname": "tax_account", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Tax Account", + "options": "Account", + "reqd": 1 + }, + { + "fieldname": "column_break_5", + "fieldtype": "Column Break" + }, + { + "fieldname": "zip_file", + "fieldtype": "Attach", + "label": "Zip File" + }, + { + "description": "Click on Import Invoices button once the zip file has been attached to the document. Any errors related to processing will be shown in the Error Log.", + "fieldname": "import_invoices", + "fieldtype": "Button", + "label": "Import Invoices", + "options": "process_file_data" + }, + { + "fieldname": "status", + "fieldtype": "Data", + "label": "Status", + "read_only": 1 + }, + { + "fieldname": "invoice_series", + "fieldtype": "Select", + "label": "Invoice Series", + "options": "ACC-PINV-.YYYY.-", + "reqd": 1 + }, + { + "fieldname": "default_buying_price_list", + "fieldtype": "Link", + "label": "Default Buying Price List", + "options": "Price List", + "reqd": 1 + }, + { + "fieldname": "upload_xml_invoices_section", + "fieldtype": "Section Break", + "label": "Upload XML Invoices" + } + ], + "links": [], + "modified": "2019-12-10 16:37:26.793398", + "modified_by": "Administrator", + "module": "Regional", + "name": "Import Supplier Invoice", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py new file mode 100644 index 00000000000..72fe17fb379 --- /dev/null +++ b/erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py @@ -0,0 +1,402 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +from decimal import Decimal +import json +import re +import traceback +import zipfile +import frappe, erpnext +from frappe import _ +from frappe.model.document import Document +from frappe.custom.doctype.custom_field.custom_field import create_custom_field +from frappe.utils.data import format_datetime +from bs4 import BeautifulSoup as bs +from frappe.utils import cint, flt, today, nowdate, add_days, get_files_path, get_datetime_str +import dateutil +from frappe.utils.file_manager import save_file + +class ImportSupplierInvoice(Document): + def validate(self): + if not frappe.db.get_value("Stock Settings", fieldname="stock_uom"): + frappe.throw(_("Please set default UOM in Stock Settings")) + + def autoname(self): + if not self.name: + self.name = "Import Invoice on " + format_datetime(self.creation) + + def import_xml_data(self): + import_file = frappe.get_doc("File", {"file_url": self.zip_file}) + self.publish("File Import", _("Processing XML Files"), 1, 3) + + self.file_count = 0 + self.purchase_invoices_count = 0 + self.default_uom = frappe.db.get_value("Stock Settings", fieldname="stock_uom") + + with zipfile.ZipFile(get_full_path(self.zip_file)) as zf: + for file_name in zf.namelist(): + content = get_file_content(file_name, zf) + file_content = bs(content, "xml") + self.prepare_data_for_import(file_content, file_name, content) + + if self.purchase_invoices_count == self.file_count: + self.status = "File Import Completed" + self.publish("File Import", _("XML Files Processed"), 2, 3) + else: + self.status = "Partially Completed - Check Error Log" + self.publish("File Import", _("XML Files Processed"), 2, 3) + + self.save() + self.publish("File Import", _("XML Files Processed"), 3, 3) + + def prepare_data_for_import(self, file_content, file_name, encoded_content): + for line in file_content.find_all("DatiGeneraliDocumento"): + invoices_args = { + "company": self.company, + "naming_series": self.invoice_series, + "document_type": line.TipoDocumento.text, + "bill_date": get_datetime_str(line.Data.text), + "invoice_no": line.Numero.text, + "total_discount": 0, + "items": [], + "buying_price_list": self.default_buying_price_list + } + + if not invoices_args.get("invoice_no", ''): return + + supp_dict = get_supplier_details(file_content) + invoices_args["destination_code"] = get_destination_code_from_file(file_content) + self.prepare_items_for_invoice(file_content, invoices_args) + invoices_args["taxes"] = get_taxes_from_file(file_content, self.tax_account) + invoices_args["terms"] = get_payment_terms_from_file(file_content) + + supplier_name = create_supplier(self.supplier_group, supp_dict) + address = create_address(supplier_name, supp_dict) + pi_name = create_purchase_invoice(supplier_name, file_name, invoices_args, self.name) + + self.file_count += 1 + if pi_name: + self.purchase_invoices_count += 1 + file_save = save_file(file_name, encoded_content, "Purchase Invoice", + pi_name, folder=None, decode=False, is_private=0, df=None) + + def prepare_items_for_invoice(self, file_content, invoices_args): + qty = 1 + rate, tax_rate = [0 ,0] + uom = self.default_uom + + #read file for item information + for line in file_content.find_all("DettaglioLinee"): + if line.find("PrezzoUnitario") and line.find("PrezzoTotale"): + rate = flt(line.PrezzoUnitario.text) or 0 + line_total = flt(line.PrezzoTotale.text) or 0 + + if rate and flt(line_total) / rate != 1.0 and line.find("Quantita"): + qty = flt(line.Quantita.text) or 0 + if line.find("UnitaMisura"): + uom = create_uom(line.UnitaMisura.text) + + if (rate < 0 and line_total < 0): + qty *= -1 + invoices_args["return_invoice"] = 1 + + if line.find("AliquotaIVA"): + tax_rate = flt(line.AliquotaIVA.text) + + line_str = re.sub('[^A-Za-z0-9]+', '-', line.Descrizione.text) + item_name = line_str[0:140] + + invoices_args['items'].append({ + "item_code": self.item_code, + "item_name": item_name, + "description": line_str, + "qty": qty, + "uom": uom, + "rate": abs(rate), + "conversion_factor": 1.0, + "tax_rate": tax_rate + }) + + for disc_line in line.find_all("ScontoMaggiorazione"): + if disc_line.find("Percentuale"): + invoices_args["total_discount"] += flt((flt(disc_line.Percentuale.text) / 100) * (rate * qty)) + + def process_file_data(self): + self.status = "Processing File Data" + self.save() + frappe.enqueue_doc(self.doctype, self.name, "import_xml_data", queue="long", timeout=3600) + + def publish(self, title, message, count, total): + frappe.publish_realtime("import_invoice_update", {"title": title, "message": message, "count": count, "total": total}) + +def get_file_content(file_name, zip_file_object): + content = '' + encoded_content = zip_file_object.read(file_name) + + try: + content = encoded_content.decode("utf-8-sig") + except UnicodeDecodeError: + try: + content = encoded_content.decode("utf-16") + except UnicodeDecodeError as e: + frappe.log_error(message=e, title="UTF-16 encoding error for File Name: " + file_name) + + return content + +def get_supplier_details(file_content): + supplier_info = {} + for line in file_content.find_all("CedentePrestatore"): + supplier_info['tax_id'] = line.DatiAnagrafici.IdPaese.text + line.DatiAnagrafici.IdCodice.text + if line.find("CodiceFiscale"): + supplier_info['fiscal_code'] = line.DatiAnagrafici.CodiceFiscale.text + + if line.find("RegimeFiscale"): + supplier_info['fiscal_regime'] = line.DatiAnagrafici.RegimeFiscale.text + + if line.find("Denominazione"): + supplier_info['supplier'] = line.DatiAnagrafici.Anagrafica.Denominazione.text + + if line.find("Nome"): + supplier_info['supplier'] = (line.DatiAnagrafici.Anagrafica.Nome.text + + " " + line.DatiAnagrafici.Anagrafica.Cognome.text) + + supplier_info['address_line1'] = line.Sede.Indirizzo.text + supplier_info['city'] = line.Sede.Comune.text + if line.find("Provincia"): + supplier_info['province'] = line.Sede.Provincia.text + + supplier_info['pin_code'] = line.Sede.CAP.text + supplier_info['country'] = get_country(line.Sede.Nazione.text) + + return supplier_info + +def get_taxes_from_file(file_content, tax_account): + taxes = [] + #read file for taxes information + for line in file_content.find_all("DatiRiepilogo"): + if line.find("AliquotaIVA"): + if line.find("EsigibilitaIVA"): + descr = line.EsigibilitaIVA.text + else: + descr = "None" + taxes.append({ + "charge_type": "Actual", + "account_head": tax_account, + "tax_rate": flt(line.AliquotaIVA.text) or 0, + "description": descr, + "tax_amount": flt(line.Imposta.text) if len(line.find("Imposta"))!=0 else 0 + }) + + return taxes + +def get_payment_terms_from_file(file_content): + terms = [] + #Get mode of payment dict from setup + mop_options = frappe.get_meta('Mode of Payment').fields[4].options + mop_str = re.sub('\n', ',', mop_options) + mop_dict = dict(item.split("-") for item in mop_str.split(",")) + #read file for payment information + for line in file_content.find_all("DettaglioPagamento"): + mop_code = line.ModalitaPagamento.text + '-' + mop_dict.get(line.ModalitaPagamento.text) + if line.find("DataScadenzaPagamento"): + due_date = dateutil.parser.parse(line.DataScadenzaPagamento.text).strftime("%Y-%m-%d") + else: + due_date = today() + terms.append({ + "mode_of_payment_code": mop_code, + "bank_account_iban": line.IBAN.text if line.find("IBAN") else "", + "due_date": due_date, + "payment_amount": line.ImportoPagamento.text + }) + + return terms + +def get_destination_code_from_file(file_content): + destination_code = '' + for line in file_content.find_all("DatiTrasmissione"): + destination_code = line.CodiceDestinatario.text + + return destination_code + +def create_supplier(supplier_group, args): + args = frappe._dict(args) + + existing_supplier_name = frappe.db.get_value("Supplier", + filters={"tax_id": args.tax_id}, fieldname="name") + if existing_supplier_name: + pass + else: + existing_supplier_name = frappe.db.get_value("Supplier", + filters={"name": args.supplier}, fieldname="name") + + if existing_supplier_name: + filters = [ + ["Dynamic Link", "link_doctype", "=", "Supplier"], + ["Dynamic Link", "link_name", "=", args.existing_supplier_name], + ["Dynamic Link", "parenttype", "=", "Contact"] + ] + + if not frappe.get_list("Contact", filters): + new_contact = frappe.new_doc("Contact") + new_contact.first_name = args.supplier + new_contact.append('links', { + "link_doctype": "Supplier", + "link_name": existing_supplier_name + }) + new_contact.insert(ignore_mandatory=True) + + return existing_supplier_name + else: + + new_supplier = frappe.new_doc("Supplier") + new_supplier.supplier_name = args.supplier + new_supplier.supplier_group = supplier_group + new_supplier.tax_id = args.tax_id + new_supplier.fiscal_code = args.fiscal_code + new_supplier.fiscal_regime = args.fiscal_regime + new_supplier.save() + + new_contact = frappe.new_doc("Contact") + new_contact.first_name = args.supplier + new_contact.append('links', { + "link_doctype": "Supplier", + "link_name": new_supplier.name + }) + + new_contact.insert(ignore_mandatory=True) + + return new_supplier.name + +def create_address(supplier_name, args): + args = frappe._dict(args) + + filters = [ + ["Dynamic Link", "link_doctype", "=", "Supplier"], + ["Dynamic Link", "link_name", "=", supplier_name], + ["Dynamic Link", "parenttype", "=", "Address"] + ] + + existing_address = frappe.get_list("Address", filters) + + if args.address_line1: + new_address_doc = frappe.new_doc("Address") + new_address_doc.address_line1 = args.address_line1 + + if args.city: + new_address_doc.city = args.city + else: + new_address_doc.city = "Not Provided" + + for field in ["province", "pincode", "country"]: + if args.get(field): + new_address_doc.set(field, args.get(field)) + + for address in existing_address: + address_doc = frappe.get_doc("Address", address["name"]) + if (address_doc.address_line1 == new_address_doc.address_line1 and + address_doc.pincode == new_address_doc.pincode): + return address + + new_address_doc.append("links", { + "link_doctype": "Supplier", + "link_name": supplier_name + }) + new_address_doc.address_type = "Billing" + new_address_doc.insert(ignore_mandatory=True) + return new_address_doc.name + else: + return None + +def create_purchase_invoice(supplier_name, file_name, args, name): + args = frappe._dict(args) + pi = frappe.get_doc({ + "doctype": "Purchase Invoice", + "company": args.company, + "currency": erpnext.get_company_currency(args.company), + "naming_series": args.naming_series, + "supplier": supplier_name, + "is_return": args.is_return, + "posting_date": today(), + "bill_no": args.bill_no, + "buying_price_list": args.buying_price_list, + "bill_date": args.bill_date, + "destination_code": args.destination_code, + "document_type": args.document_type, + "disable_rounded_total": 1, + "items": args["items"], + "taxes": args["taxes"] + }) + + try: + pi.set_missing_values() + pi.insert(ignore_mandatory=True) + + #if discount exists in file, apply any discount on grand total + if args.total_discount > 0: + pi.apply_discount_on = "Grand Total" + pi.discount_amount = args.total_discount + pi.save() + #adjust payment amount to match with grand total calculated + calc_total = 0 + adj = 0 + for term in args.terms: + calc_total += flt(term["payment_amount"]) + if flt(calc_total - flt(pi.grand_total)) != 0: + adj = calc_total - flt(pi.grand_total) + pi.payment_schedule = [] + for term in args.terms: + pi.append('payment_schedule',{"mode_of_payment_code": term["mode_of_payment_code"], + "bank_account_iban": term["bank_account_iban"], + "due_date": term["due_date"], + "payment_amount": flt(term["payment_amount"]) - adj }) + adj = 0 + pi.imported_grand_total = calc_total + pi.save() + return pi.name + except Exception as e: + frappe.db.set_value("Import Supplier Invoice", name, "status", "Error") + frappe.log_error(message=e, + title="Create Purchase Invoice: " + args.get("bill_no") + "File Name: " + file_name) + return None + +def get_country(code): + existing_country_name = frappe.db.get_value("Country", + filters={"code": code}, fieldname="name") + if existing_country_name: + return existing_country_name + else: + frappe.throw(_("Country Code in File does not match with country code set up in the system")) + +def create_uom(uom): + existing_uom = frappe.db.get_value("UOM", + filters={"uom_name": uom}, fieldname="uom_name") + if existing_uom: + return existing_uom + else: + new_uom = frappe.new_doc("UOM") + new_uom.uom_name = uom + new_uom.save() + return new_uom.uom_name + +def get_full_path(file_name): + """Returns file path from given file name""" + file_path = file_name + + if "/" not in file_path: + file_path = "/files/" + file_path + + if file_path.startswith("/private/files/"): + file_path = get_files_path(*file_path.split("/private/files/", 1)[1].split("/"), is_private=1) + + elif file_path.startswith("/files/"): + file_path = get_files_path(*file_path.split("/files/", 1)[1].split("/")) + + elif file_path.startswith("http"): + pass + + elif not self.file_url: + frappe.throw(_("There is some problem with the file url: {0}").format(file_path)) + + return file_path \ No newline at end of file diff --git a/erpnext/regional/doctype/import_supplier_invoice/test_import_supplier_invoice.py b/erpnext/regional/doctype/import_supplier_invoice/test_import_supplier_invoice.py new file mode 100644 index 00000000000..d1caf77fc2c --- /dev/null +++ b/erpnext/regional/doctype/import_supplier_invoice/test_import_supplier_invoice.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestImportSupplierInvoice(unittest.TestCase): + pass diff --git a/erpnext/regional/italy/setup.py b/erpnext/regional/italy/setup.py index 1526d6f62f0..2d0ad66b0a0 100644 --- a/erpnext/regional/italy/setup.py +++ b/erpnext/regional/italy/setup.py @@ -155,6 +155,31 @@ def make_custom_fields(update=True): fetch_from="country.code"), dict(fieldname='state_code', label='State Code', fieldtype='Data', insert_after='state', print_hide=1) + ], + 'Purchase Invoice': [ + dict(fieldname='document_type', label='Document Type', + fieldtype='Data', insert_after='company', print_hide=1, read_only=1 + ), + dict(fieldname='destination_code', label='Destination Code', + fieldtype='Data', insert_after='company', print_hide=1, read_only=1 + ), + dict(fieldname='imported_grand_total', label='Imported Grand Total', + fieldtype='Data', insert_after='update_auto_repeat_reference', print_hide=1, read_only=1 + ) + ], + 'Purchase Taxes and Charges': [ + dict(fieldname='tax_rate', label='Tax Rate', + fieldtype='Data', insert_after='parenttype', print_hide=1, read_only=0 + ) + ], + 'Supplier': [ + dict(fieldname='fiscal_code', label='Fiscal Code', + fieldtype='Data', insert_after='tax_id', print_hide=1, read_only=1 + ), + dict(fieldname='fiscal_regime', label='Fiscal Regime', + fieldtype='Select', insert_after='fiscal_code', print_hide=1, read_only=1, + options= "\nRF01\nRF02\nRF04\nRF05\nRF06\nRF07\nRF08\nRF09\nRF10\nRF11\nRF12\nRF13\nRF14\nRF15\nRF16\nRF17\nRF18\nRF19" + ) ] } diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py index bc8d00d8b8b..2af72f8e276 100644 --- a/erpnext/regional/italy/utils.py +++ b/erpnext/regional/italy/utils.py @@ -13,6 +13,8 @@ from erpnext.regional.italy import state_codes def update_itemised_tax_data(doc): if not doc.taxes: return + if doc.doctype == "Purchase Invoice": return + itemised_tax = get_itemised_tax(doc.taxes) for row in doc.items: diff --git a/erpnext/regional/print_format/purchase_einvoice/__init__.py b/erpnext/regional/print_format/purchase_einvoice/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/regional/print_format/purchase_einvoice/purchase_einvoice.json b/erpnext/regional/print_format/purchase_einvoice/purchase_einvoice.json new file mode 100644 index 00000000000..88f31dd1308 --- /dev/null +++ b/erpnext/regional/print_format/purchase_einvoice/purchase_einvoice.json @@ -0,0 +1,23 @@ +{ + "align_labels_right": 0, + "creation": "2019-10-16 00:47:08.877767", + "custom_format": 0, + "disabled": 1, + "doc_type": "Purchase Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
\\t\\t\\t\\t

Purchase Invoice
{{ doc.name }}\\t\\t\\t\\t

\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
\\nCedente/prestatore (fornitore)\\n\\nCessionario/committente (cliente)\\n
\\n

Identificstivo fiscale ai fini IVA: {{frappe.db.get_value(\\\"Supplier\\\", doc.supplier, \\\"tax_id\\\")}}

\\n

Codice fiscale: {{frappe.db.get_value(\\\"Supplier\\\", doc.supplier, \\\"fiscal_code\\\")}}

\\n

Denominazione: {{frappe.db.get_value(\\\"Supplier\\\", doc.supplier, \\\"supplier_name\\\")}}

\\n

Regime fiscale: {{frappe.db.get_value(\\\"Supplier\\\", doc.supplier, \\\"fiscal_regime\\\")}}

\\n

Indrizo: {{frappe.db.get_value(\\\"Address\\\", doc.supplier_address, \\\"address_line1\\\")}}

\\n

Commune: {{frappe.db.get_value(\\\"Address\\\", doc.supplier_address, \\\"city\\\")}} Provincia: {{frappe.db.get_value(\\\"Address\\\", doc.supplier_address, \\\"state_code\\\")}}

\\n

Cap: {{(frappe.db.get_value(\\\"Address\\\", doc.supplier_address, \\\"pincode\\\")) or \\\" \\\"}} Nazione: {{frappe.db.get_value(\\\"Address\\\", doc.supplier_address, \\\"country\\\")}}

\\n
\\n

Identificstivo fiscale ai fini IVA: {{frappe.db.get_value(\\\"Company\\\", doc.company, \\\"tax_id\\\")}}

\\n

Codice fiscale: {{frappe.db.get_value(\\\"Company\\\", doc.company, \\\"fiscal_code\\\")}}

\\n

Denominazione: {{doc.company}}

\\n

Indrizo: {{frappe.db.get_value(\\\"Address\\\", doc.shipping_address, \\\"address_line1\\\")}}

\\n

Commune: {{frappe.db.get_value(\\\"Address\\\", doc.shipping_address, \\\"city\\\")}} Provincia: {{frappe.db.get_value(\\\"Address\\\", doc.shipping_address, \\\"state_code\\\")}}

\\n

Cap: {{frappe.db.get_value(\\\"Address\\\", doc.shipping_address, \\\"pincode\\\")}} Nazione: {{frappe.db.get_value(\\\"Address\\\", doc.shipping_address, \\\"country\\\")}}

\\n
\\n
\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
\\nTipologla\\n\\nArt. 73\\n\\nNumero documento\\n\\nData documento\\n\\nCodice destinatario\\n
\\n{{doc.document_type or \\\" \\\"}}\\n\\n{{\\\" \\\"}}\\n\\n{{doc.bill_no or \\\" \\\"}}\\n\\n{{doc.get_formatted(\\\"bill_date\\\") or \\\" \\\"}}\\n\\n{{doc.destination_code or \\\" \\\"}}\\n
\\n
\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n{%- for row in doc.items -%}\\n\\n\\n\\n\\n\\n\\n\\n{%- endfor -%}\\n\\n
\\nDescrizione\\n\\nQuantita\\n\\nPrezzo unitario\\n\\nUM\\n\\n%IVA\\n\\nPrezzo totale\\n
\\n{{row.description or \\\" \\\"}}\\n\\n{{row.get_formatted(\\\"qty\\\", doc)}}\\n\\n{{row.get_formatted(\\\"rate\\\", doc)}}\\n\\n{{row.get_formatted(\\\"uom\\\", doc)}}\\n\\n{{row.get_formatted(\\\"tax_rate\\\", doc)}}\\n\\n{{row.get_formatted(\\\"amount\\\", doc)}}\\n
\\n
\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n{%- for row in doc.taxes -%}\\n\\n\\n\\n\\n\\n\\n\\n{%- endfor -%}\\n\\n
\\nesigibilita immediata / riferimenti normativi\\n\\n%IVA\\n\\nSpese accessorie\\n\\nArr.\\n\\nTotale imponibile\\n\\nTotale Imposta\\n
\\n{% if 'None' in row.description %}\\n {{ \\\" \\\" }}\\n{% else %}\\n{{row.description}}\\n{% endif %}\\n\\n{{row.get_formatted(\\\"tax_rate\\\", doc)}}\\n\\n{{\\\"0,00\\\"}}\\n\\n{{\\\" \\\"}}\\n\\n{{doc.get_formatted(\\\"base_net_total\\\")}}\\n\\n{{row.get_formatted(\\\"tax_amount\\\", doc)}}\\n
\\n
\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
\\nImporto bolio\\n\\nSconto/Magglorazione\\n\\nArr.\\n\\nTotale documento\\n
\\n{{\\\" \\\"}}\\n\\n{{\\\" \\\"}}\\n\\n{{\\\" \\\"}}\\n\\n{{doc.get_formatted(\\\"base_grand_total\\\")}}\\n
\\n
\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"_custom_html\", \"print_hide\": 0, \"label\": \"Custom HTML\", \"fieldtype\": \"HTML\", \"options\": \"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n{%- for row in doc.payment_schedule -%}\\n\\n\\n\\n\\n\\n\\n{%- endfor -%}\\n\\n
\\nModalita pagamento\\n\\nIBAN\\n\\nInstituto\\n\\nData scadenza\\n\\nImporto\\n
\\n{{row.get_formatted(\\\"mode_of_payment_code\\\",doc)}}\\n\\n{{row.get_formatted(\\\"bank_account_iban\\\",doc)}}\\n\\n{{\\\" \\\"}}\\n\\n{{row.get_formatted(\\\"due_date\\\",doc)}}\\n\\n{{row.get_formatted(\\\"payment_amount\\\",doc)}}\\n
\"}]", + "idx": 0, + "line_breaks": 0, + "modified": "2019-10-16 23:32:37.709344", + "modified_by": "Administrator", + "module": "Regional", + "name": "Purchase eInvoice", + "owner": "Administrator", + "print_format_builder": 1, + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file From 243283eec875fa7c4f57caa2615c0c466d1cf312 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 24 Mar 2020 11:34:44 +0530 Subject: [PATCH 020/104] fix: batch selection popup not coming for stock entry --- erpnext/public/js/utils/serial_no_batch_selector.js | 6 +++++- erpnext/stock/doctype/stock_entry/stock_entry.js | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index 23895ee4c02..101ac9cd610 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -313,11 +313,15 @@ erpnext.SerialNoBatchSelector = Class.extend({ frappe.throw(__(`Batch ${val} already selected.`)); return; } + + let batch_number = me.item.batch_no || + this.grid_row.on_grid_fields_dict.batch_no.get_value(); + if (me.warehouse_details.name) { frappe.call({ method: 'erpnext.stock.doctype.batch.batch.get_batch_qty', args: { - batch_no: me.item.batch_no, + batch_no: batch_number, warehouse: me.warehouse_details.name, item_code: me.item_code }, diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 92cc8f65047..23ee9f472b8 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -60,7 +60,8 @@ frappe.ui.form.on('Stock Entry', { } } - if(item.s_warehouse) filters["warehouse"] = item.s_warehouse; + filters["warehouse"] = item.s_warehouse || item.t_warehouse; + return { query : "erpnext.controllers.queries.get_batch_no", filters: filters @@ -886,7 +887,7 @@ erpnext.stock.select_batch_and_serial_no = (frm, item) => { } } - if(item && !item.has_serial_no && item.has_batch_no) return; + if(item && !item.has_serial_no && !item.has_batch_no) return; if (frm.doc.purpose === 'Material Receipt') return; frappe.require("assets/erpnext/js/utils/serial_no_batch_selector.js", function() { From 87b3dbb2146da8061b8babea76036eb5e4566f30 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 2 Dec 2019 09:37:09 +0530 Subject: [PATCH 021/104] fix: Manufacturing UX, added calendar view for job card --- erpnext/manufacturing/doctype/bom/bom.js | 5 - .../doctype/bom/bom_dashboard.py | 4 +- .../doctype/job_card/job_card.js | 141 +- .../doctype/job_card/job_card.json | 1234 +++---------- .../doctype/job_card/job_card.py | 55 +- .../doctype/job_card/job_card_calendar.js | 21 + .../job_card_time_log/job_card_time_log.json | 247 +-- .../production_plan/production_plan.js | 3 +- .../production_plan/production_plan.json | 1618 +++-------------- .../production_plan_dashboard.py | 2 +- .../doctype/work_order/work_order.js | 178 +- .../doctype/work_order/work_order.json | 4 +- .../doctype/work_order/work_order.py | 38 +- .../doctype/work_order/work_order_calendar.js | 2 + .../work_order/work_order_dashboard.py | 3 +- .../work_order_operation.json | 9 +- 16 files changed, 918 insertions(+), 2646 deletions(-) create mode 100644 erpnext/manufacturing/doctype/job_card/job_card_calendar.js diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js index 8283fd7e6fc..3acaee4ffbd 100644 --- a/erpnext/manufacturing/doctype/bom/bom.js +++ b/erpnext/manufacturing/doctype/bom/bom.js @@ -6,7 +6,6 @@ frappe.provide("erpnext.bom"); frappe.ui.form.on("BOM", { setup: function(frm) { frm.custom_make_buttons = { - 'BOM': 'Duplicate BOM', 'Work Order': 'Work Order', 'Quality Inspection': 'Quality Inspection' }; @@ -91,10 +90,6 @@ frappe.ui.form.on("BOM", { } if(frm.doc.docstatus!=0) { - frm.add_custom_button(__("Duplicate BOM"), function() { - frm.copy_doc(); - }, __("Create")); - frm.add_custom_button(__("Work Order"), function() { frm.trigger("make_work_order"); }, __("Create")); diff --git a/erpnext/manufacturing/doctype/bom/bom_dashboard.py b/erpnext/manufacturing/doctype/bom/bom_dashboard.py index 060cd53ef19..1571125bb06 100644 --- a/erpnext/manufacturing/doctype/bom/bom_dashboard.py +++ b/erpnext/manufacturing/doctype/bom/bom_dashboard.py @@ -23,7 +23,5 @@ def get_data(): 'label': _('Subcontract'), 'items': ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'] } - ], - 'disable_create_buttons': ["Item", "Purchase Order", "Purchase Receipt", - "Purchase Invoice", "Job Card", "Stock Entry"] + ] } diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js index 1d9544d34f4..6db8f2f5b38 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.js +++ b/erpnext/manufacturing/doctype/job_card/job_card.js @@ -7,6 +7,8 @@ frappe.ui.form.on('Job Card', { if(frm.doc.docstatus == 0) { frm.set_df_property("operation", "read_only", frm.doc.operation_id ? 1 : 0); } + frappe.flags.pause_job = 0; + frappe.flags.resume_job = 0; if(!frm.doc.__islocal && frm.doc.items && frm.doc.items.length) { if (frm.doc.for_quantity != frm.doc.transferred_qty) { @@ -18,44 +20,99 @@ frappe.ui.form.on('Job Card', { if (frm.doc.for_quantity != frm.doc.transferred_qty) { frm.add_custom_button(__("Material Transfer"), () => { frm.trigger("make_stock_entry"); - }); + }).addClass("btn-primary"); } } - if (frm.doc.docstatus == 0) { - frm.trigger("make_dashboard"); + if (frm.doc.docstatus == 0 && frm.doc.for_quantity > frm.doc.total_completed_qty + && (!frm.doc.items.length || frm.doc.for_quantity == frm.doc.transferred_qty)) { + frm.trigger("prepare_timer_buttons"); + } + }, - if (!frm.doc.job_started) { - frm.add_custom_button(__("Start Job"), () => { - let row = frappe.model.add_child(frm.doc, 'Job Card Time Log', 'time_logs'); - row.from_time = frappe.datetime.now_datetime(); - frm.set_value('job_started', 1); - frm.set_value('started_time' , row.from_time); - frm.save(); - }); - } else { - frm.add_custom_button(__("Complete Job"), () => { - let completed_time = frappe.datetime.now_datetime(); - frm.doc.time_logs.forEach(d => { - if (d.from_time && !d.to_time) { - d.to_time = completed_time; - frm.set_value('started_time' , ''); - frm.set_value('job_started', 0); - frm.save(); + prepare_timer_buttons: function(frm) { + frm.trigger("make_dashboard"); + if (!frm.doc.job_started) { + frm.add_custom_button(__("Start"), () => { + if (!frm.doc.employee) { + frappe.prompt({fieldtype: 'Link', label: __('Employee'), options: "Employee", + fieldname: 'employee'}, d => { + if (d.employee) { + frm.set_value("employee", d.employee); } - }) - }); - } + + frm.events.start_job(frm); + }, __("Enter Value"), __("Start")); + } else { + frm.events.start_job(frm); + } + }).addClass("btn-primary"); + } else if (frm.doc.status == "On Hold") { + frm.add_custom_button(__("Resume"), () => { + frappe.flags.resume_job = 1; + frm.events.start_job(frm); + }).addClass("btn-primary"); + } else { + frm.add_custom_button(__("Pause"), () => { + frappe.flags.pause_job = 1; + frm.set_value("status", "On Hold"); + frm.events.complete_job(frm); + }); + + frm.add_custom_button(__("Complete"), () => { + 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")); + }).addClass("btn-primary"); } }, + start_job: function(frm) { + let row = frappe.model.add_child(frm.doc, 'Job Card Time Log', 'time_logs'); + row.from_time = frappe.datetime.now_datetime(); + frm.set_value('job_started', 1); + frm.set_value('started_time' , row.from_time); + frm.set_value("status", "Work In Progress"); + + if (!frappe.flags.resume_job) { + frm.set_value('current_time' , 0); + } + + frm.save(); + }, + + complete_job: function(frm, completed_time, completed_qty) { + frm.doc.time_logs.forEach(d => { + if (d.from_time && !d.to_time) { + d.to_time = completed_time || frappe.datetime.now_datetime(); + d.completed_qty = completed_qty || 0; + + if(frappe.flags.pause_job) { + let currentIncrement = moment(d.to_time).diff(moment(d.from_time),"seconds") || 0; + frm.set_value('current_time' , currentIncrement + (frm.doc.current_time || 0)); + } else { + frm.set_value('started_time' , ''); + frm.set_value('job_started', 0); + frm.set_value('current_time' , 0); + } + + frm.save(); + } + }); + }, + make_dashboard: function(frm) { if(frm.doc.__islocal) return; frm.dashboard.refresh(); const timer = ` -
+
00 : 00 @@ -63,11 +120,16 @@ frappe.ui.form.on('Job Card', { 00
`; - var section = frm.dashboard.add_section(timer); + var section = frm.toolbar.page.add_inner_message(timer); - if (frm.doc.started_time) { - let currentIncrement = moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.started_time),"seconds"); - initialiseTimer(); + let currentIncrement = frm.doc.current_time || 0; + if (frm.doc.started_time || frm.doc.current_time) { + if (frm.doc.status == "On Hold") { + updateStopwatch(currentIncrement); + } else { + currentIncrement += moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.started_time),"seconds"); + initialiseTimer(); + } function initialiseTimer() { const interval = setInterval(function() { @@ -93,6 +155,10 @@ frappe.ui.form.on('Job Card', { } }, + hide_timer: function(frm) { + frm.toolbar.page.inner_toolbar.find(".stopwatch").remove(); + }, + for_quantity: function(frm) { frm.doc.items = []; frm.call({ @@ -122,5 +188,22 @@ frappe.ui.form.on('Job Card', { timer: function(frm) { return `` + }, + + set_total_completed_qty: function(frm) { + frm.doc.total_completed_qty = 0; + frm.doc.time_logs.forEach(d => { + if (d.completed_qty) { + frm.doc.total_completed_qty += d.completed_qty; + } + }); + + refresh_field("total_completed_qty"); } -}); \ No newline at end of file +}); + +frappe.ui.form.on('Job Card Time Log', { + completed_qty: function(frm) { + frm.events.set_total_completed_qty(frm); + } +}) \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json index 39c5cce313b..fd39af1faad 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.json +++ b/erpnext/manufacturing/doctype/job_card/job_card.json @@ -1,1004 +1,300 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "PO-JOB.#####", - "beta": 0, - "creation": "2018-07-09 17:23:29.518745", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "autoname": "naming_series:", + "creation": "2018-07-09 17:23:29.518745", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "naming_series", + "work_order", + "bom_no", + "workstation", + "operation", + "column_break_4", + "posting_date", + "company", + "remarks", + "production_section", + "production_item", + "item_name", + "for_quantity", + "wip_warehouse", + "column_break_12", + "employee", + "employee_name", + "status", + "project", + "timing_detail", + "time_logs", + "section_break_13", + "total_completed_qty", + "total_time_in_mins", + "column_break_15", + "section_break_8", + "items", + "more_information", + "operation_id", + "transferred_qty", + "requested_qty", + "column_break_20", + "barcode", + "job_started", + "started_time", + "current_time", + "amended_from" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "work_order", - "fieldtype": "Link", - "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": "Work Order", - "length": 0, - "no_copy": 0, - "options": "Work Order", - "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 - }, + "fieldname": "work_order", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Work Order", + "options": "Work Order", + "reqd": 1, + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "bom_no", - "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": "BOM No", - "length": 0, - "no_copy": 0, - "options": "BOM", - "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 - }, + "fetch_from": "work_order.bom_no", + "fieldname": "bom_no", + "fieldtype": "Link", + "label": "BOM No", + "options": "BOM", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "workstation", - "fieldtype": "Link", - "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": "Workstation", - "length": 0, - "no_copy": 0, - "options": "Workstation", - "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": "workstation", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Workstation", + "options": "Workstation", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "operation", - "fieldtype": "Link", - "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": "Operation", - "length": 0, - "no_copy": 0, - "options": "Operation", - "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": "operation", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Operation", + "options": "Operation", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break_4", - "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 - }, + "fieldname": "column_break_4", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fetch_if_empty": 0, - "fieldname": "posting_date", - "fieldtype": "Date", - "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": "Posting Date", - "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": "Today", + "fieldname": "posting_date", + "fieldtype": "Date", + "label": "Posting Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "company", - "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": "Company", - "length": 0, - "no_copy": 0, - "options": "Company", - "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": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "for_quantity", - "fieldtype": "Float", - "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": "For 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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "for_quantity", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Qty To Manufacture", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "wip_warehouse", - "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": "WIP Warehouse", - "length": 0, - "no_copy": 0, - "options": "Warehouse", - "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": "wip_warehouse", + "fieldtype": "Link", + "label": "WIP Warehouse", + "options": "Warehouse", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "timing_detail", - "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": "Timing Detail", - "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": "timing_detail", + "fieldtype": "Section Break", + "label": "Timing Detail" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "employee", - "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": "Employee", - "length": 0, - "no_copy": 0, - "options": "Employee", - "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": "employee", + "fieldtype": "Link", + "in_standard_filter": 1, + "label": "Employee", + "options": "Employee" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "time_logs", - "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 Logs", - "length": 0, - "no_copy": 0, - "options": "Job Card Time Log", - "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_logs", + "fieldtype": "Table", + "label": "Time Logs", + "options": "Job Card Time Log" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "section_break_13", - "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": "section_break_13", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "total_completed_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": "Total Completed Qty", - "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 - }, + "fieldname": "total_completed_qty", + "fieldtype": "Float", + "label": "Total Completed Qty", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break_15", - "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 - }, + "fieldname": "column_break_15", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "total_time_in_mins", - "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": "Total Time in Mins", - "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 - }, + "fieldname": "total_time_in_mins", + "fieldtype": "Float", + "label": "Total Time in Mins", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "section_break_8", - "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": "Raw Materials", - "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": "section_break_8", + "fieldtype": "Section Break", + "label": "Raw Materials" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "items", - "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": "Items", - "length": 0, - "no_copy": 0, - "options": "Job Card 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 - }, + "fieldname": "items", + "fieldtype": "Table", + "label": "Items", + "options": "Job Card Item", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "more_information", - "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 Information", - "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": "more_information", + "fieldtype": "Section Break", + "label": "More Information" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "operation_id", - "fieldtype": "Data", - "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": "Operation ID", - "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 - }, + "fieldname": "operation_id", + "fieldtype": "Data", + "hidden": 1, + "label": "Operation ID", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fetch_if_empty": 0, - "fieldname": "transferred_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": "Transferred Qty", - "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 - }, + "default": "0", + "fieldname": "transferred_qty", + "fieldtype": "Float", + "label": "Transferred Qty", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fetch_if_empty": 0, - "fieldname": "requested_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": "Requested Qty", - "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 - }, + "default": "0", + "fieldname": "requested_qty", + "fieldtype": "Float", + "label": "Requested Qty", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "project", - "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": "Project", - "length": 0, - "no_copy": 0, - "options": "Project", - "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": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "remarks", - "fieldtype": "Small Text", - "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": "Remarks", - "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": "remarks", + "fieldtype": "Small Text", + "label": "Remarks" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break_20", - "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 - }, + "fieldname": "column_break_20", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Open", - "fetch_if_empty": 0, - "fieldname": "status", - "fieldtype": "Select", - "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": "Status", - "length": 0, - "no_copy": 1, - "options": "Open\nWork In Progress\nMaterial Transferred\nSubmitted\nCancelled\nCompleted", - "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 - }, + "default": "Open", + "fieldname": "status", + "fieldtype": "Select", + "label": "Status", + "no_copy": 1, + "options": "Open\nWork In Progress\nMaterial Transferred\nOn Hold\nSubmitted\nCancelled\nCompleted", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "job_started", - "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": "Job Started", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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 - }, + "default": "0", + "fieldname": "job_started", + "fieldtype": "Check", + "hidden": 1, + "label": "Job Started", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "started_time", - "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": "Started Time", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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 - }, + "fieldname": "started_time", + "fieldtype": "Datetime", + "hidden": 1, + "label": "Started Time", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "amended_from", - "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": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Job Card", - "permlevel": 0, - "print_hide": 1, - "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 + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Job Card", + "print_hide": 1, + "read_only": 1 + }, + { + "default": "PO-JOB.#####", + "fieldname": "naming_series", + "fieldtype": "Select", + "label": "Naming Series", + "options": "PO-JOB.#####", + "reqd": 1 + }, + { + "fetch_from": "employee.employee_name", + "fieldname": "employee_name", + "fieldtype": "Read Only", + "label": "Employee Name" + }, + { + "fieldname": "production_section", + "fieldtype": "Section Break", + "label": "Production" + }, + { + "fieldname": "column_break_12", + "fieldtype": "Column Break" + }, + { + "fetch_from": "work_order.production_item", + "fieldname": "production_item", + "fieldtype": "Read Only", + "label": "Production Item" + }, + { + "fieldname": "barcode", + "fieldtype": "Barcode", + "label": "Barcode", + "read_only": 1 + }, + { + "fetch_from": "work_order.item_name", + "fieldname": "item_name", + "fieldtype": "Read Only", + "label": "Item Name" + }, + { + "fieldname": "current_time", + "fieldtype": "Int", + "hidden": 1, + "label": "Current Time", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-03-10 17:38:37.499871", - "modified_by": "Administrator", - "module": "Manufacturing", - "name": "Job Card", - "name_case": "", - "owner": "Administrator", + ], + "is_submittable": 1, + "modified": "2020-03-24 13:08:57.926201", + "modified_by": "Administrator", + "module": "Manufacturing", + "name": "Job Card", + "owner": "Administrator", "permissions": [ { "amend": 1, diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index 9d2e620e584..eec7d242871 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import flt, time_diff_in_hours, get_datetime +from frappe.utils import flt, time_diff_in_hours, get_datetime, time_diff from frappe.model.mapper import get_mapped_doc from frappe.model.document import Document @@ -95,8 +95,9 @@ class JobCard(Document): 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: - frappe.throw(_("Total completed qty can not be greater than for quantity")) + if 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)))) def update_work_order(self): if not self.work_order: @@ -172,6 +173,8 @@ class JobCard(Document): self.set_status(update_status) def set_status(self, update_status=False): + if self.status == "On Hold": return + self.status = { 0: "Open", 1: "Submitted", @@ -230,6 +233,7 @@ def make_stock_entry(source_name, target_doc=None): target.fg_completed_qty = source.get('for_quantity', 0) - source.get('transferred_qty', 0) target.calculate_rate_and_amount() target.set_missing_values() + target.set_stock_entry_type() doclist = get_mapped_doc("Job Card", source_name, { "Job Card": { @@ -251,3 +255,48 @@ def make_stock_entry(source_name, target_doc=None): }, target_doc, set_missing_values) return doclist + +def time_diff_in_minutes(string_ed_date, string_st_date): + return time_diff(string_ed_date, string_st_date).total_seconds() / 60 + +@frappe.whitelist() +def get_job_details(start, end, filters=None): + events = [] + + event_color = { + "Completed": "#cdf5a6", + "Material Transferred": "#ffdd9e", + "Work In Progress": "#D3D3D3" + } + + from frappe.desk.reportview import get_filters_cond + conditions = get_filters_cond("Job Card", filters, []) + + job_cards = frappe.db.sql(""" SELECT `tabJob Card`.name, `tabJob Card`.work_order, + `tabJob Card`.employee_name, `tabJob Card`.status, ifnull(`tabJob Card`.remarks, ''), + min(`tabJob Card Time Log`.from_time) as from_time, + max(`tabJob Card Time Log`.to_time) as to_time + FROM `tabJob Card` , `tabJob Card Time Log` + WHERE + `tabJob Card`.name = `tabJob Card Time Log`.parent {0} + group by `tabJob Card`.name""".format(conditions), as_dict=1) + + for d in job_cards: + subject_data = [] + for field in ["name", "work_order", "remarks", "employee_name"]: + if not d.get(field): continue + + subject_data.append(d.get(field)) + + color = event_color.get(d.status) + job_card_data = { + 'from_time': d.from_time, + 'to_time': d.to_time, + 'name': d.name, + 'subject': '\n'.join(subject_data), + 'color': color if color else "#89bcde" + } + + events.append(job_card_data) + + return events diff --git a/erpnext/manufacturing/doctype/job_card/job_card_calendar.js b/erpnext/manufacturing/doctype/job_card/job_card_calendar.js new file mode 100644 index 00000000000..cf07698ad6a --- /dev/null +++ b/erpnext/manufacturing/doctype/job_card/job_card_calendar.js @@ -0,0 +1,21 @@ +frappe.views.calendar["Job Card"] = { + field_map: { + "start": "from_time", + "end": "to_time", + "id": "name", + "title": "subject", + "color": "color", + "allDay": "allDay", + "progress": "progress" + }, + gantt: true, + filters: [ + { + "fieldtype": "Link", + "fieldname": "employee", + "options": "Employee", + "label": __("Employee") + } + ], + get_events_method: "erpnext.manufacturing.doctype.job_card.job_card.get_job_details" +}; diff --git a/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json index 2aab71dee4f..9dd54dd6182 100644 --- a/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json +++ b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json @@ -1,208 +1,57 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2019-03-08 23:56:43.187569", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "creation": "2019-03-08 23:56:43.187569", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "from_time", + "to_time", + "column_break_2", + "time_in_mins", + "completed_qty" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "from_time", - "fieldtype": "Datetime", - "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": "From Time", - "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": "from_time", + "fieldtype": "Datetime", + "in_list_view": 1, + "label": "From Time" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "to_time", - "fieldtype": "Datetime", - "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": "To Time", - "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": "to_time", + "fieldtype": "Datetime", + "in_list_view": 1, + "label": "To Time" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 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 - }, + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "time_in_mins", - "fieldtype": "Float", - "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 In Mins", - "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 - }, + "fieldname": "time_in_mins", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Time In Mins", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fetch_if_empty": 0, - "fieldname": "completed_qty", - "fieldtype": "Float", - "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": "Completed Qty", - "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 + "default": "0", + "fieldname": "completed_qty", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Completed Qty", + "reqd": 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": 1, - "max_attachments": 0, - "modified": "2019-03-10 17:08:46.504910", - "modified_by": "Administrator", - "module": "Manufacturing", - "name": "Job Card Time Log", - "name_case": "", - "owner": "Administrator", - "permissions": [], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "ASC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + ], + "istable": 1, + "modified": "2019-12-03 12:56:02.285448", + "modified_by": "Administrator", + "module": "Manufacturing", + "name": "Job Card Time Log", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "ASC", + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index 3b24d0fa0ff..2b168d1d76d 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -71,12 +71,13 @@ frappe.ui.form.on('Production Plan', { }, __('Create')); } + frm.page.set_inner_btn_group_as_primary(__('Create')); frm.trigger("material_requirement"); const projected_qty_formula = ` + {%= format_currency(data[i]["invoiced"], data[0]["currency"] ) %} {% if(!filters.show_future_payments) { %} - + {%= format_currency(data[i]["paid"], data[0]["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"] %} {% } %} - - + + {% } %} {% } %} {% } else { %} @@ -256,10 +256,10 @@ {% } else { %} {% } %} - - - - + + + + {% } %} {% } %} From cf2ab9b129afbf017d2ee222028c2bdacc1e8ab7 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 27 Mar 2020 20:43:17 +0530 Subject: [PATCH 040/104] fix: use setup from Supplier Quotation Controller --- .../supplier_quotation/supplier_quotation.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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(); From 728edacfd4231e9878b8b9d17ef55a20b7d6b3a6 Mon Sep 17 00:00:00 2001 From: Anupam K Date: Sat, 28 Mar 2020 13:48:42 +0530 Subject: [PATCH 041/104] bug: Item-wise Sales History - Billed amount --- .../report/item_wise_sales_history/item_wise_sales_history.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 }, { From 8f854c7d9397e5cd5038d0ab04dce4254577ba54 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 28 Mar 2020 14:56:45 +0530 Subject: [PATCH 042/104] fix: item code showing as mandatory even if the 'Item Naming By' is set as Naming Series in stock settings --- erpnext/public/js/utils/item_quick_entry.js | 7 +++++++ 1 file changed, 7 insertions(+) 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(); From f9ce7c2e18872cf2248ea1b0c156133cf712ff64 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Sat, 28 Mar 2020 19:12:59 +0530 Subject: [PATCH 043/104] chore: [ux] filter warehouse based on company --- erpnext/stock/report/stock_ledger/stock_ledger.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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", From 58351de79741c20bac9ba7d6e49c49f428ee72c4 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Sat, 28 Mar 2020 16:11:23 +0530 Subject: [PATCH 044/104] fix: payment request status fixes --- .../payment_request/payment_request.json | 1837 +++-------------- .../payment_request/payment_request.py | 8 +- .../payment_request/payment_request_list.js | 8 +- 3 files changed, 346 insertions(+), 1507 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index bff995ec5a5..97ae5ffde36 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -1,1560 +1,387 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "naming_series:", - "beta": 0, - "creation": "2015-12-15 22:23:24.745065", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 0, - "engine": "InnoDB", + "autoname": "naming_series:", + "creation": "2015-12-15 22:23:24.745065", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "payment_request_type", + "transaction_date", + "column_break_2", + "naming_series", + "mode_of_payment", + "party_details", + "party_type", + "party", + "column_break_4", + "reference_doctype", + "reference_name", + "transaction_details", + "grand_total", + "is_a_subscription", + "column_break_18", + "currency", + "subscription_section", + "subscription_plans", + "bank_account_details", + "bank_account", + "bank", + "bank_account_no", + "account", + "column_break_11", + "iban", + "branch_code", + "swift_number", + "recipient_and_message", + "print_format", + "email_to", + "subject", + "column_break_9", + "payment_gateway_account", + "status", + "make_sales_invoice", + "section_break_10", + "message", + "message_examples", + "mute_email", + "payment_url", + "section_break_7", + "payment_gateway", + "payment_account", + "payment_order", + "amended_from" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Inward", - "fieldname": "payment_request_type", - "fieldtype": "Select", - "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": "Payment Request Type", - "length": 0, - "no_copy": 0, - "options": "Outward\nInward", - "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": "Inward", + "fieldname": "payment_request_type", + "fieldtype": "Select", + "label": "Payment Request Type", + "options": "Outward\nInward", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "transaction_date", - "fieldtype": "Date", - "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": "Transaction Date", - "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": "transaction_date", + "fieldtype": "Date", + "label": "Transaction Date" + }, { - "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 - }, + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "naming_series", - "fieldtype": "Select", - "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": "Series", - "length": 0, - "no_copy": 1, - "options": "ACC-PRQ-.YYYY.-", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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": 1, - "translatable": 0, - "unique": 0 - }, + "fieldname": "naming_series", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Series", + "no_copy": 1, + "options": "ACC-PRQ-.YYYY.-", + "print_hide": 1, + "reqd": 1, + "set_only_once": 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 - }, + "fieldname": "mode_of_payment", + "fieldtype": "Link", + "label": "Mode of Payment", + "options": "Mode of Payment" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "party_details", - "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": "Party 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 - }, + "fieldname": "party_details", + "fieldtype": "Section Break", + "label": "Party Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "party_type", - "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": "Party Type", - "length": 0, - "no_copy": 0, - "options": "DocType", - "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": "party_type", + "fieldtype": "Link", + "label": "Party Type", + "options": "DocType" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "party", - "fieldtype": "Dynamic 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": "Party", - "length": 0, - "no_copy": 0, - "options": "party_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": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "party", + "fieldtype": "Dynamic Link", + "label": "Party", + "options": "party_type" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_4", - "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 - }, + "fieldname": "column_break_4", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "reference_doctype", - "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": 1, - "label": "Reference Doctype", - "length": 0, - "no_copy": 1, - "options": "DocType", - "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 - }, + "fieldname": "reference_doctype", + "fieldtype": "Link", + "in_standard_filter": 1, + "label": "Reference Doctype", + "no_copy": 1, + "options": "DocType", + "print_hide": 1, + "read_only": 1, + "report_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "reference_name", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Reference Name", - "length": 0, - "no_copy": 1, - "options": "reference_doctype", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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 - }, + "fieldname": "reference_name", + "fieldtype": "Dynamic Link", + "in_global_search": 1, + "in_standard_filter": 1, + "label": "Reference Name", + "no_copy": 1, + "options": "reference_doctype", + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "transaction_details", - "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": "Transaction 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 - }, + "fieldname": "transaction_details", + "fieldtype": "Section Break", + "label": "Transaction Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Amount in customer's currency", - "fieldname": "grand_total", - "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": "Amount", - "length": 0, - "no_copy": 0, - "options": "currency", - "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 - }, + "description": "Amount in customer's currency", + "fieldname": "grand_total", + "fieldtype": "Currency", + "label": "Amount", + "options": "currency" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "is_a_subscription", - "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 a Subscription", - "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_a_subscription", + "fieldtype": "Check", + "label": "Is a Subscription" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_18", - "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 - }, + "fieldname": "column_break_18", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "currency", - "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": "Transaction Currency", - "length": 0, - "no_copy": 0, - "options": "Currency", - "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 - }, + "fieldname": "currency", + "fieldtype": "Link", + "label": "Transaction Currency", + "options": "Currency", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": "", - "columns": 0, - "depends_on": "eval:doc.is_a_subscription", - "fieldname": "subscription_section", - "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": "Subscription Section", - "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": "eval:doc.is_a_subscription", + "fieldname": "subscription_section", + "fieldtype": "Section Break", + "label": "Subscription Section" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "subscription_plans", - "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": "Subscription Plans", - "length": 0, - "no_copy": 0, - "options": "Subscription Plan Detail", - "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": "subscription_plans", + "fieldtype": "Table", + "label": "Subscription Plans", + "options": "Subscription Plan Detail" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "bank_account_details", - "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": "Bank Account 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 - }, + "collapsible": 1, + "fieldname": "bank_account_details", + "fieldtype": "Section Break", + "label": "Bank Account Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "bank_account", - "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": "Bank Account", - "length": 0, - "no_copy": 0, - "options": "Bank Account", - "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": "bank_account", + "fieldtype": "Link", + "label": "Bank Account", + "options": "Bank Account" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "bank_account.bank", - "fieldname": "bank", - "fieldtype": "Read Only", - "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": "Bank", - "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 - }, + "fetch_from": "bank_account.bank", + "fieldname": "bank", + "fieldtype": "Read Only", + "label": "Bank" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "bank_account.bank_account_no", - "fieldname": "bank_account_no", - "fieldtype": "Read Only", - "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": "Bank Account No", - "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 - }, + "fetch_from": "bank_account.bank_account_no", + "fieldname": "bank_account_no", + "fieldtype": "Read Only", + "label": "Bank Account No" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "bank_account.account", - "fieldname": "account", - "fieldtype": "Read Only", - "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": "Account", - "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 - }, + "fetch_from": "bank_account.account", + "fieldname": "account", + "fieldtype": "Read Only", + "label": "Account" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_11", - "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 - }, + "fieldname": "column_break_11", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "bank_account.iban", - "fieldname": "iban", - "fieldtype": "Read Only", - "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": "IBAN", - "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": "bank_account.iban", + "fieldname": "iban", + "fieldtype": "Read Only", + "label": "IBAN" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "bank_account.branch_code", - "fieldname": "branch_code", - "fieldtype": "Read Only", - "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": "Branch Code", - "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 - }, + "fetch_from": "bank_account.branch_code", + "fieldname": "branch_code", + "fieldtype": "Read Only", + "label": "Branch Code" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "bank_account.swift_number", - "fieldname": "swift_number", - "fieldtype": "Read Only", - "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": "SWIFT Number", - "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 - }, + "fetch_from": "bank_account.swift_number", + "fieldname": "swift_number", + "fieldtype": "Read Only", + "label": "SWIFT Number" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval: doc.payment_request_type == 'Inward'", - "fieldname": "recipient_and_message", - "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": "Recipient Message And Payment 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 - }, + "depends_on": "eval: doc.payment_request_type == 'Inward'", + "fieldname": "recipient_and_message", + "fieldtype": "Section Break", + "label": "Recipient Message And Payment Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "print_format", - "fieldtype": "Select", - "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": "Print Format", - "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": "print_format", + "fieldtype": "Select", + "label": "Print Format" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "email_to", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "To", - "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": "email_to", + "fieldtype": "Data", + "in_global_search": 1, + "label": "To" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "subject", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 1, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Subject", - "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": "subject", + "fieldtype": "Data", + "in_global_search": 1, + "label": "Subject" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_9", - "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 - }, + "fieldname": "column_break_9", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval: doc.payment_request_type == 'Inward'", - "fieldname": "payment_gateway_account", - "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": "Payment Gateway Account", - "length": 0, - "no_copy": 0, - "options": "Payment Gateway Account", - "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": "eval: doc.payment_request_type == 'Inward'", + "fieldname": "payment_gateway_account", + "fieldtype": "Link", + "label": "Payment Gateway Account", + "options": "Payment Gateway Account" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Draft", - "fieldname": "status", - "fieldtype": "Select", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Status", - "length": 0, - "no_copy": 0, - "options": "\nDraft\nInitiated\nPayment Ordered\nPaid\nFailed\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": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "Draft", + "fieldname": "status", + "fieldtype": "Select", + "hidden": 1, + "in_standard_filter": 1, + "label": "Status", + "options": "\nDraft\nRequested\nInitiated\nPartially Paid\nPayment Ordered\nPaid\nFailed\nCancelled", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.reference_doctype==\"Sales Order\"", - "fieldname": "make_sales_invoice", - "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": "Make Sales Invoice", - "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 - }, + "default": "0", + "depends_on": "eval:doc.reference_doctype==\"Sales Order\"", + "fieldname": "make_sales_invoice", + "fieldtype": "Check", + "hidden": 1, + "label": "Make Sales Invoice", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval: doc.payment_request_type == 'Inward'", - "fieldname": "section_break_10", - "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 - }, + "depends_on": "eval: doc.payment_request_type == 'Inward'", + "fieldname": "section_break_10", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "message", - "fieldtype": "Text", - "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": "Message", - "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": "message", + "fieldtype": "Text", + "label": "Message" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "message_examples", - "fieldtype": "HTML", - "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": "Message Examples", - "length": 0, - "no_copy": 0, - "options": "
Message Example
\n\n<p>Dear {{ doc.contact_person }},</p>\n\n<p>Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.</p>\n\n<a href=\"{{ payment_url }}\"> click here to pay </a>\n\n
\n", - "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 - }, + "fieldname": "message_examples", + "fieldtype": "HTML", + "label": "Message Examples", + "options": "
Message Example
\n\n<p>Dear {{ doc.contact_person }},</p>\n\n<p>Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.</p>\n\n<a href=\"{{ payment_url }}\"> click here to pay </a>\n\n
\n", + "print_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "mute_email", - "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": "Mute Email", - "length": 0, - "no_copy": 1, - "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 - }, + "default": "0", + "fieldname": "mute_email", + "fieldtype": "Check", + "hidden": 1, + "label": "Mute Email", + "no_copy": 1, + "print_hide": 1, + "read_only": 1, + "report_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "payment_url", - "fieldtype": "Small Text", - "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": "payment_url", - "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 - }, + "fieldname": "payment_url", + "fieldtype": "Small Text", + "hidden": 1, + "label": "payment_url", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "doc.payment_gateway_account", - "columns": 0, - "depends_on": "eval: doc.payment_request_type == 'Inward'", - "fieldname": "section_break_7", - "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": "Payment Gateway 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 - }, + "collapsible": 1, + "collapsible_depends_on": "doc.payment_gateway_account", + "depends_on": "eval: doc.payment_request_type == 'Inward'", + "fieldname": "section_break_7", + "fieldtype": "Section Break", + "label": "Payment Gateway Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "payment_gateway_account.payment_gateway", - "fieldname": "payment_gateway", - "fieldtype": "Read Only", - "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": "Payment Gateway", - "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 - }, + "fetch_from": "payment_gateway_account.payment_gateway", + "fieldname": "payment_gateway", + "fieldtype": "Read Only", + "label": "Payment Gateway" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "payment_gateway_account.payment_account", - "fieldname": "payment_account", - "fieldtype": "Read Only", - "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": "Payment Account", - "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 - }, + "fetch_from": "payment_gateway_account.payment_account", + "fieldname": "payment_account", + "fieldtype": "Read Only", + "label": "Payment Account", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "payment_order", - "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": "Payment Order", - "length": 0, - "no_copy": 0, - "options": "Payment Order", - "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 - }, + "fieldname": "payment_order", + "fieldtype": "Link", + "label": "Payment Order", + "options": "Payment Order", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "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": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Payment Request", - "permlevel": 0, - "print_hide": 1, - "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 + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Payment Request", + "print_hide": 1, + "read_only": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-02-18 18:52:34.203239", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Payment Request", - "name_case": "", - "owner": "Administrator", + ], + "is_submittable": 1, + "modified": "2020-03-28 16:07:31.960798", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Payment Request", + "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": "Accounts User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "share": 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": "Accounts 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": "Accounts Manager", + "share": 1, + "submit": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + ], + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 6b74f477f2b..b18a938fbb0 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -66,6 +66,8 @@ class PaymentRequest(Document): if self.payment_request_type == 'Outward': self.db_set('status', 'Initiated') return + elif self.payment_request_type == 'Inward': + self.db_set('status', 'Requested') send_mail = self.payment_gateway_validation() ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) @@ -422,10 +424,14 @@ def make_status_as_paid(doc, method): "docstatus": 1}) if payment_request_name: + outstanding_amt = frappe.get_value(ref.reference_doctype, ref.reference_name, 'outstanding_amount') doc = frappe.get_doc("Payment Request", payment_request_name) - if doc.status != "Paid": + if doc.status != "Paid" and outstanding_amt <= 0: doc.db_set('status', 'Paid') frappe.db.commit() + elif doc.status != "Partially Paid" and outstanding_amt != doc.grand_total: + doc.db_set('status', 'Partially Paid') + frappe.db.commit() def get_dummy_message(doc): return frappe.render_template("""{% if doc.contact_person -%} diff --git a/erpnext/accounts/doctype/payment_request/payment_request_list.js b/erpnext/accounts/doctype/payment_request/payment_request_list.js index 0caf1c2f7ff..72833d235f8 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request_list.js +++ b/erpnext/accounts/doctype/payment_request/payment_request_list.js @@ -4,14 +4,20 @@ frappe.listview_settings['Payment Request'] = { if(doc.status == "Draft") { return [__("Draft"), "darkgrey", "status,=,Draft"]; } + if(doc.status == "Requested") { + return [__("Requested"), "green", "status,=,Requested"]; + } else if(doc.status == "Initiated") { return [__("Initiated"), "green", "status,=,Initiated"]; } + else if(doc.status == "Partially Paid") { + return [__("Partially Paid"), "orange", "status,=,Partially Paid"]; + } else if(doc.status == "Paid") { return [__("Paid"), "blue", "status,=,Paid"]; } else if(doc.status == "Cancelled") { - return [__("Cancelled"), "orange", "status,=,Cancelled"]; + return [__("Cancelled"), "red", "status,=,Cancelled"]; } } } From 1125ed883039cc2eb3fc09333c0bde28b199505e Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Sat, 28 Mar 2020 16:39:22 +0530 Subject: [PATCH 045/104] fix: currency formatting in gl entry dr cr field --- erpnext/accounts/doctype/gl_entry/gl_entry.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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", From 8ba661b8edb54454e4351cfc416bdac56976aea3 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Sat, 28 Mar 2020 20:11:26 +0530 Subject: [PATCH 046/104] chore: hyperlinks in cannot cancel message --- erpnext/controllers/buying_controller.py | 2 +- erpnext/manufacturing/doctype/work_order/work_order.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index a47507eaf7b..61bd5032cee 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -731,7 +731,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 diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 83579414812..bd2ae6c36b1 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, { From dc04cbf9a98282bc8ff6bd87cb358be126911832 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Sun, 29 Mar 2020 12:52:16 +0530 Subject: [PATCH 047/104] fix: cannot view report for course doctype - permission problem --- erpnext/education/doctype/course/course.json | 26 +++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) 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", From 1dd0c8f54c005a223296076c28ab40fd20e2acce Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Sat, 28 Mar 2020 14:07:09 +0530 Subject: [PATCH 048/104] fix: customer group price list not fetched in pos --- .../accounts/doctype/sales_invoice/sales_invoice.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index fcddab40b8f..919af057ac1 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -429,13 +429,16 @@ 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') + + self.set('selling_price_list', selling_price_list) if not for_validate: self.update_stock = cint(pos.get("update_stock")) From 7e7787c298508dbb741403b9dc5a26c8d743ea2d Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sun, 29 Mar 2020 16:33:30 +0530 Subject: [PATCH 049/104] fix: not able to add equity account in the chart of accounts --- erpnext/accounts/doctype/account/account.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From 83111a4a2a05c2b9a493bf8f834534703a426c81 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:45:37 +0530 Subject: [PATCH 050/104] fix: Expense account currency validation in Landed Cost voucher (#21074) * fix: Expense account currency validation in Landed Cost voucher * fix: Remove unused imports --- erpnext/controllers/queries.py | 14 +++++++++----- .../landed_cost_voucher/landed_cost_voucher.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) 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/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")]) From f492ba1e2dff0843d2d0383bfd55c4b1bd056790 Mon Sep 17 00:00:00 2001 From: Saqib Date: Tue, 31 Mar 2020 10:48:57 +0530 Subject: [PATCH 051/104] fix: auto created asset message (#21109) * fix: auto created asset message * Update erpnext/controllers/buying_controller.py Co-authored-by: Nabin Hait --- erpnext/controllers/buying_controller.py | 33 +++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 61bd5032cee..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: @@ -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 From d13e7d00b0b07e8c4be404dd2fbfe96ca769645c Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Tue, 31 Mar 2020 10:50:53 +0530 Subject: [PATCH 052/104] fix: email_to, party_type and party are not set in payment request (#21085) * fix: email_to, party_type and party are not set in payment request when order made from portal * fix: email_to, party_type and party are not set in payment request when order made from portal Co-authored-by: Anupam K --- erpnext/accounts/doctype/payment_request/payment_request.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 }) From b80213d65dbc34e137ca48225d24094ce122a607 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Tue, 31 Mar 2020 10:52:51 +0530 Subject: [PATCH 053/104] fix: Healthcare Domain Issues (#21112) * fix (Lab Test): None TypeError in Patient Medical Record * fix: Lab Test Template data import failing in Lab Test Item creation * fix: disabled Procedure Template shown as enabled in List View * fix: change item_code from Link to Data to avoid item not found error * fix: disabled patient shown as enabled * fix: disabled practitioner schedule shown as enabled in list view * fix: appointment reminders not working * fix: Batch not getting fetched in Clinical Procedure Item --- .../clinical_procedure/clinical_procedure.js | 20 +- .../clinical_procedure_template.js | 33 +- .../clinical_procedure_template.json | 969 ++++------------- .../clinical_procedure_template.py | 100 +- .../healthcare_settings.json | 1 + .../healthcare/doctype/lab_test/lab_test.py | 14 +- .../lab_test_template/lab_test_template.py | 7 +- erpnext/healthcare/doctype/patient/patient.js | 2 +- .../healthcare/doctype/patient/patient.json | 26 +- erpnext/healthcare/doctype/patient/patient.py | 6 +- .../patient_appointment.js | 15 +- .../patient_appointment.json | 993 ++---------------- .../patient_appointment.py | 36 +- .../patient_encounter/patient_encounter.js | 2 +- .../practitioner_schedule.json | 209 ++-- erpnext/hooks.py | 4 +- 16 files changed, 451 insertions(+), 1986 deletions(-) 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', From e4cb523181ce36250b090ffd720c90059649a220 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 31 Mar 2020 15:26:24 +0530 Subject: [PATCH 054/104] fix: serial no scan not adding the serial nos in stock entry (#21082) --- erpnext/public/js/controllers/transaction.js | 7 ++++++- .../stock/doctype/stock_entry/stock_entry.js | 17 +++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) 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/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); + } } } }); From c5a3bcca70fa2657064c55408ed04f6828348e14 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 31 Mar 2020 15:28:15 +0530 Subject: [PATCH 055/104] fix: make for quantity as non mandatory in job card (#21080) --- erpnext/manufacturing/doctype/bom/bom.js | 1 + .../doctype/job_card/job_card.js | 14 ++- .../doctype/job_card/job_card.json | 111 ++++++++---------- .../doctype/job_card/job_card.py | 38 +++--- .../doctype/work_order/work_order.py | 3 +- 5 files changed, 80 insertions(+), 87 deletions(-) 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/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index bd2ae6c36b1..8a39f7420e9 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -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) From 798d532a11bf93f7a8e393308e4de425c2fb7d14 Mon Sep 17 00:00:00 2001 From: Saqib Date: Tue, 31 Mar 2020 15:30:53 +0530 Subject: [PATCH 056/104] =?UTF-8?q?fix:=20warehouse=5Faccount=5Fmap=20not?= =?UTF-8?q?=20getting=20reset=20for=20diff=20company=20transac=E2=80=A6=20?= =?UTF-8?q?(#20997)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: warehouse_account_map not getting reset for diff company transaction * fix: potential key errors while fetching warehouse_account_map * fix: travis Co-authored-by: Nabin Hait --- erpnext/stock/__init__.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) 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 From 0541b2ee27280f79c61a4b2a6a42a851486c7ae3 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 31 Mar 2020 18:44:02 +0530 Subject: [PATCH 057/104] fix: travis --- erpnext/accounts/doctype/payment_request/payment_request.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index b18a938fbb0..9c74de4af61 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -424,12 +424,11 @@ def make_status_as_paid(doc, method): "docstatus": 1}) if payment_request_name: - outstanding_amt = frappe.get_value(ref.reference_doctype, ref.reference_name, 'outstanding_amount') doc = frappe.get_doc("Payment Request", payment_request_name) - if doc.status != "Paid" and outstanding_amt <= 0: + if doc.status != "Paid" and ref.outstanding_amount <= ref.allocated_amount: doc.db_set('status', 'Paid') frappe.db.commit() - elif doc.status != "Partially Paid" and outstanding_amt != doc.grand_total: + elif doc.status != "Partially Paid" and ref.outstanding_amount != ref.allocated_amount: doc.db_set('status', 'Partially Paid') frappe.db.commit() From 954276ff0e65075af239434c51fa576d8b1e3dc3 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 31 Mar 2020 18:48:35 +0530 Subject: [PATCH 058/104] fix: check if selling price exists then set it --- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 919af057ac1..eda80246cdb 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -438,7 +438,8 @@ class SalesInvoice(SellingController): selling_price_list = customer_price_list or customer_group_price_list or pos.get('selling_price_list') - self.set('selling_price_list', 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")) From 122049a9b4aa3902b27d222a2c80b17b7c9e201d Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 1 Apr 2020 11:04:14 +0530 Subject: [PATCH 059/104] fix: Typo in stock level validation in Stock Ledger --- erpnext/stock/stock_ledger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From a66da0ddf4f6d3d749a65d628efb7444b596cb24 Mon Sep 17 00:00:00 2001 From: Anupam K Date: Thu, 2 Apr 2020 01:06:30 +0530 Subject: [PATCH 060/104] Sum of years not needed. --- .../customer_acquisition_and_loyalty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..aabc503a1ba 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 @@ -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([str(year), calendar.month_name[month], new[0], repeat[0], new[0] + repeat[0], new[1], repeat[1], new[1] + repeat[1]]) From 29fc06376496be58b24b655c19856d52ba4ad328 Mon Sep 17 00:00:00 2001 From: Anupam K Date: Thu, 2 Apr 2020 11:34:42 +0530 Subject: [PATCH 061/104] Sum of years not needed. --- .../customer_acquisition_and_loyalty.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 aabc503a1ba..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([str(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]]) From 763aab330126267c443da6453e4b3ea3120f6333 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 2 Apr 2020 19:12:36 +0530 Subject: [PATCH 062/104] fix: Travis --- .../doctype/purchase_invoice_item/purchase_invoice_item.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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", From 4a59b1d3b5298aafc03bebb22f7ec3a0596dd6eb Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 2 Apr 2020 19:36:21 +0530 Subject: [PATCH 063/104] fix: Fixed Test Cases for Material Request - Reduce quantity on Material Transfer/Issue - No effect on Customer Provided Material Request --- .../material_request/test_material_request.py | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/erpnext/stock/doctype/material_request/test_material_request.py b/erpnext/stock/doctype/material_request/test_material_request.py index 79cdc1ad18a..b925aedd1ac 100644 --- a/erpnext/stock/doctype/material_request/test_material_request.py +++ b/erpnext/stock/doctype/material_request/test_material_request.py @@ -276,8 +276,8 @@ class TestMaterialRequest(unittest.TestCase): current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC") current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC") - self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0) - self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0) + self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0) + self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0) from erpnext.stock.doctype.material_request.material_request import make_stock_entry @@ -331,8 +331,8 @@ class TestMaterialRequest(unittest.TestCase): current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC") current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC") - self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 27.0) - self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 1.5) + self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 27.0) + self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 1.5) # check if per complete is as expected for Stock Entry cancelled se.cancel() @@ -344,8 +344,8 @@ class TestMaterialRequest(unittest.TestCase): current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC") current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC") - self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0) - self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0) + self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0) + self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0) def test_completed_qty_for_over_transfer(self): existing_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC") @@ -425,8 +425,8 @@ class TestMaterialRequest(unittest.TestCase): current_requested_qty_item1 = self._get_requested_qty("_Test Item Home Desktop 100", "_Test Warehouse - _TC") current_requested_qty_item2 = self._get_requested_qty("_Test Item Home Desktop 200", "_Test Warehouse - _TC") - self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 + 54.0) - self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 + 3.0) + self.assertEqual(current_requested_qty_item1, existing_requested_qty_item1 - 54.0) + self.assertEqual(current_requested_qty_item2, existing_requested_qty_item2 - 3.0) def test_incorrect_mapping_of_stock_entry(self): # submit material request of type Transfer @@ -512,7 +512,7 @@ class TestMaterialRequest(unittest.TestCase): mr.submit() #testing bin value after material request is submitted - self.assertEqual(_get_requested_qty(), existing_requested_qty + 54.0) + self.assertEqual(_get_requested_qty(), existing_requested_qty - 54.0) # receive items to allow issue self._insert_stock_entry(60, 6, "_Test Warehouse - _TC") @@ -609,6 +609,8 @@ class TestMaterialRequest(unittest.TestCase): def test_customer_provided_parts_mr(self): from erpnext.stock.doctype.material_request.material_request import make_stock_entry create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0) + existing_requested_qty = self._get_requested_qty("_Test Customer", "_Test Warehouse - _TC") + mr = make_material_request(item_code='CUST-0987', material_request_type='Customer Provided') se = make_stock_entry(mr.name) se.insert() @@ -617,7 +619,10 @@ class TestMaterialRequest(unittest.TestCase): self.assertEqual(se.get("items")[0].material_request, mr.name) mr = frappe.get_doc("Material Request", mr.name) mr.submit() + current_requested_qty = self._get_requested_qty("_Test Customer", "_Test Warehouse - _TC") + self.assertEqual(mr.per_ordered, 100) + self.assertEqual(existing_requested_qty, current_requested_qty) def make_material_request(**args): args = frappe._dict(args) From f8cb81c9f9c98653d1f4becff7432842225b6e83 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 2 Apr 2020 19:57:11 +0530 Subject: [PATCH 064/104] fix (tests): reload doctype --- erpnext/patches.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index de4c89c5ace..176e309ce24 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -627,10 +627,11 @@ erpnext.patches.v12_0.update_ewaybill_field_position erpnext.patches.v12_0.create_accounting_dimensions_in_missing_doctypes erpnext.patches.v11_1.set_status_for_material_request_type_manufacture erpnext.patches.v12_0.move_plaid_settings_to_doctype -execute:frappe.reload_doc('desk', 'doctype','dashboard_chart_link') -execute:frappe.reload_doc('desk', 'doctype','dashboard') -execute:frappe.reload_doc('desk', 'doctype','dashboard_chart_source') -execute:frappe.reload_doc('desk', 'doctype','dashboard_chart') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart_link') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart_source') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart') +execute:frappe.reload_doc('desk', 'doctype', 'dashboard_chart_field') erpnext.patches.v12_0.add_default_dashboards erpnext.patches.v12_0.remove_bank_remittance_custom_fields erpnext.patches.v12_0.generate_leave_ledger_entries From 44dbd98d90cd4726c6d5df308ec7456f73c6a746 Mon Sep 17 00:00:00 2001 From: Saqib Date: Fri, 3 Apr 2020 10:01:14 +0530 Subject: [PATCH 065/104] fix: cannot set warehouse on deleting all so items and updating them (#21079) * fix: cannot set warehouse on deleting all so items and updating them * fix: travis * fix: travis * fix: docname is editable in update items dialog Co-authored-by: Marica --- erpnext/controllers/accounts_controller.py | 15 +++--- erpnext/public/js/utils.js | 3 +- erpnext/stock/get_item_details.py | 60 ++++++++++++++-------- 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 5abe7366d0f..c17927a35c0 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -19,6 +19,7 @@ from erpnext.accounts.doctype.pricing_rule.utils import (apply_pricing_rule_on_t from erpnext.exceptions import InvalidCurrency from six import text_type from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions +from erpnext.stock.get_item_details import get_item_warehouse force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules") @@ -1126,16 +1127,16 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, """ Returns a Sales Order Item child item containing the default values """ - p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name) - child_item = frappe.new_doc('Sales Order Item', p_doctype, child_docname) + p_doc = frappe.get_doc(parent_doctype, parent_doctype_name) + child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname) item = frappe.get_doc("Item", item_code) child_item.item_code = item.item_code child_item.item_name = item.item_name child_item.description = item.description - child_item.reqd_by_date = p_doctype.delivery_date + child_item.reqd_by_date = p_doc.delivery_date child_item.uom = item.stock_uom child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0 - child_item.warehouse = p_doctype.set_warehouse or p_doctype.items[0].warehouse + child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True) return child_item @@ -1143,13 +1144,13 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna """ Returns a Purchase Order Item child item containing the default values """ - p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name) - child_item = frappe.new_doc('Purchase Order Item', p_doctype, child_docname) + p_doc = frappe.get_doc(parent_doctype, parent_doctype_name) + child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname) item = frappe.get_doc("Item", item_code) child_item.item_code = item.item_code child_item.item_name = item.item_name child_item.description = item.description - child_item.schedule_date = p_doctype.schedule_date + child_item.schedule_date = p_doc.schedule_date child_item.uom = item.stock_uom child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0 child_item.base_rate = 1 # Initiallize value will update in parent validation diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 98986f8bf1b..0a352648304 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -453,7 +453,8 @@ erpnext.utils.update_child_items = function(opts) { fields: [{ fieldtype:'Data', fieldname:"docname", - hidden: 0, + read_only: 1, + hidden: 1, }, { fieldtype:'Link', fieldname:"item_code", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index b76a9b064a6..d15a2597386 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -239,26 +239,13 @@ def get_basic_details(args, item, overwrite_warehouse=True): item_group_defaults = get_item_group_defaults(item.name, args.company) brand_defaults = get_brand_defaults(item.name, args.company) - if overwrite_warehouse or not args.warehouse: - warehouse = ( - args.get("set_warehouse") or - item_defaults.get("default_warehouse") or - item_group_defaults.get("default_warehouse") or - brand_defaults.get("default_warehouse") or - args.warehouse - ) - - if not warehouse: - defaults = frappe.defaults.get_defaults() or {} - warehouse_exists = frappe.db.exists("Warehouse", { - 'name': defaults.default_warehouse, - 'company': args.company - }) - if defaults.get("default_warehouse") and warehouse_exists: - warehouse = defaults.default_warehouse - - else: - warehouse = args.warehouse + defaults = frappe._dict({ + 'item_defaults': item_defaults, + 'item_group_defaults': item_group_defaults, + 'brand_defaults': brand_defaults + }) + + warehouse = get_item_warehouse(item, args, overwrite_warehouse, defaults) if args.get('doctype') == "Material Request" and not args.get('material_request_type'): args['material_request_type'] = frappe.db.get_value('Material Request', @@ -271,7 +258,7 @@ def get_basic_details(args, item, overwrite_warehouse=True): expense_account = get_asset_category_account(fieldname = "fixed_asset_account", item = args.item_code, company= args.company) #Set the UOM to the Default Sales UOM or Default Purchase UOM if configured in the Item Master - if not args.uom: + if not args.get('uom'): if args.get('doctype') in sales_doctypes: args.uom = item.sales_uom if item.sales_uom else item.stock_uom elif (args.get('doctype') in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']) or \ @@ -360,6 +347,37 @@ def get_basic_details(args, item, overwrite_warehouse=True): return out +def get_item_warehouse(item, args, overwrite_warehouse, defaults={}): + if not defaults: + defaults = frappe._dict({ + 'item_defaults' : get_item_defaults(item.name, args.company), + 'item_group_defaults' : get_item_group_defaults(item.name, args.company), + 'brand_defaults' : get_brand_defaults(item.name, args.company) + }) + + if overwrite_warehouse or not args.warehouse: + warehouse = ( + args.get("set_warehouse") or + defaults.item_defaults.get("default_warehouse") or + defaults.item_group_defaults.get("default_warehouse") or + defaults.brand_defaults.get("default_warehouse") or + args.get('warehouse') + ) + + if not warehouse: + defaults = frappe.defaults.get_defaults() or {} + warehouse_exists = frappe.db.exists("Warehouse", { + 'name': defaults.default_warehouse, + 'company': args.company + }) + if defaults.get("default_warehouse") and warehouse_exists: + warehouse = defaults.default_warehouse + + else: + warehouse = args.get('warehouse') + + return warehouse + def update_barcode_value(out): from erpnext.accounts.doctype.sales_invoice.pos import get_barcode_data barcode_data = get_barcode_data([out]) From 73bc29c011963a7f986d4879e6af565046c1816b Mon Sep 17 00:00:00 2001 From: Marica Date: Fri, 3 Apr 2020 10:06:39 +0530 Subject: [PATCH 066/104] fix: Update Received Qty in Material Request as per Stock UOM (#21055) * fix: Update Received Qty in Material Request as per Stock UOM * fix: Process each PR only once * fix: minor suggested changes Co-authored-by: Nabin Hait --- erpnext/patches.txt | 1 + ...ty_in_material_request_as_per_stock_uom.py | 30 +++++++++++++++++++ .../purchase_receipt/purchase_receipt.py | 8 ++--- 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index de4c89c5ace..9deb88f8967 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -651,3 +651,4 @@ erpnext.patches.v12_0.add_export_type_field_in_party_master erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22 erpnext.patches.v12_0.create_irs_1099_field_united_states erpnext.patches.v12_0.set_permission_einvoicing +erpnext.patches.v12_0.set_received_qty_in_material_request_as_per_stock_uom \ No newline at end of file diff --git a/erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py b/erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py new file mode 100644 index 00000000000..88c3e2e3024 --- /dev/null +++ b/erpnext/patches/v12_0/set_received_qty_in_material_request_as_per_stock_uom.py @@ -0,0 +1,30 @@ +from __future__ import unicode_literals +import frappe + +def execute(): + purchase_receipts = frappe.db.sql(""" + SELECT + parent from `tabPurchase Receipt Item` + WHERE + material_request is not null + AND docstatus=1 + """,as_dict=1) + + purchase_receipts = set([d.parent for d in purchase_receipts]) + + for pr in purchase_receipts: + doc = frappe.get_doc("Purchase Receipt", pr) + doc.status_updater = [ + { + 'source_dt': 'Purchase Receipt Item', + 'target_dt': 'Material Request Item', + 'join_field': 'material_request_item', + 'target_field': 'received_qty', + 'target_parent_dt': 'Material Request', + 'target_parent_field': 'per_received', + 'target_ref_field': 'stock_qty', + 'source_field': 'stock_qty', + 'percent_join_field': 'material_request' + } + ] + doc.update_qty() diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index fb123b9c1fa..f21c4ef8593 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -49,8 +49,8 @@ class PurchaseReceipt(BuyingController): 'target_field': 'received_qty', 'target_parent_dt': 'Material Request', 'target_parent_field': 'per_received', - 'target_ref_field': 'qty', - 'source_field': 'qty', + 'target_ref_field': 'stock_qty', + 'source_field': 'stock_qty', 'percent_join_field': 'material_request' }] if cint(self.is_return): @@ -349,7 +349,7 @@ class PurchaseReceipt(BuyingController): if warehouse_with_no_account: frappe.msgprint(_("No accounting entries for the following warehouses") + ": \n" + "\n".join(warehouse_with_no_account)) - + return process_gl_map(gl_entries) def get_asset_gl_entry(self, gl_entries): @@ -616,7 +616,7 @@ def get_item_account_wise_additional_cost(purchase_document): if not landed_cost_vouchers: return - + item_account_wise_cost = {} for lcv in landed_cost_vouchers: From 878e4cb3cedb9dbcd5831ae1f5553baef498ff87 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 3 Apr 2020 10:07:44 +0530 Subject: [PATCH 067/104] fix: lms quiz type error (#21153) --- erpnext/public/js/education/lms/quiz.js | 2 +- erpnext/www/lms/content.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/public/js/education/lms/quiz.js b/erpnext/public/js/education/lms/quiz.js index 52481291e02..91cbbf4d662 100644 --- a/erpnext/public/js/education/lms/quiz.js +++ b/erpnext/public/js/education/lms/quiz.js @@ -29,7 +29,7 @@ class Quiz { this.questions.push(question) this.wrapper.appendChild(question_wrapper); }) - if (data.activity.is_complete) { + if (data.activity && data.activity.is_complete) { this.disable() let indicator = 'red' let message = 'Your are not allowed to attempt the quiz again.' diff --git a/erpnext/www/lms/content.html b/erpnext/www/lms/content.html index 5607c0814d4..cdc71412c48 100644 --- a/erpnext/www/lms/content.html +++ b/erpnext/www/lms/content.html @@ -63,7 +63,7 @@
-

{{ content.name }} ({{ position + 1 }}/{{length}})

+

{{ content.name }} ({{ position + 1 }}/{{length}})

{% endmacro %} From 7b70679bf0005aa46ac5589c7d2e699b260bfb30 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 3 Apr 2020 15:46:48 +0530 Subject: [PATCH 068/104] fix: Mapping Customer Provided Material Request to Stock Entry - Fixed inability to map Material Request to Stock Entry - Commonified Customer Provided Item validation --- erpnext/controllers/stock_controller.py | 7 +++++++ erpnext/stock/doctype/delivery_note/delivery_note.py | 7 ------- erpnext/stock/doctype/material_request/material_request.py | 5 ++++- erpnext/stock/doctype/stock_entry/stock_entry.py | 5 +---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index c6d0c7c0a6e..f5c42b49927 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -21,6 +21,7 @@ class StockController(AccountsController): super(StockController, self).validate() self.validate_inspection() self.validate_serialized_batch() + self.validate_customer_provided_item() def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False): if self.docstatus == 2: @@ -368,6 +369,12 @@ class StockController(AccountsController): for blanket_order in blanket_orders: frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty() + def validate_customer_provided_item(self): + for d in self.get('items'): + # Customer Provided parts will have zero valuation rate + if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'): + d.allow_zero_valuation_rate = 1 + def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None, warehouse_account=None, company=None): def _delete_gl_entries(voucher_type, voucher_no): diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 3f74b54ce80..c72bb893fff 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -111,7 +111,6 @@ class DeliveryNote(SellingController): self.so_required() self.validate_proj_cust() self.check_sales_order_on_hold_or_close("against_sales_order") - self.validate_for_items() self.validate_warehouse() self.validate_uom_is_integer("stock_uom", "stock_qty") self.validate_uom_is_integer("uom", "qty") @@ -165,12 +164,6 @@ class DeliveryNote(SellingController): if not res: frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project)) - def validate_for_items(self): - for d in self.get('items'): - #Customer Provided parts will have zero valuation rate - if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'): - d.allow_zero_valuation_rate = 1 - def validate_warehouse(self): super(DeliveryNote, self).validate_warehouse() diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 78383e05a6f..c11f59fd81e 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -437,6 +437,9 @@ def make_stock_entry(source_name, target_doc=None): else: target.s_warehouse = obj.warehouse + if source_parent.material_request_type == "Customer Provided": + target.allow_zero_valuation_rate = 1 + def set_missing_values(source, target): target.purpose = source.material_request_type if source.job_card: @@ -454,7 +457,7 @@ def make_stock_entry(source_name, target_doc=None): "doctype": "Stock Entry", "validation": { "docstatus": ["=", 1], - "material_request_type": ["in", ["Material Transfer", "Material Issue"]] + "material_request_type": ["in", ["Material Transfer", "Material Issue", "Customer Provided"]] } }, "Material Request Item": { diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index b2384f1b4e9..58131ea76be 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -50,6 +50,7 @@ class StockEntry(StockController): self.validate_posting_time() self.validate_purpose() self.validate_item() + self.validate_customer_provided_item() self.validate_qty() self.set_transfer_qty() self.validate_uom_is_integer("uom", "qty") @@ -203,10 +204,6 @@ class StockEntry(StockController): frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code), frappe.MandatoryError) - #Customer Provided parts will have zero valuation rate - if frappe.db.get_value('Item', item.item_code, 'is_customer_provided_item'): - item.allow_zero_valuation_rate = 1 - def validate_qty(self): manufacture_purpose = ["Manufacture", "Material Consumption for Manufacture"] From 64ed25abfb34d91a423336d13848a5096e0b059c Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 3 Apr 2020 17:17:04 +0530 Subject: [PATCH 069/104] fix: TypeError for _ --- .../chart_of_accounts_importer/chart_of_accounts_importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py index 7f51b139de4..00311c4f66d 100644 --- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py +++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py @@ -108,7 +108,7 @@ def build_forest(data): error_messages = [] for i in data: - account_name, _, account_number, is_group, account_type, root_type = i + account_name, __, account_number, is_group, account_type, root_type = i if not account_name: error_messages.append("Row {0}: Please enter Account Name".format(line_no)) From dfe4d36e8d7fcc65d6445c11765a2430bb6ef997 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 3 Apr 2020 18:25:21 +0530 Subject: [PATCH 070/104] fix: Test Cases and block expense on outward entry - Throw error if rate present against Customer Provided Item in DN and SI - Added test cases for Sales Invoice and Delivery Note - Allow SI and DN with 0 rate in Test --- .../doctype/sales_invoice/test_sales_invoice.py | 12 +++++++++++- erpnext/controllers/stock_controller.py | 3 +++ .../doctype/delivery_note/test_delivery_note.py | 12 +++++++++++- .../stock/doctype/stock_entry/test_stock_entry.py | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 267e52a477b..ad0e9572497 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -1868,6 +1868,16 @@ class TestSalesInvoice(unittest.TestCase): item.taxes = [] item.save() + def test_customer_provided_parts_si(self): + create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0) + si = create_sales_invoice(item_code='CUST-0987', rate=0) + self.assertEqual(si.get("items")[0].allow_zero_valuation_rate, 1) + self.assertEqual(si.get("items")[0].amount, 0) + + # test if Sales Invoice with rate is allowed + si2 = create_sales_invoice(item_code='CUST-0987', do_not_save=True) + self.assertRaises(frappe.ValidationError, si2.save) + def create_sales_invoice(**args): si = frappe.new_doc("Sales Invoice") args = frappe._dict(args) @@ -1890,7 +1900,7 @@ def create_sales_invoice(**args): "gst_hsn_code": "999800", "warehouse": args.warehouse or "_Test Warehouse - _TC", "qty": args.qty or 1, - "rate": args.rate or 100, + "rate": args.rate if args.get("rate") is not None else 100, "income_account": args.income_account or "Sales - _TC", "expense_account": args.expense_account or "Cost of Goods Sold - _TC", "cost_center": args.cost_center or "_Test Cost Center - _TC", diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index f5c42b49927..5c09068a035 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -374,6 +374,9 @@ class StockController(AccountsController): # Customer Provided parts will have zero valuation rate if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'): d.allow_zero_valuation_rate = 1 + if d.parenttype in ["Delivery Note", "Sales Invoice"] and d.rate: + frappe.throw(_("Row #{0}: {1} cannot have {2} as it is a Customer Provided Item") + .format(d.idx, frappe.bold(d.item_code), frappe.bold("Rate"))) def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None, warehouse_account=None, company=None): diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index dc92c5c9ff2..47a72b21a69 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -21,6 +21,7 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation \ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order, create_dn_against_so from erpnext.accounts.doctype.account.test_account import get_inventory_account, create_account from erpnext.stock.doctype.warehouse.test_warehouse import get_warehouse +from erpnext.stock.doctype.item.test_item import create_item class TestDeliveryNote(unittest.TestCase): def setUp(self): @@ -433,6 +434,15 @@ class TestDeliveryNote(unittest.TestCase): update_delivery_note_status(dn.name, "Closed") self.assertEqual(frappe.db.get_value("Delivery Note", dn.name, "Status"), "Closed") + def test_customer_provided_parts_dn(self): + create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0) + dn = create_delivery_note(item_code='CUST-0987', rate=0) + self.assertEqual(dn.get("items")[0].allow_zero_valuation_rate, 1) + + # test if Delivery Note with rate is allowed against Customer Provided Item + dn2 = create_delivery_note(item_code='CUST-0987', do_not_save=True) + self.assertRaises(frappe.ValidationError, dn2.save) + def test_dn_billing_status_case1(self): # SO -> DN -> SI so = make_sales_order() @@ -671,7 +681,7 @@ def create_delivery_note(**args): "item_code": args.item or args.item_code or "_Test Item", "warehouse": args.warehouse or "_Test Warehouse - _TC", "qty": args.qty or 1, - "rate": args.rate or 100, + "rate": args.rate if args.get("rate") is not None else 100, "conversion_factor": 1.0, "allow_zero_valuation_rate": args.allow_zero_valuation_rate or 1, "expense_account": args.expense_account or "Cost of Goods Sold - _TC", diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index ee5f2370987..2afabe1480d 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -744,7 +744,7 @@ class TestStockEntry(unittest.TestCase): def test_customer_provided_parts_se(self): create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0) - se = make_stock_entry(item_code='CUST-0987', purporse = 'Material Receipt', qty=4, to_warehouse = "_Test Warehouse - _TC") + se = make_stock_entry(item_code='CUST-0987', purpose = 'Material Receipt', qty=4, to_warehouse = "_Test Warehouse - _TC") self.assertEqual(se.get("items")[0].allow_zero_valuation_rate, 1) self.assertEqual(se.get("items")[0].amount, 0) From dba4bd6f26c4f01d6b58f39ca51c03d0f0422ecc Mon Sep 17 00:00:00 2001 From: Saqib Date: Fri, 3 Apr 2020 19:36:00 +0530 Subject: [PATCH 071/104] fix: [ux] credit to & debit to error message (#21133) Co-authored-by: Nabin Hait --- .../doctype/purchase_invoice/purchase_invoice.py | 8 ++++++-- .../accounts/doctype/sales_invoice/sales_invoice.py | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 698c2ab333d..3933b5b1ee8 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -146,10 +146,14 @@ class PurchaseInvoice(BuyingController): ["account_type", "report_type", "account_currency"], as_dict=True) if account.report_type != "Balance Sheet": - frappe.throw(_("Credit To account must be a Balance Sheet account")) + frappe.throw(_("Please ensure {} account is a Balance Sheet account. \ + You can change the parent account to a Balance Sheet account or select a different account.") + .format(frappe.bold("Credit To")), title=_("Invalid Account")) if self.supplier and account.account_type != "Payable": - frappe.throw(_("Credit To account must be a Payable account")) + frappe.throw(_("Please ensure {} account is a Payable account. \ + Change the account type to Payable or select a different account.") + .format(frappe.bold("Credit To")), title=_("Invalid Account")) self.party_account_currency = account.account_currency diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index eda80246cdb..b6d2affee54 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -470,13 +470,17 @@ class SalesInvoice(SellingController): ["account_type", "report_type", "account_currency"], as_dict=True) if not account: - frappe.throw(_("Debit To is required")) + frappe.throw(_("Debit To is required"), title=_("Account Missing")) if account.report_type != "Balance Sheet": - frappe.throw(_("Debit To account must be a Balance Sheet account")) + frappe.throw(_("Please ensure {} account is a Balance Sheet account. \ + You can change the parent account to a Balance Sheet account or select a different account.") + .format(frappe.bold("Debit To")), title=_("Invalid Account")) if self.customer and account.account_type != "Receivable": - frappe.throw(_("Debit To account must be a Receivable account")) + frappe.throw(_("Please ensure {} account is a Receivable account. \ + Change the account type to Receivable or select a different account.") + .format(frappe.bold("Debit To")), title=_("Invalid Account")) self.party_account_currency = account.account_currency From 18cd3a029dd4997d21169b709e1493a5156c94c6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 4 Apr 2020 20:05:17 +0530 Subject: [PATCH 072/104] fix: User permissions in GSTR 3B report --- erpnext/patches.txt | 2 +- .../v11_0/add_permissions_in_gst_settings.py | 7 ++----- .../gstr_3b_report/gstr_3b_report.html | 2 +- .../gstr_3b_report/gstr_3b_report.json | 19 ++++--------------- erpnext/regional/india/setup.py | 10 ++++++++-- 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index de4c89c5ace..3146a3a6fb7 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -582,7 +582,7 @@ erpnext.patches.v11_0.rename_bom_wo_fields erpnext.patches.v12_0.set_default_homepage_type erpnext.patches.v11_0.rename_additional_salary_component_additional_salary erpnext.patches.v11_0.renamed_from_to_fields_in_project -erpnext.patches.v11_0.add_permissions_in_gst_settings +erpnext.patches.v11_0.add_permissions_in_gst_settings #2020-04-04 erpnext.patches.v11_1.setup_guardian_role execute:frappe.delete_doc('DocType', 'Notification Control') erpnext.patches.v12_0.set_gst_category diff --git a/erpnext/patches/v11_0/add_permissions_in_gst_settings.py b/erpnext/patches/v11_0/add_permissions_in_gst_settings.py index e8fcf33bede..121a20288c3 100644 --- a/erpnext/patches/v11_0/add_permissions_in_gst_settings.py +++ b/erpnext/patches/v11_0/add_permissions_in_gst_settings.py @@ -1,12 +1,9 @@ import frappe -from frappe.permissions import add_permission, update_permission_property +from erpnext.regional.india.setup import add_permissions def execute(): company = frappe.get_all('Company', filters = {'country': 'India'}) if not company: return - for doctype in ('GST HSN Code', 'GST Settings'): - add_permission(doctype, 'Accounts Manager', 0) - update_permission_property(doctype, 'Accounts Manager', 0, 'write', 1) - update_permission_property(doctype, 'Accounts Manager', 0, 'create', 1) \ No newline at end of file + add_permissions() \ No newline at end of file diff --git a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html index 2da79a63648..35f9cf674ce 100644 --- a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html +++ b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.html @@ -29,7 +29,7 @@
- + diff --git a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.json b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.json index 548d40b9745..1f208df1f23 100644 --- a/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.json +++ b/erpnext/regional/doctype/gstr_3b_report/gstr_3b_report.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "format:GSTR3B-{month}-{year}-{company_address}", "creation": "2019-02-04 11:35:55.964639", "doctype": "DocType", @@ -48,25 +49,13 @@ "read_only": 1 } ], - "modified": "2019-08-10 22:30:26.727038", + "links": [], + "modified": "2020-04-04 19:32:30.772908", "modified_by": "Administrator", "module": "Regional", "name": "GSTR 3B Report", "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "share": 1, - "write": 1 - } - ], + "permissions": [], "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index cabfde40ef4..1957e7fecca 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -77,13 +77,19 @@ def add_custom_roles_for_reports(): )).insert() def add_permissions(): - for doctype in ('GST HSN Code', 'GST Settings'): + for doctype in ('GST HSN Code', 'GST Settings', 'GSTR 3B Report'): add_permission(doctype, 'All', 0) - for role in ('Accounts Manager', 'System Manager', 'Item Manager', 'Stock Manager'): + for role in ('Accounts Manager', 'Accounts User', 'System Manager'): add_permission(doctype, role, 0) update_permission_property(doctype, role, 0, 'write', 1) update_permission_property(doctype, role, 0, 'create', 1) + if doctype == 'GST HSN Code': + for role in ('Item Manager', 'Stock Manager'): + add_permission(doctype, role, 0) + update_permission_property(doctype, role, 0, 'write', 1) + update_permission_property(doctype, role, 0, 'create', 1) + def add_print_formats(): frappe.reload_doc("regional", "print_format", "gst_tax_invoice") frappe.reload_doc("accounts", "print_format", "gst_pos_invoice") From 2378572e1b5d443569791afbb4fbcf7c8b7ad01d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 6 Apr 2020 10:15:50 +0530 Subject: [PATCH 073/104] fix: update attendace from leave application (#21154) --- erpnext/hr/doctype/leave_application/leave_application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index 39e5e1132ca..a800923a8c2 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -122,7 +122,7 @@ class LeaveApplication(Document): if self.status == "Approved": for dt in daterange(getdate(self.from_date), getdate(self.to_date)): date = dt.strftime("%Y-%m-%d") - status = "Half Day" if date == self.half_day_date else "On Leave" + status = "Half Day" if getdate(date) == getdate(self.half_day_date) else "On Leave" attendance_name = frappe.db.exists('Attendance', dict(employee = self.employee, attendance_date = date, docstatus = ('!=', 2))) From 4ea7df69b49d82a74589c8ee2b4b267506781dd1 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 6 Apr 2020 12:34:38 +0530 Subject: [PATCH 074/104] fix: change request status on payment entry cancel --- .../doctype/payment_entry/payment_entry.py | 5 ++++ .../payment_request/payment_request.py | 27 +++++++++++++------ .../payment_request/test_payment_request.py | 17 ++++++++++++ erpnext/hooks.py | 2 +- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index d65e5640263..c89742cfb7f 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -81,7 +81,12 @@ class PaymentEntry(AccountsController): self.update_advance_paid() self.update_expense_claim() self.delink_advance_entry_references() + self.set_payment_req_status() self.set_status() + + def set_payment_req_status(self): + from erpnext.accounts.doctype.payment_request.payment_request import update_payment_req_status + update_payment_req_status(self, None) def update_outstanding_amounts(self): self.set_missing_ref_details(force=True) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 9c74de4af61..b51fc355764 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -417,20 +417,31 @@ def make_payment_entry(docname): doc = frappe.get_doc("Payment Request", docname) return doc.create_payment_entry(submit=False).as_dict() -def make_status_as_paid(doc, method): +def update_payment_req_status(doc, method): + from erpnext.accounts.doctype.payment_entry.payment_entry import get_reference_details + for ref in doc.references: payment_request_name = frappe.db.get_value("Payment Request", {"reference_doctype": ref.reference_doctype, "reference_name": ref.reference_name, "docstatus": 1}) if payment_request_name: - doc = frappe.get_doc("Payment Request", payment_request_name) - if doc.status != "Paid" and ref.outstanding_amount <= ref.allocated_amount: - doc.db_set('status', 'Paid') - frappe.db.commit() - elif doc.status != "Partially Paid" and ref.outstanding_amount != ref.allocated_amount: - doc.db_set('status', 'Partially Paid') - frappe.db.commit() + ref_details = get_reference_details(ref.reference_doctype, ref.reference_name, doc.party_account_currency) + pay_req_doc = frappe.get_doc('Payment Request', payment_request_name) + status = pay_req_doc.status + + if status != "Paid" and not ref_details.outstanding_amount: + status = 'Paid' + elif status != "Partially Paid" and ref_details.outstanding_amount != ref_details.total_amount: + status = 'Partially Paid' + elif ref_details.outstanding_amount == ref_details.total_amount: + if pay_req_doc.payment_request_type == 'Outward': + status = 'Initiated' + elif pay_req_doc.payment_request_type == 'Inward': + status = 'Requested' + + pay_req_doc.db_set('status', status) + frappe.db.commit() def get_dummy_message(doc): return frappe.render_template("""{% if doc.contact_person -%} diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.py b/erpnext/accounts/doctype/payment_request/test_payment_request.py index 188ab0aecf3..8a10e2cbd95 100644 --- a/erpnext/accounts/doctype/payment_request/test_payment_request.py +++ b/erpnext/accounts/doctype/payment_request/test_payment_request.py @@ -101,6 +101,23 @@ class TestPaymentRequest(unittest.TestCase): self.assertEqual(expected_gle[gle.account][2], gle.credit) self.assertEqual(expected_gle[gle.account][3], gle.against_voucher) + def test_status(self): + si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + currency="USD", conversion_rate=50) + + pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com", + mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1) + + pe = pr.create_payment_entry() + pr.load_from_db() + + self.assertEqual(pr.status, 'Paid') + + pe.cancel() + pr.load_from_db() + + self.assertEqual(pr.status, 'Requested') + def test_multiple_payment_entries_against_sales_order(self): # Make Sales Order, grand_total = 1000 so = make_sales_order() diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 7f268d6ba14..60f4b50c515 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -245,7 +245,7 @@ doc_events = { "on_trash": "erpnext.regional.check_deletion_permission" }, "Payment Entry": { - "on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.make_status_as_paid"], + "on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status"], "on_trash": "erpnext.regional.check_deletion_permission" }, 'Address': { From d7389b1920f29b8720c2b065b12f1901dddde87f Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 6 Apr 2020 17:46:34 +0530 Subject: [PATCH 075/104] fix: material request type manufacture shows items with Is Purchase Item enabled --- erpnext/public/js/controllers/buying.js | 6 ----- .../material_request/material_request.js | 23 +++++++++++++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index 3d4c4a64595..27a9de95e0e 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -85,12 +85,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ filters:{ 'is_sub_contracted_item': 1 } } } - else if (me.frm.doc.material_request_type == "Customer Provided") { - return{ - query: "erpnext.controllers.queries.item_query", - filters:{ 'customer': me.frm.doc.customer } - } - } else { return{ query: "erpnext.controllers.queries.item_query", diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index 7ef2d6460f6..6110ea822cf 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -19,11 +19,6 @@ frappe.ui.form.on('Material Request', { frm.set_indicator_formatter('item_code', function(doc) { return (doc.qty<=doc.ordered_qty) ? "green" : "orange"; }); - frm.set_query("item_code", "items", function() { - return { - query: "erpnext.controllers.queries.item_query" - }; - }); }, onload: function(frm) { @@ -145,6 +140,8 @@ frappe.ui.form.on('Material Request', { }, get_item_data: function(frm, item) { + if (item && !item.item_code) { return; } + frm.call({ method: "erpnext.stock.get_item_details.get_item_details", child: item, @@ -359,6 +356,22 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten set_schedule_date(this.frm); }, + onload: function(doc, cdt, cdn) { + this.frm.set_query("item_code", "items", function() { + if (doc.material_request_type == "Customer Provided") { + return{ + query: "erpnext.controllers.queries.item_query", + filters:{ 'customer': me.frm.doc.customer } + } + } else if (doc.material_request_type != "Manufacture") { + return{ + query: "erpnext.controllers.queries.item_query", + filters: {'is_purchase_item': 1} + } + } + }); + }, + items_add: function(doc, cdt, cdn) { var row = frappe.get_doc(cdt, cdn); if(doc.schedule_date) { From 34288b0f38017b0ce9e5408f77e4b97afd229f25 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 6 Apr 2020 18:25:23 +0530 Subject: [PATCH 076/104] feat: (minor) purchase register filters --- .../purchase_register/purchase_register.js | 27 +++++++++++++++++ .../purchase_register/purchase_register.py | 29 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/erpnext/accounts/report/purchase_register/purchase_register.js b/erpnext/accounts/report/purchase_register/purchase_register.js index 42b35c2a997..b2b95b2b81b 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.js +++ b/erpnext/accounts/report/purchase_register/purchase_register.js @@ -34,6 +34,33 @@ frappe.query_reports["Purchase Register"] = { "label": __("Mode of Payment"), "fieldtype": "Link", "options": "Mode of Payment" + }, + { + "fieldname":"cost_center", + "label": __("Cost Center"), + "fieldtype": "Link", + "options": "Cost Center" + }, + { + "fieldname":"warehouse", + "label": __("Warehouse"), + "fieldtype": "Link", + "options": "Warehouse" + }, + { + "fieldname":"item_group", + "label": __("Item Group"), + "fieldtype": "Link", + "options": "Item Group" } ] } + +erpnext.dimension_filters.forEach((dimension) => { + frappe.query_reports["Purchase Register"].filters.splice(7, 0 ,{ + "fieldname": dimension["fieldname"], + "label": __(dimension["label"]), + "fieldtype": "Link", + "options": dimension["document_type"] + }); +}); \ No newline at end of file diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py index 3f8abb76e26..795dcb18811 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.py +++ b/erpnext/accounts/report/purchase_register/purchase_register.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import frappe from frappe.utils import flt from frappe import msgprint, _ +from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions, get_dimension_with_children def execute(filters=None): return _execute(filters) @@ -134,6 +135,34 @@ def get_conditions(filters): if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s" + if filters.get("cost_center"): + conditions += """ and exists(select name from `tabPurchase Invoice Item` + where parent=`tabPurchase Invoice`.name + and ifnull(`tabPurchase Invoice Item`.cost_center, '') = %(cost_center)s)""" + + if filters.get("warehouse"): + conditions += """ and exists(select name from `tabPurchase Invoice Item` + where parent=`tabPurchase Invoice`.name + and ifnull(`tabPurchase Invoice Item`.warehouse, '') = %(warehouse)s)""" + + if filters.get("item_group"): + conditions += """ and exists(select name from `tabPurchase Invoice Item` + where parent=`tabPurchase Invoice`.name + and ifnull(`tabPurchase Invoice Item`.item_group, '') = %(item_group)s)""" + + accounting_dimensions = get_accounting_dimensions(as_list=False) + + if accounting_dimensions: + for dimension in accounting_dimensions: + if filters.get(dimension.fieldname): + if frappe.get_cached_value('DocType', dimension.document_type, 'is_tree'): + filters[dimension.fieldname] = get_dimension_with_children(dimension.document_type, + filters.get(dimension.fieldname)) + + conditions += """ and exists(select name from `tabPurchase Invoice Item` + where parent=`tabPurchase Invoice`.name + and ifnull(`tabPurchase Invoice Item`.{0}, '') in %({0})s)""".format(dimension.fieldname) + return conditions def get_invoices(filters, additional_query_columns): From 2dd488f878d008e86a467fa635ae4db7a8a4a5b4 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 6 Apr 2020 22:13:13 +0530 Subject: [PATCH 077/104] feat: Scan Barcode in Purchase Receipt --- erpnext/public/js/controllers/transaction.js | 2 ++ .../stock/doctype/purchase_receipt/purchase_receipt.json | 8 +++++++- erpnext/stock/get_item_details.py | 6 +++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index e1c38a91297..cfdcbb816a7 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -473,6 +473,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ item_code: item.item_code, barcode: item.barcode, serial_no: item.serial_no, + batch_no: item.batch_no, set_warehouse: me.frm.doc.set_warehouse, warehouse: item.warehouse, customer: me.frm.doc.customer || me.frm.doc.party_name, @@ -599,6 +600,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ // Add the new list to the serial no. field in grid with each in new line item.serial_no = valid_serial_nos.join('\n'); + item.conversion_factor = item.conversion_factor || 1; refresh_field("serial_no", item.name, item.parentfield); if(!doc.is_return && cint(user_defaults.set_qty_in_transactions_based_on_serial_no_input)) { diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json index 63ef7ca8d82..00a50a88ef0 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json @@ -47,6 +47,7 @@ "is_subcontracted", "supplier_warehouse", "items_section", + "scan_barcode", "items", "pricing_rule_details", "pricing_rules", @@ -1053,13 +1054,18 @@ "oldfieldtype": "Date", "print_width": "100px", "width": "100px" + }, + { + "fieldname": "scan_barcode", + "fieldtype": "Data", + "label": "Scan Barcode" } ], "icon": "fa fa-truck", "idx": 261, "is_submittable": 1, "links": [], - "modified": "2019-12-30 19:12:49.709711", + "modified": "2020-04-06 16:31:37.444891", "modified_by": "Administrator", "module": "Stock", "name": "Purchase Receipt", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index d15a2597386..54dc685e4ef 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -244,7 +244,7 @@ def get_basic_details(args, item, overwrite_warehouse=True): 'item_group_defaults': item_group_defaults, 'brand_defaults': brand_defaults }) - + warehouse = get_item_warehouse(item, args, overwrite_warehouse, defaults) if args.get('doctype') == "Material Request" and not args.get('material_request_type'): @@ -278,7 +278,7 @@ def get_basic_details(args, item, overwrite_warehouse=True): "cost_center": get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults), 'has_serial_no': item.has_serial_no, 'has_batch_no': item.has_batch_no, - "batch_no": None, + "batch_no": args.get("batch_no"), "uom": args.uom, "min_order_qty": flt(item.min_order_qty) if args.doctype == "Material Request" else "", "qty": flt(args.qty) or 1.0, @@ -375,7 +375,7 @@ def get_item_warehouse(item, args, overwrite_warehouse, defaults={}): else: warehouse = args.get('warehouse') - + return warehouse def update_barcode_value(out): From 044abbace8078c5cbb58280d4b0cab5e6e795b82 Mon Sep 17 00:00:00 2001 From: Vishal Dhayagude Date: Tue, 7 Apr 2020 12:05:18 +0530 Subject: [PATCH 078/104] fix: Make Sales Invoice paid when it create from shopping cart (#20878) Co-authored-by: Saqib --- erpnext/accounts/doctype/payment_request/payment_request.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index bcf7159f843..f2b0d3db7a1 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -90,6 +90,7 @@ class PaymentRequest(Document): if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"): from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice si = make_sales_invoice(self.reference_name, ignore_permissions=True) + si.allocate_advances_automatically = True si = si.insert(ignore_permissions=True) si.submit() From d2da8bd6e2effc87e86c88b5f5ca2c5704dfc6fe Mon Sep 17 00:00:00 2001 From: Vishal Dhayagude Date: Tue, 7 Apr 2020 12:19:40 +0530 Subject: [PATCH 079/104] fix(shopping cart): UX Improvements (#21035) * fix: nontype error for resolved and moved place order button at bottom left * fix: removed inline style * fix: Request for quotation move to lower right * fix: move buttons Co-authored-by: Naren Co-authored-by: Saqib --- erpnext/public/scss/website.scss | 4 ++++ .../templates/includes/order/order_taxes.html | 20 ++++++++-------- erpnext/templates/pages/cart.html | 24 +++++++++++-------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/erpnext/public/scss/website.scss b/erpnext/public/scss/website.scss index 7b9a70d232e..735b417da17 100644 --- a/erpnext/public/scss/website.scss +++ b/erpnext/public/scss/website.scss @@ -78,3 +78,7 @@ z-index: 0; } } + +.place-order-container { + text-align: right; +} \ No newline at end of file diff --git a/erpnext/templates/includes/order/order_taxes.html b/erpnext/templates/includes/order/order_taxes.html index 4a32aa47446..ebec838d03e 100644 --- a/erpnext/templates/includes/order/order_taxes.html +++ b/erpnext/templates/includes/order/order_taxes.html @@ -10,16 +10,16 @@ {% endif %} {% for d in doc.taxes %} -{% if d.base_tax_amount > 0 %} - - - - -{% endif %} + {% if d.base_tax_amount %} + + + + + {% endif %} {% endfor %} {% if doc.doctype == 'Quotation' %} diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html index 912702e386d..3033d1587d6 100644 --- a/erpnext/templates/pages/cart.html +++ b/erpnext/templates/pages/cart.html @@ -12,16 +12,6 @@ {% block header_actions %} -{% if doc.items and cart_settings.enable_checkout %} - -{% endif %} -{% if doc.items and not cart_settings.enable_checkout %} - -{% endif %} {% endblock %} {% block page_content %} @@ -55,6 +45,20 @@

{{ _('Your cart is Empty') }}

{% endif %} + {% if doc.items %} +
+ {% if cart_settings.enable_checkout %} + + {% else %} + + {% endif %} +
+ {% endif %} + {% if doc.items %} {% if doc.tc_name %}
-

+

${__("Projected Quantity Formula")} diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json index 0be9f1a8eef..af844816e8b 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.json +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json @@ -1,1391 +1,321 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "naming_series:", - "beta": 0, - "creation": "2017-10-29 11:53:09.523362", - "custom": 0, - "default_print_format": "", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 0, - "engine": "InnoDB", + "actions": [], + "autoname": "naming_series:", + "creation": "2017-10-29 11:53:09.523362", + "doctype": "DocType", + "document_type": "Document", + "engine": "InnoDB", + "field_order": [ + "naming_series", + "company", + "get_items_from", + "column_break1", + "posting_date", + "filters", + "item_code", + "customer", + "warehouse", + "project", + "column_break2", + "from_date", + "to_date", + "sales_orders_detail", + "get_sales_orders", + "sales_orders", + "material_request_detail", + "get_material_request", + "material_requests", + "select_items_to_manufacture_section", + "get_items", + "po_items", + "material_request_planning", + "include_non_stock_items", + "include_subcontracted_items", + "ignore_existing_ordered_qty", + "column_break_25", + "for_warehouse", + "download_materials_required", + "get_items_for_mr", + "section_break_27", + "mr_items", + "other_details", + "total_planned_qty", + "total_produced_qty", + "column_break_32", + "status", + "amended_from" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fetch_if_empty": 0, - "fieldname": "naming_series", - "fieldtype": "Select", - "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": "Naming Series", - "length": 0, - "no_copy": 0, - "options": "MFG-PP-.YYYY.-", - "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": "naming_series", + "fieldtype": "Select", + "label": "Naming Series", + "options": "MFG-PP-.YYYY.-", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fetch_if_empty": 0, - "fieldname": "company", - "fieldtype": "Link", - "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": "Company", - "length": 0, - "no_copy": 0, - "options": "Company", - "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": "company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fetch_if_empty": 0, - "fieldname": "get_items_from", - "fieldtype": "Select", - "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": "Get Items From", - "length": 0, - "no_copy": 0, - "options": "\nSales Order\nMaterial Request", - "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": "get_items_from", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Get Items From", + "options": "\nSales Order\nMaterial Request" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break1", - "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 - }, + "fieldname": "column_break1", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Today", - "fetch_if_empty": 0, - "fieldname": "posting_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": 0, - "label": "Posting Date", - "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 - }, + "default": "Today", + "fieldname": "posting_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Posting Date", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "eval: doc.__islocal", - "columns": 0, - "depends_on": "eval: doc.get_items_from", - "description": "", - "fetch_if_empty": 0, - "fieldname": "filters", - "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": "Filters", - "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, + "collapsible_depends_on": "eval: doc.__islocal", + "depends_on": "eval: doc.get_items_from", + "fieldname": "filters", + "fieldtype": "Section Break", + "label": "Filters" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "item_code", - "fieldtype": "Link", - "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": "Item Code", - "length": 0, - "no_copy": 0, - "options": "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": "item_code", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item Code", + "options": "Item" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval: doc.get_items_from == \"Sales Order\"", - "fetch_if_empty": 0, - "fieldname": "customer", - "fieldtype": "Link", - "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": "Customer", - "length": 0, - "no_copy": 0, - "options": "Customer", - "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": "eval: doc.get_items_from == \"Sales Order\"", + "fieldname": "customer", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Customer", + "options": "Customer" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval: doc.get_items_from == \"Material Request\"", - "fetch_if_empty": 0, - "fieldname": "warehouse", - "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": "Warehouse", - "length": 0, - "no_copy": 0, - "options": "Warehouse", - "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": "eval: doc.get_items_from == \"Material Request\"", + "fieldname": "warehouse", + "fieldtype": "Link", + "label": "Warehouse", + "options": "Warehouse" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval: doc.get_items_from == \"Sales Order\"", - "fetch_if_empty": 0, - "fieldname": "project", - "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": "Project", - "length": 0, - "no_copy": 0, - "options": "Project", - "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": "eval: doc.get_items_from == \"Sales Order\"", + "fieldname": "project", + "fieldtype": "Link", + "label": "Project", + "options": "Project" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break2", - "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, + "fieldname": "column_break2", + "fieldtype": "Column Break", "width": "50%" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "from_date", - "fieldtype": "Date", - "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": "From Date", - "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": "from_date", + "fieldtype": "Date", + "label": "From Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "to_date", - "fieldtype": "Date", - "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": "To Date", - "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": "to_date", + "fieldtype": "Date", + "label": "To Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "eval: doc.__islocal", - "columns": 0, - "depends_on": "eval: doc.get_items_from == \"Sales Order\"", - "fetch_if_empty": 0, - "fieldname": "sales_orders_detail", - "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": "Sales Orders Detail", - "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 - }, + "collapsible": 1, + "collapsible_depends_on": "eval: doc.__islocal", + "depends_on": "eval: doc.get_items_from == \"Sales Order\"", + "fieldname": "sales_orders_detail", + "fieldtype": "Section Break", + "label": "Sales Orders" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fetch_if_empty": 0, - "fieldname": "get_sales_orders", - "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 Sales Orders", - "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": "get_sales_orders", + "fieldtype": "Button", + "label": "Get Sales Orders" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "sales_orders", - "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": "Sales Orders", - "length": 0, - "no_copy": 1, - "options": "Production Plan Sales Order", - "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": "sales_orders", + "fieldtype": "Table", + "label": "Sales Orders", + "no_copy": 1, + "options": "Production Plan Sales Order" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "eval: doc.__islocal", - "columns": 0, - "depends_on": "eval: doc.get_items_from == \"Material Request\"", - "fetch_if_empty": 0, - "fieldname": "material_request_detail", - "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": "Material Request Detail", - "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, + "collapsible_depends_on": "eval: doc.__islocal", + "depends_on": "eval: doc.get_items_from == \"Material Request\"", + "fieldname": "material_request_detail", + "fieldtype": "Section Break", + "label": "Material Request Detail" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fetch_if_empty": 0, - "fieldname": "get_material_request", - "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 Material Request", - "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": "get_material_request", + "fieldtype": "Button", + "label": "Get Material Request" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "material_requests", - "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": "Material Requests", - "length": 0, - "no_copy": 1, - "options": "Production Plan Material Request", - "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": "material_requests", + "fieldtype": "Table", + "label": "Material Requests", + "no_copy": 1, + "options": "Production Plan Material Request" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fetch_if_empty": 0, - "fieldname": "select_items_to_manufacture_section", - "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": "Select Items to Manufacture", - "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": "select_items_to_manufacture_section", + "fieldtype": "Section Break", + "label": "Select Items to Manufacture" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "get_items_from", - "fetch_if_empty": 0, - "fieldname": "get_items", - "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 Items For Work Order", - "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 - }, + "depends_on": "get_items_from", + "fieldname": "get_items", + "fieldtype": "Button", + "label": "Get Items For Work Order" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "po_items", - "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": "", - "length": 0, - "no_copy": 1, - "options": "Production Plan 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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "po_items", + "fieldtype": "Table", + "no_copy": 1, + "options": "Production Plan Item", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fetch_if_empty": 0, - "fieldname": "material_request_planning", - "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": "Material Request Planning", - "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": "material_request_planning", + "fieldtype": "Section Break", + "label": "Material Request Planning" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fetch_if_empty": 0, - "fieldname": "include_non_stock_items", - "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": "Include Non Stock Items", - "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": "1", + "fieldname": "include_non_stock_items", + "fieldtype": "Check", + "label": "Include Non Stock Items" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fetch_if_empty": 0, - "fieldname": "include_subcontracted_items", - "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": "Include Subcontracted Items", - "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": "1", + "fieldname": "include_subcontracted_items", + "fieldtype": "Check", + "label": "Include Subcontracted Items" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "If enabled, then system will create the material even if the raw materials are available", - "fetch_if_empty": 0, - "fieldname": "ignore_existing_ordered_qty", - "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": "Ignore Existing Projected 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 - }, + "default": "0", + "description": "To know more about projected quantity, click here.", + "fieldname": "ignore_existing_ordered_qty", + "fieldtype": "Check", + "label": "Ignore Existing Projected Quantity" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break_25", - "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 - }, + "fieldname": "column_break_25", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "for_warehouse", - "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": "For Warehouse", - "length": 0, - "no_copy": 0, - "options": "Warehouse", - "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": "for_warehouse", + "fieldtype": "Link", + "label": "For Warehouse", + "options": "Warehouse" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "download_materials_required", - "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": "Download Materials Required", - "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": "download_materials_required", + "fieldtype": "Button", + "label": "Download Required Materials" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "get_items_for_mr", - "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 Raw Materials For Production", - "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": "get_items_for_mr", + "fieldtype": "Button", + "label": "Get Raw Materials For Production" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "", - "fetch_if_empty": 0, - "fieldname": "section_break_27", - "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": "section_break_27", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "mr_items", - "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": "Material Request Plan Item", - "length": 0, - "no_copy": 1, - "options": "Material Request Plan 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": "mr_items", + "fieldtype": "Table", + "label": "Material Request Plan Item", + "no_copy": 1, + "options": "Material Request Plan Item" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fetch_if_empty": 0, - "fieldname": "projected_qty_formula", - "fieldtype": "HTML", - "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": "Projected Qty Formula", - "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": "other_details", + "fieldtype": "Section Break", + "label": "Other Details" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "other_details", - "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": "Other 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": "total_planned_qty", + "fieldtype": "Float", + "label": "Total Planned Qty", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fetch_if_empty": 0, - "fieldname": "total_planned_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": "Total Planned Qty", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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 - }, + "default": "0", + "fieldname": "total_produced_qty", + "fieldtype": "Float", + "label": "Total Produced Qty", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fetch_if_empty": 0, - "fieldname": "total_produced_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": "Total Produced Qty", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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 - }, + "fieldname": "column_break_32", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "column_break_32", - "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": "Draft", + "fieldname": "status", + "fieldtype": "Select", + "label": "Status", + "no_copy": 1, + "options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled\nMaterial Requested", + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Draft", - "fetch_if_empty": 0, - "fieldname": "status", - "fieldtype": "Select", - "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": "Status", - "length": 0, - "no_copy": 1, - "options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled\nMaterial Requested", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "amended_from", - "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": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Production Plan", - "permlevel": 0, - "print_hide": 1, - "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 + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Production Plan", + "print_hide": 1, + "read_only": 1 } - ], - "has_web_view": 0, - "hide_toolbar": 0, - "icon": "fa fa-calendar", - "idx": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-04-09 12:05:14.300886", - "modified_by": "Administrator", - "module": "Manufacturing", - "name": "Production Plan", - "name_case": "", - "owner": "Administrator", + ], + "icon": "fa fa-calendar", + "is_submittable": 1, + "links": [], + "modified": "2019-12-04 15:58:50.940460", + "modified_by": "Administrator", + "module": "Manufacturing", + "name": "Production Plan", + "owner": "Administrator", "permissions": [ { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 0, - "role": "Manufacturing User", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Manufacturing User", + "share": 1, + "submit": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "ASC", - "title_field": "", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + ], + "sort_field": "modified", + "sort_order": "ASC" } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py b/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py index 91c28555d61..09ec24a67a2 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan_dashboard.py @@ -6,7 +6,7 @@ def get_data(): 'fieldname': 'production_plan', 'transactions': [ { - 'label': _('Related'), + 'label': _('Transactions'), 'items': ['Work Order', 'Material Request'] }, ] diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js index 7e1ea3eb1d9..1989c10c394 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.js +++ b/erpnext/manufacturing/doctype/work_order/work_order.js @@ -6,7 +6,7 @@ frappe.ui.form.on("Work Order", { frm.custom_make_buttons = { 'Stock Entry': 'Start', 'Pick List': 'Create Pick List', - 'Job Card': 'Create Job Card', + 'Job Card': 'Create Job Card' }; // Set query for warehouses @@ -132,7 +132,8 @@ frappe.ui.form.on("Work Order", { } if (frm.doc.docstatus===1) { - frm.trigger('show_progress'); + frm.trigger('show_progress_for_items'); + frm.trigger('show_progress_for_operations'); } if (frm.doc.docstatus === 1 @@ -180,89 +181,72 @@ frappe.ui.form.on("Work Order", { make_job_card: function(frm) { let qty = 0; - const fields = [{ - fieldtype: "Link", - fieldname: "operation", - options: "Operation", - label: __("Operation"), - get_query: () => { - const filter_workstation = frm.doc.operations.filter(d => { - if (d.status != "Completed") { - return d; - } - }); + let operations_data = []; - return { - filters: { - name: ["in", (filter_workstation || []).map(d => d.operation)] - } - }; - }, - reqd: true - }, { - fieldtype: "Link", - fieldname: "workstation", - options: "Workstation", - label: __("Workstation"), - get_query: () => { - const operation = dialog.get_value("operation"); - const filter_workstation = frm.doc.operations.filter(d => { - if (d.operation == operation) { - return d; - } - }); - - return { - filters: { - name: ["in", (filter_workstation || []).map(d => d.workstation)] - } - }; - }, - onchange: () => { - const operation = dialog.get_value("operation"); - const workstation = dialog.get_value("workstation"); - if (operation && workstation) { - const row = frm.doc.operations.filter(d => d.operation == operation && d.workstation == workstation)[0]; - qty = frm.doc.qty - row.completed_qty; - - if (qty > 0) { - dialog.set_value("qty", qty); - } - } - }, - reqd: true - }, { - fieldtype: "Float", - fieldname: "qty", - label: __("For Quantity"), - reqd: true - }]; - - const dialog = frappe.prompt(fields, function(data) { - if (data.qty > qty) { - frappe.throw(__("For Quantity must be less than quantity {0}", [qty])); + const dialog = frappe.prompt({fieldname: 'operations', fieldtype: 'Table', label: __('Operations'), + fields: [ + { + fieldtype:'Link', + fieldname:'operation', + label: __('Operation'), + read_only:1, + in_list_view:1 + }, + { + fieldtype:'Link', + fieldname:'workstation', + label: __('Workstation'), + read_only:1, + in_list_view:1 + }, + { + fieldtype:'Data', + fieldname:'name', + label: __('Operation Id') + }, + { + fieldtype:'Float', + fieldname:'pending_qty', + label: __('Pending Qty'), + }, + { + fieldtype:'Float', + fieldname:'qty', + label: __('Quantity to Manufacture'), + read_only:0, + in_list_view:1, + }, + ], + data: operations_data, + in_place_edit: true, + get_data: function() { + return operations_data; } - - if (data.qty <= 0) { - frappe.throw(__("For Quantity must be greater than zero")); - } - + }, function(data) { frappe.call({ method: "erpnext.manufacturing.doctype.work_order.work_order.make_job_card", args: { work_order: frm.doc.name, - operation: data.operation, - workstation: data.workstation, - qty: data.qty - }, - callback: function(r){ - if (r.message) { - var doc = frappe.model.sync(r.message)[0]; - frappe.set_route("Form", doc.doctype, doc.name); - } + operations: data.operations, } }); - }, __("For Job Card")); + }, __("Job Card"), __("Create")); + + var pending_qty = 0; + frm.doc.operations.forEach(data => { + if(data.completed_qty != frm.doc.qty) { + pending_qty = frm.doc.qty - flt(data.completed_qty); + + dialog.fields_dict.operations.df.data.push({ + 'name': data.name, + 'operation': data.operation, + 'workstation': data.workstation, + 'qty': pending_qty, + 'pending_qty': pending_qty, + }); + } + }); + dialog.fields_dict.operations.grid.refresh(); }, make_bom: function(frm) { @@ -278,7 +262,7 @@ frappe.ui.form.on("Work Order", { }); }, - show_progress: function(frm) { + show_progress_for_items: function(frm) { var bars = []; var message = ''; var added_min = false; @@ -312,6 +296,44 @@ frappe.ui.form.on("Work Order", { frm.dashboard.add_progress(__('Status'), bars, message); }, + show_progress_for_operations: function(frm) { + if (frm.doc.operations && frm.doc.operations.length) { + + let progress_class = { + "Work in Progress": "progress-bar-warning", + "Completed": "progress-bar-success" + }; + + let bars = []; + let message = ''; + let title = ''; + let status_wise_oprtation_data = {}; + let total_completed_qty = frm.doc.qty * frm.doc.operations.length; + + frm.doc.operations.forEach(d => { + if (!status_wise_oprtation_data[d.status]) { + status_wise_oprtation_data[d.status] = [d.completed_qty, d.operation]; + } else { + status_wise_oprtation_data[d.status][0] += d.completed_qty; + status_wise_oprtation_data[d.status][1] += ', ' + d.operation; + } + }); + + for (let key in status_wise_oprtation_data) { + title = __("{0} Operations: {1}", [key, status_wise_oprtation_data[key][1].bold()]); + bars.push({ + 'title': title, + 'width': status_wise_oprtation_data[key][0] / total_completed_qty * 100 + '%', + 'progress_class': progress_class[key] + }); + + message += title + '. '; + } + + frm.dashboard.add_progress(__('Status'), bars, message); + } + }, + production_item: function(frm) { if (frm.doc.production_item) { frappe.call({ diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json index 0d073a2312b..6152fbb8402 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.json +++ b/erpnext/manufacturing/doctype/work_order/work_order.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "autoname": "naming_series:", "creation": "2013-01-10 16:34:16", @@ -468,7 +469,8 @@ "idx": 1, "image_field": "image", "is_submittable": 1, - "modified": "2019-08-28 12:29:35.315239", + "links": [], + "modified": "2019-12-04 11:20:04.695123", "modified_by": "Administrator", "module": "Manufacturing", "name": "Work Order", diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 28bcc2e0f9c..83579414812 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -6,7 +6,7 @@ import frappe import json import math from frappe import _ -from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate +from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate, get_link_to_form from frappe.model.document import Document from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, get_bom_items_as_dict from dateutil.relativedelta import relativedelta @@ -711,21 +711,41 @@ def query_sales_order(production_item): return out @frappe.whitelist() -def make_job_card(work_order, operation, workstation, qty=0): +def make_job_card(work_order, operations): + if isinstance(operations, string_types): + operations = json.loads(operations) + work_order = frappe.get_doc('Work Order', work_order) - row = get_work_order_operation_data(work_order, operation, workstation) - if row: - return create_job_card(work_order, row, qty) + for row in operations: + validate_operation_data(row) + create_job_card(work_order, row, row.get("qty"), auto_create=True) + +def validate_operation_data(row): + if row.get("qty") <= 0: + frappe.throw(_("Quantity to Manufacture can not be zero for the operation {0}") + .format( + frappe.bold(row.get("operation")) + ) + ) + + if row.get("qty") > row.get("pending_qty"): + frappe.throw(_("For operation {0}: Quantity ({1}) can not be greter than pending quantity({2})") + .format( + frappe.bold(row.get("operation")), + frappe.bold(row.get("qty")), + frappe.bold(row.get("pending_qty")) + ) + ) def create_job_card(work_order, row, qty=0, auto_create=False): doc = frappe.new_doc("Job Card") doc.update({ 'work_order': work_order.name, - 'operation': row.operation, - 'workstation': row.workstation, + 'operation': row.get("operation"), + 'workstation': row.get("workstation"), 'posting_date': nowdate(), 'for_quantity': qty or work_order.get('qty', 0), - 'operation_id': row.name, + 'operation_id': row.get("name"), 'bom_no': work_order.bom_no, 'project': work_order.project, 'company': work_order.company, @@ -738,7 +758,7 @@ def create_job_card(work_order, row, qty=0, auto_create=False): if auto_create: doc.flags.ignore_mandatory = True doc.insert() - frappe.msgprint(_("Job card {0} created").format(doc.name)) + frappe.msgprint(_("Job card {0} created").format(get_link_to_form("Job Card", doc.name))) return doc diff --git a/erpnext/manufacturing/doctype/work_order/work_order_calendar.js b/erpnext/manufacturing/doctype/work_order/work_order_calendar.js index c44b1e2700d..7ce05e9b881 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order_calendar.js +++ b/erpnext/manufacturing/doctype/work_order/work_order_calendar.js @@ -2,11 +2,13 @@ // For license information, please see license.txt frappe.views.calendar["Work Order"] = { + fields: ["planned_start_date", "planned_end_date", "status", "produced_qty", "qty", "name", "name"], field_map: { "start": "planned_start_date", "end": "planned_end_date", "id": "name", "title": "name", + "status": "status", "allDay": "allDay", "progress": function(data) { return flt(data.produced_qty) / data.qty * 100; diff --git a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py index 0d3c30ea6eb..87c090f99c3 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py +++ b/erpnext/manufacturing/doctype/work_order/work_order_dashboard.py @@ -6,7 +6,8 @@ def get_data(): 'fieldname': 'work_order', 'transactions': [ { - 'items': ['Pick List', 'Stock Entry', 'Job Card'] + 'label': _('Transactions'), + 'items': ['Stock Entry', 'Job Card', 'Pick List'] } ] } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json b/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json index 75d42cd061e..3f5e18e8130 100644 --- a/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json +++ b/erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2014-10-16 14:35:41.950175", "doctype": "DocType", "editable_grid": 1, @@ -68,6 +69,7 @@ "description": "Operation completed for how many finished goods?", "fieldname": "completed_qty", "fieldtype": "Float", + "in_list_view": 1, "label": "Completed Qty", "no_copy": 1, "read_only": 1 @@ -188,8 +190,9 @@ } ], "istable": 1, - "modified": "2019-07-16 23:01:07.720337", - "modified_by": "govindsmenokee@gmail.com", + "links": [], + "modified": "2019-12-03 19:24:29.594189", + "modified_by": "Administrator", "module": "Manufacturing", "name": "Work Order Operation", "owner": "Administrator", @@ -197,4 +200,4 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 -} +} \ No newline at end of file From 1e7cba9dd39a3890944bacb8bcf31a1fc6342c9c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 24 Mar 2020 15:43:21 +0530 Subject: [PATCH 022/104] fix: Default dimension set code cleanup --- .../public/js/utils/dimension_tree_filter.js | 69 +++++++++---------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js index 8b6de0f5179..75c5a820b46 100644 --- a/erpnext/public/js/utils/dimension_tree_filter.js +++ b/erpnext/public/js/utils/dimension_tree_filter.js @@ -1,23 +1,25 @@ frappe.provide('frappe.ui.form'); -erpnext.doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", +let default_dimensions = {}; + +let doctypes_with_dimensions = ["GL Entry", "Sales Invoice", "Purchase Invoice", "Payment Entry", "Asset", "Expense Claim", "Stock Entry", "Budget", "Payroll Entry", "Delivery Note", "Shipping Rule", "Loyalty Program", "Fee Schedule", "Fee Structure", "Stock Reconciliation", "Travel Request", "Fees", "POS Profile", "Opening Invoice Creation Tool", "Subscription", "Purchase Order", "Journal Entry", "Material Request", "Purchase Receipt", "Landed Cost Item", "Asset"]; -erpnext.child_docs = ["Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", +let child_docs = ["Sales Invoice Item", "Purchase Invoice Item", "Purchase Order Item", "Journal Entry Account", "Material Request Item", "Delivery Note Item", "Purchase Receipt Item", "Stock Entry Detail", "Payment Entry Deduction", "Landed Cost Item", "Asset Value Adjustment", "Opening Invoice Creation Tool Item", "Subscription Plan"]; frappe.call({ method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimension_filters", - callback: function(r){ + callback: function(r) { erpnext.dimension_filters = r.message[0]; - erpnext.default_dimensions = r.message[1]; + default_dimensions = r.message[1]; } }); -erpnext.doctypes_with_dimensions.forEach((doctype) => { +doctypes_with_dimensions.forEach((doctype) => { frappe.ui.form.on(doctype, { onload: function(frm) { erpnext.dimension_filters.forEach((dimension) => { @@ -27,41 +29,40 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => { "is_group": 0 }); } - - if (Object.keys(erpnext.default_dimensions).length > 0) { - if (frappe.meta.has_field(doctype, dimension['fieldname'])) { - if (frm.is_new() && frappe.meta.has_field(doctype, 'company') && frm.doc.company) { - frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]); - } - } - - if (frm.doc.items && frm.doc.items.length && frm.doc.docstatus === 0 - && (!frm.doc.items[0][dimension['fieldname']])) { - frm.doc.items[0][dimension['fieldname']] = erpnext.default_dimensions[frm.doc.company][dimension['document_type']]; - } - - if (frm.doc.accounts && frm.doc.accounts.length && frm.doc.docstatus === 0 - && (!frm.doc.items[0][dimension['fieldname']])) { - frm.doc.accounts[0][dimension['fieldname']] = erpnext.default_dimensions[frm.doc.company][dimension['document_type']]; - } - } }); }); }, company: function(frm) { - if(frm.doc.company && (Object.keys(erpnext.default_dimensions).length > 0)) { - erpnext.dimension_filters.forEach((dimension) => { - if (frappe.meta.has_field(doctype, dimension['fieldname'])) { - frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]); - } - }); + if(frm.doc.company && (Object.keys(default_dimensions || {}).length > 0) + && default_dimensions[frm.doc.company]) { + frm.trigger('update_dimension'); } }, + + update_dimension: function(frm) { + erpnext.dimension_filters.forEach((dimension) => { + if (frm.is_new()) { + if (frm.doc.company && Object.keys(default_dimensions || {}).length > 0 + && default_dimensions[frm.doc.company]) { + + if (frappe.meta.has_field(doctype, dimension['fieldname'])) { + frm.set_value(dimension['fieldname'], + default_dimensions[frm.doc.company][dimension['document_type']]); + } + + $.each(frm.doc.items || frm.doc.accounts || [], function(i, row) { + frappe.model.set_value(row.doctype, row.name, dimension['fieldname'], + default_dimensions[frm.doc.company][dimension['document_type']]) + }); + } + } + }); + } }); }); -erpnext.child_docs.forEach((doctype) => { +child_docs.forEach((doctype) => { frappe.ui.form.on(doctype, { items_add: function(frm, cdt, cdn) { erpnext.dimension_filters.forEach((dimension) => { @@ -77,14 +78,6 @@ erpnext.child_docs.forEach((doctype) => { }); }, - company: function(frm) { - if(frm.doc.company) { - erpnext.dimension_filters.forEach((dimension) => { - frm.set_value(dimension['fieldname'], erpnext.default_dimensions[frm.doc.company][dimension['document_type']]); - }); - } - }, - items_add: function(frm, cdt, cdn) { erpnext.dimension_filters.forEach((dimension) => { var row = frappe.get_doc(cdt, cdn); From 43806f3e68cccf648a5d149d5ad055395a2bf60f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 25 Mar 2020 16:52:07 +0530 Subject: [PATCH 023/104] fix: Place of supply validation in GSTR-1 report --- erpnext/regional/report/gstr_1/gstr_1.py | 27 ++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index 4f9cc7ff7a0..e9355f665e5 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -54,8 +54,8 @@ class Gstr1Report(object): return self.columns, self.data def get_data(self): - if self.filters.get("type_of_business") == "B2C Small": - self.get_b2cs_data() + if self.filters.get("type_of_business") in ("B2C Small", "B2C Large"): + self.get_b2c_data() else: for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): invoice_details = self.invoices.get(inv) @@ -69,7 +69,7 @@ class Gstr1Report(object): if taxable_value: self.data.append(row) - def get_b2cs_data(self): + def get_b2c_data(self): b2cs_output = {} for inv, items_based_on_rate in self.items_based_on_tax_rate.items(): @@ -84,7 +84,10 @@ class Gstr1Report(object): "rate": "", "taxable_value": 0, "cess_amount": 0, - "type": "" + "type": "", + "invoice_number": invoice_details.get("invoice_number"), + "posting_date": invoice_details.get("posting_date"), + "invoice_value": invoice_details.get("base_grand_total"), }) row = b2cs_output.get((rate, place_of_supply, ecommerce_gstin)) @@ -139,7 +142,7 @@ class Gstr1Report(object): where docstatus = 1 {where_conditions} order by posting_date desc """.format(select_columns=self.select_columns, doctype=self.doctype, - where_conditions=conditions), self.filters, as_dict=1) + where_conditions=conditions), self.filters, as_dict=1, debug=1) for d in invoice_data: self.invoices.setdefault(d.invoice_number, d) @@ -164,7 +167,7 @@ class Gstr1Report(object): frappe.throw(_("Please set B2C Limit in GST Settings.")) if self.filters.get("type_of_business") == "B2C Large": - conditions += """ and SUBSTR(place_of_supply, 1, 2) != SUBSTR(company_gstin, 1, 2) + conditions += """ and ifnull(SUBSTR(place_of_supply, 1, 2),'') != ifnull(SUBSTR(company_gstin, 1, 2),'') and grand_total > {0} and is_return != 1 and gst_category ='Unregistered' """.format(flt(b2c_limit)) elif self.filters.get("type_of_business") == "B2C Small": @@ -581,6 +584,11 @@ def get_b2b_json(res, gstin): if not gst_in: continue for number, invoice in iteritems(res[gst_in]): + if not invoice[0]["place_of_supply"]: + frappe.throw(_("""{0} not entered in Invoice {1}. + Please update and try again""").format(frappe.bold("Place Of Supply"), + frappe.bold(invoice[0]['invoice_number']))) + inv_item = get_basic_invoice_detail(invoice[0]) inv_item["pos"] = "%02d" % int(invoice[0]["place_of_supply"].split('-')[0]) inv_item["rchrg"] = invoice[0]["reverse_charge"] @@ -606,6 +614,9 @@ def get_b2cs_json(data, gstin): out = [] for d in data: + if not d.get("place_of_supply"): + frappe.throw(_("""{0} not entered in some invoices. + Please update and try again""").format(frappe.bold("Place Of Supply"))) pos = d.get('place_of_supply').split('-')[0] tax_details = {} @@ -642,6 +653,10 @@ def get_b2cs_json(data, gstin): def get_b2cl_json(res, gstin): out = [] for pos in res: + if not pos: + frappe.throw(_("""{0} not entered in some invoices. + Please update and try again""").format(frappe.bold("Place Of Supply"))) + b2cl_item, inv = {"pos": "%02d" % int(pos.split('-')[0]), "inv": []}, [] for row in res[pos]: From 4f1a3876ec8302df49a0336903371297d420e6b3 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 25 Mar 2020 16:54:17 +0530 Subject: [PATCH 024/104] fix: Remove debug --- erpnext/regional/report/gstr_1/gstr_1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py index e9355f665e5..a4d0bf59c11 100644 --- a/erpnext/regional/report/gstr_1/gstr_1.py +++ b/erpnext/regional/report/gstr_1/gstr_1.py @@ -142,7 +142,7 @@ class Gstr1Report(object): where docstatus = 1 {where_conditions} order by posting_date desc """.format(select_columns=self.select_columns, doctype=self.doctype, - where_conditions=conditions), self.filters, as_dict=1, debug=1) + where_conditions=conditions), self.filters, as_dict=1) for d in invoice_data: self.invoices.setdefault(d.invoice_number, d) From bcb9c285976d99b7082d9afaae836101b276f7f6 Mon Sep 17 00:00:00 2001 From: P-Froggy <60393001+P-Froggy@users.noreply.github.com> Date: Thu, 26 Mar 2020 02:35:09 +0100 Subject: [PATCH 025/104] Fix: Add missing bank accounts reference in supplier dashboard --- erpnext/buying/doctype/supplier/supplier_dashboard.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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'] From 750985dc23eba0ba9f70590d1c4cdb2a20c989e7 Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 26 Mar 2020 13:18:36 +0530 Subject: [PATCH 026/104] feat: auto set batch no on serial no selection (#20758) * feat: auto set batch no on serial no selection * fix: dialog not shown if set warehouse selected * fix: typo * fix: merge conflict * fix: callback no getting called after serial no selected * fix: callback no getting called after serial no selected * fix: available batch qty not fetched without set_warehouse selected * fix: item batch not synced with dialog batch table --- erpnext/public/js/controllers/transaction.js | 15 +- .../js/utils/serial_no_batch_selector.js | 144 +++++++++++------- erpnext/selling/sales_common.js | 9 +- erpnext/stock/doctype/serial_no/serial_no.py | 11 +- 4 files changed, 119 insertions(+), 60 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 146895097c5..ce27c6becce 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -4,7 +4,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ setup: function() { this._super(); - frappe.flags.hide_serial_batch_dialog = false; + frappe.flags.hide_serial_batch_dialog = true; frappe.ui.form.on(this.frm.doctype + " Item", "rate", function(frm, cdt, cdn) { var item = frappe.get_doc(cdt, cdn); var has_margin_field = frappe.meta.has_field(cdt, 'margin_type'); @@ -506,6 +506,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ }, () => me.frm.script_manager.trigger("price_list_rate", cdt, cdn), () => me.toggle_conversion_factor(item), + () => { + if (show_batch_dialog) + return frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"]) + .then((r) => { + if(r.message.has_batch_no || r.message.has_serial_no) { + frappe.flags.hide_serial_batch_dialog = false; + } + }); + }, () => { if(show_batch_dialog && !frappe.flags.hide_serial_batch_dialog) { var d = locals[cdt][cdn]; @@ -515,7 +524,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ erpnext.show_serial_batch_selector(me.frm, d, (item) => { me.frm.script_manager.trigger('qty', item.doctype, item.name); - }); + if (!me.frm.doc.set_warehouse) + me.frm.script_manager.trigger('warehouse', item.doctype, item.name); + }, undefined, !frappe.flags.hide_serial_batch_dialog); } }, () => me.conversion_factor(doc, cdt, cdn, true), diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index 101ac9cd610..e78ab9fb690 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -5,14 +5,13 @@ erpnext.SerialNoBatchSelector = Class.extend({ this.show_dialog = show_dialog; // frm, item, warehouse_details, has_batch, oldest let d = this.item; - if (d && d.has_batch_no && (!d.batch_no || this.show_dialog)) { - this.has_batch = 1; - this.setup(); + this.has_batch = 0; this.has_serial_no = 0; + + if (d && d.has_batch_no && (!d.batch_no || this.show_dialog)) this.has_batch = 1; // !(this.show_dialog == false) ensures that show_dialog is implictly true, even when undefined - } else if(d && d.has_serial_no && !(this.show_dialog == false)) { - this.has_batch = 0; - this.setup(); - } + if(d && d.has_serial_no && !(this.show_dialog == false)) this.has_serial_no = 1; + + this.setup(); }, setup: function() { @@ -36,16 +35,16 @@ erpnext.SerialNoBatchSelector = Class.extend({ label: __('Item Code'), default: me.item_code }, - {fieldtype:'Column Break'}, { fieldname: 'warehouse', fieldtype:'Link', options: 'Warehouse', + reqd: me.has_batch && !me.has_serial_no ? 0 : 1, label: __(me.warehouse_details.type), - default: me.warehouse_details.name, + default: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '', onchange: function(e) { - if(me.has_batch) { + if(me.has_batch && !me.has_serial_no) { fields = fields.concat(me.get_batch_fields()); } else { fields = fields.concat(me.get_serial_no_fields()); @@ -74,15 +73,16 @@ erpnext.SerialNoBatchSelector = Class.extend({ { fieldname: 'qty', fieldtype:'Float', - read_only: me.has_batch, - label: __(me.has_batch ? 'Total Qty' : 'Qty'), + read_only: me.has_batch && !me.has_serial_no, + label: __(me.has_batch && !me.has_serial_no ? 'Total Qty' : 'Qty'), default: 0 }, { fieldname: 'auto_fetch_button', fieldtype:'Button', - hidden: me.has_batch, - label: __('Fetch based on FIFO'), + hidden: me.has_batch && !me.has_serial_no, + label: __('Auto Fetch'), + description: __('Fetch Serial Numbers based on FIFO'), click: () => { let qty = this.dialog.fields_dict.qty.get_value(); let numbers = frappe.call({ @@ -90,7 +90,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ args: { qty: qty, item_code: me.item_code, - warehouse: me.warehouse_details.name, + warehouse: typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '', batch_no: me.item.batch_no || null } }); @@ -109,10 +109,12 @@ erpnext.SerialNoBatchSelector = Class.extend({ } ]; - if (this.has_batch) { + if (this.has_batch && !this.has_serial_no) { title = __("Select Batch Numbers"); fields = fields.concat(this.get_batch_fields()); } else { + // if only serial no OR + // if both batch_no & serial_no then only select serial_no and auto set batches nos title = __("Select Serial Numbers"); fields = fields.concat(this.get_serial_no_fields()); } @@ -122,25 +124,31 @@ erpnext.SerialNoBatchSelector = Class.extend({ fields: fields }); - if (this.item.serial_no) { - this.dialog.fields_dict.serial_no.set_value(this.item.serial_no); - } - this.dialog.set_primary_action(__('Insert'), function() { me.values = me.dialog.get_values(); if(me.validate()) { - me.set_items(); - me.dialog.hide(); + frappe.run_serially([ + () => me.update_batch_items(), + () => me.update_serial_no_item(), + () => me.update_batch_serial_no_items(), + () => { + refresh_field("items"); + if (me.callback) { + return me.callback(me.item); + } + }, + () => me.dialog.hide() + ]) } }); if(this.show_dialog) { let d = this.item; - if (d.has_serial_no && d.serial_no) { - this.dialog.set_value('serial_no', d.serial_no); + if (this.item.serial_no) { + this.dialog.fields_dict.serial_no.set_value(this.item.serial_no); } - - if (d.has_batch_no && d.batch_no) { + + if (this.has_batch && !this.has_serial_no && d.batch_no) { this.frm.doc.items.forEach(data => { if(data.item_code == d.item_code) { this.dialog.fields_dict.batches.df.data.push({ @@ -155,7 +163,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ } } - if (this.has_batch) { + if (this.has_batch && !this.has_serial_no) { this.update_total_qty(); } @@ -174,7 +182,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ frappe.throw(__("Please select a warehouse")); return false; } - if(this.has_batch) { + if(this.has_batch && !this.has_serial_no) { if(values.batches.length === 0 || !values.batches) { frappe.throw(__("Please select batches for batched item " + values.item_code)); @@ -193,34 +201,23 @@ erpnext.SerialNoBatchSelector = Class.extend({ } else { let serial_nos = values.serial_no || ''; if (!serial_nos || !serial_nos.replace(/\s/g, '').length) { - if (!this.show_dialog) { - frappe.throw(__("Please enter serial numbers for serialized item " - + values.item_code)); - return false; - } + frappe.throw(__("Please enter serial numbers for serialized item " + + values.item_code)); + return false; } return true; } }, - set_items: function() { - var me = this; - if(this.has_batch) { + update_batch_items() { + // clones an items if muliple batches are selected. + if(this.has_batch && !this.has_serial_no) { this.values.batches.map((batch, i) => { let batch_no = batch.batch_no; let row = ''; if (i !== 0 && !this.batch_exists(batch_no)) { - row = this.frm.add_child("items", { - 'item_code': this.item.item_code, - 'item_name': this.item.item_name, - 'price_list_rate': this.item.price_list_rate, - 'rate': this.item.rate, - 'qty': batch.selected_qty, - 'batch_no': batch_no, - 'actual_qty': this.item.actual_qty, - 'discount_percentage': this.item.discount_percentage - }); + row = this.frm.add_child("items", { ...this.item }); } else { row = this.frm.doc.items.find(i => i.batch_no === batch_no); } @@ -228,16 +225,59 @@ erpnext.SerialNoBatchSelector = Class.extend({ if (!row) { row = this.item; } - + // this ensures that qty & batch no is set this.map_row_values(row, batch, 'batch_no', 'selected_qty', this.values.warehouse); }); - } else { + } + }, + + update_serial_no_item() { + // just updates serial no for the item + if(this.has_serial_no && !this.has_batch) { this.map_row_values(this.item, this.values, 'serial_no', 'qty'); } + }, - refresh_field("items"); - this.callback && this.callback(this.item); + update_batch_serial_no_items() { + // if serial no selected is from different batches, adds new rows for each batch. + if(this.has_batch && this.has_serial_no) { + const selected_serial_nos = this.values.serial_no.split(/\n/g).filter(s => s); + + return frappe.db.get_list("Serial No", { + filters: { 'name': ["in", selected_serial_nos]}, + fields: ["batch_no", "name"] + }).then((data) => { + // data = [{batch_no: 'batch-1', name: "SR-001"}, + // {batch_no: 'batch-2', name: "SR-003"}, {batch_no: 'batch-2', name: "SR-004"}] + const batch_serial_map = data.reduce((acc, d) => { + if (!acc[d['batch_no']]) acc[d['batch_no']] = []; + acc[d['batch_no']].push(d['name']) + return acc + }, {}) + // batch_serial_map = { "batch-1": ['SR-001'], "batch-2": ["SR-003", "SR-004"]} + Object.keys(batch_serial_map).map((batch_no, i) => { + let row = ''; + const serial_no = batch_serial_map[batch_no]; + if (i == 0) { + row = this.item; + this.map_row_values(row, {qty: serial_no.length, batch_no: batch_no}, 'batch_no', + 'qty', this.values.warehouse); + } else if (!this.batch_exists(batch_no)) { + row = this.frm.add_child("items", { ...this.item }); + row.batch_no = batch_no; + } else { + row = this.frm.doc.items.find(i => i.batch_no === batch_no); + } + const values = { + 'qty': serial_no.length, + 'serial_no': serial_no.join('\n') + } + this.map_row_values(row, values, 'serial_no', + 'qty', this.values.warehouse); + }); + }) + } }, batch_exists: function(batch) { @@ -287,7 +327,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ return { filters: { item_code: me.item_code, - warehouse: me.warehouse || me.warehouse_details.name + warehouse: me.warehouse || typeof me.warehouse_details.name == "string" ? me.warehouse_details.name : '' }, query: 'erpnext.controllers.queries.get_batch_no' }; @@ -447,7 +487,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ { fieldname: 'serial_no', fieldtype: 'Small Text', - label: __(me.has_batch ? 'Selected Batch Numbers' : 'Selected Serial Numbers'), + label: __(me.has_batch && !me.has_serial_no ? 'Selected Batch Numbers' : 'Selected Serial Numbers'), onchange: function() { me.serial_list = this.get_value() .replace(/\n/g, ' ').match(/\S+/g) || []; diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 8278745a804..af100692c6f 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -413,15 +413,20 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ */ set_batch_number: function(cdt, cdn) { const doc = frappe.get_doc(cdt, cdn); - if (doc && doc.has_batch_no) { + if (doc && doc.has_batch_no && doc.warehouse) { this._set_batch_number(doc); } }, _set_batch_number: function(doc) { + let args = {'item_code': doc.item_code, 'warehouse': doc.warehouse, 'qty': flt(doc.qty) * flt(doc.conversion_factor)}; + if (doc.has_serial_no && doc.serial_no) { + args['serial_no'] = doc.serial_no + } + return frappe.call({ method: 'erpnext.stock.doctype.batch.batch.get_batch_no', - args: {'item_code': doc.item_code, 'warehouse': doc.warehouse, 'qty': flt(doc.qty) * flt(doc.conversion_factor)}, + args: args, callback: function(r) { if(r.message) { frappe.model.set_value(doc.doctype, doc.name, 'batch_no', r.message); diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 31f84c9aaed..cc186f2dbe7 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -503,12 +503,15 @@ def get_delivery_note_serial_no(item_code, qty, delivery_note): return serial_nos @frappe.whitelist() -def auto_fetch_serial_number(qty, item_code, warehouse, batch_no=None): - serial_numbers = frappe.get_list("Serial No", filters={ +def auto_fetch_serial_number(qty, item_code, warehouse, batch_nos=None): + import json + filters = { "item_code": item_code, "warehouse": warehouse, - "batch_no": batch_no, "delivery_document_no": "", "sales_invoice": "" - }, limit=qty, order_by="creation") + } + if batch_nos: filters["batch_no"] = ["in", json.loads(batch_nos)] + + serial_numbers = frappe.get_list("Serial No", filters=filters, limit=qty, order_by="creation") return [item['name'] for item in serial_numbers] From b9f81d913b605228737d8f2c8e8ee63133fc9a9a Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 26 Mar 2020 13:20:27 +0530 Subject: [PATCH 027/104] fix: currency not fetched on quotation creation (#20998) --- erpnext/selling/doctype/customer/customer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 791a3e1536a..4fca05ba7ea 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -231,9 +231,11 @@ def make_quotation(source_name, target_doc=None): target_doc.run_method("set_other_charges") target_doc.run_method("calculate_taxes_and_totals") - price_list = frappe.get_value("Customer", source_name, "default_price_list") + price_list, currency = frappe.db.get_value("Customer", source_name, ['default_price_list', 'default_currency']) if price_list: target_doc.selling_price_list = price_list + if currency: + target_doc.currency = currency return target_doc From 01f80b239de1aa87e96d4753a90b8805c032e77a Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 26 Mar 2020 13:23:06 +0530 Subject: [PATCH 028/104] fix: wrong calculation of depreciation eliminated for a period (#21032) --- .../asset_depreciations_and_balances.py | 213 +++++++++--------- 1 file changed, 112 insertions(+), 101 deletions(-) diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py index 0c99f1424cf..d7efbad240d 100644 --- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py +++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py @@ -4,126 +4,137 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import formatdate, getdate, flt, add_days +from frappe.utils import formatdate, flt, add_days + def execute(filters=None): filters.day_before_from_date = add_days(filters.from_date, -1) columns, data = get_columns(filters), get_data(filters) return columns, data - + + def get_data(filters): data = [] - + asset_categories = get_asset_categories(filters) assets = get_assets(filters) - asset_costs = get_asset_costs(assets, filters) - asset_depreciations = get_accumulated_depreciations(assets, filters) - + for asset_category in asset_categories: row = frappe._dict() - row.asset_category = asset_category - row.update(asset_costs.get(asset_category)) + # row.asset_category = asset_category + row.update(asset_category) + + row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase) - + flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset)) + + row.update(next(asset for asset in assets if asset["asset_category"] == asset_category.get("asset_category", ""))) + row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) + + flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated_during_the_period)) + + row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) - + flt(row.accumulated_depreciation_as_on_from_date)) + + row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) - + flt(row.accumulated_depreciation_as_on_to_date)) - row.cost_as_on_to_date = (flt(row.cost_as_on_from_date) + flt(row.cost_of_new_purchase) - - flt(row.cost_of_sold_asset) - flt(row.cost_of_scrapped_asset)) - - row.update(asset_depreciations.get(asset_category)) - row.accumulated_depreciation_as_on_to_date = (flt(row.accumulated_depreciation_as_on_from_date) + - flt(row.depreciation_amount_during_the_period) - flt(row.depreciation_eliminated)) - - row.net_asset_value_as_on_from_date = (flt(row.cost_as_on_from_date) - - flt(row.accumulated_depreciation_as_on_from_date)) - - row.net_asset_value_as_on_to_date = (flt(row.cost_as_on_to_date) - - flt(row.accumulated_depreciation_as_on_to_date)) - data.append(row) - + return data - + + def get_asset_categories(filters): - return frappe.db.sql_list(""" - select distinct asset_category from `tabAsset` - where docstatus=1 and company=%s and purchase_date <= %s - """, (filters.company, filters.to_date)) - + return frappe.db.sql(""" + SELECT asset_category, + ifnull(sum(case when purchase_date < %(from_date)s then + case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then + gross_purchase_amount + else + 0 + end + else + 0 + end), 0) as cost_as_on_from_date, + ifnull(sum(case when purchase_date >= %(from_date)s then + gross_purchase_amount + else + 0 + end), 0) as cost_of_new_purchase, + ifnull(sum(case when ifnull(disposal_date, 0) != 0 + and disposal_date >= %(from_date)s + and disposal_date <= %(to_date)s then + case when status = "Sold" then + gross_purchase_amount + else + 0 + end + else + 0 + end), 0) as cost_of_sold_asset, + ifnull(sum(case when ifnull(disposal_date, 0) != 0 + and disposal_date >= %(from_date)s + and disposal_date <= %(to_date)s then + case when status = "Scrapped" then + gross_purchase_amount + else + 0 + end + else + 0 + end), 0) as cost_of_scrapped_asset + from `tabAsset` + where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s + group by asset_category + """, {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1) + def get_assets(filters): return frappe.db.sql(""" - select name, asset_category, purchase_date, gross_purchase_amount, disposal_date, status - from `tabAsset` - where docstatus=1 and company=%s and purchase_date <= %s""", - (filters.company, filters.to_date), as_dict=1) - -def get_asset_costs(assets, filters): - asset_costs = frappe._dict() - for d in assets: - asset_costs.setdefault(d.asset_category, frappe._dict({ - "cost_as_on_from_date": 0, - "cost_of_new_purchase": 0, - "cost_of_sold_asset": 0, - "cost_of_scrapped_asset": 0 - })) - - costs = asset_costs[d.asset_category] - - if getdate(d.purchase_date) < getdate(filters.from_date): - if not d.disposal_date or getdate(d.disposal_date) >= getdate(filters.from_date): - costs.cost_as_on_from_date += flt(d.gross_purchase_amount) - else: - costs.cost_of_new_purchase += flt(d.gross_purchase_amount) - - if d.disposal_date and getdate(d.disposal_date) >= getdate(filters.from_date) \ - and getdate(d.disposal_date) <= getdate(filters.to_date): - if d.status == "Sold": - costs.cost_of_sold_asset += flt(d.gross_purchase_amount) - elif d.status == "Scrapped": - costs.cost_of_scrapped_asset += flt(d.gross_purchase_amount) - - return asset_costs - -def get_accumulated_depreciations(assets, filters): - asset_depreciations = frappe._dict() - for d in assets: - asset = frappe.get_doc("Asset", d.name) - - if d.asset_category in asset_depreciations: - asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation - else: - asset_depreciations.setdefault(d.asset_category, frappe._dict({ - "accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation, - "depreciation_amount_during_the_period": 0, - "depreciation_eliminated_during_the_period": 0 - })) + SELECT results.asset_category, + sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date, + sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period, + sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period + from (SELECT a.asset_category, + ifnull(sum(case when ds.schedule_date < %(from_date)s then + ds.depreciation_amount + else + 0 + end), 0) as accumulated_depreciation_as_on_from_date, + ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s + and a.disposal_date <= %(to_date)s and ds.schedule_date <= a.disposal_date then + ds.depreciation_amount + else + 0 + end), 0) as depreciation_eliminated_during_the_period, + ifnull(sum(case when ds.schedule_date >= %(from_date)s and ds.schedule_date <= %(to_date)s + and (ifnull(a.disposal_date, 0) = 0 or ds.schedule_date <= a.disposal_date) then + ds.depreciation_amount + else + 0 + end), 0) as depreciation_amount_during_the_period + from `tabAsset` a, `tabDepreciation Schedule` ds + where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent + group by a.asset_category + union + SELECT a.asset_category, + ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 + and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) + then + 0 + else + a.opening_accumulated_depreciation + end), 0) as accumulated_depreciation_as_on_from_date, + ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then + a.opening_accumulated_depreciation + else + 0 + end), 0) as depreciation_eliminated_during_the_period, + 0 as depreciation_amount_during_the_period + from `tabAsset` a + where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s + group by a.asset_category) as results + group by results.asset_category + """, {"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company}, as_dict=1) - depr = asset_depreciations[d.asset_category] - if not asset.schedules: # if no schedule, - if asset.disposal_date: - # and disposal is NOT within the period, then opening accumulated depreciation not included - if getdate(asset.disposal_date) < getdate(filters.from_date) or getdate(asset.disposal_date) > getdate(filters.to_date): - asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] = 0 - - # if no schedule, and disposal is within period, accumulated dep is the amount eliminated - if getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date): - depr.depreciation_eliminated_during_the_period += asset.opening_accumulated_depreciation - - for schedule in asset.get("schedules"): - if getdate(schedule.schedule_date) < getdate(filters.from_date): - if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date): - depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount) - elif getdate(schedule.schedule_date) <= getdate(filters.to_date): - if not asset.disposal_date: - depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount) - else: - if getdate(schedule.schedule_date) <= getdate(asset.disposal_date): - depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount) - - if asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date) and getdate(asset.disposal_date) <= getdate(filters.to_date): - if getdate(schedule.schedule_date) <= getdate(asset.disposal_date): - depr.depreciation_eliminated_during_the_period += flt(schedule.depreciation_amount) - - return asset_depreciations - def get_columns(filters): return [ { From 6b038bda0de5c7a81e942bec6602f244e02fd28b Mon Sep 17 00:00:00 2001 From: Marica Date: Thu, 26 Mar 2020 13:23:54 +0530 Subject: [PATCH 029/104] fix: Project field in Stock Entry Detail should be editable (#21000) --- .../doctype/stock_entry_detail/stock_entry_detail.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json index d86e68b7222..a848c80cf2c 100644 --- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json +++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "hash", "creation": "2013-03-29 18:22:12", "doctype": "DocType", @@ -479,8 +480,7 @@ "fieldname": "project", "fieldtype": "Link", "label": "Project", - "options": "Project", - "read_only": 1 + "options": "Project" }, { "fieldname": "po_detail", @@ -494,7 +494,8 @@ ], "idx": 1, "istable": 1, - "modified": "2019-08-20 14:01:02.319754", + "links": [], + "modified": "2020-03-19 12:34:09.836295", "modified_by": "Administrator", "module": "Stock", "name": "Stock Entry Detail", From 72430e91b267b5cc8fca9913862dba6ceace772d Mon Sep 17 00:00:00 2001 From: Raffael Meyer Date: Thu, 26 Mar 2020 08:55:14 +0100 Subject: [PATCH 030/104] fix: account groups (#21046) --- ..._kontenplan_SKR04_with_account_number.json | 387 ++++++++---------- 1 file changed, 177 insertions(+), 210 deletions(-) diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json index 275374a4b70..4ee12209caa 100644 --- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json +++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json @@ -2417,29 +2417,26 @@ "Erl\u00f6se aus Verk\u00e4ufen Sachanlageverm\u00f6gen (bei Buchgewinn)": { "account_number": "4849" }, - "Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn) (Gruppe)": { - "is_group": 1, - "Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn)": { - "account_number": "4850" - }, - "Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (bei Buchgewinn)": { - "account_number": "4851" - }, - "Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (inl\u00e4ndische Kap.Ges., bei Buchgewinn)": { - "account_number": "4852" - }, - "Anlagenabg\u00e4nge Sachanlagen (Restbuchwert bei Buchvergewinn)": { - "account_number": "4855" - }, - "Anlagenabg\u00e4nge immaterielle VG (Restbuchwert bei Buchgewinn)": { - "account_number": "4856" - }, - "Anlagenabg\u00e4nge Finanzanlagen (Restbuchwert bei Buchgewinn)": { - "account_number": "4857" - }, - "Anlagenabg\u00e4nge Finanzanlagen (inl\u00e4ndische Kap.Ges., Restbuchwert bei Buchgewinn)": { - "account_number": "4858" - } + "Erl\u00f6se aus Verk\u00e4ufen immaterieller VG (bei Buchgewinn)": { + "account_number": "4850" + }, + "Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (bei Buchgewinn)": { + "account_number": "4851" + }, + "Erl\u00f6se aus Verk\u00e4ufen Finanzanlagen (inl\u00e4ndische Kap.Ges., bei Buchgewinn)": { + "account_number": "4852" + }, + "Anlagenabg\u00e4nge Sachanlagen (Restbuchwert bei Buchvergewinn)": { + "account_number": "4855" + }, + "Anlagenabg\u00e4nge immaterielle VG (Restbuchwert bei Buchgewinn)": { + "account_number": "4856" + }, + "Anlagenabg\u00e4nge Finanzanlagen (Restbuchwert bei Buchgewinn)": { + "account_number": "4857" + }, + "Anlagenabg\u00e4nge Finanzanlagen (inl\u00e4ndische Kap.Ges., Restbuchwert bei Buchgewinn)": { + "account_number": "4858" }, "Ertr\u00e4ge aus Zuschreibungen des Sachanlageverm\u00f6gens": { "account_number": "4910", @@ -2562,20 +2559,17 @@ "Entnahme von Gegenst\u00e4nden ohne USt": { "account_number": "4605" }, - "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt (Gruppe)": { - "is_group": 1, - "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt": { - "account_number": "4630" - }, - "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt": { - "account_number": "4637" - }, - "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternnehmens ohne USt (Telefon-Nutzung)": { - "account_number": "4638" - }, - "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt (Kfz-Nutzung)": { - "account_number": "4639" - } + "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 7 % USt": { + "account_number": "4630" + }, + "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt": { + "account_number": "4637" + }, + "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternnehmens ohne USt (Telefon-Nutzung)": { + "account_number": "4638" + }, + "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens ohne USt (Kfz-Nutzung)": { + "account_number": "4639" }, "Verwendung von Gegenst\u00e4nden f. Zwecke au\u00dferhalb des Unternehmens 19 % USt (Gruppe)": { "is_group": 1, @@ -2613,14 +2607,11 @@ "Unentgeltliche Zuwendung von Gegenst\u00e4nden ohne USt": { "account_number": "4689" }, - "Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze) (Gruppe)": { - "is_group": 1, - "Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze)": { - "account_number": "4690" - }, - "Umsatzsteuerverg\u00fctungen, z.B. nach \u00a7 24 UStG": { - "account_number": "4695" - } + "Nicht steuerbare Ums\u00e4tze (Innenums\u00e4tze)": { + "account_number": "4690" + }, + "Umsatzsteuerverg\u00fctungen, z.B. nach \u00a7 24 UStG": { + "account_number": "4695" }, "Au\u00dferordentliche Ertr\u00e4ge (Gruppe)": { "is_group": 1, @@ -2630,41 +2621,35 @@ "Au\u00dferordentliche Ertr\u00e4ge finanzwirksam": { "account_number": "7401" }, - "Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam (Gruppe)": { - "is_group": 1, - "Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam": { - "account_number": "7450" - }, - "Ertr\u00e4ge durch Verschmelzung und Umwandlung": { - "account_number": "7451" - }, - "Ertr\u00e4ge durch den Verkauf von bedeutenden Beteiligungen": { - "account_number": "7452" - }, - "Ert\u00e4ge durch den Verkauf von bedeutenden Grundst\u00fccken": { - "account_number": "7453" - }, - "Gewinn aus der Ver\u00e4u\u00dferung oder der Aufgabe von Gesch\u00e4ftsaktivit\u00e4ten nach Steuern": { - "account_number": "7454" - } + "Au\u00dferordentliche Ertr\u00e4ge nicht finanzwirksam": { + "account_number": "7450" }, - "Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften (Gruppe)": { - "is_group": 1, - "Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften": { - "account_number": "7460" - }, - "Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Sachanlageverm\u00f6gen": { - "account_number": "7461" - }, - "Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Finanzanlageverm\u00f6gen": { - "account_number": "7462" - }, - "Au\u00dferordentliche Ertr\u00e4ge: Wertpapiere im Umlaufverm\u00f6gen": { - "account_number": "7463" - }, - "Au\u00dferordentliche Ertr\u00e4ge: latente Steuern": { - "account_number": "7464" - } + "Ertr\u00e4ge durch Verschmelzung und Umwandlung": { + "account_number": "7451" + }, + "Ertr\u00e4ge durch den Verkauf von bedeutenden Beteiligungen": { + "account_number": "7452" + }, + "Ert\u00e4ge durch den Verkauf von bedeutenden Grundst\u00fccken": { + "account_number": "7453" + }, + "Gewinn aus der Ver\u00e4u\u00dferung oder der Aufgabe von Gesch\u00e4ftsaktivit\u00e4ten nach Steuern": { + "account_number": "7454" + }, + "Au\u00dferordentliche Ertr\u00e4ge aus der Anwendung von \u00dcbergangsvorschriften": { + "account_number": "7460" + }, + "Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Sachanlageverm\u00f6gen": { + "account_number": "7461" + }, + "Au\u00dferordentliche Ertr\u00e4ge: Zuschreibung f. Finanzanlageverm\u00f6gen": { + "account_number": "7462" + }, + "Au\u00dferordentliche Ertr\u00e4ge: Wertpapiere im Umlaufverm\u00f6gen": { + "account_number": "7463" + }, + "Au\u00dferordentliche Ertr\u00e4ge: latente Steuern": { + "account_number": "7464" } } }, @@ -2702,40 +2687,43 @@ }, "Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 16 % USt": { "account_number": "4729" + } + }, + "Gew\u00e4hrte Skonti (Gruppe)": { + "is_group": 1, + "Gew. Skonti": { + "account_number": "4730" }, - "Gew\u00e4hrte Skonti (Gruppe)": { - "is_group": 1, - "Gew. Skonti": { - "account_number": "4730" - }, - "Gew. Skonti 7 % USt": { - "account_number": "4731" - }, - "Gew. Skonti 19 % USt": { - "account_number": "4736" - }, - "Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": { - "account_number": "4738" - }, - "Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": { - "account_number": "4741" - }, - "Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": { - "account_number": "4742" - }, - "Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": { - "account_number": "4743" - }, - "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": { - "account_number": "4745" - }, - "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": { - "account_number": "4746" - }, - "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": { - "account_number": "4748" - } + "Gew. Skonti 7 % USt": { + "account_number": "4731" }, + "Gew. Skonti 19 % USt": { + "account_number": "4736" + }, + "Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": { + "account_number": "4738" + }, + "Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": { + "account_number": "4741" + }, + "Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": { + "account_number": "4742" + }, + "Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": { + "account_number": "4743" + }, + "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": { + "account_number": "4745" + }, + "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": { + "account_number": "4746" + }, + "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": { + "account_number": "4748" + } + }, + "Gew\u00e4hrte Boni (Gruppe)": { + "is_group": 1, "Gew\u00e4hrte Boni 7 % USt": { "account_number": "4750" }, @@ -2848,103 +2836,79 @@ "account_number": "6398" } }, - "Versicherungen (Gruppe)": { - "is_group": 1, - "Versicherungen": { - "account_number": "6400" - }, - "Versicherungen f. Geb\u00e4ude, die zum Betriebsverm\u00f6gen geh\u00f6ren": { - "account_number": "6405" - }, - "Netto-Pr\u00e4mie f. R\u00fcckdeckung k\u00fcnftiger Versorgungsleistungen": { - "account_number": "6410" - }, - "Beitr\u00e4ge": { - "account_number": "6420" - }, - "Sonstige Abgaben": { - "account_number": "6430" - }, - "Steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": { - "account_number": "6436" - }, - "Steuerlich nicht abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": { - "account_number": "6437" - }, - "Ausgleichsabgabe i. S. d. Schwerbehindertengesetzes": { - "account_number": "6440" - }, - "Reparaturen und Instandhaltung von Bauten": { - "account_number": "6450" - }, - "Reparaturen und Instandhaltung von technischenAnlagen und Maschinen": { - "account_number": "6460" - }, - "Reparaturen und Instandhaltung von anderen Anlagen und Betriebs- und Gesch\u00e4ftsausstattung": { - "account_number": "6470" - }, - "Zuf\u00fchrung zu Aufwandsr\u00fcckstellungen": { - "account_number": "6475" - }, - "Reparaturen und Instandhaltung von anderen Anlagen": { - "account_number": "6485" - }, - "Sonstige Reparaturen und Instandhaltungen": { - "account_number": "6490" - }, - "Wartungskosten f. Hard- und Software": { - "account_number": "6495" - }, - "Mietleasing (bewegliche Wirtschaftsg\u00fcter)": { - "account_number": "6498" - } + "Versicherungen": { + "account_number": "6400" + }, + "Versicherungen f. Geb\u00e4ude, die zum Betriebsverm\u00f6gen geh\u00f6ren": { + "account_number": "6405" + }, + "Netto-Pr\u00e4mie f. R\u00fcckdeckung k\u00fcnftiger Versorgungsleistungen": { + "account_number": "6410" + }, + "Beitr\u00e4ge": { + "account_number": "6420" + }, + "Sonstige Abgaben": { + "account_number": "6430" + }, + "Steuerlich abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": { + "account_number": "6436" + }, + "Steuerlich nicht abzugsf\u00e4hige Versp\u00e4tungszuschl\u00e4ge und Zwangsgelder": { + "account_number": "6437" + }, + "Ausgleichsabgabe i. S. d. Schwerbehindertengesetzes": { + "account_number": "6440" + }, + "Reparaturen und Instandhaltung von Bauten": { + "account_number": "6450" + }, + "Reparaturen und Instandhaltung von technischenAnlagen und Maschinen": { + "account_number": "6460" + }, + "Reparaturen und Instandhaltung von anderen Anlagen und Betriebs- und Gesch\u00e4ftsausstattung": { + "account_number": "6470" + }, + "Zuf\u00fchrung zu Aufwandsr\u00fcckstellungen": { + "account_number": "6475" + }, + "Reparaturen und Instandhaltung von anderen Anlagen": { + "account_number": "6485" + }, + "Sonstige Reparaturen und Instandhaltungen": { + "account_number": "6490" + }, + "Wartungskosten f. Hard- und Software": { + "account_number": "6495" + }, + "Mietleasing (bewegliche Wirtschaftsg\u00fcter)": { + "account_number": "6498" }, "Fahrzeugkosten (Gruppe)": { "is_group": 1, "Fahrzeugkosten": { "account_number": "6500" }, - "Kfz-Versicherungen (Gruppe)": { - "is_group": 1, - "Kfz-Versicherungen": { - "account_number": "6520" - } + "Kfz-Versicherungen": { + "account_number": "6520" }, - "Laufende Kfz-Betriebskosten (Gruppe)": { - "is_group": 1, - "Laufende Kfz-Betriebskosten": { - "account_number": "6530" - } + "Laufende Kfz-Betriebskosten": { + "account_number": "6530" }, - "Kfz-Reparaturen (Gruppe)": { - "is_group": 1, - "Kfz-Reparaturen": { - "account_number": "6540" - } + "Kfz-Reparaturen": { + "account_number": "6540" }, - "Garagenmiete (Gruppe)": { - "is_group": 1, - "Garagenmiete": { - "account_number": "6550" - } + "Garagenmiete": { + "account_number": "6550" }, - "Mietleasing Kfz (Gruppe)": { - "is_group": 1, - "Mietleasing Kfz": { - "account_number": "6560" - } + "Mietleasing Kfz": { + "account_number": "6560" }, - "Sonstige Kfz-Kosten (Gruppe)": { - "is_group": 1, - "Sonstige Kfz-Kosten": { - "account_number": "6570" - } + "Sonstige Kfz-Kosten": { + "account_number": "6570" }, - "Mautgeb\u00fchren (Gruppe)": { - "is_group": 1, - "Mautgeb\u00fchren": { - "account_number": "6580" - } + "Mautgeb\u00fchren": { + "account_number": "6580" }, "Kfz-Kosten f. betrieblich genutzte zum Privatverm\u00f6gen geh\u00f6rende Kraftfahrzeuge": { "account_number": "6590" @@ -3006,20 +2970,23 @@ "Nicht abzugsf\u00e4hige Betriebsausgaben aus Werbe- und Repr\u00e4sentationskosten": { "account_number": "6645" }, - "Reisekosten Arbeitnehmer": { - "account_number": "6650" - }, - "Reisekosten Arbeitnehmer \u00dcbernachtungsaufwand": { - "account_number": "6660" - }, - "Reisekosten Arbeitnehmer Fahrtkosten": { - "account_number": "6663" - }, - "Reisekosten Arbeitnehmer Verpflegungsmehraufwand": { - "account_number": "6664" - }, - "Kilometergelderstattung Arbeitnehmer": { - "account_number": "6668" + "Reisekosten Arbeitnehmer (Gruppe)": { + "is_group": 1, + "Reisekosten Arbeitnehmer": { + "account_number": "6650" + }, + "Reisekosten Arbeitnehmer \u00dcbernachtungsaufwand": { + "account_number": "6660" + }, + "Reisekosten Arbeitnehmer Fahrtkosten": { + "account_number": "6663" + }, + "Reisekosten Arbeitnehmer Verpflegungsmehraufwand": { + "account_number": "6664" + }, + "Kilometergelderstattung Arbeitnehmer": { + "account_number": "6668" + } }, "Reisekosten Unternehmer (Gruppe)": { "is_group": 1, From 3c378aaac743ded787365019d426970bfbb0cc46 Mon Sep 17 00:00:00 2001 From: Marica Date: Thu, 26 Mar 2020 13:28:42 +0530 Subject: [PATCH 031/104] fix: Make shelf life mandatory in Batched Item if it has expiry date (#21045) --- erpnext/stock/doctype/batch/batch.py | 7 +++++-- erpnext/stock/doctype/item/item.json | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py index 8ae978eaf05..9b7249e66b9 100644 --- a/erpnext/stock/doctype/batch/batch.py +++ b/erpnext/stock/doctype/batch/batch.py @@ -122,8 +122,11 @@ class Batch(Document): self.expiry_date = add_days(self.manufacturing_date, shelf_life_in_days) if has_expiry_date and not self.expiry_date: - frappe.msgprint(_('Expiry date is mandatory for selected item.')) - frappe.throw(_("Set item's shelf life in days, to set expiry based on manufacturing date plus shelf-life.")) + frappe.throw(msg=_("Please set {0} for Batched Item {1}, which is used to set {2} on Submit.") \ + .format(frappe.bold("Shelf Life in Days"), + frappe.utils.get_link_to_form("Item", self.item), + frappe.bold("Batch Expiry Date")), + title=_("Expiry Date Mandatory")) def get_name_from_naming_series(self): """ diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index 3503e7cc1c5..aa6b2fedd7c 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -343,7 +343,8 @@ { "fieldname": "shelf_life_in_days", "fieldtype": "Int", - "label": "Shelf Life In Days" + "label": "Shelf Life In Days", + "mandatory_depends_on": "eval:doc.has_batch_no && doc.has_expiry_date" }, { "default": "2099-12-31", @@ -1045,7 +1046,7 @@ "image_field": "image", "links": [], "max_attachments": 1, - "modified": "2020-01-02 19:13:59.295963", + "modified": "2020-03-24 16:14:36.950677", "modified_by": "Administrator", "module": "Stock", "name": "Item", From 8a5587749b5f8c73bc72831d4e223911791ed426 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Thu, 26 Mar 2020 13:29:36 +0530 Subject: [PATCH 032/104] fix: Added hidden GL column in general ledger (#21022) Co-authored-by: Nabin Hait --- erpnext/accounts/report/general_ledger/general_ledger.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index f45911f90e5..6c9dec90f8c 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -131,7 +131,7 @@ def get_gl_entries(filters): gl_entries = frappe.db.sql( """ select - posting_date, account, party_type, party, + name as gl_entry, posting_date, account, party_type, party, voucher_type, voucher_no, cost_center, project, against_voucher_type, against_voucher, account_currency, remarks, against, is_opening {select_fields} @@ -362,6 +362,12 @@ def get_columns(filters): currency = get_company_currency(company) columns = [ + { + "fieldname": "gl_entry", + "fieldtype": "Link", + "options": "GL Entry", + "hidden": 1 + }, { "label": _("Posting Date"), "fieldname": "posting_date", From ff49a2f0b61483b0614018b902b9b206ffdaa623 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 26 Mar 2020 13:36:21 +0530 Subject: [PATCH 033/104] fix: Ignored user permission for parent_company and existing_company field in Company (#21010) --- erpnext/setup/doctype/company/company.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 5ce51a6e8d9..3eb8949a5fa 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -157,6 +157,7 @@ { "fieldname": "parent_company", "fieldtype": "Link", + "ignore_user_permissions": 1, "in_list_view": 1, "label": "Parent Company", "options": "Company" @@ -277,6 +278,7 @@ "depends_on": "eval:doc.create_chart_of_accounts_based_on===\"Existing Company\"", "fieldname": "existing_company", "fieldtype": "Link", + "ignore_user_permissions": 1, "label": "Existing Company ", "no_copy": 1, "options": "Company" @@ -728,7 +730,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2020-03-18 18:26:03.145312", + "modified": "2020-03-22 18:26:03.145312", "modified_by": "Administrator", "module": "Setup", "name": "Company", From c944676bb5cef15a535494ac7808f97e386b5639 Mon Sep 17 00:00:00 2001 From: marination Date: Thu, 26 Mar 2020 14:49:28 +0530 Subject: [PATCH 034/104] fix: Updated Bin Requested Qty logic --- erpnext/patches.txt | 1 + .../v12_0/recalculate_requested_qty_in_bin.py | 13 ++++++++++++ erpnext/stock/stock_balance.py | 21 ++++++++++++++----- 3 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 erpnext/patches/v12_0/recalculate_requested_qty_in_bin.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index de4c89c5ace..9850a70410c 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -651,3 +651,4 @@ erpnext.patches.v12_0.add_export_type_field_in_party_master erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22 erpnext.patches.v12_0.create_irs_1099_field_united_states erpnext.patches.v12_0.set_permission_einvoicing +erpnext.patches.v12_0.recalculate_requested_qty_in_bin \ No newline at end of file diff --git a/erpnext/patches/v12_0/recalculate_requested_qty_in_bin.py b/erpnext/patches/v12_0/recalculate_requested_qty_in_bin.py new file mode 100644 index 00000000000..8267df95e11 --- /dev/null +++ b/erpnext/patches/v12_0/recalculate_requested_qty_in_bin.py @@ -0,0 +1,13 @@ +from __future__ import unicode_literals +import frappe +from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty + +def execute(): + bin_details = frappe.db.sql(""" + SELECT item_code, warehouse + FROM `tabBin`""",as_dict=1) + + for entry in bin_details: + update_bin_qty(entry.get("item_code"), entry.get("warehouse"), { + "indented_qty": get_indented_qty(entry.get("item_code"), entry.get("warehouse")) + }) \ No newline at end of file diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py index e5dc6b12df7..2bdb04ed2c9 100644 --- a/erpnext/stock/stock_balance.py +++ b/erpnext/stock/stock_balance.py @@ -113,13 +113,24 @@ def get_reserved_qty(item_code, warehouse): return flt(reserved_qty[0][0]) if reserved_qty else 0 def get_indented_qty(item_code, warehouse): - indented_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor) + inward_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor) + from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr + where mr_item.item_code=%s and mr_item.warehouse=%s + and mr.material_request_type in ('Purchase', 'Manufacture') + and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name + and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse)) + + outward_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor) from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr where mr_item.item_code=%s and mr_item.warehouse=%s + and mr.material_request_type in ('Material Issue', 'Material Transfer') and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name and mr.status!='Stopped' and mr.docstatus=1""", (item_code, warehouse)) - return flt(indented_qty[0][0]) if indented_qty else 0 + inward_qty, outward_qty = flt(inward_qty[0][0]) if inward_qty else 0, flt(outward_qty[0][0]) if outward_qty else 0 + indented_qty = inward_qty - outward_qty + + return indented_qty def get_ordered_qty(item_code, warehouse): ordered_qty = frappe.db.sql(""" @@ -145,9 +156,9 @@ def update_bin_qty(item_code, warehouse, qty_dict=None): from erpnext.stock.utils import get_bin bin = get_bin(item_code, warehouse) mismatch = False - for fld, val in qty_dict.items(): - if flt(bin.get(fld)) != flt(val): - bin.set(fld, flt(val)) + for field, value in qty_dict.items(): + if flt(bin.get(field)) != flt(value): + bin.set(field, flt(value)) mismatch = True if mismatch: From 27f0d13bdd4490429453de3024451f466bc3227d Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Fri, 6 Mar 2020 20:55:02 +0530 Subject: [PATCH 035/104] feat: add status filter in issue web form --- erpnext/support/web_form/issues/issues.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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, From 0b8191d56644bc48fe092b804702a9e59a509a0f Mon Sep 17 00:00:00 2001 From: Poranut Chollavorn Date: Thu, 26 Mar 2020 13:46:36 +0000 Subject: [PATCH 036/104] fix(pos): fix pos display item instock --- .../page/point_of_sale/point_of_sale.py | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) 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 From d90f6581633df6e589c4dbb6d39a63b089f5f5ed Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 27 Mar 2020 12:54:01 +0530 Subject: [PATCH 037/104] fix: item not showing in popup while making batch --- erpnext/public/js/controllers/transaction.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 146895097c5..6c580d046f5 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -165,6 +165,16 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ return (doc.rule_applied) ? "green" : "red"; }); } + + let batch_no_field = this.frm.get_docfield("items", "batch_no"); + if (batch_no_field) { + batch_no_field.get_route_options_for_new_doc = function(row) { + return { + "item": row.doc.item_code + } + }; + } + }, onload: function() { var me = this; From b03d1327a57a9d0afbdf957bcb4dc98caf4f5127 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 27 Mar 2020 19:24:17 +0530 Subject: [PATCH 038/104] fix: Add item defaults based on global settings only if default company and warehouse is mentioned --- erpnext/stock/doctype/item/item.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) 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 \ From 2313d2d80a54d1a71141d677a7efb04a747acab4 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 27 Mar 2020 19:15:59 +0530 Subject: [PATCH 039/104] fix: total currency formatting --- .../accounts_receivable.html | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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]["paid"], data[i]["currency"]) %}{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} {%= format_currency(data[i]["credit_note"], data[0]["currency"]) %} - {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}{%= 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"]) %}{%= __("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"]) %}
(a) {{__("Outward taxable supplies(other than zero rated, nil rated and exempted")}}(a) {{__("Outward taxable supplies(other than zero rated, nil rated and exempted)")}} {{ flt(data.sup_details.osup_det.txval, 2) }} {{ flt(data.sup_details.osup_det.iamt, 2) }} {{ flt(data.sup_details.osup_det.camt, 2) }}
- {{ d.description }} - - {{ d.get_formatted("base_tax_amount") }} -
+ {{ d.description }} + + {{ d.get_formatted("base_tax_amount") }} +