From f805a76e792ca27392db5695b8ccd7902a6c02cc Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Wed, 13 Nov 2019 17:27:16 +0530 Subject: [PATCH 001/119] chore: pinned requirements --- requirements.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/requirements.txt b/requirements.txt index 28ba9f676ff..429f894edce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ frappe -unidecode -pygithub -googlemaps -python-stdnum -braintree -gocardless_pro -woocommerce -pandas -plaid-python \ No newline at end of file +Unidecode==1.1.1 +PyGithub==1.43.8 +googlemaps==3.1.1 +python-stdnum==1.11 +braintree==3.57.1 +gocardless-pro==1.10.0 +WooCommerce==2.1.1 +pandas==0.25.1 +plaid-python==3.4.0 From 3798f8bd25d6ac02c7d09da61e45db8c9a5c51e4 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 15 Nov 2019 13:59:15 +0530 Subject: [PATCH 002/119] style(requirements): alphabetically sorted requirements --- requirements.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 429f894edce..1ab84ad57b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -frappe -Unidecode==1.1.1 -PyGithub==1.43.8 -googlemaps==3.1.1 -python-stdnum==1.11 braintree==3.57.1 +frappe gocardless-pro==1.10.0 -WooCommerce==2.1.1 +googlemaps==3.1.1 pandas==0.25.1 plaid-python==3.4.0 +PyGithub==1.43.8 +python-stdnum==1.11 +Unidecode==1.1.1 +WooCommerce==2.1.1 From 73089470b18f2a04a28b3ba3391b1605e12becf4 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 15 Nov 2019 17:38:32 +0530 Subject: [PATCH 003/119] chore: pinned backwards compatible dependencies --- requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 1ab84ad57b5..c277545fab5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ braintree==3.57.1 frappe -gocardless-pro==1.10.0 +gocardless-pro==1.11.0 googlemaps==3.1.1 -pandas==0.25.1 +pandas==0.24.2 plaid-python==3.4.0 -PyGithub==1.43.8 -python-stdnum==1.11 +PyGithub==1.44.1 +python-stdnum==1.12 Unidecode==1.1.1 WooCommerce==2.1.1 From 83ed7df8cdd1332a6029c35473aa3dd40c36fee5 Mon Sep 17 00:00:00 2001 From: thefalconx33 Date: Sat, 11 Jan 2020 14:19:02 +0530 Subject: [PATCH 004/119] fix: auto cancel if movement exists --- erpnext/assets/doctype/asset/asset.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 3e7f6833a0c..86b5a11a1d1 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -132,9 +132,10 @@ class Asset(AccountsController): if len(movements) > 1: frappe.throw(_('Asset has multiple Asset Movement Entries which has to be \ cancelled manually to cancel this asset.')) - movement = frappe.get_doc('Asset Movement', movements[0].get('name')) - movement.flags.ignore_validate = True - movement.cancel() + if movements: + movement = frappe.get_doc('Asset Movement', movements[0].get('name')) + movement.flags.ignore_validate = True + movement.cancel() def make_asset_movement(self): reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice' From e5a572a4a8c914a601c8fde3273a57b48cd74276 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Mon, 6 Jan 2020 12:34:53 +0530 Subject: [PATCH 005/119] fix: Group by sales register report --- .../item_wise_sales_register.js | 35 +- .../item_wise_sales_register.py | 335 ++++++++++++++++-- .../report/sales_register/sales_register.py | 4 +- 3 files changed, 330 insertions(+), 44 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index 9dd9b3fad48..cff51cb8d64 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -4,48 +4,67 @@ frappe.query_reports["Item-wise Sales Register"] = { "filters": [ { - "fieldname":"date_range", + "fieldname": "date_range", "label": __("Date Range"), "fieldtype": "DateRange", "default": [frappe.datetime.add_months(frappe.datetime.get_today(),-1), frappe.datetime.get_today()], "reqd": 1 }, { - "fieldname":"customer", + "fieldname": "customer", "label": __("Customer"), "fieldtype": "Link", "options": "Customer" }, { - "fieldname":"company", + "fieldname": "company", "label": __("Company"), "fieldtype": "Link", "options": "Company", "default": frappe.defaults.get_user_default("Company") }, { - "fieldname":"mode_of_payment", + "fieldname": "mode_of_payment", "label": __("Mode of Payment"), "fieldtype": "Link", "options": "Mode of Payment" }, { - "fieldname":"warehouse", + "fieldname": "warehouse", "label": __("Warehouse"), "fieldtype": "Link", "options": "Warehouse" }, { - "fieldname":"brand", + "fieldname": "brand", "label": __("Brand"), "fieldtype": "Link", "options": "Brand" }, { - "fieldname":"item_group", + "fieldname": "item_group", "label": __("Item Group"), "fieldtype": "Link", "options": "Item Group" + }, + { + "label": __("Group By"), + "fieldname": "group_by", + "fieldtype": "Select", + "options": ["Customer", "Item", "Item Group", "Invoice"] } - ] + ], + "formatter": function(value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + + if (data && data.bold) { + // value = $(`${value}`); + // var $value = $(value).css("font-weight", "bold"); + // $value.addClass("text-danger"); + value = value.bold(); + + } + + return value; + }, } diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index 9da89ff2c9f..af6a7b4d62c 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -15,23 +15,31 @@ def execute(filters=None): def _execute(filters=None, additional_table_columns=None, additional_query_columns=None): if not filters: filters = {} filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]}) - columns = get_columns(additional_table_columns) + columns = get_columns(additional_table_columns, filters) company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency") item_list = get_items(filters, additional_query_columns) if item_list: itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency) + columns.append({ - "fieldname": "currency", - "label": _("Currency"), - "fieldtype": "Data", - "width": 80 + 'fieldname': 'currency', + 'label': _('Currency'), + 'fieldtype': 'Currency', + 'width': 80, + 'hidden': 1 }) + mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list])) so_dn_map = get_delivery_notes_against_sales_order(item_list) + if filters.get('group_by'): + grand_total = get_grand_total(filters) + data = [] + prev_group_by_value = '' + for d in item_list: delivery_note = None if d.delivery_note: @@ -42,57 +50,271 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum if not delivery_note and d.update_stock: delivery_note = d.parent - row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.customer, d.customer_name] + + if filters.get('group_by'): + if filters.get('group_by') == 'Item': + group_by_field = 'item_code' + elif filters.get('group_by') == 'Invoice': + group_by_field = 'parent' + else: + group_by_field = frappe.scrub(filters.get('group_by')) + + if prev_group_by_value != d.get(group_by_field): + if prev_group_by_value: + total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) + data.append(total_row) + data.append({}) + + prev_group_by_value = d.get(group_by_field) + + total_row = { + group_by_field: d.get(group_by_field), + 'stock_qty': 0.0, + 'amount': 0.0, + 'bold': 1, + 'total_tax': 0.0, + 'total': 0.0 + } + + row = { + 'item_code': d.item_code, + 'item_name': d.item_name, + 'item_group': d.item_group, + 'description': d.description, + 'invoice': d.parent, + 'posting_date': d.posting_date, + 'customer': d.customer, + 'customer_name': d.customer_name + } if additional_query_columns: for col in additional_query_columns: - row.append(d.get(col)) + row.update({ + col: d.get(col) + }) - row += [ - d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])), - d.territory, d.project, d.company, d.sales_order, - delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom - ] + row.update({ + 'customer_group': d.customer_group, + 'debit_to': d.debit_to, + 'mode_of_payment': ", ".join(mode_of_payments.get(d.parent, [])), + 'territory': d.territory, + 'project': d.project, + 'company': d.company, + 'sales_order': d.sales_order, + 'delivery_note': d.delivery_note, + 'income_account': d.income_account, + 'cost_center': d.cost_center, + 'stock_qty': d.stock_qty, + 'stock_uom': d.stock_uom + }) if d.stock_uom != d.uom and d.stock_qty: - row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] + row.update({ + 'rate': (d.base_net_rate * d.qty)/d.stock_qty, + 'amount': d.base_net_amount + }) else: - row += [d.base_net_rate, d.base_net_amount] + row.update({ + 'rate': d.base_net_rate, + 'amount': d.base_net_amount + }) total_tax = 0 for tax in tax_columns: item_tax = itemised_tax.get(d.name, {}).get(tax, {}) - row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)] + row.update({ + frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0), + frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0), + }) total_tax += flt(item_tax.get("tax_amount")) - row += [total_tax, d.base_net_amount + total_tax, company_currency] + row.update({ + 'total_tax': total_tax, + 'total': d.base_net_amount + total_tax, + 'currency': company_currency + }) + + if filters.get('group_by'): + total_row['stock_qty'] += row['stock_qty'] + total_row['amount'] += row['amount'] + total_row['total_tax'] += row['total_tax'] + total_row['total'] += row['total'] data.append(row) + if filters.get('group_by'): + total_row['percent_gt'] = frappe.bold(total_row['total']/grand_total * 100) + data.append(total_row) + data.append({}) + return columns, data -def get_columns(additional_table_columns): +def get_columns(additional_table_columns, filters): columns = [ - _("Item Code") + ":Link/Item:120", _("Item Name") + "::120", - _("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Sales Invoice:120", - _("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120", - _("Customer Name") + "::120"] + { + 'label': _('Item Code'), + 'fieldname': 'item_code', + 'fieldtype': 'Link', + 'options': 'Item', + 'width': 120 + }, + { + 'label': _('Item Name'), + 'fieldname': 'item_name', + 'fieldtype': 'Data', + 'width': 120 + }, + { + 'label': _('Item Group'), + 'fieldname': 'item_group', + 'fieldtype': 'Link', + 'options': 'Item Group', + 'width': 120 + }, + { + 'label': _('Description'), + 'fieldname': 'description', + 'fieldtype': 'Data', + 'width': 150 + }, + { + 'label': _('Invoice'), + 'fieldname': 'invoice', + 'fieldtype': 'Link', + 'options': 'Sales Invoice', + 'width': 120 + }, + { + 'label': _('Posting Date'), + 'fieldname': 'posting_date', + 'fieldtype': 'Date', + 'width': 120 + }, + { + 'label': _('Customer'), + 'fieldname': 'customer', + 'fieldtype': 'Link', + 'options': 'Customer', + 'width': 120 + }, + { + 'label': _('Customer Name'), + 'fieldname': 'customer_name', + 'fieldtype': 'Data', + 'width': 120 + } + ] if additional_table_columns: columns += additional_table_columns columns += [ - _("Customer Group") + ":Link/Customer Group:120", - _("Receivable Account") + ":Link/Account:120", - _("Mode of Payment") + "::120", _("Territory") + ":Link/Territory:80", - _("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100", - _("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100", - _("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140", - _("Stock Qty") + ":Float:120", _("Stock UOM") + "::100", - _("Rate") + ":Currency/currency:120", - _("Amount") + ":Currency/currency:120" + { + 'label': _('Customer Group'), + 'fieldname': 'customer_group', + 'fieldtype': 'Link', + 'options': 'Customer Group', + 'width': 120 + }, + { + 'label': _('Receivable Account'), + 'fieldname': 'debit_to', + 'fieldtype': 'Link', + 'options': 'Account', + 'width': 80 + }, + { + 'label': _('Mode Of Payment'), + 'fieldname': 'mode_of_payment', + 'fieldtype': 'Data', + 'width': 120 + }, + { + 'label': _("Territory"), + 'fieldname': 'territory', + 'fieldtype': 'Link', + 'options': 'Territory', + 'width': 80 + }, + { + 'label': _('Project'), + 'fieldname': 'project', + 'fieldtype': 'Link', + 'options': 'Project', + 'width': 80 + }, + { + 'label': _('Company'), + 'fieldname': 'company', + 'fieldtype': 'Link', + 'options': 'Company', + 'width': 80 + }, + { + 'label': _('Sales Order'), + 'fieldname': 'sales_order', + 'fieldtype': 'Link', + 'options': 'Sales Order', + 'width': 100 + }, + { + 'label': _("Delivery Note"), + 'fieldname': 'delivery_note', + 'fieldtype': 'Link', + 'options': 'Delivery Note', + 'width': 100 + }, + { + 'label': _('Income Account'), + 'fieldname': 'income_account', + 'fieldtype': 'Link', + 'options': 'Account', + 'width': 100 + }, + { + 'label': _("Cost Center"), + 'fieldname': 'cost_center', + 'fieldtype': 'Link', + 'options': 'Cost Center', + 'width': 100 + }, + { + 'label': _('Stock Qty'), + 'fieldname': 'stock_qty', + 'fieldtype': 'Float', + 'width': 100 + }, + { + 'label': _('Stock UOM'), + 'fieldname': 'stock_uom', + 'fieldtype': 'Link', + 'options': 'UOM', + 'width': 100 + }, + { + 'label': _('Rate'), + 'fieldname': 'rate', + 'fieldtype': 'Float', + 'options': 'currency', + 'width': 100 + }, + { + 'label': _('Amount'), + 'fieldname': 'amount', + 'fieldtype': 'Currency', + 'options': 'currency', + 'width': 100 + } ] + if filters.get('group_by'): + columns.append({ + 'label': _('% Of Grand Total'), + 'fieldname': 'percent_gt', + 'fieldtype': 'Float', + 'width': 80 + }) + return columns def get_conditions(filters): @@ -127,6 +349,16 @@ def get_conditions(filters): where parent=`tabSales Invoice`.name and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)""" + if not filters.get("group_by"): + conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc" + + if filters.get("group_by"): + if filters.get("group_by") == 'Invoice': + conditions += " ORDER BY `tabSales Invoice Item`.parent desc" + elif filters.get("group_by") == 'Item': + conditions += " ORDER BY `tabSales Invoice Item`.item_code desc" + else: + conditions += " ORDER BY {0}".format(frappe.scrub(filters.get("group_by"))) return conditions @@ -157,7 +389,6 @@ def get_items(filters, additional_query_columns): from `tabSales Invoice`, `tabSales Invoice Item` where `tabSales Invoice`.name = `tabSales Invoice Item`.parent and `tabSales Invoice`.docstatus = 1 %s %s - order by `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc """.format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1) def get_delivery_notes_against_sales_order(item_list): @@ -177,6 +408,15 @@ def get_delivery_notes_against_sales_order(item_list): return so_dn_map +def get_grand_total(filters): + conditions = get_conditions(filters) + + return frappe.db.sql(""" SELECT + SUM(`tabSales Invoice`.grand_total) + FROM `tabSales Invoice` + WHERE `tabSales Invoice`.docstatus = 1 %s + """ % (conditions), filters)[0][0] + def get_deducted_taxes(): return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'") @@ -264,9 +504,36 @@ def get_tax_accounts(item_list, columns, company_currency, tax_columns.sort() for desc in tax_columns: - columns.append(desc + " Rate:Data:80") - columns.append(desc + " Amount:Currency/currency:100") + columns.append({ + 'label': _(desc + ' Rate'), + 'fieldname': frappe.scrub(desc + ' Rate'), + 'fieldtype': 'Float', + 'width': 100 + }) - columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:100"] + columns.append({ + 'label': _(desc + ' Amount'), + 'fieldname': frappe.scrub(desc + ' Amount'), + 'fieldtype': 'Currency', + 'options': 'currency', + 'width': 100 + }) + + columns += [ + { + 'label': _('Total Tax'), + 'fieldname': 'total_tax', + 'fieldtype': 'Currency', + 'options': 'currency', + 'width': 100 + }, + { + 'label': _('Total'), + 'fieldname': 'total', + 'fieldtype': 'Currency', + 'options': 'currency', + 'width': 100 + } + ] return itemised_tax, tax_columns diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index afdd31df16d..2be90bc5264 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -139,7 +139,7 @@ def get_columns(invoice_list, additional_table_columns): columns +=[ { - 'label': _("Custmer Group"), + 'label': _("Customer Group"), 'fieldname': 'customer_group', 'fieldtype': 'Link', 'options': 'Customer Group', @@ -175,7 +175,7 @@ def get_columns(invoice_list, additional_table_columns): 'label': _("Project"), 'fieldname': 'project', 'fieldtype': 'Link', - 'options': 'project', + 'options': 'Project', 'width': 80 }, { From 30111e640343f1bf16fafb1ec0257f9e6df773de Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 9 Jan 2020 08:41:09 +0530 Subject: [PATCH 006/119] fix: Remove group-by item --- .../item_wise_sales_register/item_wise_sales_register.js | 5 +---- .../item_wise_sales_register/item_wise_sales_register.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index cff51cb8d64..1303cb93fce 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -51,16 +51,13 @@ frappe.query_reports["Item-wise Sales Register"] = { "label": __("Group By"), "fieldname": "group_by", "fieldtype": "Select", - "options": ["Customer", "Item", "Item Group", "Invoice"] + "options": ["Customer", "Item Group", "Invoice"] } ], "formatter": function(value, row, column, data, default_formatter) { value = default_formatter(value, row, column, data); if (data && data.bold) { - // value = $(`${value}`); - // var $value = $(value).css("font-weight", "bold"); - // $value.addClass("text-danger"); value = value.bold(); } diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index af6a7b4d62c..43562976bbb 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -68,7 +68,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum prev_group_by_value = d.get(group_by_field) total_row = { - group_by_field: d.get(group_by_field), + 'item_code': d.get(group_by_field), 'stock_qty': 0.0, 'amount': 0.0, 'bold': 1, From ea5e0a9d5bfb55dd98214b0bb5e2452ad744705d Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Sat, 11 Jan 2020 16:37:46 +0530 Subject: [PATCH 007/119] fix: Grand total query fix --- .../item_wise_sales_register.js | 2 +- .../item_wise_sales_register.py | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index 1303cb93fce..765d761fc4c 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -51,7 +51,7 @@ frappe.query_reports["Item-wise Sales Register"] = { "label": __("Group By"), "fieldname": "group_by", "fieldtype": "Select", - "options": ["Customer", "Item Group", "Invoice"] + "options": ["Customer", "Item Group", "Item", "Invoice"] } ], "formatter": function(value, row, column, data, default_formatter) { diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index 43562976bbb..1c786936901 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -54,10 +54,13 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum if filters.get('group_by'): if filters.get('group_by') == 'Item': group_by_field = 'item_code' + subtotal_display_field = 'customer' elif filters.get('group_by') == 'Invoice': group_by_field = 'parent' + subtotal_display_field = 'item_code' else: group_by_field = frappe.scrub(filters.get('group_by')) + subtotal_display_field = 'item_code' if prev_group_by_value != d.get(group_by_field): if prev_group_by_value: @@ -68,7 +71,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum prev_group_by_value = d.get(group_by_field) total_row = { - 'item_code': d.get(group_by_field), + subtotal_display_field: d.get(group_by_field), 'stock_qty': 0.0, 'amount': 0.0, 'bold': 1, @@ -350,15 +353,17 @@ def get_conditions(filters): and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)""" if not filters.get("group_by"): - conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc" + conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_group desc" if filters.get("group_by"): if filters.get("group_by") == 'Invoice': conditions += " ORDER BY `tabSales Invoice Item`.parent desc" elif filters.get("group_by") == 'Item': - conditions += " ORDER BY `tabSales Invoice Item`.item_code desc" - else: - conditions += " ORDER BY {0}".format(frappe.scrub(filters.get("group_by"))) + conditions += " ORDER BY `tabSales Invoice Item`.item_code" + elif filters.get("group_by") == 'Item Group': + conditions += " ORDER BY `tabSales Invoice Item`.`item_group`" + elif filters.get("group_by") == 'Customer': + conditions += " ORDER BY `tabSales Invoice`.customer" return conditions @@ -388,8 +393,8 @@ def get_items(filters, additional_query_columns): `tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0} from `tabSales Invoice`, `tabSales Invoice Item` where `tabSales Invoice`.name = `tabSales Invoice Item`.parent - and `tabSales Invoice`.docstatus = 1 %s %s - """.format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1) + and `tabSales Invoice`.docstatus = 1 {1} {2} + """.format(additional_query_columns or '', conditions, match_conditions), filters, as_dict=1, debug=1) def get_delivery_notes_against_sales_order(item_list): so_dn_map = frappe._dict() @@ -409,13 +414,13 @@ def get_delivery_notes_against_sales_order(item_list): return so_dn_map def get_grand_total(filters): - conditions = get_conditions(filters) return frappe.db.sql(""" SELECT SUM(`tabSales Invoice`.grand_total) FROM `tabSales Invoice` - WHERE `tabSales Invoice`.docstatus = 1 %s - """ % (conditions), filters)[0][0] + WHERE `tabSales Invoice`.docstatus = 1 + and posting_date between %s and %s + """, (filters.get('from_date'), filters.get('to_date')))[0][0] def get_deducted_taxes(): return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'") From 4dfe8ab483a5be4183d7ef0251e5634a91fec53d Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Sun, 12 Jan 2020 22:14:45 +0530 Subject: [PATCH 008/119] fix: Remove debug param --- .../report/item_wise_sales_register/item_wise_sales_register.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index 1c786936901..65a4b24a595 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -394,7 +394,7 @@ def get_items(filters, additional_query_columns): from `tabSales Invoice`, `tabSales Invoice Item` where `tabSales Invoice`.name = `tabSales Invoice Item`.parent and `tabSales Invoice`.docstatus = 1 {1} {2} - """.format(additional_query_columns or '', conditions, match_conditions), filters, as_dict=1, debug=1) + """.format(additional_query_columns or '', conditions, match_conditions), filters, as_dict=1) #nosec def get_delivery_notes_against_sales_order(item_list): so_dn_map = frappe._dict() From c52ef56875d12e0ae0cb47f93145ef4ed811c6d0 Mon Sep 17 00:00:00 2001 From: thefalconx33 Date: Mon, 13 Jan 2020 12:43:49 +0530 Subject: [PATCH 009/119] fix: remove default customer as party type --- .../doctype/journal_entry_account/journal_entry_account.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json index ab811d81b25..dbf4e5c4b41 100644 --- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json +++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json @@ -90,7 +90,6 @@ "fieldtype": "Column Break" }, { - "default": "Customer", "fieldname": "party_type", "fieldtype": "Link", "in_list_view": 1, @@ -272,7 +271,7 @@ ], "idx": 1, "istable": 1, - "modified": "2019-10-02 12:23:21.693443", + "modified": "2020-01-13 12:41:33.968025", "modified_by": "Administrator", "module": "Accounts", "name": "Journal Entry Account", From 7d7027f47c40199420a084e1b862ff6b771b8b97 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 13 Jan 2020 15:09:21 +0530 Subject: [PATCH 010/119] fix: Remove patch to set automatic tax fetching from item tax template (#20235) * fix: Remove patch to set automatic tax fetching from item tax template * fix: Remove duplicate patch --- erpnext/patches.txt | 1 - .../set_default_for_add_taxes_from_item_tax_template.py | 5 ----- 2 files changed, 6 deletions(-) delete mode 100644 erpnext/patches/v12_0/set_default_for_add_taxes_from_item_tax_template.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index f1dfb10729c..514305e95e2 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -645,7 +645,6 @@ erpnext.patches.v12_0.set_expense_account_in_landed_cost_voucher_taxes erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings erpnext.patches.v12_0.set_payment_entry_status erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields -erpnext.patches.v12_0.set_default_for_add_taxes_from_item_tax_template erpnext.patches.v12_0.remove_denied_leaves_from_leave_ledger erpnext.patches.v12_0.update_price_or_product_discount erpnext.patches.v12_0.add_export_type_field_in_party_master diff --git a/erpnext/patches/v12_0/set_default_for_add_taxes_from_item_tax_template.py b/erpnext/patches/v12_0/set_default_for_add_taxes_from_item_tax_template.py deleted file mode 100644 index 06ee7981980..00000000000 --- a/erpnext/patches/v12_0/set_default_for_add_taxes_from_item_tax_template.py +++ /dev/null @@ -1,5 +0,0 @@ -import frappe - -def execute(): - frappe.db.set_value("Accounts Settings", None, "add_taxes_from_item_tax_template", 1) - frappe.db.set_default("add_taxes_from_item_tax_template", 1) \ No newline at end of file From 6e1ef4f5c2ef9eae9628775a8977cbb18aaf9508 Mon Sep 17 00:00:00 2001 From: Saqib Date: Tue, 14 Jan 2020 11:38:00 +0530 Subject: [PATCH 011/119] fix: gl not generated on manual asset creation (#20266) --- erpnext/assets/doctype/asset/asset.js | 51 ++++++++++++--------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index f6a7fa20d08..a53ff881777 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -338,25 +338,12 @@ frappe.ui.form.on('Asset', { }) }, - purchase_receipt: function(frm) { + purchase_receipt: (frm) => { frm.trigger('toggle_reference_doc'); - if (frm.doc.purchase_receipt) { if (frm.doc.item_code) { frappe.db.get_doc('Purchase Receipt', frm.doc.purchase_receipt).then(pr_doc => { - frm.set_value('company', pr_doc.company); - frm.set_value('purchase_date', pr_doc.posting_date); - const item = pr_doc.items.find(item => item.item_code === frm.doc.item_code); - if (!item) { - frm.set_value('purchase_receipt', ''); - frappe.msgprint({ - title: __('Invalid Purchase Receipt'), - message: __("The selected Purchase Receipt doesn't contains selected Asset Item."), - indicator: 'red' - }); - } - frm.set_value('gross_purchase_amount', item.base_net_rate); - frm.set_value('location', item.asset_location); + frm.events.set_values_from_purchase_doc(frm, 'Purchase Receipt', pr_doc) }); } else { frm.set_value('purchase_receipt', ''); @@ -368,24 +355,12 @@ frappe.ui.form.on('Asset', { } }, - purchase_invoice: function(frm) { + purchase_invoice: (frm) => { frm.trigger('toggle_reference_doc'); if (frm.doc.purchase_invoice) { if (frm.doc.item_code) { frappe.db.get_doc('Purchase Invoice', frm.doc.purchase_invoice).then(pi_doc => { - frm.set_value('company', pi_doc.company); - frm.set_value('purchase_date', pi_doc.posting_date); - const item = pi_doc.items.find(item => item.item_code === frm.doc.item_code); - if (!item) { - frm.set_value('purchase_invoice', ''); - frappe.msgprint({ - title: __('Invalid Purchase Invoice'), - message: __("The selected Purchase Invoice doesn't contains selected Asset Item."), - indicator: 'red' - }); - } - frm.set_value('gross_purchase_amount', item.base_net_rate); - frm.set_value('location', item.asset_location); + frm.events.set_values_from_purchase_doc(frm, 'Purchase Invoice', pi_doc) }); } else { frm.set_value('purchase_invoice', ''); @@ -397,6 +372,24 @@ frappe.ui.form.on('Asset', { } }, + set_values_from_purchase_doc: function(frm, doctype, purchase_doc) { + frm.set_value('company', purchase_doc.company); + frm.set_value('purchase_date', purchase_doc.posting_date); + const item = purchase_doc.items.find(item => item.item_code === frm.doc.item_code); + if (!item) { + doctype_field = frappe.scrub(doctype) + frm.set_value(doctype_field, ''); + frappe.msgprint({ + title: __(`Invalid ${doctype}`), + message: __(`The selected ${doctype} doesn't contains selected Asset Item.`), + indicator: 'red' + }); + } + frm.set_value('gross_purchase_amount', item.base_net_rate + item.item_tax_amount); + frm.set_value('purchase_receipt_amount', item.base_net_rate + item.item_tax_amount); + frm.set_value('location', item.asset_location); + }, + set_depreciation_rate: function(frm, row) { if (row.total_number_of_depreciations && row.frequency_of_depreciation && row.expected_value_after_useful_life) { From eb7893768bdc9daf38571f915e3c79ccf984620f Mon Sep 17 00:00:00 2001 From: Saqib Date: Tue, 14 Jan 2020 12:07:30 +0530 Subject: [PATCH 012/119] fix: payment entry can be created against on hold PI (#20271) --- .../doctype/purchase_invoice/purchase_invoice.js | 15 +++++++++++++-- .../doctype/purchase_invoice/purchase_invoice.py | 7 ++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 643de7d300a..c5c54837a7b 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -167,8 +167,15 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ make_comment_dialog_and_block_invoice: function(){ const me = this; - const title = __('Add Comment'); + const title = __('Block Invoice'); const fields = [ + { + fieldname: 'release_date', + read_only: 0, + fieldtype:'Date', + label: __('Release Date'), + default: me.frm.doc.release_date + }, { fieldname: 'hold_comment', read_only: 0, @@ -187,7 +194,11 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({ const dialog_data = me.dialog.get_values(); frappe.call({ 'method': 'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.block_invoice', - 'args': {'name': me.frm.doc.name, 'hold_comment': dialog_data.hold_comment}, + 'args': { + 'name': me.frm.doc.name, + 'hold_comment': dialog_data.hold_comment, + 'release_date': dialog_data.release_date + }, 'callback': (r) => me.frm.reload_doc() }); me.dialog.hide(); diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 917acba92c9..1a14a2a732d 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -927,9 +927,10 @@ class PurchaseInvoice(BuyingController): def on_recurring(self, reference_doc, auto_repeat_doc): self.due_date = None - def block_invoice(self, hold_comment=None): + def block_invoice(self, hold_comment=None, release_date=None): self.db_set('on_hold', 1) self.db_set('hold_comment', cstr(hold_comment)) + self.db_set('release_date', release_date) def unblock_invoice(self): self.db_set('on_hold', 0) @@ -1013,10 +1014,10 @@ def unblock_invoice(name): @frappe.whitelist() -def block_invoice(name, hold_comment): +def block_invoice(name, hold_comment, release_date): if frappe.db.exists('Purchase Invoice', name): pi = frappe.get_doc('Purchase Invoice', name) - pi.block_invoice(hold_comment) + pi.block_invoice(hold_comment, release_date) @frappe.whitelist() def make_inter_company_sales_invoice(source_name, target_doc=None): From e3b6a14ab1bd0b6b94555afbc0d4320260548f02 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 14 Jan 2020 12:12:54 +0530 Subject: [PATCH 013/119] fix: filter issue for the stock and account value comparision report --- .../stock_and_account_value_comparison.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py index eef121e542f..94ec314e8c9 100644 --- a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py +++ b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py @@ -43,7 +43,7 @@ def get_data(report_filters): def get_stock_ledger_data(report_filters, filters): if report_filters.account: warehouses = get_warehouses_based_on_account(report_filters.account, - report_filters.warehouse) + report_filters.company) filters["warehouse"] = ("in", warehouses) From 6e115638a13cd278ddcd3ac5b5853fb1bab999f5 Mon Sep 17 00:00:00 2001 From: Pranav Nachnekar Date: Wed, 15 Jan 2020 09:19:28 +0000 Subject: [PATCH 014/119] fix: remove `debugger` statement (#20295) backport of https://github.com/frappe/erpnext/pull/20294 --- erpnext/selling/doctype/sales_order/sales_order.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 45dd51891c9..fa765dfaad9 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -135,8 +135,6 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( } if(doc.status !== 'Closed') { if(doc.status !== 'On Hold') { - debugger; - allow_delivery = this.frm.doc.items.some(item => item.delivered_by_supplier === 0 && item.qty > flt(item.delivered_qty)) && !this.frm.doc.skip_delivery_note From fed9e2861cdc305136ecb63ffd24b269335f4507 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 15 Jan 2020 16:35:02 +0530 Subject: [PATCH 015/119] fix: incorrect number of GL Entries error in stock entry (#20297) --- erpnext/controllers/stock_controller.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index fc2128f2a42..aa3ce9d4d04 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -67,6 +67,7 @@ class StockController(AccountsController): gl_list = [] warehouse_with_no_account = [] + precision = frappe.get_precision("GL Entry", "debit_in_account_currency") for item_row in voucher_details: sle_list = sle_map.get(item_row.name) if sle_list: @@ -92,7 +93,7 @@ class StockController(AccountsController): "against": item_row.expense_account, "cost_center": item_row.cost_center, "remarks": self.get("remarks") or "Accounting Entry for Stock", - "debit": flt(sle.stock_value_difference, 2), + "debit": flt(sle.stock_value_difference, precision), "is_opening": item_row.get("is_opening") or self.get("is_opening") or "No", }, warehouse_account[sle.warehouse]["account_currency"], item=item_row)) @@ -102,7 +103,7 @@ class StockController(AccountsController): "against": warehouse_account[sle.warehouse]["account"], "cost_center": item_row.cost_center, "remarks": self.get("remarks") or "Accounting Entry for Stock", - "credit": flt(sle.stock_value_difference, 2), + "credit": flt(sle.stock_value_difference, precision), "project": item_row.get("project") or self.get("project"), "is_opening": item_row.get("is_opening") or self.get("is_opening") or "No" }, item=item_row)) From 8c45ae73b3a44de6be3e6b21b36420bff5afde79 Mon Sep 17 00:00:00 2001 From: Saqib Date: Wed, 15 Jan 2020 16:36:19 +0530 Subject: [PATCH 016/119] fix: get existing payment req amount only from unpaid req (#20290) --- 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 6133b1ccd4b..1aff43c7177 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -373,6 +373,7 @@ def get_existing_payment_request_amount(ref_dt, ref_dn): reference_doctype = %s and reference_name = %s and docstatus = 1 + and status != 'Paid' """, (ref_dt, ref_dn)) return flt(existing_payment_request_amount[0][0]) if existing_payment_request_amount else 0 From 8dfd5535f171944b07405a46884fb40917f78c9f Mon Sep 17 00:00:00 2001 From: sahil28297 <37302950+sahil28297@users.noreply.github.com> Date: Wed, 15 Jan 2020 18:57:20 +0530 Subject: [PATCH 017/119] fix(patch): do not append taxes to template if account name is not set (#20311) --- .../move_item_tax_to_item_tax_template.py | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py index 5a127950006..31d500ea2f7 100644 --- a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py +++ b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py @@ -49,12 +49,13 @@ def execute(): item_tax_template_name = get_item_tax_template(item_tax_templates, item_tax_map, item_code) # update the item tax table - item = frappe.get_doc("Item", item_code) - item.set("taxes", []) - item.append("taxes", {"item_tax_template": item_tax_template_name, "tax_category": ""}) frappe.db.sql("delete from `tabItem Tax` where parent=%s and parenttype='Item'", item_code) - for d in item.taxes: - d.db_insert() + if item_tax_template_name: + item = frappe.get_doc("Item", item_code) + item.set("taxes", []) + item.append("taxes", {"item_tax_template": item_tax_template_name, "tax_category": ""}) + for d in item.taxes: + d.db_insert() doctypes = [ 'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice', @@ -95,30 +96,35 @@ def get_item_tax_template(item_tax_templates, item_tax_map, item_code, parenttyp else: parts = tax_type.strip().split(" - ") account_name = " - ".join(parts[:-1]) - company = get_company(parts[-1], parenttype, parent) - parent_account = frappe.db.get_value("Account", - filters={"account_type": "Tax", "root_type": "Liability", "is_group": 0, "company": company}, fieldname="parent_account") - if not parent_account: + if not account_name: + tax_type = None + else: + company = get_company(parts[-1], parenttype, parent) parent_account = frappe.db.get_value("Account", - filters={"account_type": "Tax", "root_type": "Liability", "is_group": 1, "company": company}) - filters = { - "account_name": account_name, - "company": company, - "account_type": "Tax", - "parent_account": parent_account - } - tax_type = frappe.db.get_value("Account", filters) - if not tax_type: - account = frappe.new_doc("Account") - account.update(filters) - account.insert() - tax_type = account.name + filters={"account_type": "Tax", "root_type": "Liability", "is_group": 0, "company": company}, fieldname="parent_account") + if not parent_account: + parent_account = frappe.db.get_value("Account", + filters={"account_type": "Tax", "root_type": "Liability", "is_group": 1, "company": company}) + filters = { + "account_name": account_name, + "company": company, + "account_type": "Tax", + "parent_account": parent_account + } + tax_type = frappe.db.get_value("Account", filters) + if not tax_type: + account = frappe.new_doc("Account") + account.update(filters) + account.insert() + tax_type = account.name - item_tax_template.append("taxes", {"tax_type": tax_type, "tax_rate": tax_rate}) - item_tax_templates.setdefault(item_tax_template.title, {}) - item_tax_templates[item_tax_template.title][tax_type] = tax_rate - item_tax_template.save() - return item_tax_template.name + if tax_type: + item_tax_template.append("taxes", {"tax_type": tax_type, "tax_rate": tax_rate}) + item_tax_templates.setdefault(item_tax_template.title, {}) + item_tax_templates[item_tax_template.title][tax_type] = tax_rate + if item_tax_template.get("taxes"): + item_tax_template.save() + return item_tax_template.name def get_company(company_abbr, parenttype=None, parent=None): if parenttype and parent: From 89affd8d09863a18011313b33927b21f54fe231b Mon Sep 17 00:00:00 2001 From: sahil28297 <37302950+sahil28297@users.noreply.github.com> Date: Wed, 15 Jan 2020 18:58:09 +0530 Subject: [PATCH 018/119] fix(patch): reload tax category (#20307) --- .../doctype/tax_category/tax_category.json | 240 +++++++++--------- .../patches/v8_7/sync_india_custom_fields.py | 4 +- 2 files changed, 123 insertions(+), 121 deletions(-) diff --git a/erpnext/accounts/doctype/tax_category/tax_category.json b/erpnext/accounts/doctype/tax_category/tax_category.json index 3556e127675..1e3ae455b37 100644 --- a/erpnext/accounts/doctype/tax_category/tax_category.json +++ b/erpnext/accounts/doctype/tax_category/tax_category.json @@ -1,134 +1,134 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "field:title", - "beta": 0, - "creation": "2018-11-22 23:38:39.668804", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "field:title", + "beta": 0, + "creation": "2018-11-22 23:38:39.668804", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "title", - "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": "Title", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "title", + "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": "Title", + "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": 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-22 23:38:39.668804", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Tax Category", - "name_case": "", - "owner": "Administrator", + ], + "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": "2020-01-15 17:14:28.951793", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Tax Category", + "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": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "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, "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": "Accounts Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "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 Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "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": "Accounts User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "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": "Accounts User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 0 } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0, "track_views": 0 -} \ No newline at end of file +} diff --git a/erpnext/patches/v8_7/sync_india_custom_fields.py b/erpnext/patches/v8_7/sync_india_custom_fields.py index 80d66c2ab19..73e1b182e82 100644 --- a/erpnext/patches/v8_7/sync_india_custom_fields.py +++ b/erpnext/patches/v8_7/sync_india_custom_fields.py @@ -13,6 +13,8 @@ def execute(): frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_declaration_category') frappe.reload_doc('hr', 'doctype', 'employee_tax_exemption_proof_submission_detail') + frappe.reload_doc('accounts', 'doctype', 'tax_category') + for doctype in ["Sales Invoice", "Delivery Note", "Purchase Invoice"]: frappe.db.sql("""delete from `tabCustom Field` where dt = %s and fieldname in ('port_code', 'shipping_bill_number', 'shipping_bill_date')""", doctype) @@ -29,4 +31,4 @@ def execute(): update tabAddress set gst_state_number=concat("0", gst_state_number) where ifnull(gst_state_number, '') != '' and gst_state_number<10 - """) \ No newline at end of file + """) From 611e23c149cdba96f8848e8813036de49b9eae55 Mon Sep 17 00:00:00 2001 From: Saqib Date: Wed, 15 Jan 2020 19:05:42 +0530 Subject: [PATCH 019/119] fix: make jv depreciations only if calculate depr is checked (#20283) --- erpnext/assets/doctype/asset/depreciation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 2d23f77014e..ad671ba0f2c 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -22,7 +22,7 @@ def post_depreciation_entries(date=None): def get_depreciable_assets(date): return frappe.db.sql_list("""select a.name from tabAsset a, `tabDepreciation Schedule` ds - where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s + where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s and a.calculate_depreciation = 1 and a.status in ('Submitted', 'Partially Depreciated') and ifnull(ds.journal_entry, '')=''""", date) From 6ba6ba27bd991695b60589271a124a66d4b60b48 Mon Sep 17 00:00:00 2001 From: Marica Date: Wed, 15 Jan 2020 19:22:21 +0530 Subject: [PATCH 020/119] fix: Missing argument in status updater (#20284) --- erpnext/controllers/status_updater.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index 2b2c27b052f..8b275a64fb3 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -182,7 +182,7 @@ class StatusUpdater(Document): if args.get('no_allowance'): item['reduce_by'] = item[args['target_field']] - item[args['target_ref_field']] if item['reduce_by'] > .01: - self.limits_crossed_error(args, item) + self.limits_crossed_error(args, item, "qty") elif item[args['target_ref_field']]: self.check_overflow_with_allowance(item, args) From 0a50088a0e8a5d7634de8416a93c59112f83bced Mon Sep 17 00:00:00 2001 From: Marica Date: Wed, 15 Jan 2020 19:24:10 +0530 Subject: [PATCH 021/119] fix: Applied query on PO Supplier popup field in Material Request. (#20232) --- .../doctype/material_request/material_request.js | 15 +++++++++++++-- .../doctype/material_request/material_request.py | 12 ++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js index 935d61310eb..7ef2d6460f6 100644 --- a/erpnext/stock/doctype/material_request/material_request.js +++ b/erpnext/stock/doctype/material_request/material_request.js @@ -230,8 +230,19 @@ frappe.ui.form.on('Material Request', { make_purchase_order: function(frm) { frappe.prompt( - {fieldname:'default_supplier', label: __('For Default Supplier (optional)'), description: __('Selected Supplier\ - must be the Default Supplier of one of the items below.'), fieldtype: 'Link', options: 'Supplier'}, + { + label: __('For Default Supplier (Optional)'), + fieldname:'default_supplier', + fieldtype: 'Link', + options: 'Supplier', + description: __('Select a Supplier from the Default Supplier List of the items below.'), + get_query: () => { + return{ + query: "erpnext.stock.doctype.material_request.material_request.get_default_supplier_query", + filters: {'doc': frm.doc.name} + } + } + }, (values) => { frappe.model.open_mapped_doc({ method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order", diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 44e890cc50e..6531e095b84 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -386,6 +386,18 @@ def get_material_requests_based_on_supplier(supplier): return material_requests, supplier_items +def get_default_supplier_query(doctype, txt, searchfield, start, page_len, filters): + doc = frappe.get_doc("Material Request", filters.get("doc")) + item_list = [] + for d in doc.items: + item_list.append(d.item_code) + + return frappe.db.sql("""select default_supplier + from `tabItem Default` + where parent in ({0}) and + default_supplier IS NOT NULL + """.format(', '.join(['%s']*len(item_list))),tuple(item_list)) + @frappe.whitelist() def make_supplier_quotation(source_name, target_doc=None): def postprocess(source, target_doc): From 7721954bbb01c84b285350d905616558d19d4830 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 16 Jan 2020 13:37:20 +0530 Subject: [PATCH 022/119] fix: Multiple fixes based on testing on pre-release branch (#20303) * fix: Multiple fixes based on testing on pre-release branch * fix: reload hr settings --- .../purchase_order/purchase_order.json | 6 +- .../employee_advance/employee_advance.js | 8 +- .../employee_advance/employee_advance.py | 7 +- .../hr/doctype/expense_claim/expense_claim.js | 12 +- .../hr/doctype/expense_claim/expense_claim.py | 1 + .../expense_claim_advance.json | 305 +++++------------- erpnext/manufacturing/doctype/bom/bom.py | 44 ++- .../doctype/work_order/work_order.py | 5 - erpnext/patches.txt | 2 +- .../stock/doctype/stock_entry/stock_entry.py | 40 +-- erpnext/stock/get_item_details.py | 9 +- 11 files changed, 148 insertions(+), 291 deletions(-) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json index 9201eef9b49..d82e128735e 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.json +++ b/erpnext/buying/doctype/purchase_order/purchase_order.json @@ -1,5 +1,4 @@ { - "actions": [], "allow_import": 1, "autoname": "naming_series:", "creation": "2013-05-21 16:16:39", @@ -48,7 +47,6 @@ "ignore_pricing_rule", "sec_warehouse", "set_warehouse", - "set_reserve_warehouse", "col_break_warehouse", "is_subcontracted", "supplier_warehouse", @@ -58,6 +56,7 @@ "section_break_48", "pricing_rules", "raw_material_details", + "set_reserve_warehouse", "supplied_items", "sb_last_purchase", "total_qty", @@ -1054,8 +1053,7 @@ "icon": "fa fa-file-text", "idx": 105, "is_submittable": 1, - "links": [], - "modified": "2019-12-30 19:11:54.122264", + "modified": "2020-01-14 18:54:39.694448", "modified_by": "Administrator", "module": "Buying", "name": "Purchase Order", diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.js b/erpnext/hr/doctype/employee_advance/employee_advance.js index ba62853336d..389660387b7 100644 --- a/erpnext/hr/doctype/employee_advance/employee_advance.js +++ b/erpnext/hr/doctype/employee_advance/employee_advance.js @@ -47,7 +47,7 @@ frappe.ui.form.on('Employee Advance', { } if (frm.doc.docstatus === 1 - && (flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount)) + && (flt(frm.doc.claimed_amount) + flt(frm.doc.return_amount) < flt(frm.doc.paid_amount)) && frappe.model.can_create("Journal Entry")) { frm.add_custom_button(__("Return"), function() { @@ -96,12 +96,12 @@ frappe.ui.form.on('Employee Advance', { frappe.call({ method: 'erpnext.hr.doctype.employee_advance.employee_advance.make_return_entry', args: { - 'employee_name': frm.doc.employee, + 'employee': frm.doc.employee, 'company': frm.doc.company, 'employee_advance_name': frm.doc.name, 'return_amount': flt(frm.doc.paid_amount - frm.doc.claimed_amount), - 'mode_of_payment': frm.doc.mode_of_payment, - 'advance_account': frm.doc.advance_account + 'advance_account': frm.doc.advance_account, + 'mode_of_payment': frm.doc.mode_of_payment }, callback: function(r) { const doclist = frappe.model.sync(r.message); diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py index 7fe2ebc79e0..f10e3b6ce26 100644 --- a/erpnext/hr/doctype/employee_advance/employee_advance.py +++ b/erpnext/hr/doctype/employee_advance/employee_advance.py @@ -133,7 +133,8 @@ def make_bank_entry(dt, dn): return je.as_dict() @frappe.whitelist() -def make_return_entry(employee_name, company, employee_advance_name, return_amount, mode_of_payment, advance_account): +def make_return_entry(employee, company, employee_advance_name, + return_amount, advance_account, mode_of_payment=None): return_account = get_default_bank_cash_account(company, account_type='Cash', mode_of_payment = mode_of_payment) je = frappe.new_doc('Journal Entry') je.posting_date = nowdate() @@ -147,7 +148,7 @@ def make_return_entry(employee_name, company, employee_advance_name, return_amou 'reference_type': 'Employee Advance', 'reference_name': employee_advance_name, 'party_type': 'Employee', - 'party': employee_name, + 'party': employee, 'is_advance': 'Yes' }) @@ -159,5 +160,5 @@ def make_return_entry(employee_name, company, employee_advance_name, return_amou }) return je.as_dict() - + diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js index 0d37c10e9cc..3194007f231 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.js +++ b/erpnext/hr/doctype/expense_claim/expense_claim.js @@ -213,13 +213,14 @@ frappe.ui.form.on("Expense Claim", { }, update_employee_advance_claimed_amount: function(frm) { + console.log("update_employee_advance_claimed_amount") let amount_to_be_allocated = frm.doc.grand_total; $.each(frm.doc.advances || [], function(i, advance){ if (amount_to_be_allocated >= advance.unclaimed_amount){ - frm.doc.advances[i].allocated_amount = frm.doc.advances[i].unclaimed_amount; + advance.allocated_amount = frm.doc.advances[i].unclaimed_amount; amount_to_be_allocated -= advance.allocated_amount; } else{ - frm.doc.advances[i].allocated_amount = amount_to_be_allocated; + advance.allocated_amount = amount_to_be_allocated; amount_to_be_allocated = 0; } frm.refresh_field("advances"); @@ -295,6 +296,7 @@ frappe.ui.form.on("Expense Claim", { doc: frm.doc, callback: () => { refresh_field("taxes"); + frm.trigger("update_employee_advance_claimed_amount"); } }); } @@ -331,16 +333,12 @@ frappe.ui.form.on("Expense Claim", { frappe.ui.form.on("Expense Claim Detail", { amount: function(frm, cdt, cdn) { var child = locals[cdt][cdn]; - var doc = frm.doc; frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.amount); - cur_frm.cscript.calculate_total(doc,cdt,cdn); }, sanctioned_amount: function(frm, cdt, cdn) { - var doc = frm.doc; - cur_frm.cscript.calculate_total(doc,cdt,cdn); + cur_frm.cscript.calculate_total(frm.doc, cdt, cdn); frm.trigger("get_taxes"); - frm.trigger("calculate_grand_total"); } }); diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index 4519fdc20b2..d29b3f75879 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -243,6 +243,7 @@ class ExpenseClaim(AccountsController): precision = self.precision("total_advance_amount") if flt(self.total_advance_amount, precision) > flt(self.total_claimed_amount, precision): frappe.throw(_("Total advance amount cannot be greater than total claimed amount")) + if self.total_sanctioned_amount \ and flt(self.total_advance_amount, precision) > flt(self.total_sanctioned_amount, precision): frappe.throw(_("Total advance amount cannot be greater than total sanctioned amount")) diff --git a/erpnext/hr/doctype/expense_claim_advance/expense_claim_advance.json b/erpnext/hr/doctype/expense_claim_advance/expense_claim_advance.json index b5e4fd16f8e..64eb3095b3d 100644 --- a/erpnext/hr/doctype/expense_claim_advance/expense_claim_advance.json +++ b/erpnext/hr/doctype/expense_claim_advance/expense_claim_advance.json @@ -1,238 +1,93 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "beta": 0, - "creation": "2017-10-09 16:53:26.410762", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 1, - "engine": "InnoDB", + "creation": "2017-10-09 16:53:26.410762", + "doctype": "DocType", + "document_type": "Document", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "employee_advance", + "posting_date", + "advance_paid", + "unclaimed_amount", + "allocated_amount", + "advance_account" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "fieldname": "employee_advance", - "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": "Employee Advance", - "length": 0, - "no_copy": 1, - "oldfieldname": "journal_voucher", - "oldfieldtype": "Link", - "options": "Employee Advance", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "250px", - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "columns": 2, + "fieldname": "employee_advance", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Employee Advance", + "no_copy": 1, + "oldfieldname": "journal_voucher", + "oldfieldtype": "Link", + "options": "Employee Advance", + "print_width": "250px", + "reqd": 1, "width": "250px" - }, + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "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": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, + "columns": 2, + "fieldname": "posting_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Posting Date", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "fieldname": "advance_paid", - "fieldtype": "Currency", - "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": "Advance Paid", - "length": 0, - "no_copy": 0, - "options": "Company:company.default_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, - "unique": 0 - }, + "columns": 2, + "fieldname": "advance_paid", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Advance Paid", + "options": "Company:company:default_currency", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "fieldname": "unclaimed_amount", - "fieldtype": "Currency", - "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": "Unclaimed amount", - "length": 0, - "no_copy": 1, - "oldfieldname": "advance_amount", - "oldfieldtype": "Currency", - "options": "Company:company.default_currency", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "120px", - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "columns": 2, + "fieldname": "unclaimed_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Unclaimed amount", + "no_copy": 1, + "oldfieldname": "advance_amount", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "print_width": "120px", + "read_only": 1, + "reqd": 1, "width": "120px" - }, + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 2, - "fieldname": "allocated_amount", - "fieldtype": "Currency", - "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": "Allocated amount", - "length": 0, - "no_copy": 1, - "oldfieldname": "allocated_amount", - "oldfieldtype": "Currency", - "options": "Company:company.default_currency", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "print_width": "120px", - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0, + "columns": 2, + "fieldname": "allocated_amount", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Allocated amount", + "no_copy": 1, + "oldfieldname": "allocated_amount", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "print_width": "120px", "width": "120px" - }, + }, { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "advance_account", - "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": "Advance Account", - "length": 0, - "no_copy": 0, - "options": "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, - "unique": 0 + "fieldname": "advance_account", + "fieldtype": "Link", + "hidden": 1, + "label": "Advance Account", + "options": "Account" } - ], - "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": "2017-10-09 19:59:48.818139", - "modified_by": "Administrator", - "module": "HR", - "name": "Expense Claim Advance", - "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": "DESC", - "track_changes": 0, - "track_seen": 0 + ], + "istable": 1, + "modified": "2020-01-14 17:49:17.968373", + "modified_by": "Administrator", + "module": "HR", + "name": "Expense Claim Advance", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 686b1967eb5..98f10059712 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -633,7 +633,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite is_stock_item=is_stock_item, qty_field="stock_qty", select_columns = """, bom_item.source_warehouse, bom_item.operation, - bom_item.include_item_in_manufacturing, bom_item.description, + bom_item.include_item_in_manufacturing, bom_item.description, bom_item.rate, (Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""") items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True) @@ -647,7 +647,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite qty_field="stock_qty" if fetch_qty_in_stock_uom else "qty", select_columns = """, bom_item.uom, bom_item.conversion_factor, bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing, - bom_item.description """) + bom_item.description, bom_item.base_rate as rate """) items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True) for item in items: @@ -760,11 +760,17 @@ def get_boms_in_bottom_up_order(bom_no=None): def add_additional_cost(stock_entry, work_order): # Add non stock items cost in the additional cost - bom = frappe.get_doc('BOM', work_order.bom_no) - table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items' + stock_entry.additional_costs = [] expenses_included_in_valuation = frappe.get_cached_value("Company", work_order.company, "expenses_included_in_valuation") + add_non_stock_items_cost(stock_entry, work_order, expenses_included_in_valuation) + add_operations_cost(stock_entry, work_order, expenses_included_in_valuation) + +def add_non_stock_items_cost(stock_entry, work_order, expense_account): + bom = frappe.get_doc('BOM', work_order.bom_no) + table = 'exploded_items' if work_order.get('use_multi_level_bom') else 'items' + items = {} for d in bom.get(table): items.setdefault(d.item_code, d.amount) @@ -772,11 +778,35 @@ def add_additional_cost(stock_entry, work_order): non_stock_items = frappe.get_all('Item', fields="name", filters={'name': ('in', list(items.keys())), 'ifnull(is_stock_item, 0)': 0}, as_list=1) + non_stock_items_cost = 0.0 for name in non_stock_items: + non_stock_items_cost += flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity) + + stock_entry.append('additional_costs', { + 'expense_account': expense_account, + 'description': _("Non stock items"), + 'amount': non_stock_items_cost + }) + +def add_operations_cost(stock_entry, work_order=None, expense_account=None): + from erpnext.stock.doctype.stock_entry.stock_entry import get_operating_cost_per_unit + operating_cost_per_unit = get_operating_cost_per_unit(work_order, stock_entry.bom_no) + + if operating_cost_per_unit: stock_entry.append('additional_costs', { - 'expense_account': expenses_included_in_valuation, - 'description': name[0], - 'amount': flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity) + "expense_account": expense_account, + "description": _("Operating Cost as per Work Order / BOM"), + "amount": operating_cost_per_unit * flt(stock_entry.fg_completed_qty) + }) + + if work_order and work_order.additional_operating_cost and work_order.qty: + additional_operating_cost_per_unit = \ + flt(work_order.additional_operating_cost) / flt(work_order.qty) + + stock_entry.append('additional_costs', { + "expense_account": expense_account, + "description": "Additional Operating Cost", + "amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty) }) @frappe.whitelist() diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 1cb69012083..b4dc3a55699 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -13,7 +13,6 @@ from dateutil.relativedelta import relativedelta from erpnext.stock.doctype.item.item import validate_end_of_life from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError from erpnext.projects.doctype.timesheet.timesheet import OverlapError -from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty from frappe.utils.csvutils import getlink @@ -671,10 +670,6 @@ def make_stock_entry(work_order_id, purpose, qty=None): stock_entry.from_warehouse = wip_warehouse stock_entry.to_warehouse = work_order.fg_warehouse stock_entry.project = work_order.project - if purpose=="Manufacture": - additional_costs = get_additional_costs(work_order, fg_qty=stock_entry.fg_completed_qty, - company=work_order.company) - stock_entry.set("additional_costs", additional_costs) stock_entry.set_stock_entry_type() stock_entry.get_items() diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 514305e95e2..17c9a20766d 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -13,6 +13,7 @@ erpnext.patches.v4_0.apply_user_permissions erpnext.patches.v4_0.move_warehouse_user_to_restrictions erpnext.patches.v4_0.global_defaults_to_system_settings erpnext.patches.v4_0.update_incharge_name_to_sales_person_in_maintenance_schedule +execute:frappe.reload_doc("HR", "doctype", "HR Settings") #2020-01-16 execute:frappe.reload_doc('stock', 'doctype', 'warehouse') # 2017-04-24 execute:frappe.reload_doc('accounts', 'doctype', 'sales_invoice') # 2016-08-31 execute:frappe.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-29 @@ -513,7 +514,6 @@ erpnext.patches.v11_0.rename_employee_loan_to_loan erpnext.patches.v11_0.move_leave_approvers_from_employee #13-06-2018 erpnext.patches.v11_0.update_department_lft_rgt erpnext.patches.v11_0.add_default_email_template_for_leave -execute:frappe.reload_doc("HR", "doctype", "HR Settings") erpnext.patches.v11_0.set_default_email_template_in_hr #08-06-2018 erpnext.patches.v11_0.uom_conversion_data #30-06-2018 erpnext.patches.v10_0.taxes_issue_with_pos diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 8f678837773..996727042e3 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -478,15 +478,17 @@ class StockEntry(StockController): def set_basic_rate_for_finished_goods(self, raw_material_cost, scrap_material_cost): if self.purpose in ["Manufacture", "Repack"]: for d in self.get("items"): - if (d.transfer_qty and (d.bom_no or d.t_warehouse) and raw_material_cost + if (d.transfer_qty and (d.bom_no or d.t_warehouse) and (getattr(self, "pro_doc", frappe._dict()).scrap_warehouse != d.t_warehouse)): - d.basic_rate = flt((raw_material_cost - scrap_material_cost) / flt(d.transfer_qty), d.precision("basic_rate")) - d.basic_amount = flt((raw_material_cost - scrap_material_cost), d.precision("basic_amount")) - if (not d.basic_rate and self.work_order and - frappe.db.get_single_value("Manufacturing Settings", "material_consumption")): - d.basic_rate = get_valuation_rate_for_finished_good_entry(self.work_order) or 0 - d.basic_amount = d.basic_rate * d.qty + if self.work_order \ + and frappe.db.get_single_value("Manufacturing Settings", "material_consumption"): + bom_items = self.get_bom_raw_materials(d.transfer_qty) + raw_material_cost = sum([flt(d.qty)*flt(d.rate) for d in bom_items.values()]) + + if raw_material_cost: + d.basic_rate = flt((raw_material_cost - scrap_material_cost) / flt(d.transfer_qty), d.precision("basic_rate")) + d.basic_amount = flt((raw_material_cost - scrap_material_cost), d.precision("basic_amount")) def distribute_additional_costs(self): if self.purpose == "Material Issue": @@ -1402,30 +1404,6 @@ def get_work_order_details(work_order, company): "additional_costs": get_additional_costs(work_order, fg_qty=pending_qty_to_produce, company=company) } -def get_additional_costs(work_order=None, bom_no=None, fg_qty=None, company=None): - additional_costs = [] - operating_cost_per_unit = get_operating_cost_per_unit(work_order, bom_no) - expenses_included_in_valuation = frappe.get_cached_value("Company", company, "expenses_included_in_valuation") - - if operating_cost_per_unit: - additional_costs.append({ - "expense_account": expenses_included_in_valuation, - "description": "Operating Cost as per Work Order / BOM", - "amount": operating_cost_per_unit * flt(fg_qty) - }) - - if work_order and work_order.additional_operating_cost and work_order.qty: - additional_operating_cost_per_unit = \ - flt(work_order.additional_operating_cost) / flt(work_order.qty) - - additional_costs.append({ - "expense_account": expenses_included_in_valuation, - "description": "Additional Operating Cost", - "amount": additional_operating_cost_per_unit * flt(fg_qty) - }) - - return additional_costs - def get_operating_cost_per_unit(work_order=None, bom_no=None): operating_cost_per_unit = 0 if work_order: diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 6fc6990df76..dec3801feaa 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -608,7 +608,7 @@ def get_item_price(args, item_code, ignore_party=False): return frappe.db.sql(""" select name, price_list_rate, uom from `tabItem Price` {conditions} - order by uom desc, min_qty desc, valid_from desc """.format(conditions=conditions), args) + order by valid_from desc, min_qty desc, uom desc """.format(conditions=conditions), args) def get_price_list_rate_for(args, item_code): """ @@ -630,7 +630,8 @@ def get_price_list_rate_for(args, item_code): "customer": args.get('customer'), "supplier": args.get('supplier'), "uom": args.get('uom'), - "min_qty": args.get('qty'), + "min_qty": args.get('qty') if args.get('price_list_uom_dependant')\ + else flt(args.get('qty')) * flt(args.get("conversion_factor", 1)), "transaction_date": args.get('transaction_date'), } @@ -644,8 +645,8 @@ def get_price_list_rate_for(args, item_code): for field in ["customer", "supplier"]: del item_price_args[field] - general_price_list_rate = get_item_price(item_price_args, item_code, ignore_party=args.get("ignore_party")) - + general_price_list_rate = get_item_price(item_price_args, item_code, + ignore_party=args.get("ignore_party")) if not general_price_list_rate: del item_price_args["min_qty"] general_price_list_rate = get_item_price(item_price_args, item_code, ignore_party=args.get("ignore_party")) From 514d3c37b98b532dec473f4ab5927a71dc7f1325 Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 16 Jan 2020 13:38:21 +0530 Subject: [PATCH 023/119] fix: hide total amount field from journal entry PF (#20325) --- .../doctype/journal_entry/journal_entry.json | 2193 ++++------------- 1 file changed, 477 insertions(+), 1716 deletions(-) diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json index 2f9f215fe86..f5991241a72 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.json +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json @@ -1,1780 +1,541 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "naming_series:", - "beta": 0, - "creation": "2013-03-25 10:53:52", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 0, + "allow_import": 1, + "autoname": "naming_series:", + "creation": "2013-03-25 10:53:52", + "doctype": "DocType", + "document_type": "Document", + "engine": "InnoDB", + "field_order": [ + "entry_type_and_date", + "title", + "voucher_type", + "naming_series", + "column_break1", + "posting_date", + "company", + "finance_book", + "2_add_edit_gl_entries", + "accounts", + "section_break99", + "cheque_no", + "cheque_date", + "user_remark", + "column_break99", + "total_debit", + "total_credit", + "difference", + "get_balance", + "multi_currency", + "total_amount_currency", + "total_amount", + "total_amount_in_words", + "reference", + "clearance_date", + "remark", + "paid_loan", + "inter_company_journal_entry_reference", + "column_break98", + "bill_no", + "bill_date", + "due_date", + "write_off", + "write_off_based_on", + "get_outstanding_invoices", + "column_break_30", + "write_off_amount", + "printing_settings", + "pay_to_recd_from", + "column_break_35", + "letter_head", + "select_print_heading", + "addtional_info", + "mode_of_payment", + "payment_order", + "column_break3", + "is_opening", + "stock_entry", + "subscription_section", + "auto_repeat", + "amended_from" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "entry_type_and_date", - "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": "", - "length": 0, - "no_copy": 0, - "options": "fa fa-flag", - "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": "entry_type_and_date", + "fieldtype": "Section Break", + "options": "fa fa-flag" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "title", - "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": "Title", - "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 - }, + "allow_on_submit": 1, + "fieldname": "title", + "fieldtype": "Data", + "hidden": 1, + "label": "Title", + "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, - "default": "Journal Entry", - "fieldname": "voucher_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": 1, - "label": "Entry Type", - "length": 0, - "no_copy": 0, - "oldfieldname": "voucher_type", - "oldfieldtype": "Select", - "options": "Journal Entry\nInter Company Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry\nExchange Rate Revaluation", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "Journal Entry", + "fieldname": "voucher_type", + "fieldtype": "Select", + "in_standard_filter": 1, + "label": "Entry Type", + "oldfieldname": "voucher_type", + "oldfieldtype": "Select", + "options": "Journal Entry\nInter Company Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry\nExchange Rate Revaluation", + "reqd": 1, + "search_index": 1 + }, { - "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": "ACC-JV-.YYYY.-", - "permlevel": 0, - "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", + "label": "Series", + "no_copy": 1, + "oldfieldname": "naming_series", + "oldfieldtype": "Select", + "options": "ACC-JV-.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": "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, - "oldfieldtype": "Column Break", - "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", + "oldfieldtype": "Column Break", "width": "50%" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 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": 1, - "oldfieldname": "posting_date", - "oldfieldtype": "Date", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "posting_date", + "fieldtype": "Date", + "label": "Posting Date", + "no_copy": 1, + "oldfieldname": "posting_date", + "oldfieldtype": "Date", + "reqd": 1, + "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": 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, - "oldfieldname": "company", - "oldfieldtype": "Link", - "options": "Company", - "permlevel": 0, - "print_hide": 1, - "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 - }, + "fieldname": "company", + "fieldtype": "Link", + "in_standard_filter": 1, + "label": "Company", + "oldfieldname": "company", + "oldfieldtype": "Link", + "options": "Company", + "print_hide": 1, + "remember_last_selected_value": 1, + "reqd": 1, + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "finance_book", - "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": "Finance Book", - "length": 0, - "no_copy": 0, - "options": "Finance Book", - "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": "finance_book", + "fieldtype": "Link", + "label": "Finance Book", + "options": "Finance Book" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "2_add_edit_gl_entries", - "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": "", - "length": 0, - "no_copy": 0, - "oldfieldtype": "Section Break", - "options": "fa fa-table", - "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": "2_add_edit_gl_entries", + "fieldtype": "Section Break", + "oldfieldtype": "Section Break", + "options": "fa fa-table" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "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": "Accounting Entries", - "length": 0, - "no_copy": 0, - "oldfieldname": "entries", - "oldfieldtype": "Table", - "options": "Journal Entry Account", - "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": "accounts", + "fieldtype": "Table", + "label": "Accounting Entries", + "oldfieldname": "entries", + "oldfieldtype": "Table", + "options": "Journal Entry Account", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break99", - "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, - "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_break99", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "cheque_no", - "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": "Reference Number", - "length": 0, - "no_copy": 1, - "oldfieldname": "cheque_no", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "cheque_no", + "fieldtype": "Data", + "in_global_search": 1, + "in_list_view": 1, + "label": "Reference Number", + "no_copy": 1, + "oldfieldname": "cheque_no", + "oldfieldtype": "Data", + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "cheque_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": "Reference Date", - "length": 0, - "no_copy": 1, - "oldfieldname": "cheque_date", - "oldfieldtype": "Date", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "cheque_date", + "fieldtype": "Date", + "label": "Reference Date", + "no_copy": 1, + "oldfieldname": "cheque_date", + "oldfieldtype": "Date", + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "user_remark", - "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": "User Remark", - "length": 0, - "no_copy": 1, - "oldfieldname": "user_remark", - "oldfieldtype": "Small Text", - "permlevel": 0, - "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": "user_remark", + "fieldtype": "Small Text", + "label": "User Remark", + "no_copy": 1, + "oldfieldname": "user_remark", + "oldfieldtype": "Small Text", + "print_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break99", - "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_break99", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "total_debit", - "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": "Total Debit", - "length": 0, - "no_copy": 1, - "oldfieldname": "total_debit", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "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": "total_debit", + "fieldtype": "Currency", + "label": "Total Debit", + "no_copy": 1, + "oldfieldname": "total_debit", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "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": "total_credit", - "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": "Total Credit", - "length": 0, - "no_copy": 1, - "oldfieldname": "total_credit", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "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": "total_credit", + "fieldtype": "Currency", + "label": "Total Credit", + "no_copy": 1, + "oldfieldname": "total_credit", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "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, - "depends_on": "difference", - "fieldname": "difference", - "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": "Difference (Dr - Cr)", - "length": 0, - "no_copy": 1, - "oldfieldname": "difference", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "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 - }, + "depends_on": "difference", + "fieldname": "difference", + "fieldtype": "Currency", + "label": "Difference (Dr - Cr)", + "no_copy": 1, + "oldfieldname": "difference", + "oldfieldtype": "Currency", + "options": "Company:company:default_currency", + "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, - "depends_on": "difference", - "fieldname": "get_balance", - "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": "Make Difference Entry", - "length": 0, - "no_copy": 0, - "oldfieldtype": "Button", - "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": "difference", + "fieldname": "get_balance", + "fieldtype": "Button", + "label": "Make Difference Entry", + "oldfieldtype": "Button" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "multi_currency", - "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": "Multi Currency", - "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 - }, + "default": "0", + "fieldname": "multi_currency", + "fieldtype": "Check", + "label": "Multi Currency", + "print_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "total_amount_currency", - "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": "Total Amount Currency", - "length": 0, - "no_copy": 1, - "options": "Currency", - "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": "total_amount_currency", + "fieldtype": "Link", + "hidden": 1, + "label": "Total Amount Currency", + "no_copy": 1, + "options": "Currency", + "print_hide": 1, + "read_only": 1, + "report_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "fieldname": "total_amount", - "fieldtype": "Currency", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Total Amount", - "length": 0, - "no_copy": 1, - "options": "total_amount_currency", - "permlevel": 0, - "print_hide": 0, - "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 - }, + "bold": 1, + "fieldname": "total_amount", + "fieldtype": "Currency", + "hidden": 1, + "in_list_view": 1, + "label": "Total Amount", + "no_copy": 1, + "options": "total_amount_currency", + "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": "total_amount_in_words", - "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": "Total Amount in Words", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "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": "total_amount_in_words", + "fieldtype": "Data", + "hidden": 1, + "label": "Total Amount in Words", + "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": 1, - "columns": 0, - "fieldname": "reference", - "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": "Reference", - "length": 0, - "no_copy": 0, - "options": "fa fa-pushpin", - "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, + "fieldname": "reference", + "fieldtype": "Section Break", + "label": "Reference", + "options": "fa fa-pushpin" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "clearance_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": "Clearance Date", - "length": 0, - "no_copy": 1, - "oldfieldname": "clearance_date", - "oldfieldtype": "Date", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "clearance_date", + "fieldtype": "Date", + "label": "Clearance Date", + "no_copy": 1, + "oldfieldname": "clearance_date", + "oldfieldtype": "Date", + "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, - "description": "", - "fieldname": "remark", - "fieldtype": "Small Text", - "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": "Remark", - "length": 0, - "no_copy": 1, - "oldfieldname": "remark", - "oldfieldtype": "Small Text", - "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": "remark", + "fieldtype": "Small Text", + "in_global_search": 1, + "label": "Remark", + "no_copy": 1, + "oldfieldname": "remark", + "oldfieldtype": "Small Text", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "paid_loan", - "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": "Paid Loan", - "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 - }, + "fieldname": "paid_loan", + "fieldtype": "Data", + "hidden": 1, + "label": "Paid Loan", + "print_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.voucher_type== \"Inter Company Journal Entry\"", - "fieldname": "inter_company_journal_entry_reference", - "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": "Inter Company Journal Entry Reference", - "length": 0, - "no_copy": 0, - "options": "Journal Entry", - "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 - }, + "depends_on": "eval:doc.voucher_type== \"Inter Company Journal Entry\"", + "fieldname": "inter_company_journal_entry_reference", + "fieldtype": "Link", + "label": "Inter Company Journal Entry Reference", + "options": "Journal Entry", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break98", - "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_break98", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "bill_no", - "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": "Bill No", - "length": 0, - "no_copy": 0, - "oldfieldname": "bill_no", - "oldfieldtype": "Data", - "permlevel": 0, - "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": "bill_no", + "fieldtype": "Data", + "label": "Bill No", + "oldfieldname": "bill_no", + "oldfieldtype": "Data", + "print_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "bill_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": "Bill Date", - "length": 0, - "no_copy": 0, - "oldfieldname": "bill_date", - "oldfieldtype": "Date", - "permlevel": 0, - "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": "bill_date", + "fieldtype": "Date", + "label": "Bill Date", + "oldfieldname": "bill_date", + "oldfieldtype": "Date", + "print_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "due_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": "Due Date", - "length": 0, - "no_copy": 0, - "oldfieldname": "due_date", - "oldfieldtype": "Date", - "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": "due_date", + "fieldtype": "Date", + "label": "Due Date", + "oldfieldname": "due_date", + "oldfieldtype": "Date" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", - "fieldname": "write_off", - "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": "Write Off", - "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, + "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", + "fieldname": "write_off", + "fieldtype": "Section Break", + "label": "Write Off" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Accounts Receivable", - "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", - "fieldname": "write_off_based_on", - "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": "Write Off Based On", - "length": 0, - "no_copy": 0, - "options": "Accounts Receivable\nAccounts Payable", - "permlevel": 0, - "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": "Accounts Receivable", + "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", + "fieldname": "write_off_based_on", + "fieldtype": "Select", + "label": "Write Off Based On", + "options": "Accounts Receivable\nAccounts Payable", + "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, - "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", - "fieldname": "get_outstanding_invoices", - "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 Outstanding Invoices", - "length": 0, - "no_copy": 0, - "options": "get_outstanding_invoices", - "permlevel": 0, - "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 - }, + "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", + "fieldname": "get_outstanding_invoices", + "fieldtype": "Button", + "label": "Get Outstanding Invoices", + "options": "get_outstanding_invoices", + "print_hide": 1 + }, { - "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, - "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", - "fieldname": "write_off_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": "Write Off Amount", - "length": 0, - "no_copy": 0, - "options": "Company:company:default_currency", - "permlevel": 0, - "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 - }, + "depends_on": "eval:doc.voucher_type == 'Write Off Entry'", + "fieldname": "write_off_amount", + "fieldtype": "Currency", + "label": "Write Off Amount", + "options": "Company:company:default_currency", + "print_hide": 1, + "report_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "printing_settings", - "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": "Printing Settings", - "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": "printing_settings", + "fieldtype": "Section Break", + "label": "Printing Settings" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "pay_to_recd_from", - "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": "Pay To / Recd From", - "length": 0, - "no_copy": 1, - "permlevel": 0, - "print_hide": 0, - "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_on_submit": 1, + "fieldname": "pay_to_recd_from", + "fieldtype": "Data", + "label": "Pay To / Recd From", + "no_copy": 1, + "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_35", - "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_35", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "letter_head", - "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": "Letter Head", - "length": 0, - "no_copy": 0, - "options": "Letter Head", - "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 - }, + "allow_on_submit": 1, + "fieldname": "letter_head", + "fieldtype": "Link", + "label": "Letter Head", + "options": "Letter Head" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "select_print_heading", - "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 Heading", - "length": 0, - "no_copy": 1, - "oldfieldname": "select_print_heading", - "oldfieldtype": "Link", - "options": "Print Heading", - "permlevel": 0, - "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_on_submit": 1, + "fieldname": "select_print_heading", + "fieldtype": "Link", + "label": "Print Heading", + "no_copy": 1, + "oldfieldname": "select_print_heading", + "oldfieldtype": "Link", + "options": "Print Heading", + "print_hide": 1, + "report_hide": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "addtional_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": "More Information", - "length": 0, - "no_copy": 0, - "oldfieldtype": "Section Break", - "options": "fa fa-file-text", - "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, + "fieldname": "addtional_info", + "fieldtype": "Section Break", + "label": "More Information", + "oldfieldtype": "Section Break", + "options": "fa fa-file-text" + }, { - "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": "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": 1, - "options": "Payment Order", - "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": "payment_order", + "fieldtype": "Link", + "label": "Payment Order", + "no_copy": 1, + "options": "Payment Order", + "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": "column_break3", - "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, - "oldfieldtype": "Column Break", - "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_break3", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", "width": "50%" - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "No", - "description": "", - "fieldname": "is_opening", - "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": "Is Opening", - "length": 0, - "no_copy": 0, - "oldfieldname": "is_opening", - "oldfieldtype": "Select", - "options": "No\nYes", - "permlevel": 0, - "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 - }, + "default": "No", + "fieldname": "is_opening", + "fieldtype": "Select", + "label": "Is Opening", + "oldfieldname": "is_opening", + "oldfieldtype": "Select", + "options": "No\nYes", + "print_hide": 1, + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:in_list([\"Credit Note\", \"Debit Note\"], doc.voucher_type)", - "fieldname": "stock_entry", - "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": "Stock Entry", - "length": 0, - "no_copy": 0, - "options": "Stock Entry", - "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 - }, + "depends_on": "eval:in_list([\"Credit Note\", \"Debit Note\"], doc.voucher_type)", + "fieldname": "stock_entry", + "fieldtype": "Link", + "label": "Stock Entry", + "options": "Stock Entry", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "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 - }, + "fieldname": "subscription_section", + "fieldtype": "Section Break", + "label": "Subscription Section" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "auto_repeat", - "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": "Auto Repeat", - "length": 0, - "no_copy": 1, - "options": "Auto Repeat", - "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_on_submit": 1, + "fieldname": "auto_repeat", + "fieldtype": "Link", + "label": "Auto Repeat", + "no_copy": 1, + "options": "Auto Repeat", + "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": "amended_from", - "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": "Amended From", - "length": 0, - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Link", - "options": "Journal Entry", - "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", + "ignore_user_permissions": 1, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Link", + "options": "Journal Entry", + "print_hide": 1, + "read_only": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-file-text", - "idx": 176, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "menu_index": 0, - "modified": "2019-01-07 16:52:02.838365", - "modified_by": "Administrator", - "module": "Accounts", - "name": "Journal Entry", - "owner": "Administrator", + ], + "icon": "fa fa-file-text", + "idx": 176, + "is_submittable": 1, + "modified": "2020-01-16 13:05:30.634226", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Journal Entry", + "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": 1, - "role": "Accounts User", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 1, - "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, + "import": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "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": "Auditor", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Auditor" } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 1, - "search_fields": "voucher_type,posting_date, due_date, cheque_no", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "title", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + ], + "search_fields": "voucher_type,posting_date, due_date, cheque_no", + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "title", + "track_changes": 1 } \ No newline at end of file From 5511912251a0cf9714ff972042b2eb1dc9d2366f Mon Sep 17 00:00:00 2001 From: Himanshu Date: Thu, 16 Jan 2020 13:39:03 +0530 Subject: [PATCH 024/119] fix: don't hide primary_address_and_contact_detail (#20321) --- erpnext/selling/doctype/customer/customer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index 68f75a03495..30220614e9b 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -103,7 +103,7 @@ frappe.ui.form.on("Customer", { } frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Customer'} - frm.toggle_display(['address_html','contact_html','primary_address_and_contact_detail'], !frm.doc.__islocal); + frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal); if(!frm.doc.__islocal) { frappe.contacts.render_address_and_contact(frm); From d16e7c096b04eac34d9692cd46ec91a56ebc2949 Mon Sep 17 00:00:00 2001 From: Vishal Dhayagude Date: Fri, 17 Jan 2020 11:44:20 +0530 Subject: [PATCH 025/119] fix: salary structure assignment filter employee based on company (#20319) * fix: pick company from employee salary structure * fix: Salary structure assignment fetch company from enmployee * Revert "fix: Salary structure assignment fetch company from enmployee" This reverts commit ab2da691c79646d6d095f347ea3e273f466ee34f. * fix: Salary structure assignment fetch company from enmployee * fix: filter on company for salary structure assignment * fix: minor changes * fix: minor changes * fix: added company to salary strucutre assignment --- .../salary_structure/salary_structure.js | 4 ++-- .../salary_structure/salary_structure.py | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js index dd34ef2ae2c..672be0c2fc2 100755 --- a/erpnext/hr/doctype/salary_structure/salary_structure.js +++ b/erpnext/hr/doctype/salary_structure/salary_structure.js @@ -46,7 +46,7 @@ frappe.ui.form.on('Salary Structure', { frm.trigger("toggle_fields"); frm.fields_dict['earnings'].grid.set_column_disp("default_amount", false); frm.fields_dict['deductions'].grid.set_column_disp("default_amount", false); - + if(frm.doc.docstatus === 1) { frm.add_custom_button(__("Preview Salary Slip"), function() { frm.trigger('preview_salary_slip'); @@ -75,6 +75,7 @@ frappe.ui.form.on('Salary Structure', { title: __("Assign to Employees"), fields: [ {fieldname: "sec_break", fieldtype: "Section Break", label: __("Filter Employees By (Optional)")}, + {fieldname: "company", fieldtype: "Link", options: "Company", label: __("Company"), default: frm.doc.company, read_only:1}, {fieldname: "grade", fieldtype: "Link", options: "Employee Grade", label: __("Employee Grade")}, {fieldname:'department', fieldtype:'Link', options: 'Department', label: __('Department')}, {fieldname:'designation', fieldtype:'Link', options: 'Designation', label: __('Designation')}, @@ -87,7 +88,6 @@ frappe.ui.form.on('Salary Structure', { ], primary_action: function() { var data = d.get_values(); - frappe.call({ doc: frm.doc, method: "assign_salary_structure", diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py index 0e1a74f3702..568277f8a73 100644 --- a/erpnext/hr/doctype/salary_structure/salary_structure.py +++ b/erpnext/hr/doctype/salary_structure/salary_structure.py @@ -81,24 +81,24 @@ class SalaryStructure(Document): return employees @frappe.whitelist() - def assign_salary_structure(self, grade=None, department=None, designation=None,employee=None, + def assign_salary_structure(self, company=None, grade=None, department=None, designation=None,employee=None, from_date=None, base=None,variable=None): - employees = self.get_employees(grade= grade,department= department,designation= designation,name=employee) + employees = self.get_employees(company= company, grade= grade,department= department,designation= designation,name=employee) if employees: if len(employees) > 20: frappe.enqueue(assign_salary_structure_for_employees, timeout=600, employees=employees, salary_structure=self,from_date=from_date, base=base,variable=variable) else: - assign_salary_structure_for_employees(employees, self,from_date=from_date, base=base,variable=variable) + assign_salary_structure_for_employees(employees, self, from_date=from_date, base=base,variable=variable) else: frappe.msgprint(_("No Employee Found")) -def assign_salary_structure_for_employees(employees, salary_structure,from_date=None, base=None,variable=None): +def assign_salary_structure_for_employees(employees, salary_structure, from_date=None, base=None,variable=None): salary_structures_assignments = [] - existing_assignments_for = get_existing_assignments(employees, salary_structure.name,from_date) + existing_assignments_for = get_existing_assignments(employees, salary_structure, from_date) count=0 for employee in employees: if employee in existing_assignments_for: @@ -117,6 +117,7 @@ def create_salary_structures_assignment(employee, salary_structure, from_date, b assignment = frappe.new_doc("Salary Structure Assignment") assignment.employee = employee assignment.salary_structure = salary_structure.name + assignment.company = salary_structure.company assignment.from_date = from_date assignment.base = base assignment.variable = variable @@ -125,12 +126,12 @@ def create_salary_structures_assignment(employee, salary_structure, from_date, b return assignment.name -def get_existing_assignments(employees, salary_structure,from_date): +def get_existing_assignments(employees, salary_structure, from_date): salary_structures_assignments = frappe.db.sql_list(""" select distinct employee from `tabSalary Structure Assignment` where salary_structure=%s and employee in (%s) - and from_date=%s and docstatus=1 - """ % ('%s', ', '.join(['%s']*len(employees)),'%s'), [salary_structure] + employees+[from_date]) + and from_date=%s and company= %s and docstatus=1 + """ % ('%s', ', '.join(['%s']*len(employees)),'%s', '%s'), [salary_structure.name] + employees+[from_date]+[salary_structure.company]) if salary_structures_assignments: frappe.msgprint(_("Skipping Salary Structure Assignment for the following employees, as Salary Structure Assignment records already exists against them. {0}") .format("\n".join(salary_structures_assignments))) @@ -170,7 +171,7 @@ def make_salary_slip(source_name, target_doc = None, employee = None, as_print = def get_employees(salary_structure): employees = frappe.get_list('Salary Structure Assignment', filters={'salary_structure': salary_structure, 'docstatus': 1}, fields=['employee']) - + if not employees: frappe.throw(_("There's no Employee with Salary Structure: {0}. \ Assign {1} to an Employee to preview Salary Slip").format(salary_structure, salary_structure)) From c2b9598966d164732fb0137f88c86d583feec75e Mon Sep 17 00:00:00 2001 From: Pranav Nachnekar Date: Fri, 17 Jan 2020 06:15:03 +0000 Subject: [PATCH 026/119] fix: imporer escaping (#20329) --- .../doctype/authorization_control/authorization_control.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/setup/doctype/authorization_control/authorization_control.py b/erpnext/setup/doctype/authorization_control/authorization_control.py index 6a184b1a166..55e1ed0d3a7 100644 --- a/erpnext/setup/doctype/authorization_control/authorization_control.py +++ b/erpnext/setup/doctype/authorization_control/authorization_control.py @@ -76,7 +76,7 @@ class AuthorizationControl(TransactionBase): add_cond = '' auth_value = av_dis - if val == 1: add_cond += " and system_user = '"+ frappe.db.escape(session['user']) +"'" + if val == 1: add_cond += " and system_user = {0}".format(frappe.db.escape(session['user'])) elif val == 2: add_cond += " and system_role IN %s" % ("('"+"','".join(frappe.get_roles())+"')") else: add_cond += " and ifnull(system_user,'') = '' and ifnull(system_role,'') = ''" @@ -85,7 +85,7 @@ class AuthorizationControl(TransactionBase): if doc_obj: if doc_obj.doctype == 'Sales Invoice': customer = doc_obj.customer else: customer = doc_obj.customer_name - add_cond = " and master_name = '"+ frappe.db.escape(customer) +"'" + add_cond = " and master_name = {0}".format(frappe.db.escape(customer)) if based_on == 'Itemwise Discount': if doc_obj: for t in doc_obj.get("items"): From 4dfff5a2719ed84a24e7d9b54869f274899bb9f6 Mon Sep 17 00:00:00 2001 From: Rohan Date: Fri, 17 Jan 2020 11:46:00 +0530 Subject: [PATCH 027/119] fix: handle default value for batch size in BOM operation (#20327) --- erpnext/manufacturing/doctype/bom/bom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 98f10059712..3561f3637df 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -588,7 +588,7 @@ class BOM(WebsiteGenerator): for d in self.operations: if not d.description: d.description = frappe.db.get_value('Operation', d.operation, 'description') - if not d.batch_size > 0: + if not d.batch_size or d.batch_size <= 0: d.batch_size = 1 def get_list_context(context): From d85e144944e1689dd689988ce915fbd0e0564a09 Mon Sep 17 00:00:00 2001 From: "Parth J. Kharwar" Date: Fri, 17 Jan 2020 11:47:49 +0530 Subject: [PATCH 028/119] chore: changed employee contact field name (#20227) --- erpnext/hr/doctype/employee/employee.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json index 9291820524e..4a60dba30e5 100644 --- a/erpnext/hr/doctype/employee/employee.json +++ b/erpnext/hr/doctype/employee/employee.json @@ -265,7 +265,7 @@ "bold": 1, "fieldname": "person_to_be_contacted", "fieldtype": "Data", - "label": "Emergency Contact" + "label": "Emergency Contact Name" }, { "fieldname": "relation", @@ -782,7 +782,7 @@ "icon": "fa fa-user", "idx": 24, "image_field": "image", - "modified": "2019-09-12 14:21:12.711280", + "modified": "2020-01-09 04:23:55.611366", "modified_by": "Administrator", "module": "HR", "name": "Employee", From 4b893b1d5138e9746693f5e16c1a63910cc1bf1c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 17 Jan 2020 15:57:43 +0530 Subject: [PATCH 029/119] fix: Plaid TypeError in add_bank_accounts (#20336) --- .../doctype/plaid_settings/plaid_settings.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index 4af1d740946..a04d6c5be73 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -53,7 +53,11 @@ def add_institution(token, response): @frappe.whitelist() def add_bank_accounts(response, bank, company): - response = json.loads(response) if not "accounts" in response else response + try: + response = json.loads(response) + except TypeError: + pass + bank = json.loads(bank) result = [] From 15963525853ddeddad23a9eb90a2a08d9513d839 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 17 Jan 2020 15:59:02 +0530 Subject: [PATCH 030/119] fix: close_opportunity_after_days field is in selling settings (#20334) --- erpnext/crm/doctype/opportunity/opportunity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 4e0eebd0de9..12f8fb95ff4 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -308,7 +308,7 @@ def set_multiple_status(names, status): def auto_close_opportunity(): """ auto close the `Replied` Opportunities after 7 days """ - auto_close_after_days = frappe.db.get_value("Support Settings", "Support Settings", "close_opportunity_after_days") or 15 + auto_close_after_days = frappe.db.get_single_value("Selling Settings", "close_opportunity_after_days") or 15 opportunities = frappe.db.sql(""" select name from tabOpportunity where status='Replied' and modified Date: Mon, 20 Jan 2020 15:44:48 +0530 Subject: [PATCH 031/119] fix: deprecated fetching item price based on min_qty (#20346) --- erpnext/stock/doctype/item_price/item_price.py | 4 ++-- .../stock/doctype/item_price/test_item_price.py | 8 +------- erpnext/stock/get_item_details.py | 17 ++--------------- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py index 4c496cb59a7..957c41546b3 100644 --- a/erpnext/stock/doctype/item_price/item_price.py +++ b/erpnext/stock/doctype/item_price/item_price.py @@ -13,7 +13,7 @@ from frappe.model.document import Document class ItemPrice(Document): - + def validate(self): self.validate_item() self.validate_dates() @@ -51,7 +51,7 @@ class ItemPrice(Document): def check_duplicates(self): conditions = "where item_code=%(item_code)s and price_list=%(price_list)s and name != %(name)s" - for field in ['uom', 'min_qty', 'valid_from', + for field in ['uom', 'valid_from', 'valid_upto', 'packing_unit', 'customer', 'supplier']: if self.get(field): conditions += " and {0} = %({1})s".format(field, field) diff --git a/erpnext/stock/doctype/item_price/test_item_price.py b/erpnext/stock/doctype/item_price/test_item_price.py index 3782f540cf2..702acc38fe4 100644 --- a/erpnext/stock/doctype/item_price/test_item_price.py +++ b/erpnext/stock/doctype/item_price/test_item_price.py @@ -21,7 +21,7 @@ class TestItemPrice(unittest.TestCase): def test_addition_of_new_fields(self): # Based on https://github.com/frappe/erpnext/issues/8456 test_fields_existance = [ - 'supplier', 'customer', 'uom', 'min_qty', 'lead_time_days', + 'supplier', 'customer', 'uom', 'lead_time_days', 'packing_unit', 'valid_from', 'valid_upto', 'note' ] doc_fields = frappe.copy_doc(test_records[1]).__dict__.keys() @@ -43,7 +43,6 @@ class TestItemPrice(unittest.TestCase): args = { "price_list": doc.price_list, - "min_qty": doc.min_qty, "customer": doc.customer, "uom": "_Test UOM", "transaction_date": '2017-04-18', @@ -58,7 +57,6 @@ class TestItemPrice(unittest.TestCase): doc = frappe.copy_doc(test_records[2]) args = { "price_list": doc.price_list, - "min_qty": 30, "customer": doc.customer, "uom": "_Test UOM", "transaction_date": '2017-04-18', @@ -74,7 +72,6 @@ class TestItemPrice(unittest.TestCase): args = { "price_list": doc.price_list, - "min_qty": doc.min_qty, "customer": "_Test Customer", "uom": "_Test UOM", "transaction_date": '2017-04-18', @@ -90,7 +87,6 @@ class TestItemPrice(unittest.TestCase): args = { "price_list": doc.price_list, - "min_qty": doc.min_qty, "qty": 7, "uom": "_Test UOM", "transaction_date": "01-15-2019" @@ -105,7 +101,6 @@ class TestItemPrice(unittest.TestCase): args = { "price_list": doc.price_list, - "min_qty": doc.min_qty, "customer": "_Test Customer", "uom": "_Test UOM", "transaction_date": "2017-04-25", @@ -121,7 +116,6 @@ class TestItemPrice(unittest.TestCase): args = { "price_list": doc.price_list, - "min_qty": doc.min_qty, "uom": "_Test UOM", "qty": 7, } diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index dec3801feaa..b76a9b064a6 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -581,7 +581,7 @@ def get_item_price(args, item_code, ignore_party=False): Get name, price_list_rate from Item Price based on conditions Check if the desired qty is within the increment of the packing list. :param args: dict (or frappe._dict) with mandatory fields price_list, uom - optional fields min_qty, transaction_date, customer, supplier + optional fields transaction_date, customer, supplier :param item_code: str, Item Doctype field item_code """ @@ -599,24 +599,16 @@ def get_item_price(args, item_code, ignore_party=False): else: conditions += " and (customer is null or customer = '') and (supplier is null or supplier = '')" - if args.get('min_qty'): - conditions += " and ifnull(min_qty, 0) <= %(min_qty)s" - if args.get('transaction_date'): conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')""" return frappe.db.sql(""" select name, price_list_rate, uom from `tabItem Price` {conditions} - order by valid_from desc, min_qty desc, uom desc """.format(conditions=conditions), args) + order by valid_from desc, uom desc """.format(conditions=conditions), args) def get_price_list_rate_for(args, item_code): """ - Return Price Rate based on min_qty of each Item Price Rate.\ - For example, desired qty is 10 and Item Price Rates exists - for min_qty 9 and min_qty 20. It returns Item Price Rate for qty 9 as - the best fit in the range of avaliable min_qtyies - :param customer: link to Customer DocType :param supplier: link to Supplier DocType :param price_list: str (Standard Buying or Standard Selling) @@ -630,8 +622,6 @@ def get_price_list_rate_for(args, item_code): "customer": args.get('customer'), "supplier": args.get('supplier'), "uom": args.get('uom'), - "min_qty": args.get('qty') if args.get('price_list_uom_dependant')\ - else flt(args.get('qty')) * flt(args.get("conversion_factor", 1)), "transaction_date": args.get('transaction_date'), } @@ -647,9 +637,6 @@ def get_price_list_rate_for(args, item_code): general_price_list_rate = get_item_price(item_price_args, item_code, ignore_party=args.get("ignore_party")) - if not general_price_list_rate: - del item_price_args["min_qty"] - general_price_list_rate = get_item_price(item_price_args, item_code, ignore_party=args.get("ignore_party")) if not general_price_list_rate and args.get("uom") != args.get("stock_uom"): item_price_args["uom"] = args.get("stock_uom") From 19c5e031a94c2c0082c1bad1e735c5f7459280ad Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Mon, 20 Jan 2020 17:52:53 +0530 Subject: [PATCH 032/119] fix: incorrect number of gl entries issue (#20350) --- erpnext/manufacturing/doctype/bom/bom.py | 22 ++++++++++--------- .../stock/doctype/stock_entry/stock_entry.py | 2 ++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 3561f3637df..7f7ffa14bfa 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -782,11 +782,12 @@ def add_non_stock_items_cost(stock_entry, work_order, expense_account): for name in non_stock_items: non_stock_items_cost += flt(items.get(name[0])) * flt(stock_entry.fg_completed_qty) / flt(bom.quantity) - stock_entry.append('additional_costs', { - 'expense_account': expense_account, - 'description': _("Non stock items"), - 'amount': non_stock_items_cost - }) + if non_stock_items_cost: + stock_entry.append('additional_costs', { + 'expense_account': expense_account, + 'description': _("Non stock items"), + 'amount': non_stock_items_cost + }) def add_operations_cost(stock_entry, work_order=None, expense_account=None): from erpnext.stock.doctype.stock_entry.stock_entry import get_operating_cost_per_unit @@ -803,11 +804,12 @@ def add_operations_cost(stock_entry, work_order=None, expense_account=None): additional_operating_cost_per_unit = \ flt(work_order.additional_operating_cost) / flt(work_order.qty) - stock_entry.append('additional_costs', { - "expense_account": expense_account, - "description": "Additional Operating Cost", - "amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty) - }) + if additional_operating_cost_per_unit: + stock_entry.append('additional_costs', { + "expense_account": expense_account, + "description": "Additional Operating Cost", + "amount": additional_operating_cost_per_unit * flt(stock_entry.fg_completed_qty) + }) @frappe.whitelist() def get_bom_diff(bom1, bom2): diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 996727042e3..9892e7571d4 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -682,6 +682,8 @@ class StockEntry(StockController): if item_account_wise_additional_cost: for d in self.get("items"): for account, amount in iteritems(item_account_wise_additional_cost.get((d.item_code, d.name), {})): + if not amount: continue + gl_entries.append(self.get_gl_dict({ "account": account, "against": d.expense_account, From 541881162ac9fa1faf88bea25756a0b839bbf5eb Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 20 Jan 2020 19:42:49 +0530 Subject: [PATCH 033/119] fix: calculate remaining leave balance (#20342) * fix: calculate remaining leave balance * fix: nonetype issue in the total leaves calculation --- erpnext/hr/doctype/leave_application/leave_application.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py index 915cea149d8..8c109464fdf 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.py +++ b/erpnext/hr/doctype/leave_application/leave_application.py @@ -520,8 +520,7 @@ def get_pending_leaves_for_period(employee, leave_type, from_date, to_date): def get_remaining_leaves(allocation, leaves_taken, date, expiry): ''' Returns minimum leaves remaining after comparing with remaining days for allocation expiry ''' - def _get_remaining_leaves(allocated_leaves, end_date): - remaining_leaves = flt(allocated_leaves) + flt(leaves_taken) + def _get_remaining_leaves(remaining_leaves, end_date): if remaining_leaves > 0: remaining_days = date_diff(end_date, date) + 1 @@ -529,10 +528,11 @@ def get_remaining_leaves(allocation, leaves_taken, date, expiry): return remaining_leaves - total_leaves = allocation.total_leaves_allocated + total_leaves = flt(allocation.total_leaves_allocated) + flt(leaves_taken) if expiry and allocation.unused_leaves: - remaining_leaves = _get_remaining_leaves(allocation.unused_leaves, expiry) + remaining_leaves = flt(allocation.unused_leaves) + flt(leaves_taken) + remaining_leaves = _get_remaining_leaves(remaining_leaves, expiry) total_leaves = flt(allocation.new_leaves_allocated) + flt(remaining_leaves) From 05f4be69f4573d7013cba2a66f3c82ca9a3deadf Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 21 Jan 2020 13:04:26 +0530 Subject: [PATCH 034/119] fix: Don't fetch price list rate on change of qty (#20362) --- erpnext/public/js/controllers/transaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 512bcf9f4fb..8870d75e39a 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -968,7 +968,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ qty: function(doc, cdt, cdn) { let item = frappe.get_doc(cdt, cdn); - this.conversion_factor(doc, cdt, cdn, false); + this.conversion_factor(doc, cdt, cdn, true); this.apply_pricing_rule(item, true); }, From c32249a72f4201eb4209f56c0d16f99475df656d Mon Sep 17 00:00:00 2001 From: Chinmay Pai Date: Tue, 21 Jan 2020 14:12:49 +0530 Subject: [PATCH 035/119] fix: Set Quotation expired if not Ordered or Lost (#20365) Co-authored-by: Chinmay Pai Co-authored-by: KanchanChauhan --- erpnext/selling/doctype/quotation/quotation.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 488331a8102..00471c762c8 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -185,8 +185,12 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False): return doclist def set_expired_status(): - frappe.db.sql("""UPDATE `tabQuotation` SET `status` = 'Expired' - WHERE `status` != "Expired" AND `valid_till` < %s""", (nowdate())) + frappe.db.sql(""" + UPDATE + `tabQuotation` SET `status` = 'Expired' + WHERE + `status` not in ('Ordered', 'Expired', 'Lost', 'Cancelled') AND `valid_till` < %s + """, (nowdate())) @frappe.whitelist() def make_sales_invoice(source_name, target_doc=None): From c759b06f16b715b432d1c78ee8542a5d4a9876c1 Mon Sep 17 00:00:00 2001 From: Saqib Date: Tue, 21 Jan 2020 15:26:46 +0530 Subject: [PATCH 036/119] fix: account not added to child company (#20364) * fix: account not added to child company * fix: removed print Co-authored-by: Nabin Hait --- erpnext/accounts/doctype/account/account.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index cf1748f6a7f..1407d5f5fe3 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -95,29 +95,29 @@ class Account(NestedSet): # ignore validation while creating new compnay or while syncing to child companies if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation: return - ancestors = get_root_company(self.company) if ancestors: if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"): return - 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: 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"]) - for d in frappe.db.get_values('Account', - { "company": ["in", descendants], "account_name": parent_acc_name, - "account_number": parent_acc_number }, - ["company", "name"], as_dict=True): + filters = { + "company": ["in", descendants], + "account_name": parent_acc_name, + } + if parent_acc_number: + filters["account_number"] = parent_acc_number + + for d in frappe.db.get_values('Account', filters=filters, fieldname=["company", "name"], as_dict=True): parent_acc_name_map[d["company"]] = d["name"] if not parent_acc_name_map: return - self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name) def validate_group_or_ledger(self): @@ -175,7 +175,6 @@ class Account(NestedSet): filters["account_number"] = self.account_number child_account = frappe.db.get_value("Account", filters, 'name') - if not child_account: doc = frappe.copy_doc(self) doc.flags.ignore_root_company_validation = True From 87fe2143bee4ac4ada6152b35ba348110c1e6c26 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 21 Jan 2020 15:32:12 +0530 Subject: [PATCH 037/119] fix: not able to import chart of account if parent account is missing (#20367) --- .../chart_of_accounts_importer.py | 6 +++++- 1 file changed, 5 insertions(+), 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 9bf5887b38f..7f51b139de4 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 @@ -96,7 +96,11 @@ def build_forest(data): if parent_account == account_name == child: return [parent_account] elif account_name == child: - return [child] + return_parent(data, parent_account) + parent_account_list = return_parent(data, parent_account) + if not parent_account_list: + frappe.throw(_("The parent account {0} does not exists") + .format(parent_account)) + return [child] + parent_account_list charts_map, paths = {}, [] From 813726b4152828ff767a558867dcc884b62d0efb Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 21 Jan 2020 19:22:27 +0530 Subject: [PATCH 038/119] fix: Zero division error while making finished good entry against the work order --- erpnext/stock/doctype/stock_entry/stock_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 9892e7571d4..8f1d8ef8546 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -484,7 +484,7 @@ class StockEntry(StockController): if self.work_order \ and frappe.db.get_single_value("Manufacturing Settings", "material_consumption"): bom_items = self.get_bom_raw_materials(d.transfer_qty) - raw_material_cost = sum([flt(d.qty)*flt(d.rate) for d in bom_items.values()]) + raw_material_cost = sum([flt(row.qty)*flt(row.rate) for row in bom_items.values()]) if raw_material_cost: d.basic_rate = flt((raw_material_cost - scrap_material_cost) / flt(d.transfer_qty), d.precision("basic_rate")) From f38d9d8f0dbec4457bf9068b0f7d32b69fe95066 Mon Sep 17 00:00:00 2001 From: thefalconx33 Date: Wed, 22 Jan 2020 12:22:55 +0530 Subject: [PATCH 039/119] fix: tuple index out of range error --- erpnext/assets/doctype/asset/asset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 86b5a11a1d1..0df6a6c7de0 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -620,7 +620,7 @@ def get_asset_account(account_name, asset=None, asset_category=None, company=Non if not account: if not asset_category: - frappe.throw(_("Set {0} in company {2}").format(account_name.replace('_', ' ').title(), company)) + frappe.throw(_("Set {0} in company {1}").format(account_name.replace('_', ' ').title(), company)) else: frappe.throw(_("Set {0} in asset category {1} or company {2}") .format(account_name.replace('_', ' ').title(), asset_category, company)) From 61b9fe6a81ea890fb5062b83800c490973e4c77e Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 22 Jan 2020 14:43:37 +0530 Subject: [PATCH 040/119] fix: lead date comparison issue --- erpnext/crm/doctype/lead/lead.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py index 1dae4b9fc1c..e037d272930 100644 --- a/erpnext/crm/doctype/lead/lead.py +++ b/erpnext/crm/doctype/lead/lead.py @@ -53,8 +53,8 @@ class Lead(SellingController): if self.contact_date and getdate(self.contact_date) < getdate(nowdate()): frappe.throw(_("Next Contact Date cannot be in the past")) - if self.ends_on and self.contact_date and\ - (self.ends_on < self.contact_date): + if (self.ends_on and self.contact_date and + (getdate(self.ends_on) < getdate(self.contact_date))): frappe.throw(_("Ends On date cannot be before Next Contact Date.")) def on_update(self): From 79f630661a85222191e6f897ec6ca6210aca546b Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 22 Jan 2020 16:53:30 +0530 Subject: [PATCH 041/119] fix: lead details duplicate entries --- .../crm/report/lead_details/lead_details.json | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/erpnext/crm/report/lead_details/lead_details.json b/erpnext/crm/report/lead_details/lead_details.json index 17800fd4bc9..cdeb6bbe384 100644 --- a/erpnext/crm/report/lead_details/lead_details.json +++ b/erpnext/crm/report/lead_details/lead_details.json @@ -1,28 +1,29 @@ { - "add_total_row": 0, - "creation": "2013-10-22 11:58:16", - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 3, - "is_standard": "Yes", - "modified": "2018-09-26 18:59:46.520731", - "modified_by": "Administrator", - "module": "CRM", - "name": "Lead Details", - "owner": "Administrator", - "prepared_report": 0, - "query": "SELECT\n `tabLead`.name as \"Lead Id:Link/Lead:120\",\n `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2)\n\t) as 'Address::180',\n\t`tabAddress`.state as \"State::100\",\n\t`tabAddress`.pincode as \"Pincode::70\",\n\t`tabAddress`.country as \"Country::100\",\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Id::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\",\n\t`tabLead`.notes as \"Notes::360\",\n `tabLead`.owner as \"Owner:Link/User:120\"\nFROM\n\t`tabLead`\n\tleft join `tabDynamic Link` on (\n\t\t`tabDynamic Link`.link_name=`tabLead`.name\n\t)\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.name=`tabDynamic Link`.parent\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc", - "ref_doctype": "Lead", - "report_name": "Lead Details", - "report_type": "Query Report", + "add_total_row": 0, + "creation": "2013-10-22 11:58:16", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 3, + "is_standard": "Yes", + "modified": "2020-01-22 16:51:56.591110", + "modified_by": "Administrator", + "module": "CRM", + "name": "Lead Details", + "owner": "Administrator", + "prepared_report": 0, + "query": "SELECT\n `tabLead`.name as \"Lead Id:Link/Lead:120\",\n `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2)\n\t) as 'Address::180',\n\t`tabAddress`.state as \"State::100\",\n\t`tabAddress`.pincode as \"Pincode::70\",\n\t`tabAddress`.country as \"Country::100\",\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Id::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\",\n\t`tabLead`.notes as \"Notes::360\",\n `tabLead`.owner as \"Owner:Link/User:120\"\nFROM\n\t`tabLead`\n\tleft join `tabDynamic Link` on (\n\t\t`tabDynamic Link`.link_name=`tabLead`.name \n\t\tand `tabDynamic Link`.parenttype = 'Address'\n\t)\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.name=`tabDynamic Link`.parent\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc", + "ref_doctype": "Lead", + "report_name": "Lead Details", + "report_type": "Query Report", "roles": [ { "role": "Sales User" - }, + }, { "role": "Sales Manager" - }, + }, { "role": "System Manager" } From 144012a5de1ea1f7deb6750f333b3b26e1798c08 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 23 Jan 2020 12:42:42 +0530 Subject: [PATCH 042/119] fix: unlink references from batch on cacnellation of stock transactions --- .../accounts/doctype/purchase_invoice/purchase_invoice.py | 1 + erpnext/controllers/stock_controller.py | 7 +++++++ erpnext/stock/doctype/purchase_receipt/purchase_receipt.py | 1 + erpnext/stock/doctype/stock_entry/stock_entry.py | 1 + 4 files changed, 10 insertions(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 1a14a2a732d..261b0f03f7a 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -866,6 +866,7 @@ class PurchaseInvoice(BuyingController): # because updating ordered qty in bin depends upon updated ordered qty in PO if self.update_stock == 1: self.update_stock_ledger() + self.unlink_reference_from_batch() self.make_gl_entries_on_cancel() self.update_project() diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index aa3ce9d4d04..723ede87a30 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -235,6 +235,13 @@ class StockController(AccountsController): frappe.throw(_("{0} {1}: Cost Center is mandatory for Item {2}").format( _(self.doctype), self.name, item.get("item_code"))) + def unlink_reference_from_batch(self): + frappe.db.sql(""" UPDATE `tabBatch` + SET reference_doctype = NULL, reference_name = NULL + WHERE + reference_doctype = %s and reference_name = %s + """, (self.doctype, self.name)) + def get_sl_entries(self, d, args): sl_dict = frappe._dict({ "item_code": d.get("item_code", None), diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 691f92ffa72..e068dd7610f 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -195,6 +195,7 @@ class PurchaseReceipt(BuyingController): # because updating ordered qty in bin depends upon updated ordered qty in PO self.update_stock_ledger() self.make_gl_entries_on_cancel() + self.unlink_reference_from_batch() def get_current_stock(self): for d in self.get('supplied_items'): diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 9892e7571d4..89bcc9300f9 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -110,6 +110,7 @@ class StockEntry(StockController): self.update_cost_in_project() self.update_transferred_qty() self.update_quality_inspection() + self.unlink_reference_from_batch() def set_job_card_data(self): if self.job_card and not self.work_order: From 89f42eef49a9db1404997b216d827fd357947677 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 23 Jan 2020 15:49:39 +0530 Subject: [PATCH 043/119] fix: add serial no button not working --- erpnext/public/js/utils/serial_no_batch_selector.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index da731950b1a..4ec12ce8e7f 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -316,7 +316,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ frappe.call({ method: 'erpnext.stock.doctype.batch.batch.get_batch_qty', args: { - batch_no: this.doc.batch_no, + batch_no: me.item.batch_no, warehouse: me.warehouse_details.name, item_code: me.item_code }, @@ -392,6 +392,10 @@ erpnext.SerialNoBatchSelector = Class.extend({ delivery_document_no: "" } + if (this.has_batch) { + serial_no_filters["batch_no"] = this.item.batch_no; + } + if (me.warehouse_details.name) { serial_no_filters['warehouse'] = me.warehouse_details.name; } From 5860427bc58682cbe75ed46dee3fc8c392a15394 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 23 Jan 2020 17:36:52 +0530 Subject: [PATCH 044/119] delete the auto created batch --- .../doctype/purchase_invoice/purchase_invoice.py | 2 +- erpnext/controllers/stock_controller.py | 16 ++++++++++------ .../doctype/purchase_receipt/purchase_receipt.py | 2 +- erpnext/stock/doctype/stock_entry/stock_entry.py | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 261b0f03f7a..d4676ff0375 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -866,7 +866,7 @@ class PurchaseInvoice(BuyingController): # because updating ordered qty in bin depends upon updated ordered qty in PO if self.update_stock == 1: self.update_stock_ledger() - self.unlink_reference_from_batch() + self.delete_auto_created_batches() self.make_gl_entries_on_cancel() self.update_project() diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 723ede87a30..2b47a2c09b8 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -235,12 +235,16 @@ class StockController(AccountsController): frappe.throw(_("{0} {1}: Cost Center is mandatory for Item {2}").format( _(self.doctype), self.name, item.get("item_code"))) - def unlink_reference_from_batch(self): - frappe.db.sql(""" UPDATE `tabBatch` - SET reference_doctype = NULL, reference_name = NULL - WHERE - reference_doctype = %s and reference_name = %s - """, (self.doctype, self.name)) + def delete_auto_created_batches(self): + for d in self.items: + if not d.batch_no: continue + + d.batch_no = None + d.db_set("batch_no", None) + + for data in frappe.get_all("Batch", + {'reference_name': self.name, 'reference_doctype': self.doctype}): + frappe.delete_doc("Batch", data.name) def get_sl_entries(self, d, args): sl_dict = frappe._dict({ diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index e068dd7610f..09adb567513 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -195,7 +195,7 @@ class PurchaseReceipt(BuyingController): # because updating ordered qty in bin depends upon updated ordered qty in PO self.update_stock_ledger() self.make_gl_entries_on_cancel() - self.unlink_reference_from_batch() + self.delete_auto_created_batches() def get_current_stock(self): for d in self.get('supplied_items'): diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 89bcc9300f9..cf01d3253ee 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -110,7 +110,7 @@ class StockEntry(StockController): self.update_cost_in_project() self.update_transferred_qty() self.update_quality_inspection() - self.unlink_reference_from_batch() + self.delete_auto_created_batches() def set_job_card_data(self): if self.job_card and not self.work_order: From ba4f565ca37567f2944b1c96983c2069e172fec7 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 23 Jan 2020 17:42:57 +0530 Subject: [PATCH 045/119] fix: Order GL entries by creation time in General ledger --- erpnext/accounts/report/general_ledger/general_ledger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index ec3fb1fc9c2..b32a54f5cc1 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -119,7 +119,7 @@ def get_gl_entries(filters): select_fields = """, debit, credit, debit_in_account_currency, credit_in_account_currency """ - order_by_statement = "order by posting_date, account" + order_by_statement = "order by posting_date, account, creation" if filters.get("group_by") == _("Group by Voucher"): order_by_statement = "order by posting_date, voucher_type, voucher_no" From 245fc49089f68b28da23b6adba37639574dc9eb3 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 24 Jan 2020 15:50:40 +0530 Subject: [PATCH 046/119] fix: healthcare settings registration fee NoneType error (#20396) --- .../healthcare_settings.json | 1238 ++--------------- 1 file changed, 95 insertions(+), 1143 deletions(-) diff --git a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json index 3bd2501a264..f6521183097 100644 --- a/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json +++ b/erpnext/healthcare/doctype/healthcare_settings/healthcare_settings.json @@ -1,1368 +1,320 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, + "actions": [], "beta": 1, "creation": "2017-05-09 11:26:22.337760", - "custom": 0, - "docstatus": 0, "doctype": "DocType", - "document_type": "", "editable_grid": 1, "engine": "InnoDB", + "field_order": [ + "sb_op_settings", + "patient_master_name", + "manage_customer", + "default_medical_code_standard", + "column_break_9", + "collect_registration_fee", + "registration_fee", + "manage_appointment_invoice_automatically", + "max_visit", + "valid_days", + "healthcare_service_items", + "inpatient_visit_charge_item", + "op_consulting_charge_item", + "column_break_13", + "clinical_procedure_consumable_item", + "out_patient_sms_alerts", + "reg_sms", + "reg_msg", + "app_con", + "app_con_msg", + "no_con", + "column_break_16", + "app_rem", + "app_rem_msg", + "rem_before", + "sb_in_ac", + "income_account", + "sb_r_ac", + "receivable_account", + "sb_lab_settings", + "create_test_on_si_submit", + "require_sample_collection", + "require_test_result_approval", + "column_break_34", + "employee_name_and_designation_in_print", + "custom_signature_in_print", + "laboratory_sms_alerts", + "sms_printed", + "column_break_28", + "sms_emailed" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "sb_op_settings", "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": "Out Patient Settings", - "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": "Out Patient Settings" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "patient_master_name", "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": "Patient Name By", - "length": 0, - "no_copy": 0, - "options": "Patient Name\nNaming Series", - "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": "Patient Name\nNaming Series" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "1", "description": "If checked, a customer will be created, mapped to Patient.\nPatient Invoices will be created against this Customer. You can also select existing Customer while creating Patient.", "fieldname": "manage_customer", "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": "Manage Customer", - "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": "Manage Customer" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "default_medical_code_standard", "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 Medical Code Standard", - "length": 0, - "no_copy": 0, - "options": "Medical Code Standard", - "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": "Medical Code Standard" }, { - "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 + "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": "collect_registration_fee", "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": "Collect Fee for Patient Registration", - "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": "Collect Fee for Patient Registration" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "depends_on": "collect_registration_fee", "fieldname": "registration_fee", "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": "Registration Fee", - "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 + "mandatory_depends_on": "eval:doc.collect_registration_fee == 1", + "options": "Currency" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "0", "description": "Manage Appointment Invoice submit and cancel automatically for Patient Encounter", "fieldname": "manage_appointment_invoice_automatically", "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": "Invoice Appointments Automatically", - "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": "Invoice Appointments Automatically" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "max_visit", "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": "Patient Encounters in valid days", - "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": "Patient Encounters in valid days" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "valid_days", "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": "Valid number of days", - "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": "Valid number of days" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "fieldname": "healthcare_service_items", "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": "Healthcare Service 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 + "label": "Healthcare Service Items" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "inpatient_visit_charge_item", "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 Visit Charge Item", - "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 + "options": "Item" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "op_consulting_charge_item", "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": "Out Patient Consulting Charge Item", - "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 + "options": "Item" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_13", - "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": "clinical_procedure_consumable_item", "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": "Clinical Procedure Consumable Item", - "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 + "options": "Item" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "fieldname": "out_patient_sms_alerts", "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": "Out Patient SMS Alerts", - "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": "Out Patient SMS Alerts" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "default": "0", "fieldname": "reg_sms", "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": "Patient Registration", - "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": "Patient Registration" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "Hello {{doc.patient}}, Thank you for registering with {{doc.company}}. Your ID is {{doc.id}} . Please note this ID for future reference. \nThank You, Get well soon!", "depends_on": "reg_sms", "fieldname": "reg_msg", "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": "Registration 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 + "label": "Registration Message" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "default": "0", "fieldname": "app_con", "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": "Appointment Confirmation", - "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": "Appointment Confirmation" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "Hello {{doc.patient}}, You have scheduled an appointment with {{doc.practitioner}} by {{doc.start_dt}} at {{doc.company}}.\nThank you, Good day!", "depends_on": "app_con", "fieldname": "app_con_msg", "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": "Confirmation 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 + "label": "Confirmation Message" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "default": "0", "depends_on": "app_con", "description": "Do not confirm if appointment is created for the same day", "fieldname": "no_con", "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": "Avoid Confirmation", - "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": "Avoid Confirmation" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_16", - "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": "app_rem", "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": "Appointment Reminder", - "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": "Appointment Reminder" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "Hello {{doc.patient}}, You have an appointment with {{doc.practitioner}} by {{doc.appointment_time}} at {{doc.company}}.\nThank you, Good day!\n", "depends_on": "app_rem", "fieldname": "app_rem_msg", "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": "Reminder 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 + "label": "Reminder Message" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "depends_on": "app_rem", "fieldname": "rem_before", "fieldtype": "Time", - "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": "Remind Before", - "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": "Remind Before" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "description": "Default income accounts to be used if not set in Healthcare Practitioner to book Appointment charges.", "fieldname": "sb_in_ac", "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": "Income Account", - "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": "Income Account" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "income_account", "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": "Income Account", - "length": 0, - "no_copy": 0, - "options": "Party 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 + "options": "Party Account" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "description": "Default receivable accounts to be used if not set in Patient to book Appointment charges.", "fieldname": "sb_r_ac", "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": "Receivable Account", - "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": "Receivable Account" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "receivable_account", "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": "Receivable Account", - "length": 0, - "no_copy": 0, - "options": "Party 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 + "options": "Party Account" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "fieldname": "sb_lab_settings", "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": "Laboratory Settings", - "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": "Laboratory Settings" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "default": "0", "fieldname": "create_test_on_si_submit", "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": "Create Lab Test(s) on Sales Invoice Submit", - "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": "Create Lab Test(s) on Sales Invoice Submit" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "default": "0", "description": "Create documents for sample collection", "fieldname": "require_sample_collection", "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": "Manage 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 + "label": "Manage Sample Collection" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "default": "0", "fieldname": "require_test_result_approval", "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": "Require Lab Test Approval", - "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": "Require Lab Test Approval" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_34", - "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": "1", "fieldname": "employee_name_and_designation_in_print", "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": "Employee name and designation in print", - "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": "Employee name and designation in print" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "depends_on": "eval:doc.employee_name_and_designation_in_print == '0'\n", "fieldname": "custom_signature_in_print", "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": "Custom Signature in Print", - "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": "Custom Signature in Print" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, "collapsible": 1, - "columns": 0, "fieldname": "laboratory_sms_alerts", "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": "Laboratory SMS Alerts", - "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": "Laboratory SMS Alerts" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "Hello {{doc.patient}}, Your {{doc.lab_test_name}} result is ready with {{doc.company }}. \nThank You, Good day!", "fieldname": "sms_printed", "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": "Result Printed", - "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": "Result Printed" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "column_break_28", - "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": "Hello {{doc.patient}}, Your {{doc.lab_test_name}} result has been emailed to {{doc.email}}. \n{{doc.company }}. \nThank You, Good day!", "fieldname": "sms_emailed", "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": "Result Emailed", - "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": "Result Emailed" } ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, "issingle": 1, - "istable": 0, - "max_attachments": 0, - "modified": "2018-10-09 22:03:37.449441", + "links": [], + "modified": "2020-01-23 13:39:06.078738", "modified_by": "Administrator", "module": "Healthcare", "name": "Healthcare Settings", - "name_case": "", "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": 0, "role": "Healthcare Administrator", - "set_user_permissions": 0, "share": 1, - "submit": 0, "write": 1 } ], "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, "restrict_to_domain": "Healthcare", - "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + "track_changes": 1 } \ No newline at end of file From 3ca67ceebb9a0e940d247945e92dfff1d5a14873 Mon Sep 17 00:00:00 2001 From: Marica Date: Fri, 24 Jan 2020 15:52:12 +0530 Subject: [PATCH 047/119] fix: Product Page non-stock item status (#20384) --- erpnext/shopping_cart/product_info.py | 4 ++-- erpnext/utilities/product.py | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/erpnext/shopping_cart/product_info.py b/erpnext/shopping_cart/product_info.py index d69b5e3a215..a7da09cb808 100644 --- a/erpnext/shopping_cart/product_info.py +++ b/erpnext/shopping_cart/product_info.py @@ -7,7 +7,7 @@ import frappe from erpnext.shopping_cart.cart import _get_cart_quotation from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings \ import get_shopping_cart_settings, show_quantity_in_website -from erpnext.utilities.product import get_price, get_qty_in_stock +from erpnext.utilities.product import get_price, get_qty_in_stock, get_non_stock_item_status @frappe.whitelist(allow_guest=True) def get_product_info_for_website(item_code): @@ -31,7 +31,7 @@ def get_product_info_for_website(item_code): product_info = { "price": price, "stock_qty": stock_status.stock_qty, - "in_stock": stock_status.in_stock if stock_status.is_stock_item else 1, + "in_stock": stock_status.in_stock if stock_status.is_stock_item else get_non_stock_item_status(item_code, "website_warehouse"), "qty": 0, "uom": frappe.db.get_value("Item", item_code, "stock_uom"), "show_stock_qty": show_quantity_in_website(), diff --git a/erpnext/utilities/product.py b/erpnext/utilities/product.py index a2867c8806a..1c0d4c38c73 100644 --- a/erpnext/utilities/product.py +++ b/erpnext/utilities/product.py @@ -124,3 +124,11 @@ def get_price(item_code, price_list, customer_group, company, qty=1): price_obj["formatted_price"] = "" return price_obj + +def get_non_stock_item_status(item_code, item_warehouse_field): +#if item belongs to product bundle, check if bundle items are in stock + if frappe.db.exists("Product Bundle", item_code): + items = frappe.get_doc("Product Bundle", item_code).get_all_children() + return all([ get_qty_in_stock(d.item_code, item_warehouse_field).in_stock for d in items ]) + else: + return 1 From 2a3cd7d601382a320c12c9681d603524f5364ed8 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 24 Jan 2020 16:11:16 +0530 Subject: [PATCH 048/119] fix(Healthcare): disabled Lab Test Template shown as Enabled in List View (#20379) * fix (Healthcare): disabled Lab Test Template shown as enabled in List View * fix: remove custom disabled button and unhide disabled field --- .../lab_test_template/lab_test_template.js | 105 +- .../lab_test_template/lab_test_template.json | 1234 ++++------------- .../lab_test_template/lab_test_template.py | 114 +- .../lab_test_template_list.js | 10 +- 4 files changed, 332 insertions(+), 1131 deletions(-) diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.js b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.js index 3eb4f6abbbd..5c9bf49e608 100644 --- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.js +++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.js @@ -3,17 +3,17 @@ frappe.ui.form.on("Lab Test Template",{ lab_test_name: function(frm) { - if(!frm.doc.lab_test_code) + if (!frm.doc.lab_test_code) frm.set_value("lab_test_code", frm.doc.lab_test_name); - if(!frm.doc.lab_test_description) + if (!frm.doc.lab_test_description) frm.set_value("lab_test_description", frm.doc.lab_test_name); }, - refresh : function(frm){ + refresh : function(frm) { // Restrict Special, Grouped type templates in Child TestGroups frm.set_query("lab_test_template", "lab_test_groups", function() { return { filters: { - lab_test_template_type:['in',['Single','Compound']] + lab_test_template_type: ['in',['Single','Compound']] } }; }); @@ -23,83 +23,44 @@ frappe.ui.form.on("Lab Test Template",{ cur_frm.cscript.custom_refresh = function(doc) { cur_frm.set_df_property("lab_test_code", "read_only", doc.__islocal ? 0 : 1); - if(!doc.__islocal) { - cur_frm.add_custom_button(__('Change Template Code'), function() { - change_template_code(cur_frm,doc); - } ); - if(doc.disabled == 1){ - cur_frm.add_custom_button(__('Enable Template'), function() { - enable_template(cur_frm); - } ); - } - else{ - cur_frm.add_custom_button(__('Disable Template'), function() { - disable_template(cur_frm); - } ); - } + if (!doc.__islocal) { + cur_frm.add_custom_button(__("Change Template Code"), function() { + change_template_code(doc); + }); } }; -var disable_template = function(frm){ - var doc = frm.doc; - frappe.call({ - method: "erpnext.healthcare.doctype.lab_test_template.lab_test_template.disable_enable_test_template", - args: {status: 1, name: doc.name, is_billable: doc.is_billable}, - callback: function(){ - cur_frm.reload_doc(); - } - }); -}; - -var enable_template = function(frm){ - var doc = frm.doc; - frappe.call({ - method: "erpnext.healthcare.doctype.lab_test_template.lab_test_template.disable_enable_test_template", - args: {status: 0, name: doc.name, is_billable: doc.is_billable}, - callback: function(){ - cur_frm.reload_doc(); - } - }); -}; - - -var change_template_code = function(frm,doc){ - var d = new frappe.ui.Dialog({ +let change_template_code = function(doc) { + let d = new frappe.ui.Dialog({ title:__("Change Template Code"), fields:[ { "fieldtype": "Data", - "label": "Test Template Code", - "fieldname": "Test Code", - reqd:1 - }, - { - "fieldtype": "Button", - "label": __("Change Code"), - click: function() { - var values = d.get_values(); - if(!values) - return; - change_test_code_from_template(values["Test Code"],doc); - d.hide(); - } + "label": "Lab Test Template Code", + "fieldname": "lab_test_code", + reqd: 1 } - ] + ], + primary_action: function() { + let values = d.get_values(); + if (values) { + frappe.call({ + "method": "erpnext.healthcare.doctype.lab_test_template.lab_test_template.change_test_code_from_template", + "args": {lab_test_code: values.lab_test_code, doc: doc}, + callback: function (data) { + frappe.set_route("Form", "Lab Test Template", data.message); + } + }); + } + d.hide(); + }, + primary_action_label: __("Change Template Code") }); d.show(); - d.set_values({ - 'Test Code': doc.lab_test_code - }); - var change_test_code_from_template = function(lab_test_code,doc){ - frappe.call({ - "method": "erpnext.healthcare.doctype.lab_test_template.lab_test_template.change_test_code_from_template", - "args": {lab_test_code: lab_test_code, doc: doc}, - callback: function (data) { - frappe.set_route("Form", "Lab Test Template", data.message); - } - }); - }; + d.set_values({ + "lab_test_code": doc.lab_test_code + }); }; frappe.ui.form.on("Lab Test Template", "lab_test_name", function(frm){ @@ -124,8 +85,8 @@ frappe.ui.form.on("Lab Test Template", "lab_test_description", function(frm){ }); frappe.ui.form.on("Lab Test Groups", "template_or_new_line", function (frm, cdt, cdn) { - var child = locals[cdt][cdn]; - if(child.template_or_new_line =="Add new line"){ + let child = locals[cdt][cdn]; + if (child.template_or_new_line == "Add new line") { frappe.model.set_value(cdt, cdn, 'lab_test_template', ""); frappe.model.set_value(cdt, cdn, 'lab_test_description', ""); } diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json index a707560f650..fcfecba5767 100644 --- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json +++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.json @@ -1,1036 +1,276 @@ { - "allow_copy": 1, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:lab_test_code", - "beta": 1, - "creation": "2016-03-29 17:35:36.761223", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 0, + "actions": [], + "allow_copy": 1, + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:lab_test_code", + "beta": 1, + "creation": "2016-03-29 17:35:36.761223", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "lab_test_name", + "item", + "lab_test_code", + "lab_test_group", + "department", + "column_break_3", + "lab_test_template_type", + "disabled", + "is_billable", + "lab_test_rate", + "section_break_normal", + "lab_test_uom", + "lab_test_normal_range", + "column_break_10", + "section_break_compound", + "normal_test_templates", + "section_break_special", + "sensitivity", + "special_test_template", + "section_break_group", + "lab_test_groups", + "section_break_description", + "lab_test_description", + "sb_sample_collection", + "sample", + "sample_uom", + "sample_quantity", + "sample_collection_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": "lab_test_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": 1, - "label": "Test Name", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "lab_test_name", + "fieldtype": "Data", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Test Name", + "no_copy": 1, + "reqd": 1, + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "item", - "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", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "item", + "fieldtype": "Link", + "label": "Item", + "no_copy": 1, + "options": "Item", + "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": "lab_test_code", - "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": "Item Code", - "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, + "fieldname": "lab_test_code", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Item Code", + "no_copy": 1, + "reqd": 1, "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "lab_test_group", - "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": "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "lab_test_group", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "in_standard_filter": 1, + "label": "Item Group", + "options": "Item Group", + "reqd": 1, + "search_index": 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": 0, - "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": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "department", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "in_standard_filter": 1, + "label": "Department", + "options": "Medical Department", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_3", - "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_3", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "description": "Single for results which require only a single input, result UOM and normal value \n
\nCompound for results which require multiple input fields with corresponding event names, result UOMs and normal values\n
\nDescriptive for tests which have multiple result components and corresponding result entry fields. \n
\nGrouped for test templates which are a group of other test templates.\n
\nNo Result for tests with no results. Also, no Lab Test is created. e.g.. Sub Tests for Grouped results.", - "fieldname": "lab_test_template_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": 1, - "label": "Result Format", - "length": 0, - "no_copy": 0, - "options": "\nSingle\nCompound\nDescriptive\nGrouped\nNo Result", - "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": "Single for results which require only a single input, result UOM and normal value \n
\nCompound for results which require multiple input fields with corresponding event names, result UOMs and normal values\n
\nDescriptive for tests which have multiple result components and corresponding result entry fields. \n
\nGrouped for test templates which are a group of other test templates.\n
\nNo Result for tests with no results. Also, no Lab Test is created. e.g.. Sub Tests for Grouped results.", + "fieldname": "lab_test_template_type", + "fieldtype": "Select", + "in_standard_filter": 1, + "label": "Result Format", + "options": "\nSingle\nCompound\nDescriptive\nGrouped\nNo Result" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "depends_on": "eval:doc.lab_test_template_type != 'Grouped'", - "description": "If unchecked, the item wont be appear in Sales Invoice, but can be used in group test creation. ", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "default": "1", + "depends_on": "eval:doc.lab_test_template_type != 'Grouped'", + "description": "If unchecked, the item wont be appear in Sales Invoice, but can be used in group test creation. ", + "fieldname": "is_billable", + "fieldtype": "Check", + "label": "Is billable", + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.is_billable == 1", - "description": "This value is updated in the Default Sales Price List.", - "fieldname": "lab_test_rate", - "fieldtype": "Currency", - "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": "Standard Selling 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 - }, + "depends_on": "eval:doc.is_billable == 1", + "description": "This value is updated in the Default Sales Price List.", + "fieldname": "lab_test_rate", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Standard Selling Rate" + }, { - "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.lab_test_template_type == 'Single'", - "fieldname": "section_break_normal", - "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": "Lab Routine", - "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.lab_test_template_type == 'Single'", + "fieldname": "section_break_normal", + "fieldtype": "Section Break", + "label": "Lab Routine" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "lab_test_uom", - "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": "UOM", - "length": 0, - "no_copy": 0, - "options": "Lab Test UOM", - "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": "lab_test_uom", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "in_list_view": 1, + "label": "UOM", + "options": "Lab Test UOM" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "lab_test_normal_range", - "fieldtype": "Long 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": "Normal Range", - "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": "lab_test_normal_range", + "fieldtype": "Long Text", + "ignore_xss_filter": 1, + "label": "Normal Range" + }, { - "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, - "collapsible_depends_on": "", - "columns": 0, - "depends_on": "eval:doc.lab_test_template_type == 'Compound'", - "fieldname": "section_break_compound", - "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": "Compound", - "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.lab_test_template_type == 'Compound'", + "fieldname": "section_break_compound", + "fieldtype": "Section Break", + "label": "Compound" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "normal_test_templates", - "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, - "length": 0, - "no_copy": 0, - "options": "Normal Test 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": "normal_test_templates", + "fieldtype": "Table", + "options": "Normal Test Template" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.lab_test_template_type == 'Descriptive'", - "fieldname": "section_break_special", - "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": "Special", - "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.lab_test_template_type == 'Descriptive'", + "fieldname": "section_break_special", + "fieldtype": "Section Break", + "label": "Special" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fieldname": "sensitivity", - "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": "Sensitivity", - "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": "sensitivity", + "fieldtype": "Check", + "label": "Sensitivity" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "special_test_template", - "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, - "length": 0, - "no_copy": 0, - "options": "Special Test 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": "special_test_template", + "fieldtype": "Table", + "options": "Special Test Template" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.lab_test_template_type == 'Grouped'", - "fieldname": "section_break_group", - "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": "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 - }, + "depends_on": "eval:doc.lab_test_template_type == 'Grouped'", + "fieldname": "section_break_group", + "fieldtype": "Section Break", + "label": "Group" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "lab_test_groups", - "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": 0, - "options": "Lab Test Groups", - "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": "lab_test_groups", + "fieldtype": "Table", + "options": "Lab Test Groups" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_description", - "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_description", + "fieldtype": "Section Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "lab_test_description", - "fieldtype": "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": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "lab_test_description", + "fieldtype": "Text", + "ignore_xss_filter": 1, + "label": "Description", + "no_copy": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sb_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 - }, + "fieldname": "sb_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": "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", + "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": 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": 1, - "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", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fieldname": "sample_quantity", - "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 - }, + "default": "0", + "fieldname": "sample_quantity", + "fieldtype": "Float", + "label": "Quantity" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sample_collection_details", - "fieldtype": "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 - }, + "fieldname": "sample_collection_details", + "fieldtype": "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, - "default": "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 - }, + "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, - "default": "0", - "fieldname": "disabled", - "fieldtype": "Check", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 1, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "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" } - ], - "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-09-04 11:16:02.349707", - "modified_by": "Administrator", - "module": "Healthcare", - "name": "Lab Test Template", - "name_case": "", - "owner": "Administrator", + ], + "links": [], + "modified": "2020-01-21 21:02:16.108347", + "modified_by": "ruchamahabal2@gmail.com", + "module": "Healthcare", + "name": "Lab Test 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": "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": "Laboratory User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 0 + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Laboratory User", + "share": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Healthcare", - "search_fields": "lab_test_code,lab_test_name,lab_test_template_type", - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "lab_test_name", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + ], + "restrict_to_domain": "Healthcare", + "search_fields": "lab_test_code,lab_test_name,lab_test_template_type", + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "lab_test_name", + "track_changes": 1 } \ No newline at end of file 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 101e143c123..89f2defb14b 100644 --- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py +++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py @@ -8,59 +8,76 @@ from frappe.model.document import Document from frappe import _ class LabTestTemplate(Document): + def after_insert(self): + if not self.item: + create_item_from_template(self) + + def validate(self): + self.enable_disable_item() + 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) - item_price = item_price_exist(self) + # if change_in_item update Item and Price List + if self.change_in_item and self.is_billable and self.item: + self.update_item() + item_price = self.item_price_exists() if not item_price: - if(self.lab_test_rate != 0.0): + if self.lab_test_rate != 0.0: price_list_name = frappe.db.get_value("Price List", {"selling": 1}) - if(self.lab_test_rate): + if self.lab_test_rate: make_item_price(self.lab_test_code, price_list_name, self.lab_test_rate) else: make_item_price(self.lab_test_code, price_list_name, 0.0) else: frappe.db.set_value("Item Price", item_price, "price_list_rate", self.lab_test_rate) - frappe.db.set_value(self.doctype,self.name,"change_in_item",0) - 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) + + elif not self.is_billable and self.item: + frappe.db.set_value("Item", self.item, "disabled", 1) + self.reload() - def after_insert(self): - if not self.item: - create_item_from_template(self) - - #Call before delete the template def on_trash(self): - # remove template refernce from item and disable item - if(self.item): + # remove template reference from item and disable item + if self.item: try: - frappe.delete_doc("Item",self.item, force=True) + frappe.delete_doc("Item", self.item) except Exception: - frappe.throw(_("""Not permitted. Please disable the Test Template""")) + frappe.throw(_("Not permitted. Please disable the Lab Test Template")) -def item_price_exist(doc): - item_price = frappe.db.exists({ - "doctype": "Item Price", - "item_code": doc.lab_test_code}) - if(item_price): - return item_price[0][0] - else: - return False + 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) + + def update_item(self): + item = frappe.get_doc("Item", self.item) + if item: + item.update({ + "item_name": self.lab_test_name, + "item_group": self.lab_test_group, + "disabled": 0, + "standard_rate": self.lab_test_rate, + "description": self.lab_test_description + }) + item.save() + + def item_price_exists(self): + item_price = frappe.db.exists({"doctype": "Item Price", "item_code": self.lab_test_code}) + if item_price: + return item_price[0][0] + else: + return False -def updating_item(self): - frappe.db.sql("""update `tabItem` set item_name=%s, item_group=%s, disabled=0, standard_rate=%s, - description=%s, modified=NOW() where item_code=%s""", - (self.lab_test_name, self.lab_test_group , self.lab_test_rate, self.lab_test_description, self.item)) def create_item_from_template(doc): - if(doc.is_billable == 1): + if doc.is_billable: disabled = 0 else: disabled = 1 - #insert item + # insert item item = frappe.get_doc({ "doctype": "Item", "item_code": doc.lab_test_code, @@ -77,9 +94,9 @@ def create_item_from_template(doc): "stock_uom": "Unit" }).insert(ignore_permissions=True) - #insert item price - #get item price list to insert item price - if(doc.lab_test_rate != 0.0): + # insert item price + # 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): make_item_price(item.name, price_list_name, doc.lab_test_rate) @@ -88,10 +105,10 @@ def create_item_from_template(doc): make_item_price(item.name, price_list_name, 0.0) item.standard_rate = 0.0 item.save(ignore_permissions = True) - #Set item to the template + # Set item in the template frappe.db.set_value("Lab Test Template", doc.name, "item", item.name) - doc.reload() #refresh the doc after insert. + doc.reload() def make_item_price(item, price_list_name, item_price): frappe.get_doc({ @@ -103,22 +120,13 @@ def make_item_price(item, price_list_name, item_price): @frappe.whitelist() def change_test_code_from_template(lab_test_code, doc): - args = json.loads(doc) - doc = frappe._dict(args) + doc = frappe._dict(json.loads(doc)) - item_exist = frappe.db.exists({ - "doctype": "Item", - "item_code": lab_test_code}) - if(item_exist): - frappe.throw(_("Code {0} already exist").format(lab_test_code)) + if frappe.db.exists({ "doctype": "Item", "item_code": lab_test_code}): + frappe.throw(_("Lab Test Item {0} already exist").format(lab_test_code)) else: - frappe.rename_doc("Item", doc.name, lab_test_code, ignore_permissions = True) - frappe.db.set_value("Lab Test Template",doc.name,"lab_test_code",lab_test_code) - frappe.rename_doc("Lab Test Template", doc.name, lab_test_code, ignore_permissions = True) + rename_doc("Item", doc.name, lab_test_code, ignore_permissions=True) + frappe.db.set_value("Lab Test Template", doc.name, "lab_test_code", lab_test_code) + frappe.db.set_value("Lab Test Template", doc.name, "lab_test_name", lab_test_code) + rename_doc("Lab Test Template", doc.name, lab_test_code, ignore_permissions=True) return lab_test_code - -@frappe.whitelist() -def disable_enable_test_template(status, name, is_billable): - frappe.db.set_value("Lab Test Template",name,"disabled",status) - if(is_billable == 1): - frappe.db.set_value("Item",name,"disabled",status) diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js index a16a72f55b2..a86075fc943 100644 --- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js +++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template_list.js @@ -3,13 +3,5 @@ */ frappe.listview_settings['Lab Test Template'] = { add_fields: ["lab_test_name", "lab_test_code", "lab_test_rate"], - filters:[["disabled","=",0]], - /* get_indicator: function(doc) { - if(doc.disabled==1){ - return [__("Disabled"), "red", "disabled,=,Disabled"]; - } - if(doc.disabled==0){ - return [__("Enabled"), "green", "disabled,=,0"]; - } - } */ + filters: [["disabled", "=", 0]] }; From 9e3dc25b1cbb47257bc73393edbd8783ce2c2e90 Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Fri, 24 Jan 2020 16:14:38 +0530 Subject: [PATCH 049/119] fix: Duplicate Attendance Due Wrong Date format (#20389) --- erpnext/hr/doctype/attendance/attendance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hr/doctype/attendance/attendance.py b/erpnext/hr/doctype/attendance/attendance.py index b8081128ff9..e612c3d7572 100644 --- a/erpnext/hr/doctype/attendance/attendance.py +++ b/erpnext/hr/doctype/attendance/attendance.py @@ -13,7 +13,7 @@ class Attendance(Document): def validate_duplicate_record(self): res = frappe.db.sql("""select name from `tabAttendance` where employee = %s and attendance_date = %s and name != %s and docstatus != 2""", - (self.employee, self.attendance_date, self.name)) + (self.employee, getdate(self.attendance_date), self.name)) if res: frappe.throw(_("Attendance for employee {0} is already marked").format(self.employee)) From 92c999afcbfe0c0e2e940a1f53b00369deb9b6df Mon Sep 17 00:00:00 2001 From: Saqib Date: Fri, 24 Jan 2020 16:23:05 +0530 Subject: [PATCH 050/119] fix: wrong outstanding invoices fetched against employee (#20374) --- erpnext/accounts/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index e01d6d5dc7f..5ad8cb50d5f 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -640,8 +640,9 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2 if account: - root_type = frappe.get_cached_value("Account", account, "root_type") + root_type, account_type = frappe.get_cached_value("Account", account, ["root_type", "account_type"]) party_account_type = "Receivable" if root_type == "Asset" else "Payable" + party_account_type = account_type or party_account_type else: party_account_type = erpnext.get_party_account_type(party_type) From 25a7330db0a2072aa890ecd885b17c947ca28833 Mon Sep 17 00:00:00 2001 From: Himanshu Warekar Date: Fri, 24 Jan 2020 17:36:59 +0530 Subject: [PATCH 051/119] fix: change primary addr fieldtype to Text --- erpnext/selling/doctype/customer/customer.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index c2c8c1971a9..250973b7497 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -322,8 +322,9 @@ }, { "fieldname": "primary_address", - "fieldtype": "Read Only", - "label": "Primary Address" + "fieldtype": "Text", + "label": "Primary Address", + "read_only": 1 }, { "collapsible": 1, @@ -469,7 +470,7 @@ "icon": "fa fa-user", "idx": 363, "image_field": "image", - "modified": "2019-09-06 12:40:31.801424", + "modified": "2020-01-24 15:06:03.483799", "modified_by": "Administrator", "module": "Selling", "name": "Customer", From 8d9145aaac9e278b9c1e641180c55220b5aabde1 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Mon, 27 Jan 2020 08:48:04 +0530 Subject: [PATCH 052/119] fix: Code cleanup and commonification --- .../item_wise_sales_register.js | 6 +- .../item_wise_sales_register.py | 298 +++++++++++------- 2 files changed, 182 insertions(+), 122 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index 765d761fc4c..8a9c76f26f8 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -51,17 +51,15 @@ frappe.query_reports["Item-wise Sales Register"] = { "label": __("Group By"), "fieldname": "group_by", "fieldtype": "Select", - "options": ["Customer", "Item Group", "Item", "Invoice"] + "options": ["Customer Group", "Customer", "Item Group", "Item", "Territory", "Invoice"] } ], "formatter": function(value, row, column, data, default_formatter) { value = default_formatter(value, row, column, data); - if (data && data.bold) { value = value.bold(); } - return value; - }, + } } diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index 65a4b24a595..57a99ef76a9 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe, erpnext from frappe import _ -from frappe.utils import flt +from frappe.utils import flt, cstr from frappe.model.meta import get_field_precision from frappe.utils.xlsxutils import handle_html from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments @@ -23,23 +23,16 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum if item_list: itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency) - columns.append({ - 'fieldname': 'currency', - 'label': _('Currency'), - 'fieldtype': 'Currency', - 'width': 80, - 'hidden': 1 - }) - mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list])) so_dn_map = get_delivery_notes_against_sales_order(item_list) - if filters.get('group_by'): - grand_total = get_grand_total(filters) - data = [] + total_row_map = {} prev_group_by_value = '' + if filters.get('group_by'): + grand_total = get_grand_total(filters, 'Sales Invoice') + for d in item_list: delivery_note = None if d.delivery_note: @@ -50,35 +43,6 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum if not delivery_note and d.update_stock: delivery_note = d.parent - - if filters.get('group_by'): - if filters.get('group_by') == 'Item': - group_by_field = 'item_code' - subtotal_display_field = 'customer' - elif filters.get('group_by') == 'Invoice': - group_by_field = 'parent' - subtotal_display_field = 'item_code' - else: - group_by_field = frappe.scrub(filters.get('group_by')) - subtotal_display_field = 'item_code' - - if prev_group_by_value != d.get(group_by_field): - if prev_group_by_value: - total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) - data.append(total_row) - data.append({}) - - prev_group_by_value = d.get(group_by_field) - - total_row = { - subtotal_display_field: d.get(group_by_field), - 'stock_qty': 0.0, - 'amount': 0.0, - 'bold': 1, - 'total_tax': 0.0, - 'total': 0.0 - } - row = { 'item_code': d.item_code, 'item_name': d.item_name, @@ -87,7 +51,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum 'invoice': d.parent, 'posting_date': d.posting_date, 'customer': d.customer, - 'customer_name': d.customer_name + 'customer_name': d.customer_name, + 'customer_group': d.customer_group, } if additional_query_columns: @@ -97,7 +62,6 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum }) row.update({ - 'customer_group': d.customer_group, 'debit_to': d.debit_to, 'mode_of_payment': ", ".join(mode_of_payments.get(d.parent, [])), 'territory': d.territory, @@ -138,42 +102,56 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum }) if filters.get('group_by'): - total_row['stock_qty'] += row['stock_qty'] - total_row['amount'] += row['amount'] - total_row['total_tax'] += row['total_tax'] - total_row['total'] += row['total'] + row.update({'percent_gt': flt(row['total']/grand_total) * 100}) + group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters) + data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map, + group_by_field, subtotal_display_field, grand_total) + update_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) data.append(row) if filters.get('group_by'): - total_row['percent_gt'] = frappe.bold(total_row['total']/grand_total * 100) + total_row = total_row_map.get(prev_group_by_value or d.get('item_name')) + total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) data.append(total_row) data.append({}) return columns, data def get_columns(additional_table_columns, filters): - columns = [ - { - 'label': _('Item Code'), - 'fieldname': 'item_code', - 'fieldtype': 'Link', - 'options': 'Item', - 'width': 120 - }, - { - 'label': _('Item Name'), - 'fieldname': 'item_name', - 'fieldtype': 'Data', - 'width': 120 - }, - { - 'label': _('Item Group'), - 'fieldname': 'item_group', - 'fieldtype': 'Link', - 'options': 'Item Group', - 'width': 120 - }, + columns = [] + + if filters.get('group_by') != ('Item'): + columns.extend( + [ + { + 'label': _('Item Code'), + 'fieldname': 'item_code', + 'fieldtype': 'Link', + 'options': 'Item', + 'width': 120 + }, + { + 'label': _('Item Name'), + 'fieldname': 'item_name', + 'fieldtype': 'Data', + 'width': 120 + } + ] + ) + + if filters.get('group_by') not in ('Item', 'Item Group'): + columns.extend([ + { + 'label': _('Item Group'), + 'fieldname': 'item_group', + 'fieldtype': 'Link', + 'options': 'Item Group', + 'width': 120 + } + ]) + + columns.extend([ { 'label': _('Description'), 'fieldname': 'description', @@ -192,33 +170,41 @@ def get_columns(additional_table_columns, filters): 'fieldname': 'posting_date', 'fieldtype': 'Date', 'width': 120 - }, - { - 'label': _('Customer'), - 'fieldname': 'customer', - 'fieldtype': 'Link', - 'options': 'Customer', - 'width': 120 - }, - { - 'label': _('Customer Name'), - 'fieldname': 'customer_name', - 'fieldtype': 'Data', - 'width': 120 } - ] + ]) + + if filters.get('group_by') != 'Customer': + columns.extend([ + { + 'label': _('Customer Group'), + 'fieldname': 'customer_group', + 'fieldtype': 'Link', + 'options': 'Customer Group', + 'width': 120 + } + ]) + + if filters.get('group_by') not in ('Customer', 'Customer Group'): + columns.extend([ + { + 'label': _('Customer'), + 'fieldname': 'customer', + 'fieldtype': 'Link', + 'options': 'Customer', + 'width': 120 + }, + { + 'label': _('Customer Name'), + 'fieldname': 'customer_name', + 'fieldtype': 'Data', + 'width': 120 + } + ]) if additional_table_columns: columns += additional_table_columns columns += [ - { - 'label': _('Customer Group'), - 'fieldname': 'customer_group', - 'fieldtype': 'Link', - 'options': 'Customer Group', - 'width': 120 - }, { 'label': _('Receivable Account'), 'fieldname': 'debit_to', @@ -231,14 +217,22 @@ def get_columns(additional_table_columns, filters): 'fieldname': 'mode_of_payment', 'fieldtype': 'Data', 'width': 120 - }, - { - 'label': _("Territory"), - 'fieldname': 'territory', - 'fieldtype': 'Link', - 'options': 'Territory', - 'width': 80 - }, + } + ] + + if filters.get('group_by') != 'Terriotory': + columns.extend([ + { + 'label': _("Territory"), + 'fieldname': 'territory', + 'fieldtype': 'Link', + 'options': 'Territory', + 'width': 80 + } + ]) + + + columns += [ { 'label': _('Project'), 'fieldname': 'project', @@ -307,6 +301,13 @@ def get_columns(additional_table_columns, filters): 'fieldtype': 'Currency', 'options': 'currency', 'width': 100 + }, + { + 'fieldname': 'currency', + 'label': _('Currency'), + 'fieldtype': 'Currency', + 'width': 80, + 'hidden': 1 } ] @@ -337,35 +338,34 @@ def get_conditions(filters): and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)""" if filters.get("warehouse"): - conditions += """ and exists(select name from `tabSales Invoice Item` - where parent=`tabSales Invoice`.name - and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s)""" + conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s""" if filters.get("brand"): - conditions += """ and exists(select name from `tabSales Invoice Item` - where parent=`tabSales Invoice`.name - and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)""" + conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s""" if filters.get("item_group"): - conditions += """ and exists(select name from `tabSales Invoice Item` - where parent=`tabSales Invoice`.name - and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)""" + conditions += """and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s""" if not filters.get("group_by"): conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_group desc" + else: + conditions += get_group_by_conditions(filters, 'Sales Invoice') + + return conditions + +def get_group_by_conditions(filters, doctype): if filters.get("group_by"): if filters.get("group_by") == 'Invoice': - conditions += " ORDER BY `tabSales Invoice Item`.parent desc" + return "ORDER BY `tab{0} Item`.parent desc".format(doctype) elif filters.get("group_by") == 'Item': - conditions += " ORDER BY `tabSales Invoice Item`.item_code" + return "ORDER BY `tab{0} Item`.`item_code`".format(doctype) elif filters.get("group_by") == 'Item Group': - conditions += " ORDER BY `tabSales Invoice Item`.`item_group`" - elif filters.get("group_by") == 'Customer': - conditions += " ORDER BY `tabSales Invoice`.customer" + return "ORDER BY `tab{0} Item`.{1}".format(doctype, frappe.scrub(filters.get('group_by'))) + elif filters.get("group_by") in ('Customer', 'Customer Group', 'Territory', 'Supplier'): + return "ORDER BY `tab{0}`.{1}".format(doctype, frappe.scrub(filters.get('group_by'))) - return conditions def get_items(filters, additional_query_columns): conditions = get_conditions(filters) @@ -413,14 +413,14 @@ def get_delivery_notes_against_sales_order(item_list): return so_dn_map -def get_grand_total(filters): +def get_grand_total(filters, doctype): return frappe.db.sql(""" SELECT - SUM(`tabSales Invoice`.grand_total) - FROM `tabSales Invoice` - WHERE `tabSales Invoice`.docstatus = 1 + SUM(`tab{0}`.base_grand_total) + FROM `tab{0}` + WHERE `tab{0}`.docstatus = 1 and posting_date between %s and %s - """, (filters.get('from_date'), filters.get('to_date')))[0][0] + """.format(doctype), (filters.get('from_date'), filters.get('to_date')))[0][0] def get_deducted_taxes(): return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'") @@ -542,3 +542,65 @@ def get_tax_accounts(item_list, columns, company_currency, ] return itemised_tax, tax_columns + +def add_total_row(data, filters, prev_group_by_value, item, total_row_map, + group_by_field, subtotal_display_field, grand_total): + if prev_group_by_value != item.get(group_by_field, ''): + if prev_group_by_value: + total_row = total_row_map.get(prev_group_by_value) + total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) + data.append(total_row) + data.append({}) + + prev_group_by_value = item.get(group_by_field, '') + + total_row_map.setdefault(item.get(group_by_field, ''), { + subtotal_display_field: get_display_value(filters, group_by_field, item), + 'stock_qty': 0.0, + 'amount': 0.0, + 'bold': 1, + 'total_tax': 0.0, + 'total': 0.0 + }) + + return data, prev_group_by_value + +def get_display_value(filters, group_by_field, item): + if filters.get('group_by') == 'Item': + return "Item: " + cstr(item.get('item_code')) \ + + "

" + "Item Name: " + cstr(item.get('item_name')) + elif filters.get('group_by') in ('Customer', 'Supplier'): + return filters.get('group_by')+": " + cstr(item.get(frappe.scrub(filters.get('group_by')))) \ + + "

" + filters.get('group_by') + " Name: " + item.get(frappe.scrub(filters.get('group_by'))+'_name', '') + else: + return item.get(group_by_field) + +def get_group_by_and_display_fields(filters): + if filters.get('group_by') == 'Item': + group_by_field = 'item_code' + subtotal_display_field = 'invoice' + elif filters.get('group_by') == 'Invoice': + group_by_field = 'parent' + subtotal_display_field = 'item_code' + else: + group_by_field = frappe.scrub(filters.get('group_by')) + subtotal_display_field = 'item_code' + + return group_by_field, subtotal_display_field + +def update_total_row(item, total_row_map, group_by_value, tax_columns): + total_row = total_row_map.get(group_by_value) + total_row['stock_qty'] += item['stock_qty'] + total_row['amount'] += item['amount'] + total_row['total_tax'] += item['total_tax'] + total_row['total'] += item['total'] + + for tax in tax_columns: + total_row.setdefault(frappe.scrub(tax + ' Amount'), 0.0) + total_row.setdefault(frappe.scrub(tax + ' Rate'), 0.0) + total_row[frappe.scrub(tax + ' Rate')] += flt(item[frappe.scrub(tax + ' Rate')]) + total_row[frappe.scrub(tax + ' Amount')] += flt(item[frappe.scrub(tax + ' Amount')]) + + + + From 6f27e9798020f71bc8378243ba2d2446c360dfcc Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Mon, 27 Jan 2020 08:48:38 +0530 Subject: [PATCH 053/119] fix: Add group by functionality to purchase register --- .../item_wise_purchase_register.js | 16 +- .../item_wise_purchase_register.py | 258 +++++++++++++++--- 2 files changed, 241 insertions(+), 33 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js index e936a173734..f88906a0f1f 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js @@ -34,6 +34,20 @@ frappe.query_reports["Item-wise Purchase Register"] = { "label": __("Mode of Payment"), "fieldtype": "Link", "options": "Mode of Payment" + }, + { + "label": __("Group By"), + "fieldname": "group_by", + "fieldtype": "Select", + "options": ["Supplier", "Item Group", "Item", "Invoice"] } - ] + ], + "formatter": function(value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + if (data && data.bold) { + value = value.bold(); + + } + return value; + } } diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 380b208548c..3a5a4548f5a 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -5,7 +5,9 @@ from __future__ import unicode_literals import frappe, erpnext from frappe import _ from frappe.utils import flt -from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts +from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (get_tax_accounts, + get_grand_total, add_total_row, get_display_value, get_group_by_and_display_fields, update_total_row, + get_group_by_conditions) def execute(filters=None): return _execute(filters) @@ -13,7 +15,7 @@ def execute(filters=None): def _execute(filters=None, additional_table_columns=None, additional_query_columns=None): if not filters: filters = {} filters.update({"from_date": filters.get("date_range")[0], "to_date": filters.get("date_range")[1]}) - columns = get_columns(additional_table_columns) + columns = get_columns(additional_table_columns, filters) company_currency = erpnext.get_company_currency(filters.company) @@ -23,16 +25,15 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency, doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges") - columns.append({ - "fieldname": "currency", - "label": _("Currency"), - "fieldtype": "Data", - "width": 80 - }) - po_pr_map = get_purchase_receipts_against_purchase_order(item_list) data = [] + total_row_map = {} + prev_group_by_value = '' + + if filters.get('group_by'): + grand_total = get_grand_total(filters, 'Purchase Invoice') + for d in item_list: if not d.stock_qty: continue @@ -44,51 +45,240 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, [])) expense_account = d.expense_account or aii_account_map.get(d.company) - row = [d.item_code, d.item_name, d.item_group, d.description, d.parent, d.posting_date, d.supplier, - d.supplier_name] + + row = { + 'item_code': d.item_code, + 'item_name': d.item_name, + 'item_group': d.item_group, + 'description': d.description, + 'invoice': d.parent, + 'posting_date': d.posting_date, + 'customer': d.supplier, + 'customer_name': d.supplier_name + } if additional_query_columns: for col in additional_query_columns: - row.append(d.get(col)) + row.update({ + col: d.get(col) + }) - row += [ - d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order, - purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_amount / d.stock_qty, d.base_net_amount - ] + row.update({ + 'credit_to': d.credit_to, + 'mode_of_payment': d.mode_of_payment, + 'project': d.project, + 'company': d.company, + 'purchase_order': d.purchase_order, + 'purchase_receipt': d.purchase_receipt, + 'expense_account': expense_account, + 'stock_qty': d.stock_qty, + 'stock_uom': d.stock_uom, + 'rate': d.base_net_amount / d.stock_qty, + 'amount': d.base_net_amount + }) total_tax = 0 for tax in tax_columns: item_tax = itemised_tax.get(d.name, {}).get(tax, {}) - row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)] + row.update({ + frappe.scrub(tax + ' Rate'): item_tax.get("tax_rate", 0), + frappe.scrub(tax + ' Amount'): item_tax.get("tax_amount", 0), + }) total_tax += flt(item_tax.get("tax_amount")) - row += [total_tax, d.base_net_amount + total_tax, company_currency] + row.update({ + 'total_tax': total_tax, + 'total': d.base_net_amount + total_tax, + 'currency': company_currency + }) + + if filters.get('group_by'): + row.update({'percent_gt': flt(row['total']/grand_total) * 100}) + group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters) + data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map, + group_by_field, subtotal_display_field, grand_total) + update_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) data.append(row) + if filters.get('group_by'): + total_row = total_row_map.get(prev_group_by_value or d.get('item_name')) + total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) + data.append(total_row) + data.append({}) + return columns, data -def get_columns(additional_table_columns): - columns = [ - _("Item Code") + ":Link/Item:120", _("Item Name") + "::120", - _("Item Group") + ":Link/Item Group:100", "Description::150", _("Invoice") + ":Link/Purchase Invoice:120", - _("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120", - "Supplier Name::120" - ] +def get_columns(additional_table_columns, filters): + + columns = [] + + if filters.get('group_by') != ('Item'): + columns.extend( + [ + { + 'label': _('Item Code'), + 'fieldname': 'item_code', + 'fieldtype': 'Link', + 'options': 'Item', + 'width': 120 + }, + { + 'label': _('Item Name'), + 'fieldname': 'item_name', + 'fieldtype': 'Data', + 'width': 120 + } + ] + ) + + if filters.get('group_by') not in ('Item', 'Item Group'): + columns.extend([ + { + 'label': _('Item Group'), + 'fieldname': 'item_group', + 'fieldtype': 'Link', + 'options': 'Item Group', + 'width': 120 + } + ]) + + columns.extend([ + { + 'label': _('Description'), + 'fieldname': 'description', + 'fieldtype': 'Data', + 'width': 150 + }, + { + 'label': _('Invoice'), + 'fieldname': 'invoice', + 'fieldtype': 'Link', + 'options': 'Purchase Invoice', + 'width': 120 + }, + { + 'label': _('Posting Date'), + 'fieldname': 'posting_date', + 'fieldtype': 'Date', + 'width': 120 + } + ]) + + if filters.get('group_by') != 'Supplier': + columns.extend([ + { + 'label': _('Supplier'), + 'fieldname': 'supplier', + 'fieldtype': 'Link', + 'options': 'Supplier', + 'width': 120 + }, + { + 'label': _('Supplier Name'), + 'fieldname': 'supplier_name', + 'fieldtype': 'Data', + 'width': 120 + } + ]) if additional_table_columns: columns += additional_table_columns columns += [ - "Payable Account:Link/Account:120", - _("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80", - _("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100", - _("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140", - _("Stock Qty") + ":Float:120", _("Stock UOM") + "::100", - _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120" + { + 'label': _('Payable Account'), + 'fieldname': 'credit_to', + 'fieldtype': 'Link', + 'options': 'Account', + 'width': 80 + }, + { + 'label': _('Mode Of Payment'), + 'fieldname': 'mode_of_payment', + 'fieldtype': 'Data', + 'width': 120 + }, + { + 'label': _('Project'), + 'fieldname': 'project', + 'fieldtype': 'Link', + 'options': 'Project', + 'width': 80 + }, + { + 'label': _('Company'), + 'fieldname': 'company', + 'fieldtype': 'Link', + 'options': 'Company', + 'width': 80 + }, + { + 'label': _('Purchase Order'), + 'fieldname': 'purchase_order', + 'fieldtype': 'Link', + 'options': 'Purchase Order', + 'width': 100 + }, + { + 'label': _("Purchase Receipt"), + 'fieldname': 'Purchase Receipt', + 'fieldtype': 'Link', + 'options': 'Purchase Receipt', + 'width': 100 + }, + { + 'label': _('Expense Account'), + 'fieldname': 'expense_account', + 'fieldtype': 'Link', + 'options': 'Account', + 'width': 100 + }, + { + 'label': _('Stock Qty'), + 'fieldname': 'stock_qty', + 'fieldtype': 'Float', + 'width': 100 + }, + { + 'label': _('Stock UOM'), + 'fieldname': 'stock_uom', + 'fieldtype': 'Link', + 'options': 'UOM', + 'width': 100 + }, + { + 'label': _('Rate'), + 'fieldname': 'rate', + 'fieldtype': 'Float', + 'options': 'currency', + 'width': 100 + }, + { + 'label': _('Amount'), + 'fieldname': 'amount', + 'fieldtype': 'Currency', + 'options': 'currency', + 'width': 100 + }, + { + 'fieldname': 'currency', + 'label': _('Currency'), + 'fieldtype': 'Currency', + 'width': 80, + 'hidden': 1 + } ] + if filters.get('group_by'): + columns.append({ + 'label': _('% Of Grand Total'), + 'fieldname': 'percent_gt', + 'fieldtype': 'Float', + 'width': 80 + }) + return columns def get_conditions(filters): @@ -103,6 +293,11 @@ def get_conditions(filters): if filters.get(opts[0]): conditions += opts[1] + if not filters.get("group_by"): + conditions += "ORDER BY `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc" + else: + conditions += get_group_by_conditions(filters, 'Purchase Invoice') + return conditions def get_items(filters, additional_query_columns): @@ -129,7 +324,6 @@ def get_items(filters, additional_query_columns): from `tabPurchase Invoice`, `tabPurchase Invoice Item` where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and `tabPurchase Invoice`.docstatus = 1 %s %s - order by `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc """.format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1) def get_aii_accounts(): From 612e3b77fdf8da501739d33aacd67a8da316b7fe Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 27 Jan 2020 14:23:05 +0530 Subject: [PATCH 054/119] fix: incorrect status for fraction of outstanding amount (#20370) --- .../doctype/sales_invoice/sales_invoice.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 24024dc3100..a421cc4d6dc 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1232,24 +1232,27 @@ class SalesInvoice(SellingController): self.status = 'Draft' return + precision = self.precision("outstanding_amount") + outstanding_amount = flt(self.outstanding_amount, precision) + if not status: if self.docstatus == 2: status = "Cancelled" elif self.docstatus == 1: - if flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed': + if outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed': self.status = "Overdue and Discounted" - elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()): + elif outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()): self.status = "Overdue" - elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed': + elif outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed': self.status = "Unpaid and Discounted" - elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()): + elif outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()): self.status = "Unpaid" #Check if outstanding amount is 0 due to credit note issued against invoice - elif flt(self.outstanding_amount) <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}): + elif outstanding_amount <= 0 and self.is_return == 0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}): self.status = "Credit Note Issued" elif self.is_return == 1: self.status = "Return" - elif flt(self.outstanding_amount)<=0: + elif outstanding_amount <=0: self.status = "Paid" else: self.status = "Submitted" From 148951e6f30d7858bbed043fe3df08eafbee094e Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 27 Jan 2020 15:18:45 +0530 Subject: [PATCH 055/119] fix: Finance book filtering in financial statements (#20411) * fix: Finance book filtering in financial statements * fix: Use IS NULL instead of ifnull --- erpnext/accounts/report/balance_sheet/balance_sheet.js | 3 ++- erpnext/accounts/report/cash_flow/cash_flow.js | 3 ++- erpnext/accounts/report/cash_flow/cash_flow.py | 4 ++-- .../consolidated_financial_statement.js | 3 ++- .../consolidated_financial_statement.py | 4 ++-- erpnext/accounts/report/financial_statements.py | 4 ++-- erpnext/accounts/report/general_ledger/general_ledger.js | 3 ++- erpnext/accounts/report/general_ledger/general_ledger.py | 2 +- .../profit_and_loss_statement/profit_and_loss_statement.js | 3 ++- erpnext/accounts/report/trial_balance/trial_balance.js | 3 ++- erpnext/accounts/report/trial_balance/trial_balance.py | 4 ++-- 11 files changed, 21 insertions(+), 15 deletions(-) diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.js b/erpnext/accounts/report/balance_sheet/balance_sheet.js index 8c11514aa64..c4c24c0bab3 100644 --- a/erpnext/accounts/report/balance_sheet/balance_sheet.js +++ b/erpnext/accounts/report/balance_sheet/balance_sheet.js @@ -14,6 +14,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { frappe.query_reports["Balance Sheet"]["filters"].push({ "fieldname": "include_default_book_entries", "label": __("Include Default Book Entries"), - "fieldtype": "Check" + "fieldtype": "Check", + "default": 1 }); }); diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js index 03940f4b246..89244c3781a 100644 --- a/erpnext/accounts/report/cash_flow/cash_flow.js +++ b/erpnext/accounts/report/cash_flow/cash_flow.js @@ -20,7 +20,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { { "fieldname": "include_default_book_entries", "label": __("Include Default Book Entries"), - "fieldtype": "Check" + "fieldtype": "Check", + "default": 1 } ); }); \ No newline at end of file diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py index 98c25b7514a..0b124774479 100644 --- a/erpnext/accounts/report/cash_flow/cash_flow.py +++ b/erpnext/accounts/report/cash_flow/cash_flow.py @@ -130,11 +130,11 @@ def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters = frappe._dict(filters) if filters.finance_book: - cond = " and finance_book = %s" %(frappe.db.escape(filters.finance_book)) + cond = " AND (finance_book in (%s, '') OR finance_book IS NULL)" %(frappe.db.escape(filters.finance_book)) if filters.include_default_book_entries: company_fb = frappe.db.get_value("Company", company, 'default_finance_book') - cond = """ and finance_book in (%s, %s) + cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL) """ %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb)) gl_sum = frappe.db.sql_list(""" diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js index e69a993e8ce..48a030a99ed 100644 --- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js +++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js @@ -58,7 +58,8 @@ frappe.query_reports["Consolidated Financial Statement"] = { { "fieldname": "include_default_book_entries", "label": __("Include Default Book Entries"), - "fieldtype": "Check" + "fieldtype": "Check", + "default": 1 } ] } diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py index 418a23c2d7e..e9eb819cc64 100644 --- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py +++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py @@ -389,9 +389,9 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): if filters.get("finance_book"): if filters.get("include_default_book_entries"): - additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)") + additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") else: - additional_conditions.append("finance_book in (%(finance_book)s)") + additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)") return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else "" diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 40d5682726d..32d9075f443 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -408,9 +408,9 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): if filters.get("finance_book"): if filters.get("include_default_book_entries"): - additional_conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)") + additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") else: - additional_conditions.append("finance_book in (%(finance_book)s)") + additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)") if accounting_dimensions: for dimension in accounting_dimensions: diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index 4a287060b39..ac49d373d47 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -154,7 +154,8 @@ frappe.query_reports["General Ledger"] = { { "fieldname": "include_default_book_entries", "label": __("Include Default Book Entries"), - "fieldtype": "Check" + "fieldtype": "Check", + "default": 1 } ] } diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index b32a54f5cc1..0939354efa7 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -184,7 +184,7 @@ def get_conditions(filters): if filters.get("finance_book"): if filters.get("include_default_book_entries"): - conditions.append("finance_book in (%(finance_book)s, %(company_fb)s)") + conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") else: conditions.append("finance_book in (%(finance_book)s)") diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js index a8362bf62dd..baa0bda7005 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js @@ -23,7 +23,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { { "fieldname": "include_default_book_entries", "label": __("Include Default Book Entries"), - "fieldtype": "Check" + "fieldtype": "Check", + "default": 1 } ); }); diff --git a/erpnext/accounts/report/trial_balance/trial_balance.js b/erpnext/accounts/report/trial_balance/trial_balance.js index f15b5b1a19e..622bab6946f 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.js +++ b/erpnext/accounts/report/trial_balance/trial_balance.js @@ -85,7 +85,8 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { { "fieldname": "include_default_book_entries", "label": __("Include Default Book Entries"), - "fieldtype": "Check" + "fieldtype": "Check", + "default": 1 } ], "formatter": erpnext.financial_statements.formatter, diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py index faeee0f76aa..69285cc9634 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.py +++ b/erpnext/accounts/report/trial_balance/trial_balance.py @@ -103,9 +103,9 @@ def get_rootwise_opening_balances(filters, report_type): where lft >= %s and rgt <= %s)""" % (lft, rgt) if filters.finance_book: - fb_conditions = " and finance_book = %(finance_book)s" + fb_conditions = " AND finance_book = %(finance_book)s" if filters.include_default_book_entries: - fb_conditions = " and (finance_book in (%(finance_book)s, %(company_fb)s))" + fb_conditions = " AND (finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)" additional_conditions += fb_conditions From eec0ee83e228f20db1694098589fb8469d227971 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Mon, 27 Jan 2020 15:48:01 +0530 Subject: [PATCH 056/119] fix: Changes in total row display --- .../item_wise_sales_register.py | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index 57a99ef76a9..cf48ad4701d 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -355,17 +355,14 @@ def get_conditions(filters): return conditions def get_group_by_conditions(filters, doctype): - - if filters.get("group_by"): - if filters.get("group_by") == 'Invoice': - return "ORDER BY `tab{0} Item`.parent desc".format(doctype) - elif filters.get("group_by") == 'Item': - return "ORDER BY `tab{0} Item`.`item_code`".format(doctype) - elif filters.get("group_by") == 'Item Group': - return "ORDER BY `tab{0} Item`.{1}".format(doctype, frappe.scrub(filters.get('group_by'))) - elif filters.get("group_by") in ('Customer', 'Customer Group', 'Territory', 'Supplier'): - return "ORDER BY `tab{0}`.{1}".format(doctype, frappe.scrub(filters.get('group_by'))) - + if filters.get("group_by") == 'Invoice': + return "ORDER BY `tab{0} Item`.parent desc".format(doctype) + elif filters.get("group_by") == 'Item': + return "ORDER BY `tab{0} Item`.`item_code`".format(doctype) + elif filters.get("group_by") == 'Item Group': + return "ORDER BY `tab{0} Item`.{1}".format(doctype, frappe.scrub(filters.get('group_by'))) + elif filters.get("group_by") in ('Customer', 'Customer Group', 'Territory', 'Supplier'): + return "ORDER BY `tab{0}`.{1}".format(doctype, frappe.scrub(filters.get('group_by'))) def get_items(filters, additional_query_columns): conditions = get_conditions(filters) @@ -420,7 +417,7 @@ def get_grand_total(filters, doctype): FROM `tab{0}` WHERE `tab{0}`.docstatus = 1 and posting_date between %s and %s - """.format(doctype), (filters.get('from_date'), filters.get('to_date')))[0][0] + """.format(doctype), (filters.get('from_date'), filters.get('to_date')))[0][0] #nosec def get_deducted_taxes(): return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'") @@ -567,13 +564,22 @@ def add_total_row(data, filters, prev_group_by_value, item, total_row_map, def get_display_value(filters, group_by_field, item): if filters.get('group_by') == 'Item': - return "Item: " + cstr(item.get('item_code')) \ - + "

" + "Item Name: " + cstr(item.get('item_name')) + if item.get('item_code') != item.get('item_name'): + value = item.get('item_code') + "

" + \ + "" + item.get('item_name') + "" + else: + value = cstr(item.get('item_code')) elif filters.get('group_by') in ('Customer', 'Supplier'): - return filters.get('group_by')+": " + cstr(item.get(frappe.scrub(filters.get('group_by')))) \ - + "

" + filters.get('group_by') + " Name: " + item.get(frappe.scrub(filters.get('group_by'))+'_name', '') + party = frappe.scrub(filters.get('group_by')) + if item.get(party) != item.get(party+'_name'): + value = item.get(party) + "

" + \ + "" + item.get(party+'_name') + "" + else: + value = item.get(party) else: - return item.get(group_by_field) + value = item.get(group_by_field) + + return value def get_group_by_and_display_fields(filters): if filters.get('group_by') == 'Item': From b4b410f1d2a2a59828eb8b5aee5d15ce4ebf120f Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 27 Jan 2020 16:06:15 +0530 Subject: [PATCH 057/119] refac: filters and columns of fixed asset register report (#20420) --- .../fixed_asset_register.js | 23 ++++- .../fixed_asset_register.py | 95 ++++++++++++------- 2 files changed, 78 insertions(+), 40 deletions(-) diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js index 8c737d066b9..91ce9ce7fe9 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.js @@ -20,6 +20,16 @@ frappe.query_reports["Fixed Asset Register"] = { default: 'In Location', reqd: 1 }, + { + fieldname:"purchase_date", + label: __("Purchase Date"), + fieldtype: "Date" + }, + { + fieldname:"available_for_use_date", + label: __("Available For Use Date"), + fieldtype: "Date" + }, { fieldname:"finance_book", label: __("Finance Book"), @@ -27,10 +37,15 @@ frappe.query_reports["Fixed Asset Register"] = { options: "Finance Book" }, { - fieldname:"date", - label: __("Date"), - fieldtype: "Date", - default: frappe.datetime.get_today() + fieldname:"asset_category", + label: __("Asset Category"), + fieldtype: "Link", + options: "Asset Category" + }, + { + fieldname:"is_existing_asset", + label: __("Is Existing Asset"), + fieldtype: "Check" }, ] }; diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py index 14984441d00..fa2fe7b4a3c 100644 --- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py +++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py @@ -40,6 +40,42 @@ def get_columns(filters): "fieldname": "status", "width": 90 }, + { + "label": _("Purchase Date"), + "fieldtype": "Date", + "fieldname": "purchase_date", + "width": 90 + }, + { + "label": _("Available For Use Date"), + "fieldtype": "Date", + "fieldname": "available_for_use_date", + "width": 90 + }, + { + "label": _("Gross Purchase Amount"), + "fieldname": "gross_purchase_amount", + "options": "Currency", + "width": 90 + }, + { + "label": _("Asset Value"), + "fieldname": "asset_value", + "options": "Currency", + "width": 90 + }, + { + "label": _("Opening Accumulated Depreciation"), + "fieldname": "opening_accumulated_depreciation", + "options": "Currency", + "width": 90 + }, + { + "label": _("Depreciated Amount"), + "fieldname": "depreciated_amount", + "options": "Currency", + "width": 90 + }, { "label": _("Cost Center"), "fieldtype": "Link", @@ -54,25 +90,6 @@ def get_columns(filters): "options": "Department", "width": 100 }, - { - "label": _("Location"), - "fieldtype": "Link", - "fieldname": "location", - "options": "Location", - "width": 100 - }, - { - "label": _("Purchase Date"), - "fieldtype": "Date", - "fieldname": "purchase_date", - "width": 90 - }, - { - "label": _("Gross Purchase Amount"), - "fieldname": "gross_purchase_amount", - "options": "Currency", - "width": 90 - }, { "label": _("Vendor Name"), "fieldtype": "Data", @@ -80,25 +97,29 @@ def get_columns(filters): "width": 100 }, { - "label": _("Available For Use Date"), - "fieldtype": "Date", - "fieldname": "available_for_use_date", - "width": 90 - }, - { - "label": _("Asset Value"), - "fieldname": "asset_value", - "options": "Currency", - "width": 90 + "label": _("Location"), + "fieldtype": "Link", + "fieldname": "location", + "options": "Location", + "width": 100 }, ] def get_conditions(filters): - conditions = {'docstatus': 1} + conditions = { 'docstatus': 1 } status = filters.status + date = filters.date - if filters.company: + if filters.get('company'): conditions["company"] = filters.company + if filters.get('purchase_date'): + conditions["purchase_date"] = ('<=', filters.get('purchase_date')) + if filters.get('available_for_use_date'): + conditions["available_for_use_date"] = ('<=', filters.get('available_for_use_date')) + if filters.get('is_existing_asset'): + conditions["is_existing_asset"] = filters.get('is_existing_asset') + if filters.get('asset_category'): + conditions["asset_category"] = filters.get('asset_category') # In Store assets are those that are not sold or scrapped operand = 'not in' @@ -114,7 +135,7 @@ def get_data(filters): data = [] conditions = get_conditions(filters) - depreciation_amount_map = get_finance_book_value_map(filters.date, filters.finance_book) + depreciation_amount_map = get_finance_book_value_map(filters) pr_supplier_map = get_purchase_receipt_supplier_map() pi_supplier_map = get_purchase_invoice_supplier_map() @@ -136,6 +157,8 @@ def get_data(filters): "cost_center": asset.cost_center, "vendor_name": pr_supplier_map.get(asset.purchase_receipt) or pi_supplier_map.get(asset.purchase_invoice), "gross_purchase_amount": asset.gross_purchase_amount, + "opening_accumulated_depreciation": asset.opening_accumulated_depreciation, + "depreciated_amount": depreciation_amount_map.get(asset.name) or 0.0, "available_for_use_date": asset.available_for_use_date, "location": asset.location, "asset_category": asset.asset_category, @@ -146,9 +169,9 @@ def get_data(filters): return data -def get_finance_book_value_map(date, finance_book=''): - if not date: - date = today() +def get_finance_book_value_map(filters): + date = filters.get('purchase_date') or filters.get('available_for_use_date') or today() + return frappe._dict(frappe.db.sql(''' Select parent, SUM(depreciation_amount) FROM `tabDepreciation Schedule` @@ -157,7 +180,7 @@ def get_finance_book_value_map(date, finance_book=''): AND schedule_date<=%s AND journal_entry IS NOT NULL AND ifnull(finance_book, '')=%s - GROUP BY parent''', (date, cstr(finance_book)))) + GROUP BY parent''', (date, cstr(filters.finance_book or '')))) def get_purchase_receipt_supplier_map(): return frappe._dict(frappe.db.sql(''' Select From 875bac8bb9cf924547cfced624ffb444a9b58165 Mon Sep 17 00:00:00 2001 From: NahuelOperto Date: Mon, 27 Jan 2020 08:58:01 -0300 Subject: [PATCH 058/119] Fix sql injection --- erpnext/setup/doctype/item_group/item_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py index 22375ae22c3..9f258828660 100644 --- a/erpnext/setup/doctype/item_group/item_group.py +++ b/erpnext/setup/doctype/item_group/item_group.py @@ -119,7 +119,7 @@ def get_product_list_for_group(product_group=None, start=0, limit=10, search=Non or I.name like %(search)s)""" search = "%" + cstr(search) + "%" - query += """order by I.weightage desc, in_stock desc, I.modified desc limit %s, %s""" % (start, limit) + query += """order by I.weightage desc, in_stock desc, I.modified desc limit %s, %s""" % (cint(start), cint(limit)) data = frappe.db.sql(query, {"product_group": product_group,"search": search, "today": nowdate()}, as_dict=1) data = adjust_qty_for_expired_items(data) From 6fbafa1924fe8e7874c0aebeaeee48d2f3b1903b Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 27 Jan 2020 17:46:09 +0530 Subject: [PATCH 059/119] fix: only fetch driver address if not set --- erpnext/stock/doctype/delivery_trip/delivery_trip.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.json b/erpnext/stock/doctype/delivery_trip/delivery_trip.json index 0a526243bc4..e78bf6b5049 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.json +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.json @@ -163,6 +163,7 @@ }, { "fetch_from": "driver.address", + "fetch_if_empty": 1, "fieldname": "driver_address", "fieldtype": "Link", "label": "Driver Address", @@ -170,7 +171,8 @@ } ], "is_submittable": 1, - "modified": "2019-09-27 15:43:01.975139", + "links": [], + "modified": "2020-01-26 22:37:14.824021", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Trip", From fe56c7ce399839a2cb0f28c5eef02b12cfdf5ce6 Mon Sep 17 00:00:00 2001 From: Marica Date: Tue, 28 Jan 2020 12:44:03 +0530 Subject: [PATCH 060/119] fix: Column 'project' in where clause is ambiguous (#20439) * fix: Column 'project' in where clause is ambiguous * fix: Fixed alias in query --- erpnext/accounts/doctype/budget/budget.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py index b76cdf3d1c4..084514cbfa7 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -210,10 +210,10 @@ def get_requested_amount(args, budget): item_code = args.get('item_code') condition = get_other_condition(args, budget, 'Material Request') - data = frappe.db.sql(""" select ifnull((sum(mri.stock_qty - mri.ordered_qty) * rate), 0) as amount - from `tabMaterial Request Item` mri, `tabMaterial Request` mr where mr.name = mri.parent and - mri.item_code = %s and mr.docstatus = 1 and mri.stock_qty > mri.ordered_qty and {0} and - mr.material_request_type = 'Purchase' and mr.status != 'Stopped'""".format(condition), item_code, as_list=1) + data = frappe.db.sql(""" select ifnull((sum(child.stock_qty - child.ordered_qty) * rate), 0) as amount + from `tabMaterial Request Item` child, `tabMaterial Request` parent where parent.name = child.parent and + child.item_code = %s and parent.docstatus = 1 and child.stock_qty > child.ordered_qty and {0} and + parent.material_request_type = 'Purchase' and parent.status != 'Stopped'""".format(condition), item_code, as_list=1) return data[0][0] if data else 0 @@ -221,10 +221,10 @@ def get_ordered_amount(args, budget): item_code = args.get('item_code') condition = get_other_condition(args, budget, 'Purchase Order') - data = frappe.db.sql(""" select ifnull(sum(poi.amount - poi.billed_amt), 0) as amount - from `tabPurchase Order Item` poi, `tabPurchase Order` po where - po.name = poi.parent and poi.item_code = %s and po.docstatus = 1 and poi.amount > poi.billed_amt - and po.status != 'Closed' and {0}""".format(condition), item_code, as_list=1) + data = frappe.db.sql(""" select ifnull(sum(child.amount - child.billed_amt), 0) as amount + from `tabPurchase Order Item` child, `tabPurchase Order` parent where + parent.name = child.parent and child.item_code = %s and parent.docstatus = 1 and child.amount > child.billed_amt + and parent.status != 'Closed' and {0}""".format(condition), item_code, as_list=1) return data[0][0] if data else 0 @@ -233,16 +233,15 @@ def get_other_condition(args, budget, for_doc): budget_against_field = frappe.scrub(args.get("budget_against_field")) if budget_against_field and args.get(budget_against_field): - condition += " and %s = '%s'" %(budget_against_field, args.get(budget_against_field)) + condition += " and child.%s = '%s'" %(budget_against_field, args.get(budget_against_field)) if args.get('fiscal_year'): date_field = 'schedule_date' if for_doc == 'Material Request' else 'transaction_date' start_date, end_date = frappe.db.get_value('Fiscal Year', args.get('fiscal_year'), ['year_start_date', 'year_end_date']) - alias = 'mr' if for_doc == 'Material Request' else 'po' - condition += """ and %s.%s - between '%s' and '%s' """ %(alias, date_field, start_date, end_date) + condition += """ and parent.%s + between '%s' and '%s' """ %(date_field, start_date, end_date) return condition From f2838c4a134ada97b998745d85cf7bb06035c4eb Mon Sep 17 00:00:00 2001 From: Pranav Nachnekar Date: Tue, 28 Jan 2020 07:22:42 +0000 Subject: [PATCH 061/119] fix: discounting not applied on sales invoice created by subscriptions (#20432) * fix: imporer escaping * fix: discounting not applied on sales invoice created by subscriptions --- erpnext/accounts/doctype/subscription/subscription.json | 6 ++++-- erpnext/accounts/doctype/subscription/subscription.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/subscription/subscription.json b/erpnext/accounts/doctype/subscription/subscription.json index 29cb62a3972..32b97ba80b5 100644 --- a/erpnext/accounts/doctype/subscription/subscription.json +++ b/erpnext/accounts/doctype/subscription/subscription.json @@ -1,4 +1,5 @@ { + "actions": [], "autoname": "ACC-SUB-.YYYY.-.#####", "creation": "2017-07-18 17:50:43.967266", "doctype": "DocType", @@ -155,7 +156,7 @@ "fieldname": "apply_additional_discount", "fieldtype": "Select", "label": "Apply Additional Discount On", - "options": "\nGrand Total\nNet total" + "options": "\nGrand Total\nNet Total" }, { "fieldname": "cb_2", @@ -196,7 +197,8 @@ "fieldtype": "Column Break" } ], - "modified": "2019-07-25 18:45:38.579579", + "links": [], + "modified": "2020-01-27 14:37:32.845173", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription", diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py index 54827503759..98d07c71a3a 100644 --- a/erpnext/accounts/doctype/subscription/subscription.py +++ b/erpnext/accounts/doctype/subscription/subscription.py @@ -280,7 +280,7 @@ class Subscription(Document): if self.additional_discount_percentage or self.additional_discount_amount: discount_on = self.apply_additional_discount - invoice.apply_additional_discount = discount_on if discount_on else 'Grand Total' + invoice.apply_discount_on = discount_on if discount_on else 'Grand Total' # Subscription period invoice.from_date = self.current_invoice_start From df94f0565ea1f83bb9f1298de13b0775708cde35 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 28 Jan 2020 14:08:48 +0530 Subject: [PATCH 062/119] fix: cannot complete task if dependent task are not completed / cancelled (#20434) --- erpnext/projects/doctype/task/task.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py index 45f26814a65..f2ba80f096f 100755 --- a/erpnext/projects/doctype/task/task.py +++ b/erpnext/projects/doctype/task/task.py @@ -56,8 +56,8 @@ class Task(NestedSet): def validate_status(self): if self.status!=self.get_db_value("status") and self.status == "Completed": for d in self.depends_on: - if frappe.db.get_value("Task", d.task, "status") != "Completed": - frappe.throw(_("Cannot close task {0} as its dependant task {1} is not closed.").format(frappe.bold(self.name), frappe.bold(d.task))) + if frappe.db.get_value("Task", d.task, "status") not in ("Completed", "Cancelled"): + frappe.throw(_("Cannot complete task {0} as its dependant tasks {1} are not completed / cancelled.").format(frappe.bold(self.name), frappe.bold(d.task))) close_all_assignments(self.doctype, self.name) From 8e5b812a97d86eb73e0f7c396ce3fcd232b4078a Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 28 Jan 2020 14:34:54 +0530 Subject: [PATCH 063/119] fix: incorrect work order qty for sub assembly items (#20448) --- .../manufacturing/doctype/production_plan/production_plan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 25c385fb1e5..10a8d8fc9bd 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -729,6 +729,6 @@ def get_sub_assembly_items(bom_no, bom_data): }) bom_item = bom_data.get(key) - bom_item["stock_qty"] += d.stock_qty + bom_item["stock_qty"] += d.stock_qty / d.parent_bom_qty get_sub_assembly_items(bom_item.get("bom_no"), bom_data) From d4d641a07ea886d26c43f107cfc446cc965df7bd Mon Sep 17 00:00:00 2001 From: 0Pranav Date: Wed, 29 Jan 2020 09:32:40 +0530 Subject: [PATCH 064/119] fix: missing plus button in request for quotaion for supplier quotation --- .../doctype/request_for_quotation/request_for_quotation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js index 2f0cfa64fc8..455bd68ecff 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js @@ -9,7 +9,7 @@ cur_frm.add_fetch('contact', 'email_id', 'email_id') frappe.ui.form.on("Request for Quotation",{ setup: function(frm) { frm.custom_make_buttons = { - 'Supplier Quotation': 'Supplier Quotation' + 'Supplier Quotation': 'Create' } frm.fields_dict["suppliers"].grid.get_field("contact").get_query = function(doc, cdt, cdn) { From 7524ecbc59d33efc454c4f0904057f81379969ae Mon Sep 17 00:00:00 2001 From: Raffael Meyer Date: Thu, 30 Jan 2020 00:08:25 +0100 Subject: [PATCH 065/119] fix #20469 --- erpnext/regional/report/datev/datev.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py index 589165173ac..a58e13a0947 100644 --- a/erpnext/regional/report/datev/datev.py +++ b/erpnext/regional/report/datev/datev.py @@ -160,7 +160,7 @@ def get_gl_entries(filters, as_dict): where gl.company = %(company)s and DATE(gl.posting_date) >= %(from_date)s and DATE(gl.posting_date) <= %(to_date)s - order by 'Belegdatum', gl.voucher_no""", filters, as_dict=as_dict, as_utf8=1) + order by 'Belegdatum', gl.voucher_no""", filters, as_dict=as_dict) return gl_entries From e552e958de3d3780ee2474b7a3bc2af29b973e8e Mon Sep 17 00:00:00 2001 From: Parth Kharwar Date: Thu, 30 Jan 2020 12:12:42 +0530 Subject: [PATCH 066/119] fix: rename breadcrumb for Brand DocType from Selling to Stock --- erpnext/public/js/conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js index 095e744926b..0f88f133501 100644 --- a/erpnext/public/js/conf.js +++ b/erpnext/public/js/conf.js @@ -50,7 +50,7 @@ $.extend(frappe.breadcrumbs.preferred, { "Territory": "Selling", "Sales Person": "Selling", "Sales Partner": "Selling", - "Brand": "Selling" + "Brand": "Stock" }); $.extend(frappe.breadcrumbs.module_map, { From ba4d9469ffd974001e4caab04beeda21f135a0b9 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 30 Jan 2020 15:33:51 +0530 Subject: [PATCH 067/119] fix: Do not show any finance book record if no finance book filter is applied --- erpnext/accounts/report/cash_flow/cash_flow.py | 2 ++ erpnext/accounts/report/financial_statements.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py index 0b124774479..702c81ccb76 100644 --- a/erpnext/accounts/report/cash_flow/cash_flow.py +++ b/erpnext/accounts/report/cash_flow/cash_flow.py @@ -136,6 +136,8 @@ def get_account_type_based_gl_data(company, start_date, end_date, account_type, cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL) """ %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb)) + else: + cond = "AND (finance_book = '' OR finance_book IS NULL)" gl_sum = frappe.db.sql_list(""" select sum(credit) - sum(debit) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 32d9075f443..a1ecaae2a11 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -13,7 +13,7 @@ import frappe, erpnext from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency from erpnext.accounts.utils import get_fiscal_year from frappe import _ -from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate) +from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate, cstr) from six import itervalues from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions @@ -356,7 +356,7 @@ def set_gl_entries_by_account( "company": company, "from_date": from_date, "to_date": to_date, - "finance_book": filters.get("finance_book") + "finance_book": cstr(filters.get("finance_book")) } if filters.get("include_default_book_entries"): @@ -411,6 +411,8 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") else: additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)") + else: + additional_conditions.append("(finance_book = '' OR finance_book IS NULL)") if accounting_dimensions: for dimension in accounting_dimensions: From a175e06149b130dce7433a95c532d98e4d59d3f6 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Jan 2020 18:56:35 +0000 Subject: [PATCH 068/119] fix: pymysql.err.InternalError about t2.bank_account_no due to removal of field from Journal Entry Account table: #20343 --- .../doctype/bank_reconciliation/bank_reconciliation.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py index 90cdf834c59..3613a1ef696 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py @@ -21,10 +21,6 @@ class BankReconciliation(Document): if not self.include_reconciled_entries: condition = " and (clearance_date is null or clearance_date='0000-00-00')" - account_cond = "" - if self.bank_account_no: - account_cond = " and t2.bank_account_no = {0}".format(frappe.db.escape(self.bank_account_no)) - journal_entries = frappe.db.sql(""" select "Journal Entry" as payment_document, t1.name as payment_entry, @@ -36,10 +32,10 @@ class BankReconciliation(Document): where t2.parent = t1.name and t2.account = %s and t1.docstatus=1 and t1.posting_date >= %s and t1.posting_date <= %s - and ifnull(t1.is_opening, 'No') = 'No' {0} {1} + and ifnull(t1.is_opening, 'No') = 'No' {0} group by t2.account, t1.name order by t1.posting_date ASC, t1.name DESC - """.format(condition, account_cond), (self.bank_account, self.from_date, self.to_date), as_dict=1) + """.format(condition), (self.bank_account, self.from_date, self.to_date), as_dict=1) if self.bank_account_no: condition = " and bank_account = %(bank_account_no)s" From feaa82a8eab5b5c415cdbff718b6eb64b1aaf9d6 Mon Sep 17 00:00:00 2001 From: racitup Date: Mon, 20 Jan 2020 19:41:08 +0000 Subject: [PATCH 069/119] fix: KeyError about bank_account_no due to non-existent field: #20343 --- .../doctype/bank_reconciliation/bank_reconciliation.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py index 3613a1ef696..d5ba49abd0f 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py @@ -68,11 +68,10 @@ class BankReconciliation(Document): from `tabSales Invoice Payment` sip, `tabSales Invoice` si, `tabAccount` account where sip.account=%(account)s and si.docstatus=1 and sip.parent = si.name - and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s {0} + and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s order by si.posting_date ASC, si.name DESC - """.format(condition), - {"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1) + """, {"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1) entries = sorted(list(payment_entries)+list(journal_entries+list(pos_entries)), key=lambda k: k['posting_date'] or getdate(nowdate())) From a05450821182bce276f1242761b5b2a670b03663 Mon Sep 17 00:00:00 2001 From: racitup Date: Tue, 21 Jan 2020 00:47:10 +0000 Subject: [PATCH 070/119] fix: Plaid automatic_synchronization TypeError on filter & add info log message #20343 --- .../doctype/plaid_settings/plaid_settings.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index a04d6c5be73..9e22dc07bb6 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -133,8 +133,11 @@ def sync_transactions(bank, bank_account): try: transactions = get_transactions(bank=bank, bank_account=bank_account, start_date=start_date, end_date=end_date) + result = [] if transactions: + frappe.logger().info("Plaid is adding {} Bank Transactions from '{}' between {} and {}".format( + len(transactions), bank_account, start_date, end_date)) for transaction in transactions: result.append(new_bank_transaction(transaction)) @@ -201,7 +204,7 @@ def automatic_synchronization(): settings = frappe.get_doc("Plaid Settings", "Plaid Settings") if settings.enabled == 1 and settings.automatic_sync == 1: - plaid_accounts = frappe.get_all("Bank Account", filter={"integration_id": ["!=", ""]}, fields=["name", "bank"]) + plaid_accounts = frappe.get_all("Bank Account", filters={"integration_id": ["!=", ""]}, fields=["name", "bank"]) for plaid_account in plaid_accounts: frappe.enqueue("erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions", bank=plaid_account.bank, bank_account=plaid_account.name) From bee017e17c78aed52dee5ebf4f92fa4184dfa08e Mon Sep 17 00:00:00 2001 From: racitup Date: Tue, 21 Jan 2020 15:07:47 +0000 Subject: [PATCH 071/119] fix: Plaid transaction import order, transaction_id duplicate check, added transaction category tags --- .../doctype/plaid_settings/plaid_settings.py | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index 9e22dc07bb6..970793f7468 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -10,6 +10,7 @@ from frappe.model.document import Document from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_connector import PlaidConnector from frappe.utils import getdate, formatdate, today, add_months +from frappe.desk.doctype.tag.tag import add_tag class PlaidSettings(Document): pass @@ -135,11 +136,11 @@ def sync_transactions(bank, bank_account): transactions = get_transactions(bank=bank, bank_account=bank_account, start_date=start_date, end_date=end_date) result = [] - if transactions: - frappe.logger().info("Plaid is adding {} Bank Transactions from '{}' between {} and {}".format( - len(transactions), bank_account, start_date, end_date)) - for transaction in transactions: - result.append(new_bank_transaction(transaction)) + for transaction in reversed(transactions): + result += new_bank_transaction(transaction) + + frappe.logger().info("Plaid added {} new Bank Transactions from '{}' between {} and {}".format( + len(result), bank_account, start_date, end_date)) frappe.db.set_value("Bank Account", bank_account, "last_integration_date", getdate(end_date)) @@ -178,6 +179,13 @@ def new_bank_transaction(transaction): status = "Pending" if transaction["pending"] == "True" else "Settled" + try: + tags = [] + tags += transaction["category"] + tags += ["Plaid Cat. {}".format(transaction["category_id"])] + except KeyError: + pass + if not frappe.db.exists("Bank Transaction", dict(transaction_id=transaction["transaction_id"])): try: new_transaction = frappe.get_doc({ @@ -188,11 +196,16 @@ def new_bank_transaction(transaction): "debit": debit, "credit": credit, "currency": transaction["iso_currency_code"], + "transaction_id": transaction["transaction_id"], + "reference_number": transaction["payment_meta"]["reference_number"], "description": transaction["name"] }) new_transaction.insert() new_transaction.submit() + for tag in tags: + add_tag(tag, "Bank Transaction", new_transaction.name) + result.append(new_transaction.name) except Exception: From a1e3202054235d7b7ab30ec3b3b3cb78eabf86b0 Mon Sep 17 00:00:00 2001 From: racitup Date: Wed, 22 Jan 2020 04:32:15 +0000 Subject: [PATCH 072/119] fix: Bank Reconciliation Bank Account and Bank Account No field names --- .../bank_reconciliation.js | 6 +++--- .../bank_reconciliation.json | 18 +++++++--------- .../bank_reconciliation.py | 21 ++++++++----------- .../rename_bank_reconciliation_fields.py | 16 ++++++++++++++ 4 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 erpnext/patches/v12_0/rename_bank_reconciliation_fields.py diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js index 7c94455b9ba..19fadbf6ded 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js @@ -3,16 +3,16 @@ frappe.ui.form.on("Bank Reconciliation", { setup: function(frm) { - frm.add_fetch("bank_account", "account_currency", "account_currency"); + frm.add_fetch("account", "account_currency", "account_currency"); }, onload: function(frm) { let default_bank_account = frappe.defaults.get_user_default("Company")? locals[":Company"][frappe.defaults.get_user_default("Company")]["default_bank_account"]: ""; - frm.set_value("bank_account", default_bank_account); + frm.set_value("account", default_bank_account); - frm.set_query("bank_account", function() { + frm.set_query("account", function() { return { "filters": { "account_type": ["in",["Bank","Cash"]], diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json index e2f967daccb..b85ef3e9c4d 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.json @@ -19,10 +19,9 @@ "bold": 0, "collapsible": 0, "columns": 0, - "description": "Select account head of the bank where cheque was deposited.", - "fetch_from": "bank_account_no.account", + "fetch_from": "bank_account.account", "fetch_if_empty": 1, - "fieldname": "bank_account", + "fieldname": "account", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -31,7 +30,7 @@ "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, - "label": "Bank Account", + "label": "Account", "length": 0, "no_copy": 0, "options": "Account", @@ -164,7 +163,6 @@ "length": 0, "no_copy": 0, "permlevel": 0, - "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, @@ -183,8 +181,9 @@ "bold": 0, "collapsible": 0, "columns": 0, + "description": "Select the Bank Account to reconcile.", "fetch_if_empty": 0, - "fieldname": "bank_account_no", + "fieldname": "bank_account", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -193,12 +192,11 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Bank Account No", + "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, @@ -450,7 +448,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2019-04-09 18:41:06.110453", + "modified": "2020-01-22 00:00:00.000000", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Reconciliation", @@ -483,4 +481,4 @@ "track_changes": 0, "track_seen": 0, "track_views": 0 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py index d5ba49abd0f..804bcd8bdf0 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py @@ -30,15 +30,12 @@ class BankReconciliation(Document): from `tabJournal Entry` t1, `tabJournal Entry Account` t2 where - t2.parent = t1.name and t2.account = %s and t1.docstatus=1 - and t1.posting_date >= %s and t1.posting_date <= %s - and ifnull(t1.is_opening, 'No') = 'No' {0} + t2.parent = t1.name and t2.account = %(account)s and t1.docstatus=1 + and t1.posting_date >= %(from)s and t1.posting_date <= %(to)s + and ifnull(t1.is_opening, 'No') = 'No' %(condition)s group by t2.account, t1.name order by t1.posting_date ASC, t1.name DESC - """.format(condition), (self.bank_account, self.from_date, self.to_date), as_dict=1) - - if self.bank_account_no: - condition = " and bank_account = %(bank_account_no)s" + """, {"condition":condition, "account":self.account, "from":self.from_date, "to":self.to_date}, as_dict=1) payment_entries = frappe.db.sql(""" select @@ -51,12 +48,12 @@ class BankReconciliation(Document): from `tabPayment Entry` where (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1 - and posting_date >= %(from)s and posting_date <= %(to)s {0} + and posting_date >= %(from)s and posting_date <= %(to)s + and bank_account = %(bank_account)s order by posting_date ASC, name DESC - """.format(condition), - {"account":self.bank_account, "from":self.from_date, - "to":self.to_date, "bank_account_no": self.bank_account_no}, as_dict=1) + """, {"account":self.account, "from":self.from_date, + "to":self.to_date, "bank_account": self.bank_account}, as_dict=1) pos_entries = [] if self.include_pos_transactions: @@ -71,7 +68,7 @@ class BankReconciliation(Document): and account.name = sip.account and si.posting_date >= %(from)s and si.posting_date <= %(to)s order by si.posting_date ASC, si.name DESC - """, {"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1) + """, {"account":self.account, "from":self.from_date, "to":self.to_date}, as_dict=1) entries = sorted(list(payment_entries)+list(journal_entries+list(pos_entries)), key=lambda k: k['posting_date'] or getdate(nowdate())) diff --git a/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py b/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py new file mode 100644 index 00000000000..8918b9df7a0 --- /dev/null +++ b/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py @@ -0,0 +1,16 @@ +import frappe + +def _rename_single_field(**kwargs): + count = frappe.db.sql("SELECT COUNT(*) FROM tabSingles WHERE doctype='{doctype}' AND field='{new_name}';".format(**kwargs))[0][0] + if count == 0: + frappe.db.sql("UPDATE tabSingles SET field='{new_name}' WHERE doctype='{doctype}' AND field='{old_name}';".format(**kwargs)) + +def execute(): + BR = "Bank Reconciliation" + AC = "account" + BA = "bank_account" + BAN = "bank_account_no" + + _rename_single_field(doctype = BR, old_name = BA , new_name = AC) + _rename_single_field(doctype = BR, old_name = BAN, new_name = BA) + frappe.reload_doc("Accounts", "doctype", BR) From eef73a0d920598f5722ae324aed18a274b23be47 Mon Sep 17 00:00:00 2001 From: racitup Date: Fri, 24 Jan 2020 23:40:16 +0000 Subject: [PATCH 073/119] manually added patch for bank reconciliation fields since develop branch was in a different place #20380 --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 17c9a20766d..bbb875a3191 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -648,3 +648,4 @@ erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields erpnext.patches.v12_0.remove_denied_leaves_from_leave_ledger 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 From 814001a90fcf84e910136cfead34973cdef434e5 Mon Sep 17 00:00:00 2001 From: racitup Date: Wed, 22 Jan 2020 04:41:41 +0000 Subject: [PATCH 074/119] fix: attempt at pymysql InternalError 1054 about clearance_date in field list when removing payments from bank transactions --- .../bank_transaction_payments.json | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.json b/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.json index a75e866997d..ab3f60d32c0 100644 --- a/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.json +++ b/erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.json @@ -110,6 +110,15 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "depends_on": "eval:doc.docstatus==1", + "fieldname": "clearance_date", + "fieldtype": "Date", + "label": "Clearance Date", + "no_copy": 1, + "print_hide": 1, + "read_only": 1 } ], "has_web_view": 0, @@ -122,7 +131,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-12-06 10:57:02.635141", + "modified": "2020-01-22 00:00:00.000000", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction Payments", @@ -138,4 +147,4 @@ "track_changes": 1, "track_seen": 0, "track_views": 0 -} \ No newline at end of file +} From 08661250d231f07a5068db3903a6bb16134c5eed Mon Sep 17 00:00:00 2001 From: racitup Date: Thu, 30 Jan 2020 14:48:42 +0000 Subject: [PATCH 075/119] Ignore codacy SQL injection warning (internal code only) and add copyright notice --- erpnext/patches/v12_0/rename_bank_reconciliation_fields.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py b/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py index 8918b9df7a0..01b1dde6073 100644 --- a/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py +++ b/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py @@ -1,9 +1,12 @@ +# Copyright (c) 2020, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + import frappe def _rename_single_field(**kwargs): - count = frappe.db.sql("SELECT COUNT(*) FROM tabSingles WHERE doctype='{doctype}' AND field='{new_name}';".format(**kwargs))[0][0] + count = frappe.db.sql("SELECT COUNT(*) FROM tabSingles WHERE doctype='{doctype}' AND field='{new_name}';".format(**kwargs))[0][0] #nosec if count == 0: - frappe.db.sql("UPDATE tabSingles SET field='{new_name}' WHERE doctype='{doctype}' AND field='{old_name}';".format(**kwargs)) + frappe.db.sql("UPDATE tabSingles SET field='{new_name}' WHERE doctype='{doctype}' AND field='{old_name}';".format(**kwargs)) #nosec def execute(): BR = "Bank Reconciliation" From 9826291c524f0b09c341e0b6501c918205897435 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 31 Jan 2020 09:08:29 +0530 Subject: [PATCH 076/119] fix: Filtering fixes in financial statement --- erpnext/accounts/report/cash_flow/cash_flow.py | 9 ++++----- .../consolidated_financial_statement.py | 9 ++++----- erpnext/accounts/report/financial_statements.py | 11 ++++------- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py index 702c81ccb76..3c2aa654d98 100644 --- a/erpnext/accounts/report/cash_flow/cash_flow.py +++ b/erpnext/accounts/report/cash_flow/cash_flow.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import cint +from frappe.utils import cint, cstr from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data) from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss from erpnext.accounts.utils import get_fiscal_year @@ -130,14 +130,13 @@ def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters = frappe._dict(filters) if filters.finance_book: - cond = " AND (finance_book in (%s, '') OR finance_book IS NULL)" %(frappe.db.escape(filters.finance_book)) if filters.include_default_book_entries: company_fb = frappe.db.get_value("Company", company, 'default_finance_book') - cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL) """ %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb)) - else: - cond = "AND (finance_book = '' OR finance_book IS NULL)" + else: + cond = " AND (finance_book in (%s, '') OR finance_book IS NULL)" %(frappe.db.escape(cstr(filters.finance_book))) + gl_sum = frappe.db.sql_list(""" select sum(credit) - sum(debit) diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py index e9eb819cc64..4a79b6a340e 100644 --- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py +++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py @@ -387,11 +387,10 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): if from_date: additional_conditions.append("gl.posting_date >= %(from_date)s") - if filters.get("finance_book"): - if filters.get("include_default_book_entries"): - additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") - else: - additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)") + if filters.get("include_default_book_entries"): + additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") + else: + additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)") return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else "" diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index a1ecaae2a11..57e8e0ea8fc 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -406,14 +406,11 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): filters.cost_center = get_cost_centers_with_children(filters.cost_center) additional_conditions.append("cost_center in %(cost_center)s") - if filters.get("finance_book"): - if filters.get("include_default_book_entries"): - additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") - else: - additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)") + if filters.get("include_default_book_entries"): + additional_conditions.append("(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)") else: - additional_conditions.append("(finance_book = '' OR finance_book IS NULL)") - + additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)") + if accounting_dimensions: for dimension in accounting_dimensions: if filters.get(dimension): From bb7cf81d52facee21971aa353cd3193020535fe6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 31 Jan 2020 11:16:30 +0530 Subject: [PATCH 077/119] fix: Cash flow filter fix --- erpnext/accounts/report/cash_flow/cash_flow.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py index 3c2aa654d98..e349a6aaaf0 100644 --- a/erpnext/accounts/report/cash_flow/cash_flow.py +++ b/erpnext/accounts/report/cash_flow/cash_flow.py @@ -129,14 +129,13 @@ def get_account_type_based_gl_data(company, start_date, end_date, account_type, cond = "" filters = frappe._dict(filters) - if filters.finance_book: - if filters.include_default_book_entries: - company_fb = frappe.db.get_value("Company", company, 'default_finance_book') - cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL) - """ %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb)) - else: - cond = " AND (finance_book in (%s, '') OR finance_book IS NULL)" %(frappe.db.escape(cstr(filters.finance_book))) - + if filters.include_default_book_entries: + company_fb = frappe.db.get_value("Company", company, 'default_finance_book') + cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL) + """ %(frappe.db.escape(filters.finance_book), frappe.db.escape(company_fb)) + else: + cond = " AND (finance_book in (%s, '') OR finance_book IS NULL)" %(frappe.db.escape(cstr(filters.finance_book))) + gl_sum = frappe.db.sql_list(""" select sum(credit) - sum(debit) From 43886ca01676a8856f430a914e33f27ea37c89fc Mon Sep 17 00:00:00 2001 From: "Parth J. Kharwar" Date: Fri, 31 Jan 2020 14:37:56 +0530 Subject: [PATCH 078/119] fix: employee checkin doctype time permissions (#20473) --- .../employee_checkin/employee_checkin.js | 8 ++- .../employee_checkin/employee_checkin.json | 60 ++++++++++++++++++- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/erpnext/hr/doctype/employee_checkin/employee_checkin.js b/erpnext/hr/doctype/employee_checkin/employee_checkin.js index f11cc9b2522..c2403ca2bd9 100644 --- a/erpnext/hr/doctype/employee_checkin/employee_checkin.js +++ b/erpnext/hr/doctype/employee_checkin/employee_checkin.js @@ -2,7 +2,9 @@ // For license information, please see license.txt frappe.ui.form.on('Employee Checkin', { - // refresh: function(frm) { - - // } + setup: (frm) => { + if(!frm.doc.time) { + frm.set_value("time", frappe.datetime.now_datetime()); + } + } }); diff --git a/erpnext/hr/doctype/employee_checkin/employee_checkin.json b/erpnext/hr/doctype/employee_checkin/employee_checkin.json index 08fa4afa5cb..75f699751b8 100644 --- a/erpnext/hr/doctype/employee_checkin/employee_checkin.json +++ b/erpnext/hr/doctype/employee_checkin/employee_checkin.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "autoname": "EMP-CKIN-.MM.-.YYYY.-.######", "creation": "2019-06-10 11:56:34.536413", @@ -23,7 +24,6 @@ { "fieldname": "employee", "fieldtype": "Link", - "in_list_view": 1, "label": "Employee", "options": "Employee", "reqd": 1 @@ -32,14 +32,17 @@ "fetch_from": "employee.employee_name", "fieldname": "employee_name", "fieldtype": "Data", + "in_list_view": 1, "label": "Employee Name", "read_only": 1 }, { "fieldname": "log_type", "fieldtype": "Select", + "in_list_view": 1, "label": "Log Type", - "options": "\nIN\nOUT" + "options": "\nIN\nOUT", + "reqd": 1 }, { "fieldname": "shift", @@ -58,6 +61,7 @@ "fieldtype": "Datetime", "in_list_view": 1, "label": "Time", + "permlevel": 1, "reqd": 1 }, { @@ -103,7 +107,8 @@ "label": "Shift Actual End" } ], - "modified": "2019-07-23 23:47:33.975263", + "links": [], + "modified": "2020-01-23 04:57:42.551355", "modified_by": "Administrator", "module": "HR", "name": "Employee Checkin", @@ -147,9 +152,58 @@ "role": "HR User", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "read": 1, + "role": "Employee", + "write": 1 + }, + { + "delete": 1, + "email": 1, + "export": 1, + "permlevel": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "delete": 1, + "email": 1, + "export": 1, + "permlevel": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "write": 1 + }, + { + "delete": 1, + "email": 1, + "export": 1, + "permlevel": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "share": 1, + "write": 1 + }, + { + "permlevel": 1, + "read": 1, + "role": "Employee" } ], "sort_field": "modified", "sort_order": "ASC", + "title_field": "employee_name", "track_changes": 1 } \ No newline at end of file From 831a7ddd6f43b58f3625edf85d8f74f729736ccb Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 1 Feb 2020 23:14:11 +0530 Subject: [PATCH 079/119] fix: Minor fixes --- .../item_wise_sales_register.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index cf48ad4701d..dc900f09e36 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -106,7 +106,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters) data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map, group_by_field, subtotal_display_field, grand_total) - update_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) + add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) data.append(row) @@ -565,10 +565,10 @@ def add_total_row(data, filters, prev_group_by_value, item, total_row_map, def get_display_value(filters, group_by_field, item): if filters.get('group_by') == 'Item': if item.get('item_code') != item.get('item_name'): - value = item.get('item_code') + "

" + \ - "" + item.get('item_name') + "" + value = cstr(item.get('item_code')) + "

" + \ + "" + cstr(item.get('item_name')) + "" else: - value = cstr(item.get('item_code')) + value = item.get('item_code', '') elif filters.get('group_by') in ('Customer', 'Supplier'): party = frappe.scrub(filters.get('group_by')) if item.get(party) != item.get(party+'_name'): @@ -594,7 +594,7 @@ def get_group_by_and_display_fields(filters): return group_by_field, subtotal_display_field -def update_total_row(item, total_row_map, group_by_value, tax_columns): +def add_sub_total_row(item, total_row_map, group_by_value, tax_columns): total_row = total_row_map.get(group_by_value) total_row['stock_qty'] += item['stock_qty'] total_row['amount'] += item['amount'] From a4219f1cfe8bba35134f6bbc0df80d75a5aaf7a0 Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 3 Feb 2020 15:40:53 +0530 Subject: [PATCH 080/119] fix: gst permission for gst settings & hsn code (#20501) * fix: gst permission for gst settings & hsn code * Fix: Typo Co-authored-by: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> --- erpnext/regional/india/setup.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 14fdba013c7..cabfde40ef4 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -79,9 +79,10 @@ def add_custom_roles_for_reports(): def add_permissions(): for doctype in ('GST HSN Code', 'GST Settings'): add_permission(doctype, 'All', 0) - add_permission(doctype, 'Accounts Manager', 0) - update_permission_property(doctype, 'Accounts Manager', 0, 'write', 1) - update_permission_property(doctype, 'Accounts Manager', 0, 'create', 1) + for role in ('Accounts Manager', 'System Manager', '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") @@ -718,4 +719,4 @@ def get_tds_details(accounts, fiscal_year): doctype="Tax Withholding Category", accounts=accounts, rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20, "single_threshold": 2500, "cumulative_threshold": 0}]) - ] \ No newline at end of file + ] From f3c94315c36da6b071f64fb5297924d39fbd5695 Mon Sep 17 00:00:00 2001 From: Saqib Date: Mon, 3 Feb 2020 15:53:22 +0530 Subject: [PATCH 081/119] feat: add tax category in pos profile (#20414) * feat: add tax category in pos profile * fix: review fixes --- erpnext/accounts/doctype/pos_profile/pos_profile.json | 10 +++++++++- .../accounts/doctype/sales_invoice/sales_invoice.py | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json index aa9f85a05ab..fba1bed9dd1 100644 --- a/erpnext/accounts/doctype/pos_profile/pos_profile.json +++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json @@ -3,6 +3,7 @@ "autoname": "Prompt", "creation": "2013-05-24 12:15:51", "doctype": "DocType", + "engine": "InnoDB", "field_order": [ "disabled", "section_break_2", @@ -50,6 +51,7 @@ "income_account", "expense_account", "taxes_and_charges", + "tax_category", "apply_discount_on", "accounting_dimensions_section", "cost_center", @@ -381,11 +383,17 @@ { "fieldname": "dimension_col_break", "fieldtype": "Column Break" + }, + { + "fieldname": "tax_category", + "fieldtype": "Link", + "label": "Tax Category", + "options": "Tax Category" } ], "icon": "icon-cog", "idx": 1, - "modified": "2019-05-25 22:56:30.352693", + "modified": "2020-01-24 15:52:03.797701", "modified_by": "Administrator", "module": "Accounts", "name": "POS Profile", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index a421cc4d6dc..0dc889c0b7a 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -412,6 +412,9 @@ 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") if not for_validate and not self.customer: self.customer = pos.customer From 85c6480b412cc3d76c180fbc80b65afe6061ba18 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Mon, 3 Feb 2020 16:16:42 +0530 Subject: [PATCH 082/119] fix(Report): Quality Review report sql fix (#20425) * fix: report fix * fix: add QM permission * fix: add QM permission --- .../quality_review/quality_review.json | 14 ++++++- .../report/review/review.json | 38 ++++++++++--------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/erpnext/quality_management/doctype/quality_review/quality_review.json b/erpnext/quality_management/doctype/quality_review/quality_review.json index bd5e9351f46..a345dac026d 100644 --- a/erpnext/quality_management/doctype/quality_review/quality_review.json +++ b/erpnext/quality_management/doctype/quality_review/quality_review.json @@ -73,7 +73,7 @@ "reqd": 1 } ], - "modified": "2019-05-26 23:12:47.302189", + "modified": "2020-02-01 10:57:27.119312", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality Review", @@ -102,6 +102,18 @@ "role": "All", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Quality Manager", + "share": 1, + "write": 1 } ], "sort_field": "modified", diff --git a/erpnext/quality_management/report/review/review.json b/erpnext/quality_management/report/review/review.json index 7fce2d4c57c..7fff0fdca6c 100644 --- a/erpnext/quality_management/report/review/review.json +++ b/erpnext/quality_management/report/review/review.json @@ -1,24 +1,28 @@ { - "add_total_row": 0, - "creation": "2018-10-16 12:28:43.651915", - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "modified": "2018-10-16 15:23:25.667237", - "modified_by": "Administrator", - "module": "Quality Management", - "name": "Review", - "owner": "Administrator", - "prepared_report": 0, - "query": "SELECT\n `tabQuality Action`.name as \"Name:Data:200\",\n `tabQuality Action`.action as \"Action:Select/[corrective,Preventive]:200\",\n `tabQuality Action`.review as \"Review:Link/Quality Review:200\",\n `tabQuality Action`.date as \"Date:Date:120\",\n `tabQuality Action`.status as \"Status:Select/Planned:150\"\nFROM\n `tabQuality Action`\nWHERE\n `tabQuality Action`.type='Quality Review'\n \n ", - "ref_doctype": "Quality Action", - "report_name": "Review", - "report_type": "Query Report", + "add_total_row": 0, + "creation": "2018-10-16 12:28:43.651915", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-02-01 11:04:47.299453", + "modified_by": "Administrator", + "module": "Quality Management", + "name": "Review", + "owner": "Administrator", + "prepared_report": 0, + "query": "SELECT\n `tabQuality Action`.name as \"Name:Data:200\",\n `tabQuality Action`.corrective_preventive as \"Action:Select/[Corrective,Preventive]:200\",\n `tabQuality Action`.document_type as \"Document Type:Select/[Quality Review, Quality Feedback]:200\",\n `tabQuality Action`.date as \"Date:Date:120\",\n `tabQuality Action`.status as \"Status:Select/Planned:150\"\nFROM\n `tabQuality Action`\nWHERE\n `tabQuality Action`.document_type='Quality Review'\n \n ", + "ref_doctype": "Quality Action", + "report_name": "Review", + "report_type": "Query Report", "roles": [ { "role": "System Manager" + }, + { + "role": "Quality Manager" } ] } \ No newline at end of file From 3ef80f2d2eee76dddf85924dd6ca93d912d5cb5c Mon Sep 17 00:00:00 2001 From: Pranav Nachnekar Date: Mon, 3 Feb 2020 11:35:30 +0000 Subject: [PATCH 083/119] fix: disallow quick entry for doctypes with tree view (#20453) * fix: imporer escaping * fix: disallow quick entry for doctypes with tree view --- .../doctype/cost_center/cost_center.json | 5 +- erpnext/assets/doctype/location/location.json | 565 +--------- .../customer_group/customer_group.json | 8 +- .../setup/doctype/item_group/item_group.json | 1001 ++++------------- .../doctype/sales_person/sales_person.json | 470 +------- .../setup/doctype/territory/territory.json | 614 +++------- .../stock/doctype/warehouse/warehouse.json | 7 +- 7 files changed, 459 insertions(+), 2211 deletions(-) diff --git a/erpnext/accounts/doctype/cost_center/cost_center.json b/erpnext/accounts/doctype/cost_center/cost_center.json index 5149be216b3..976f05ad637 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.json +++ b/erpnext/accounts/doctype/cost_center/cost_center.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_copy": 1, "allow_import": 1, "allow_rename": 1, @@ -123,7 +124,8 @@ ], "icon": "fa fa-money", "idx": 1, - "modified": "2019-09-16 14:44:17.103548", + "links": [], + "modified": "2020-01-28 13:50:23.430434", "modified_by": "Administrator", "module": "Accounts", "name": "Cost Center", @@ -162,7 +164,6 @@ "role": "Purchase User" } ], - "quick_entry": 1, "search_fields": "parent_cost_center, is_group", "show_name_in_global_search": 1, "sort_field": "modified", diff --git a/erpnext/assets/doctype/location/location.json b/erpnext/assets/doctype/location/location.json index 5dc13062b26..5ecc72ab913 100644 --- a/erpnext/assets/doctype/location/location.json +++ b/erpnext/assets/doctype/location/location.json @@ -1,580 +1,146 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "field:location_name", - "beta": 0, "creation": "2018-05-07 12:49:22.595974", - "custom": 0, - "docstatus": 0, "doctype": "DocType", - "document_type": "", "editable_grid": 1, "engine": "InnoDB", + "field_order": [ + "location_name", + "parent_location", + "cb_details", + "is_container", + "is_group", + "sb_location_details", + "latitude", + "longitude", + "cb_latlong", + "area", + "area_uom", + "sb_geolocation", + "location", + "tree_details", + "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": "location_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": "Location Name", - "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": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "parent_location", "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": "Parent Location", - "length": 0, - "no_copy": 0, "options": "Location", - "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 + "search_index": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "cb_details", - "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", "description": "Check if it is a hydroponic unit", "fieldname": "is_container", "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 Container", - "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 Container" }, { - "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": 0, - "columns": 0, "fieldname": "sb_location_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": "Location 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 + "label": "Location Details" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fetch_from": "parent_location.latitude", "fieldname": "latitude", "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": "Latitude", - "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 + "label": "Latitude" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fetch_from": "parent_location.longitude", "fieldname": "longitude", "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": "Longitude", - "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 + "label": "Longitude" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "cb_latlong", - "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, - "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": "area", "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": "Area", - "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, "depends_on": "eval:doc.area", "fieldname": "area_uom", "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": "Area UOM", - "length": 0, - "no_copy": 0, - "options": "UOM", - "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": "UOM" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "sb_geolocation", - "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": "location", "fieldtype": "Geolocation", - "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": "Location", - "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": "Location" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "tree_details", "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, - "label": "Tree 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 + "label": "Tree Details" }, { - "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": 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": "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": 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": "old_parent", "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": "Old Parent", - "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 + "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": "2018-07-11 13:36:30.999405", + "links": [], + "modified": "2020-01-28 13:52:22.513425", "modified_by": "Administrator", "module": "Assets", "name": "Location", @@ -582,127 +148,78 @@ "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, "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": "Stock 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": "Accounts 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": "Stock Manager", - "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": "Agriculture Manager", - "set_user_permissions": 0, "share": 1, - "submit": 0, "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": "Agriculture User", - "set_user_permissions": 0, "share": 1, - "submit": 0, "write": 1 } ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, "show_name_in_global_search": 1, "sort_field": "modified", "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/setup/doctype/customer_group/customer_group.json b/erpnext/setup/doctype/customer_group/customer_group.json index 3565b4b38a9..7fa242ae19d 100644 --- a/erpnext/setup/doctype/customer_group/customer_group.json +++ b/erpnext/setup/doctype/customer_group/customer_group.json @@ -1,11 +1,12 @@ { - "_comments": "[]", + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "field:customer_group_name", "creation": "2013-01-10 16:34:23", "doctype": "DocType", "document_type": "Setup", + "engine": "InnoDB", "field_order": [ "customer_group_name", "parent_customer_group", @@ -136,7 +137,8 @@ ], "icon": "fa fa-sitemap", "idx": 1, - "modified": "2019-09-06 12:40:14.954697", + "links": [], + "modified": "2020-01-28 13:49:23.961708", "modified_by": "Administrator", "module": "Setup", "name": "Customer Group", @@ -187,8 +189,8 @@ "role": "Sales Manager" } ], - "quick_entry": 1, "search_fields": "parent_customer_group", "show_name_in_global_search": 1, + "sort_field": "modified", "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json index 656d460e0f5..36e3e68ef43 100644 --- a/erpnext/setup/doctype/item_group/item_group.json +++ b/erpnext/setup/doctype/item_group/item_group.json @@ -1,817 +1,252 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:item_group_name", - "beta": 0, - "creation": "2013-03-28 10:35:29", - "custom": 0, - "description": "Item Classification", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:item_group_name", + "creation": "2013-03-28 10:35:29", + "description": "Item Classification", + "doctype": "DocType", + "document_type": "Setup", + "engine": "InnoDB", + "field_order": [ + "gs", + "item_group_name", + "parent_item_group", + "is_group", + "image", + "column_break_5", + "defaults", + "item_group_defaults", + "sec_break_taxes", + "taxes", + "sb9", + "show_in_website", + "route", + "weightage", + "slideshow", + "description", + "website_specifications", + "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": "gs", - "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": "General Settings", - "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": "gs", + "fieldtype": "Section Break", + "label": "General Settings" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "item_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": "Item Group Name", - "length": 0, - "no_copy": 0, - "oldfieldname": "item_group_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, + "fieldname": "item_group_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Item Group Name", + "oldfieldname": "item_group_name", + "oldfieldtype": "Data", + "reqd": 1, "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "description": "", - "fieldname": "parent_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": 0, - "label": "Parent Item Group", - "length": 0, - "no_copy": 0, - "oldfieldname": "parent_item_group", - "oldfieldtype": "Link", - "options": "Item Group", - "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 - }, + "bold": 1, + "fieldname": "parent_item_group", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "in_list_view": 1, + "label": "Parent Item Group", + "oldfieldname": "parent_item_group", + "oldfieldtype": "Link", + "options": "Item Group" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "description": "Only leaf nodes are allowed in transaction", - "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, - "oldfieldname": "is_group", - "oldfieldtype": "Select", - "options": "", - "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 - }, + "bold": 1, + "default": "0", + "description": "Only leaf nodes are allowed in transaction", + "fieldname": "is_group", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Is Group", + "oldfieldname": "is_group", + "oldfieldtype": "Select" + }, { - "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": 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": "image", + "fieldtype": "Attach Image", + "hidden": 1, + "label": "Image" + }, { - "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, - "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": "defaults", - "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": "Defaults", - "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": "defaults", + "fieldtype": "Section Break", + "label": "Defaults" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "item_group_defaults", - "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": "Item Group Defaults", - "length": 0, - "no_copy": 0, - "options": "Item Default", - "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_group_defaults", + "fieldtype": "Table", + "label": "Item Group Defaults", + "options": "Item Default" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "collapsible_depends_on": "", - "columns": 0, - "fieldname": "sec_break_taxes", - "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": "Item Tax", - "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": "sec_break_taxes", + "fieldtype": "Section Break", + "label": "Item Tax" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "taxes", - "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": "Taxes", - "length": 0, - "no_copy": 0, - "options": "Item Tax", - "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": "taxes", + "fieldtype": "Table", + "label": "Taxes", + "options": "Item Tax" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "sb9", - "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": "Website Settings", - "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": "sb9", + "fieldtype": "Section Break", + "label": "Website Settings" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "Check this if you want to show in website", - "fieldname": "show_in_website", - "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": "Show in Website", - "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 - }, + "default": "0", + "description": "Check this if you want to show in website", + "fieldname": "show_in_website", + "fieldtype": "Check", + "label": "Show in Website" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "show_in_website", - "fieldname": "route", - "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": "Route", - "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, + "depends_on": "show_in_website", + "fieldname": "route", + "fieldtype": "Data", + "label": "Route", "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "weightage", - "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": "Weightage", - "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": "weightage", + "fieldtype": "Int", + "label": "Weightage" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "show_in_website", - "description": "Show this slideshow at the top of the page", - "fieldname": "slideshow", - "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": "Slideshow", - "length": 0, - "no_copy": 0, - "options": "Website Slideshow", - "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": "show_in_website", + "description": "Show this slideshow at the top of the page", + "fieldname": "slideshow", + "fieldtype": "Link", + "label": "Slideshow", + "options": "Website Slideshow" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "show_in_website", - "description": "HTML / Banner that will show on the top of product list.", - "fieldname": "description", - "fieldtype": "Text Editor", - "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": "Description", - "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 - }, + "depends_on": "show_in_website", + "description": "HTML / Banner that will show on the top of product list.", + "fieldname": "description", + "fieldtype": "Text Editor", + "label": "Description" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "show_in_website", - "fieldname": "website_specifications", - "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": "Website Specifications", - "length": 0, - "no_copy": 0, - "options": "Item Website Specification", - "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": "show_in_website", + "fieldname": "website_specifications", + "fieldtype": "Table", + "label": "Website Specifications", + "options": "Item Website Specification" + }, { - "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, - "oldfieldname": "lft", - "oldfieldtype": "Int", - "permlevel": 0, - "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 - }, + "fieldname": "lft", + "fieldtype": "Int", + "hidden": 1, + "label": "lft", + "no_copy": 1, + "oldfieldname": "lft", + "oldfieldtype": "Int", + "print_hide": 1, + "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, - "oldfieldname": "rgt", - "oldfieldtype": "Int", - "permlevel": 0, - "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 - }, + "fieldname": "rgt", + "fieldtype": "Int", + "hidden": 1, + "label": "rgt", + "no_copy": 1, + "oldfieldname": "rgt", + "oldfieldtype": "Int", + "print_hide": 1, + "search_index": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "", - "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, - "oldfieldname": "old_parent", - "oldfieldtype": "Data", - "options": "Item Group", - "permlevel": 0, - "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": "old_parent", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 1, + "label": "old_parent", + "no_copy": 1, + "oldfieldname": "old_parent", + "oldfieldtype": "Data", + "options": "Item Group", + "print_hide": 1, + "report_hide": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-sitemap", - "idx": 1, - "image_field": "image", - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 3, - "modified": "2018-11-23 15:17:28.003933", - "modified_by": "Administrator", - "module": "Setup", - "name": "Item Group", - "name_case": "Title Case", - "owner": "Administrator", + ], + "icon": "fa fa-sitemap", + "idx": 1, + "image_field": "image", + "links": [], + "max_attachments": 3, + "modified": "2020-01-28 13:51:05.456014", + "modified_by": "Administrator", + "module": "Setup", + "name": "Item Group", + "name_case": "Title Case", + "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": "Stock Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Stock 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": "Stock User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Stock 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": "Item 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": "Item Manager", + "set_user_permissions": 1, + "share": 1, "write": 1 - }, + }, { - "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": "Sales User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales 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 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": "Accounts User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User" } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "search_fields": "parent_item_group", - "show_name_in_global_search": 1, - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 -} + ], + "search_fields": "parent_item_group", + "show_name_in_global_search": 1, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/setup/doctype/sales_person/sales_person.json b/erpnext/setup/doctype/sales_person/sales_person.json index 27f79eb41f2..b05365d2ca9 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.json +++ b/erpnext/setup/doctype/sales_person/sales_person.json @@ -1,579 +1,183 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "field:sales_person_name", - "beta": 0, "creation": "2013-01-10 16:34:24", - "custom": 0, "description": "All Sales Transactions can be tagged against multiple **Sales Persons** so that you can set and monitor targets.", - "docstatus": 0, "doctype": "DocType", "document_type": "Setup", - "editable_grid": 0, "engine": "InnoDB", + "field_order": [ + "name_and_employee_id", + "sales_person_name", + "parent_sales_person", + "commission_rate", + "is_group", + "enabled", + "cb0", + "employee", + "department", + "lft", + "rgt", + "old_parent", + "target_details_section_break", + "targets" + ], "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": "name_and_employee_id", "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 Employee ID", - "length": 0, - "no_copy": 0, - "options": "icon-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 + "options": "icon-user" }, { - "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_person_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": "Sales Person Name", - "length": 0, - "no_copy": 0, "oldfieldname": "sales_person_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": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "description": "Select company name first.", - "fetch_if_empty": 0, "fieldname": "parent_sales_person", "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 Sales Person", - "length": 0, - "no_copy": 0, "oldfieldname": "parent_sales_person", "oldfieldtype": "Link", - "options": "Sales Person", - "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": "Sales Person" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "commission_rate", "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": "Commission Rate", - "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 }, { - "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": "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, "oldfieldname": "is_group", "oldfieldtype": "Select", - "options": "", - "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, "default": "1", - "fetch_if_empty": 0, "fieldname": "enabled", "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": "Enabled", - "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": "Enabled" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "cb0", - "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 + "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": "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, - "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": "Employee" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fetch_from": "employee.department", - "fetch_if_empty": 0, "fieldname": "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": "Department", - "length": 0, - "no_copy": 0, "options": "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": 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": "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, "oldfieldname": "lft", "oldfieldtype": "Int", - "permlevel": 0, "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, - "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": 1, "oldfieldname": "rgt", "oldfieldtype": "Int", - "permlevel": 0, "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, - "fetch_if_empty": 0, "fieldname": "old_parent", "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": "old_parent", - "length": 0, "no_copy": 1, "oldfieldname": "old_parent", "oldfieldtype": "Data", - "permlevel": 0, - "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, "description": "Set targets Item Group-wise for this Sales Person.", - "fetch_if_empty": 0, "fieldname": "target_details_section_break", "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 Person Targets", - "length": 0, - "no_copy": 0, "oldfieldtype": "Section Break", - "options": "icon-bullseye", - "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": "icon-bullseye" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, "fieldname": "targets", "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": "Targets", - "length": 0, - "no_copy": 0, "oldfieldname": "target_details", "oldfieldtype": "Table", - "options": "Target Detail", - "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": "Target Detail" } ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, "icon": "icon-user", "idx": 1, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-03-22 16:26:01.706129", + "links": [], + "modified": "2020-01-28 13:50:31.891050", "modified_by": "Administrator", "module": "Setup", "name": "Sales Person", "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": "Sales Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Sales 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": "Sales User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Sales User" }, { - "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": "Sales Master Manager", - "set_user_permissions": 0, "share": 1, - "submit": 0, "write": 1 } ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, "search_fields": "parent_sales_person", "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 beadb483779..91a3dda2bb0 100644 --- a/erpnext/setup/doctype/territory/territory.json +++ b/erpnext/setup/doctype/territory/territory.json @@ -1,487 +1,173 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "field:territory_name", - "beta": 0, - "creation": "2013-01-10 16:34:24", - "custom": 0, - "description": "Classification of Customers by region", - "docstatus": 0, - "doctype": "DocType", - "document_type": "Setup", - "editable_grid": 0, + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:territory_name", + "creation": "2013-01-10 16:34:24", + "description": "Classification of Customers by region", + "doctype": "DocType", + "document_type": "Setup", + "engine": "InnoDB", + "field_order": [ + "territory_name", + "parent_territory", + "is_group", + "cb0", + "territory_manager", + "lft", + "rgt", + "old_parent", + "target_details_section_break", + "targets" + ], "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": "territory_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": "Territory Name", - "length": 0, - "no_copy": 1, - "oldfieldname": "territory_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, + "fieldname": "territory_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Territory Name", + "no_copy": 1, + "oldfieldname": "territory_name", + "oldfieldtype": "Data", + "reqd": 1, "unique": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "description": "", - "fetch_if_empty": 0, - "fieldname": "parent_territory", - "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 Territory", - "length": 0, - "no_copy": 0, - "oldfieldname": "parent_territory", - "oldfieldtype": "Link", - "options": "Territory", - "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 - }, + "bold": 1, + "fieldname": "parent_territory", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "in_list_view": 1, + "label": "Parent Territory", + "oldfieldname": "parent_territory", + "oldfieldtype": "Link", + "options": "Territory" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 1, - "collapsible": 0, - "columns": 0, - "description": "", - "fetch_if_empty": 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, - "oldfieldname": "is_group", - "oldfieldtype": "Select", - "options": "", - "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 - }, + "bold": 1, + "default": "0", + "fieldname": "is_group", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Is Group", + "oldfieldname": "is_group", + "oldfieldtype": "Select" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_if_empty": 0, - "fieldname": "cb0", - "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": "cb0", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "For reference", - "fetch_if_empty": 0, - "fieldname": "territory_manager", - "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": "Territory Manager", - "length": 0, - "no_copy": 0, - "oldfieldname": "territory_manager", - "oldfieldtype": "Link", - "options": "Sales Person", - "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": 1, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "description": "For reference", + "fieldname": "territory_manager", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Territory Manager", + "oldfieldname": "territory_manager", + "oldfieldtype": "Link", + "options": "Sales Person", + "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": "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, - "oldfieldname": "lft", - "oldfieldtype": "Int", - "permlevel": 0, - "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 - }, + "fieldname": "lft", + "fieldtype": "Int", + "hidden": 1, + "label": "lft", + "no_copy": 1, + "oldfieldname": "lft", + "oldfieldtype": "Int", + "print_hide": 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": "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, - "oldfieldname": "rgt", - "oldfieldtype": "Int", - "permlevel": 0, - "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 - }, + "fieldname": "rgt", + "fieldtype": "Int", + "hidden": 1, + "label": "rgt", + "no_copy": 1, + "oldfieldname": "rgt", + "oldfieldtype": "Int", + "print_hide": 1, + "search_index": 1 + }, { - "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": "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, - "oldfieldname": "old_parent", - "oldfieldtype": "Data", - "options": "Territory", - "permlevel": 0, - "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": "old_parent", + "fieldtype": "Link", + "hidden": 1, + "ignore_user_permissions": 1, + "label": "old_parent", + "no_copy": 1, + "oldfieldname": "old_parent", + "oldfieldtype": "Data", + "options": "Territory", + "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, - "description": "Set Item Group-wise budgets on this Territory. You can also include seasonality by setting the Distribution.", - "fetch_if_empty": 0, - "fieldname": "target_details_section_break", - "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": "Territory Targets", - "length": 0, - "no_copy": 0, - "oldfieldtype": "Section Break", - "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": "Set Item Group-wise budgets on this Territory. You can also include seasonality by setting the Distribution.", + "fieldname": "target_details_section_break", + "fieldtype": "Section Break", + "label": "Territory Targets", + "oldfieldtype": "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": "targets", - "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": "Targets", - "length": 0, - "no_copy": 0, - "oldfieldname": "target_details", - "oldfieldtype": "Table", - "options": "Target Detail", - "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": "targets", + "fieldtype": "Table", + "label": "Targets", + "oldfieldname": "target_details", + "oldfieldtype": "Table", + "options": "Target Detail" } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "icon": "fa fa-map-marker", - "idx": 1, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-03-21 16:26:58.581431", - "modified_by": "Administrator", - "module": "Setup", - "name": "Territory", - "name_case": "Title Case", - "owner": "Administrator", + ], + "icon": "fa fa-map-marker", + "idx": 1, + "links": [], + "modified": "2020-01-28 13:49:31.905800", + "modified_by": "Administrator", + "module": "Setup", + "name": "Territory", + "name_case": "Title Case", + "owner": "Administrator", "permissions": [ { - "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": "Sales 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": "Sales Master Manager", + "set_user_permissions": 1, + "share": 1, "write": 1 - }, + }, { - "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": "Sales Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales 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": "Sales User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 - }, + "email": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Sales User" + }, { - "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": 0, - "export": 0, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, - "read": 1, - "report": 0, - "role": "Maintenance User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "read": 1, + "role": "Maintenance User" } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "search_fields": "parent_territory,territory_manager", - "show_name_in_global_search": 1, - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + ], + "search_fields": "parent_territory,territory_manager", + "show_name_in_global_search": 1, + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/stock/doctype/warehouse/warehouse.json b/erpnext/stock/doctype/warehouse/warehouse.json index 646725956dc..2bf1ed89838 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.json +++ b/erpnext/stock/doctype/warehouse/warehouse.json @@ -1,10 +1,12 @@ { + "actions": [], "allow_import": 1, "allow_rename": 1, "creation": "2013-03-07 18:50:32", "description": "A logical Warehouse against which stock entries are made.", "doctype": "DocType", "document_type": "Setup", + "engine": "InnoDB", "field_order": [ "warehouse_detail", "warehouse_name", @@ -226,7 +228,8 @@ ], "icon": "fa fa-building", "idx": 1, - "modified": "2019-05-22 11:17:23.357490", + "links": [], + "modified": "2020-01-28 13:50:59.368846", "modified_by": "Administrator", "module": "Stock", "name": "Warehouse", @@ -279,8 +282,8 @@ "role": "Manufacturing User" } ], - "quick_entry": 1, "show_name_in_global_search": 1, + "sort_field": "modified", "sort_order": "DESC", "title_field": "warehouse_name" } \ No newline at end of file From ade2c36123def1ec8f01aa1487bea36405de83ac Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Mon, 3 Feb 2020 18:54:35 +0530 Subject: [PATCH 084/119] fix: Unable to submit landed cost voucher (#20494) * fix: Unable to submit landed cost voucher * fix: Test case for multiple landed cost voucher against a Purchase receipt * fix: Test Case --- .../test_landed_cost_voucher.py | 70 +++++++++++++++++++ .../purchase_receipt/purchase_receipt.py | 17 ++--- 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py index 988cf52ed05..62d369cb9d9 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py @@ -162,6 +162,76 @@ class TestLandedCostVoucher(unittest.TestCase): self.assertEqual(lcv.items[0].applicable_charges, 41.07) self.assertEqual(lcv.items[2].applicable_charges, 41.08) + def test_multiple_landed_cost_voucher_against_pr(self): + pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", + supplier_warehouse = "Stores - TCP1", do_not_save=True) + + pr.append("items", { + "item_code": "_Test Item", + "warehouse": "Stores - TCP1", + "cost_center": "Main - TCP1", + "qty": 5, + "rate": 100 + }) + + pr.submit() + + lcv1 = make_landed_cost_voucher(receipt_document_type = 'Purchase Receipt', + receipt_document=pr.name, charges=100, do_not_save=True) + + lcv1.insert() + lcv1.set('items', [ + lcv1.get('items')[0] + ]) + distribute_landed_cost_on_items(lcv1) + + lcv1.submit() + + lcv2 = make_landed_cost_voucher(receipt_document_type = 'Purchase Receipt', + receipt_document=pr.name, charges=100, do_not_save=True) + + lcv2.insert() + lcv2.set('items', [ + lcv2.get('items')[1] + ]) + distribute_landed_cost_on_items(lcv2) + + lcv2.submit() + + pr.load_from_db() + + self.assertEqual(pr.items[0].landed_cost_voucher_amount, 100) + self.assertEqual(pr.items[1].landed_cost_voucher_amount, 100) + +def make_landed_cost_voucher(** args): + args = frappe._dict(args) + ref_doc = frappe.get_doc(args.receipt_document_type, args.receipt_document) + + lcv = frappe.new_doc('Landed Cost Voucher') + lcv.company = '_Test Company' + lcv.distribute_charges_based_on = 'Amount' + + lcv.set('purchase_receipts', [{ + "receipt_document_type": args.receipt_document_type, + "receipt_document": args.receipt_document, + "supplier": ref_doc.supplier, + "posting_date": ref_doc.posting_date, + "grand_total": ref_doc.grand_total + }]) + + lcv.set("taxes", [{ + "description": "Shipping Charges", + "expense_account": "Expenses Included In Valuation - TCP1", + "amount": args.charges + }]) + + if not args.do_not_save: + lcv.insert() + if not args.do_not_submit: + lcv.submit() + + return lcv + def submit_landed_cost_voucher(receipt_document_type, receipt_document, charges=50): ref_doc = frappe.get_doc(receipt_document_type, receipt_document) diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 09adb567513..fb123b9c1fa 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -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,23 +616,16 @@ def get_item_account_wise_additional_cost(purchase_document): if not landed_cost_vouchers: return - - total_item_cost = 0 + item_account_wise_cost = {} - item_cost_allocated = [] for lcv in landed_cost_vouchers: - landed_cost_voucher_doc = frappe.get_cached_doc("Landed Cost Voucher", lcv.parent) + landed_cost_voucher_doc = frappe.get_doc("Landed Cost Voucher", lcv.parent) based_on_field = frappe.scrub(landed_cost_voucher_doc.distribute_charges_based_on) + total_item_cost = 0 for item in landed_cost_voucher_doc.items: - if item.purchase_receipt_item not in item_cost_allocated: - total_item_cost += item.get(based_on_field) - item_cost_allocated.append(item.purchase_receipt_item) - - for lcv in landed_cost_vouchers: - landed_cost_voucher_doc = frappe.get_cached_doc("Landed Cost Voucher", lcv.parent) - based_on_field = frappe.scrub(landed_cost_voucher_doc.distribute_charges_based_on) + total_item_cost += item.get(based_on_field) for item in landed_cost_voucher_doc.items: if item.receipt_document == purchase_document: From 0f90b870fb7d77a4ad68485f8ace85508860f2c6 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 5 Feb 2020 12:12:47 +0530 Subject: [PATCH 085/119] fix: SQL query in financial statements --- .../accounts/report/financial_statements.py | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 57e8e0ea8fc..75433a135f3 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -348,40 +348,42 @@ def set_gl_entries_by_account( additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters) accounts = frappe.db.sql_list("""select name from `tabAccount` - where lft >= %s and rgt <= %s""", (root_lft, root_rgt)) - additional_conditions += " and account in ({})"\ - .format(", ".join([frappe.db.escape(d) for d in accounts])) + where lft >= %s and rgt <= %s and company = %s""", (root_lft, root_rgt, company)) - gl_filters = { - "company": company, - "from_date": from_date, - "to_date": to_date, - "finance_book": cstr(filters.get("finance_book")) - } + if accounts: + additional_conditions += " and account in ({})"\ + .format(", ".join([frappe.db.escape(d) for d in accounts])) - if filters.get("include_default_book_entries"): - gl_filters["company_fb"] = frappe.db.get_value("Company", - company, 'default_finance_book') + gl_filters = { + "company": company, + "from_date": from_date, + "to_date": to_date, + "finance_book": cstr(filters.get("finance_book")) + } - for key, value in filters.items(): - if value: - gl_filters.update({ - key: value - }) + if filters.get("include_default_book_entries"): + gl_filters["company_fb"] = frappe.db.get_value("Company", + company, 'default_finance_book') - gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry` - where company=%(company)s - {additional_conditions} - and posting_date <= %(to_date)s - order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec + for key, value in filters.items(): + if value: + gl_filters.update({ + key: value + }) - if filters and filters.get('presentation_currency'): - convert_to_presentation_currency(gl_entries, get_currency(filters)) + gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year, debit_in_account_currency, credit_in_account_currency, account_currency from `tabGL Entry` + where company=%(company)s + {additional_conditions} + and posting_date <= %(to_date)s + order by account, posting_date""".format(additional_conditions=additional_conditions), gl_filters, as_dict=True) #nosec - for entry in gl_entries: - gl_entries_by_account.setdefault(entry.account, []).append(entry) + if filters and filters.get('presentation_currency'): + convert_to_presentation_currency(gl_entries, get_currency(filters)) - return gl_entries_by_account + for entry in gl_entries: + gl_entries_by_account.setdefault(entry.account, []).append(entry) + + return gl_entries_by_account def get_additional_conditions(from_date, ignore_closing_entries, filters): From b4a0c773ae5c8b6ec37edc64073175f5863981c1 Mon Sep 17 00:00:00 2001 From: "Parth J. Kharwar" Date: Wed, 5 Feb 2020 15:00:58 +0530 Subject: [PATCH 086/119] fix: half day leave date value reset (#20488) * fix: full day leaves not tagged as half day in attendance * chore: code cleanup for half day date value set --- .../hr/doctype/leave_application/leave_application.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js index 174641048b8..df4cf71b776 100755 --- a/erpnext/hr/doctype/leave_application/leave_application.js +++ b/erpnext/hr/doctype/leave_application/leave_application.js @@ -104,11 +104,16 @@ frappe.ui.form.on("Leave Application", { }, half_day: function(frm) { - if (frm.doc.from_date == frm.doc.to_date) { - frm.set_value("half_day_date", frm.doc.from_date); + if (frm.doc.half_day) { + if (frm.doc.from_date == frm.doc.to_date) { + frm.set_value("half_day_date", frm.doc.from_date); + } + else { + frm.trigger("half_day_datepicker"); + } } else { - frm.trigger("half_day_datepicker"); + frm.set_value("half_day_date", ""); } frm.trigger("calculate_total_days"); }, From 67dbeee7b28fd1f1fc8a349f4c1a01f2340c4e2c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 5 Feb 2020 09:38:05 +0530 Subject: [PATCH 087/119] fix: Add total row --- .../item_wise_purchase_register.py | 12 +++++--- .../item_wise_sales_register.py | 28 +++++++++++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 3a5a4548f5a..8b6359c134d 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -6,7 +6,7 @@ import frappe, erpnext from frappe import _ from frappe.utils import flt from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (get_tax_accounts, - get_grand_total, add_total_row, get_display_value, get_group_by_and_display_fields, update_total_row, + get_grand_total, add_total_row, get_display_value, get_group_by_and_display_fields, add_sub_total_row, get_group_by_conditions) def execute(filters=None): @@ -29,6 +29,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum data = [] total_row_map = {} + skip_total_row = 0 prev_group_by_value = '' if filters.get('group_by'): @@ -96,8 +97,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum row.update({'percent_gt': flt(row['total']/grand_total) * 100}) group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters) data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map, - group_by_field, subtotal_display_field, grand_total) - update_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) + group_by_field, subtotal_display_field, grand_total, tax_columns) + add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) data.append(row) @@ -106,8 +107,11 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) data.append(total_row) data.append({}) + add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns) + data.append(total_row_map.get('total_row')) + skip_total_row = 1 - return columns, data + return columns, data, None, None, None, skip_total_row def get_columns(additional_table_columns, filters): diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index dc900f09e36..ad2e12f8239 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -28,6 +28,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum data = [] total_row_map = {} + skip_total_row = 0 prev_group_by_value = '' if filters.get('group_by'): @@ -105,7 +106,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum row.update({'percent_gt': flt(row['total']/grand_total) * 100}) group_by_field, subtotal_display_field = get_group_by_and_display_fields(filters) data, prev_group_by_value = add_total_row(data, filters, prev_group_by_value, d, total_row_map, - group_by_field, subtotal_display_field, grand_total) + group_by_field, subtotal_display_field, grand_total, tax_columns) add_sub_total_row(row, total_row_map, d.get(group_by_field, ''), tax_columns) data.append(row) @@ -115,8 +116,11 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) data.append(total_row) data.append({}) - - return columns, data + add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns) + data.append(total_row_map.get('total_row')) + skip_total_row = 1 + + return columns, data, None, None, None, skip_total_row def get_columns(additional_table_columns, filters): columns = [] @@ -541,13 +545,13 @@ def get_tax_accounts(item_list, columns, company_currency, return itemised_tax, tax_columns def add_total_row(data, filters, prev_group_by_value, item, total_row_map, - group_by_field, subtotal_display_field, grand_total): + group_by_field, subtotal_display_field, grand_total, tax_columns): if prev_group_by_value != item.get(group_by_field, ''): if prev_group_by_value: total_row = total_row_map.get(prev_group_by_value) - total_row['percent_gt'] = flt(total_row['total']/grand_total * 100) data.append(total_row) data.append({}) + add_sub_total_row(total_row, total_row_map, 'total_row', tax_columns) prev_group_by_value = item.get(group_by_field, '') @@ -557,7 +561,18 @@ def add_total_row(data, filters, prev_group_by_value, item, total_row_map, 'amount': 0.0, 'bold': 1, 'total_tax': 0.0, - 'total': 0.0 + 'total': 0.0, + 'percent_gt': 0.0 + }) + + total_row_map.setdefault('total_row', { + subtotal_display_field: "Total", + 'stock_qty': 0.0, + 'amount': 0.0, + 'bold': 1, + 'total_tax': 0.0, + 'total': 0.0, + 'percent_gt': 0.0 }) return data, prev_group_by_value @@ -600,6 +615,7 @@ def add_sub_total_row(item, total_row_map, group_by_value, tax_columns): total_row['amount'] += item['amount'] total_row['total_tax'] += item['total_tax'] total_row['total'] += item['total'] + total_row['percent_gt'] += item['percent_gt'] for tax in tax_columns: total_row.setdefault(frappe.scrub(tax + ' Amount'), 0.0) From 8e0a9e8748665aabf45105732bf70de4e1807192 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 5 Feb 2020 16:17:16 +0530 Subject: [PATCH 088/119] fix: unsupported operand type(s) for += 'int' and 'NoneType' --- erpnext/stock/doctype/pick_list/pick_list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index c4d8c41ebb7..7ed998f979a 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -74,13 +74,13 @@ class PickList(Document): if item_map.get(key): item_map[key].qty += item.qty - item_map[key].stock_qty += item.stock_qty + item_map[key].stock_qty += flt(item.stock_qty) else: item_map[key] = item # maintain count of each item (useful to limit get query) self.item_count_map.setdefault(item_code, 0) - self.item_count_map[item_code] += item.stock_qty + self.item_count_map[item_code] += flt(item.stock_qty) return item_map.values() From 9f58e59a2c8a3ab723bd9f2973ed31ac9e80fe72 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Wed, 29 Jan 2020 21:41:56 +0530 Subject: [PATCH 089/119] fix: Label and UX fixes while creating payment entry against customer --- erpnext/accounts/doctype/bank_account/bank_account.json | 6 ++++-- erpnext/accounts/doctype/payment_entry/payment_entry.py | 4 +++- erpnext/selling/doctype/customer/customer.js | 8 ++++++++ erpnext/selling/doctype/customer/customer.json | 6 ++++-- erpnext/selling/doctype/customer/customer.py | 6 ++++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/bank_account/bank_account.json b/erpnext/accounts/doctype/bank_account/bank_account.json index 8e30b8555cb..c8ae26d9f2c 100644 --- a/erpnext/accounts/doctype/bank_account/bank_account.json +++ b/erpnext/accounts/doctype/bank_account/bank_account.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "allow_rename": 1, "creation": "2017-05-29 21:35:13.136357", @@ -82,7 +83,7 @@ "default": "0", "fieldname": "is_default", "fieldtype": "Check", - "label": "Is the Default Account" + "label": "Is Default Account" }, { "default": "0", @@ -211,7 +212,8 @@ "read_only": 1 } ], - "modified": "2019-10-02 01:34:12.417601", + "links": [], + "modified": "2020-01-29 20:42:26.458316", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Account", diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 214d6088667..d65e5640263 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -102,7 +102,9 @@ class PaymentEntry(AccountsController): self.bank = bank_data.bank self.bank_account_no = bank_data.bank_account_no - self.set(field, bank_data.account) + + if not self.get(field): + self.set(field, bank_data.account) def validate_allocated_amount(self): for d in self.get("references"): diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index 30220614e9b..0a9f9b8f0a7 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -55,6 +55,14 @@ frappe.ui.form.on("Customer", { } } }) + + frm.set_query('default_bank_account', function(c) { + return { + filters: { + 'is_company_account': 1 + } + } + }); }, customer_primary_address: function(frm){ if(frm.doc.customer_primary_address){ diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json index 250973b7497..89ce325a847 100644 --- a/erpnext/selling/doctype/customer/customer.json +++ b/erpnext/selling/doctype/customer/customer.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_events_in_timeline": 1, "allow_import": 1, "allow_rename": 1, @@ -122,7 +123,7 @@ { "fieldname": "default_bank_account", "fieldtype": "Link", - "label": "Default Bank Account", + "label": "Default Company Bank Account", "options": "Bank Account" }, { @@ -470,7 +471,8 @@ "icon": "fa fa-user", "idx": 363, "image_field": "image", - "modified": "2020-01-24 15:06:03.483799", + "links": [], + "modified": "2020-01-29 20:36:37.879581", "modified_by": "Administrator", "module": "Selling", "name": "Customer", diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 6ee02190bad..3248c998b60 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -54,6 +54,7 @@ class Customer(TransactionBase): self.validate_credit_limit_on_change() self.set_loyalty_program() self.check_customer_group_change() + self.validate_default_bank_account() # set loyalty program tier if frappe.db.exists('Customer', self.name): @@ -72,6 +73,11 @@ class Customer(TransactionBase): if self.customer_group != frappe.db.get_value('Customer', self.name, 'customer_group'): frappe.flags.customer_group_changed = True + 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))) + def on_update(self): self.validate_name_with_customer_group() self.create_primary_contact() From 3ed574532de1e034637678b7a85490f94cab4c48 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Wed, 29 Jan 2020 21:45:17 +0530 Subject: [PATCH 090/119] fix: filter --- erpnext/selling/doctype/customer/customer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index 0a9f9b8f0a7..6db4102a7bf 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -56,7 +56,7 @@ frappe.ui.form.on("Customer", { } }) - frm.set_query('default_bank_account', function(c) { + frm.set_query('default_bank_account', function() { return { filters: { 'is_company_account': 1 From d9f8347fc80455d41a44d62097f6ae91c226b47a Mon Sep 17 00:00:00 2001 From: thefalconx33 Date: Wed, 5 Feb 2020 16:40:58 +0530 Subject: [PATCH 091/119] fix: typo; serial no doesn't have amc start date --- .../doctype/maintenance_schedule/maintenance_schedule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py index 94d85f77ef4..c5bc92dcc17 100644 --- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py @@ -193,7 +193,7 @@ class MaintenanceSchedule(TransactionBase): if sr_details.amc_expiry_date and getdate(sr_details.amc_expiry_date) >= getdate(amc_start_date): throw(_("Serial No {0} is under maintenance contract upto {1}") - .format(serial_no, sr_details.amc_start_date)) + .format(serial_no, sr_details.amc_expiry_date)) if not sr_details.warehouse and sr_details.delivery_date and \ getdate(sr_details.delivery_date) >= getdate(amc_start_date): From 0eb9f7408e59a08e2cacca21259a156033868bad Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 6 Feb 2020 14:34:11 +0530 Subject: [PATCH 092/119] fix: Procurement Tracker report not working --- .../report/procurement_tracker/procurement_tracker.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/buying/report/procurement_tracker/procurement_tracker.py b/erpnext/buying/report/procurement_tracker/procurement_tracker.py index 48295bee26a..866bf0c7332 100644 --- a/erpnext/buying/report/procurement_tracker/procurement_tracker.py +++ b/erpnext/buying/report/procurement_tracker/procurement_tracker.py @@ -141,13 +141,13 @@ def get_conditions(filters): conditions = "" if filters.get("company"): - conditions += " AND company='%s'"% filters.get('company') + conditions += " AND company=%s"% frappe.db.escape(filters.get('company')) if filters.get("cost_center") or filters.get("project"): conditions += """ - AND (cost_center='%s' - OR project='%s') - """% (filters.get('cost_center'), filters.get('project')) + AND (cost_center=%s + OR project=%s) + """% (frappe.db.escape(filters.get('cost_center')), frappe.db.escape(filters.get('project'))) if filters.get("from_date"): conditions += " AND transaction_date>=%s"% filters.get('from_date') From bdfa2ff33ac56620964f24e0f058866a82413b4d Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 7 Feb 2020 11:05:33 +0530 Subject: [PATCH 093/119] fix: Do not calculate total for rate --- .../report/item_wise_sales_register/item_wise_sales_register.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index dc900f09e36..524f949a334 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -603,8 +603,6 @@ def add_sub_total_row(item, total_row_map, group_by_value, tax_columns): for tax in tax_columns: total_row.setdefault(frappe.scrub(tax + ' Amount'), 0.0) - total_row.setdefault(frappe.scrub(tax + ' Rate'), 0.0) - total_row[frappe.scrub(tax + ' Rate')] += flt(item[frappe.scrub(tax + ' Rate')]) total_row[frappe.scrub(tax + ' Amount')] += flt(item[frappe.scrub(tax + ' Amount')]) From 7027584391979b25f84b4a504c44d60aa3226411 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 7 Feb 2020 14:38:25 +0530 Subject: [PATCH 094/119] fix: time out error while submitting the purchase receipt which has more than 100 serial nos --- .../purchase_receipt/test_purchase_receipt.py | 24 +++++++ erpnext/stock/doctype/serial_no/serial_no.py | 66 ++++++++++--------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index c80b9bd04bb..707750413e0 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -262,6 +262,30 @@ class TestPurchaseReceipt(unittest.TestCase): self.assertEqual(pr2.per_billed, 80) self.assertEqual(pr2.status, "To Bill") + def test_serial_no_against_purchase_receipt(self): + from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos + + item_code = "Test Manual Created Serial No" + if not frappe.db.exists("Item", item_code): + item = make_item(item_code, dict(has_serial_no=1)) + + serial_no = random_string(5) + pr_doc = make_purchase_receipt(item_code=item_code, + qty=1, serial_no = serial_no) + + self.assertEqual(serial_no, frappe.db.get_value("Serial No", + {"purchase_document_type": "Purchase Receipt", "purchase_document_no": pr_doc.name}, "name")) + + item_code = "Test Auto Created Serial No" + if not frappe.db.exists("Item", item_code): + item = make_item(item_code, dict(has_serial_no=1, serial_no_series="KLJL.###")) + + new_pr_doc = make_purchase_receipt(item_code=item_code, qty=1) + + serial_no = get_serial_nos(new_pr_doc[0].serial_no)[0] + self.assertEqual(serial_no, frappe.db.get_value("Serial No", + {"purchase_document_type": "Purchase Receipt", "purchase_document_no": new_pr_doc.name}, "name")) + def test_not_accept_duplicate_serial_no(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 19eb398130c..855ab7a9662 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -29,13 +29,12 @@ class SerialNo(StockController): self.via_stock_ledger = False def validate(self): - if self.get("__islocal") and self.warehouse: + if self.get("__islocal") and self.warehouse and not self.via_stock_ledger: frappe.throw(_("New Serial No cannot have Warehouse. Warehouse must be set by Stock Entry or Purchase Receipt"), SerialNoCannotCreateDirectError) self.set_maintenance_status() self.validate_warehouse() self.validate_item() - self.on_stock_ledger_entry() def set_maintenance_status(self): if not self.warranty_expiry_date and not self.amc_expiry_date: @@ -68,7 +67,7 @@ class SerialNo(StockController): """ Validate whether serial no is required for this item """ - item = frappe.get_doc("Item", self.item_code) + item = frappe.get_cached_doc("Item", self.item_code) if item.has_serial_no!=1: frappe.throw(_("Item {0} is not setup for Serial Nos. Check Item master").format(self.item_code)) @@ -117,9 +116,9 @@ class SerialNo(StockController): "warranty_expiry_date"): self.set(fieldname, None) - def get_last_sle(self): + def get_last_sle(self, serial_no=None): entries = {} - sle_dict = self.get_stock_ledger_entries() + sle_dict = self.get_stock_ledger_entries(serial_no) if sle_dict: if sle_dict.get("incoming", []): entries["purchase_sle"] = sle_dict["incoming"][0] @@ -132,13 +131,28 @@ class SerialNo(StockController): return entries - def get_stock_ledger_entries(self): + def get_stock_ledger_entries(self, serial_no=None): sle_dict = {} - for sle in frappe.db.sql("""select * from `tabStock Ledger Entry` - where serial_no like %s and item_code=%s and ifnull(is_cancelled, 'No')='No' - order by posting_date desc, posting_time desc, creation desc""", - ("%%%s%%" % self.name, self.item_code), as_dict=1): - if self.name.upper() in get_serial_nos(sle.serial_no): + if not serial_no: + serial_no = self.name + + for sle in frappe.db.sql(""" + SELECT voucher_type, voucher_no, + posting_date, posting_time, incoming_rate, actual_qty, serial_no + FROM + `tabStock Ledger Entry` + WHERE + item_code=%s AND company = %s AND ifnull(is_cancelled, 'No')='No' + AND (serial_no = %s + OR serial_no like %s + OR serial_no like %s + OR serial_no like %s + ) + ORDER BY + posting_date desc, posting_time desc, creation desc""", + (self.item_code, self.company, + serial_no, serial_no+'\n%', '%\n'+serial_no, '%\n'+serial_no+'\n%'), as_dict=1): + if serial_no.upper() in get_serial_nos(sle.serial_no): if cint(sle.actual_qty) > 0: sle_dict.setdefault("incoming", []).append(sle) else: @@ -178,12 +192,11 @@ class SerialNo(StockController): where name=%s""" % (dt[0], '%s', '%s'), ('\n'.join(list(serial_nos)), item[0])) - def on_stock_ledger_entry(self): - if self.via_stock_ledger and not self.get("__islocal"): - last_sle = self.get_last_sle() - self.set_purchase_details(last_sle.get("purchase_sle")) - self.set_sales_details(last_sle.get("delivery_sle")) - self.set_maintenance_status() + def update_serial_no_reference(self, serial_no=None): + last_sle = self.get_last_sle(serial_no) + self.set_purchase_details(last_sle.get("purchase_sle")) + self.set_sales_details(last_sle.get("delivery_sle")) + self.set_maintenance_status() def process_serial_no(sle): item_det = get_item_details(sle.item_code) @@ -387,27 +400,16 @@ def get_serial_nos(serial_no): def make_serial_no(serial_no, args): sr = frappe.new_doc("Serial No") - sr.warehouse = None - sr.dont_update_if_missing.append("warehouse") - sr.flags.ignore_permissions = True sr.serial_no = serial_no sr.item_code = args.get('item_code') sr.company = args.get('company') sr.batch_no = args.get('batch_no') sr.via_stock_ledger = args.get('via_stock_ledger') or True - sr.asset = args.get('asset') - sr.location = args.get('location') - + sr.warehouse = args.get('warehouse') - if args.get('purchase_document_type'): - sr.purchase_document_type = args.get('purchase_document_type') - sr.purchase_document_no = args.get('purchase_document_no') - sr.supplier = args.get('supplier') - - sr.insert() - if args.get('warehouse'): - sr.warehouse = args.get('warehouse') - sr.save() + sr.validate_item() + sr.update_serial_no_reference(serial_no) + sr.db_insert() return sr.name From bbeacb9acf06ac319c9e30d2f2d3ba39cecb6903 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 7 Feb 2020 14:56:58 +0530 Subject: [PATCH 095/119] fix: incorrect warehouse for material request in production plan --- erpnext/manufacturing/doctype/production_plan/production_plan.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 10a8d8fc9bd..76202e5a6f3 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -625,7 +625,6 @@ def get_items_for_material_requests(doc, ignore_existing_ordered_qty=None): for data in po_items: planned_qty = data.get('required_qty') or data.get('planned_qty') ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty - warehouse = data.get("warehouse") or warehouse item_details = {} if data.get("bom") or data.get("bom_no"): From f5bff5f15d69b44ec86c8c39f539eb3e0c2dd055 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 7 Feb 2020 15:25:43 +0530 Subject: [PATCH 096/119] fix: Styling and minor fixes --- .../bank_reconciliation/bank_reconciliation.py | 6 +++--- .../doctype/plaid_settings/plaid_settings.json | 7 ++++--- .../v12_0/rename_bank_reconciliation_fields.py | 11 +++-------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py index 804bcd8bdf0..52bbe3327a8 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py @@ -35,7 +35,7 @@ class BankReconciliation(Document): and ifnull(t1.is_opening, 'No') = 'No' %(condition)s group by t2.account, t1.name order by t1.posting_date ASC, t1.name DESC - """, {"condition":condition, "account":self.account, "from":self.from_date, "to":self.to_date}, as_dict=1) + """, {"condition":condition, "account": self.account, "from": self.from_date, "to": self.to_date}, as_dict=1) payment_entries = frappe.db.sql(""" select @@ -52,8 +52,8 @@ class BankReconciliation(Document): and bank_account = %(bank_account)s order by posting_date ASC, name DESC - """, {"account":self.account, "from":self.from_date, - "to":self.to_date, "bank_account": self.bank_account}, as_dict=1) + """, {"account": self.account, "from":self.from_date, + "to": self.to_date, "bank_account": self.bank_account}, as_dict=1) pos_entries = [] if self.include_pos_transactions: diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json index df77ad8bc93..d8203d7390f 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json @@ -49,9 +49,10 @@ }, { "fieldname": "plaid_env", - "fieldtype": "Data", + "fieldtype": "Select", "in_list_view": 1, - "label": "Plaid Environment" + "label": "Plaid Environment", + "options": "sandbox\ndevelopment\nproduction" }, { "fieldname": "column_break_2", @@ -69,7 +70,7 @@ ], "issingle": 1, "links": [], - "modified": "2020-01-05 10:00:22.137832", + "modified": "2020-02-07 15:21:11.616231", "modified_by": "Administrator", "module": "ERPNext Integrations", "name": "Plaid Settings", diff --git a/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py b/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py index 01b1dde6073..caeda8ae61b 100644 --- a/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py +++ b/erpnext/patches/v12_0/rename_bank_reconciliation_fields.py @@ -9,11 +9,6 @@ def _rename_single_field(**kwargs): frappe.db.sql("UPDATE tabSingles SET field='{new_name}' WHERE doctype='{doctype}' AND field='{old_name}';".format(**kwargs)) #nosec def execute(): - BR = "Bank Reconciliation" - AC = "account" - BA = "bank_account" - BAN = "bank_account_no" - - _rename_single_field(doctype = BR, old_name = BA , new_name = AC) - _rename_single_field(doctype = BR, old_name = BAN, new_name = BA) - frappe.reload_doc("Accounts", "doctype", BR) + _rename_single_field(doctype = "Bank Reconciliation", old_name = "bank_account" , new_name = "account") + _rename_single_field(doctype = "Bank Reconciliation", old_name = "bank_account_no", new_name = "bank_account") + frappe.reload_doc("Accounts", "doctype", "Bank Reconciliation") From a9205adfbdc42dcc10afa1737425f68483ca9357 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 7 Feb 2020 15:36:38 +0530 Subject: [PATCH 097/119] fix: test cases --- .../doctype/purchase_receipt/test_purchase_receipt.py | 11 +++++++---- erpnext/stock/doctype/serial_no/serial_no.py | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 707750413e0..aa09d3bfe5f 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -158,8 +158,11 @@ class TestPurchaseReceipt(unittest.TestCase): def test_purchase_return_for_rejected_qty(self): from erpnext.stock.doctype.warehouse.test_warehouse import get_warehouse - rejected_warehouse=get_warehouse(company = "_Test Company with perpetual inventory", abbr = " - TCP1", warehouse_name = "_Test Rejected Warehouse").name - print(rejected_warehouse) + rejected_warehouse="_Test Rejected Warehouse - TCP1" + if not frappe.db.exists("Warehouse", rejected_warehouse): + get_warehouse(company = "_Test Company with perpetual inventory", + abbr = " - TCP1", warehouse_name = "_Test Rejected Warehouse").name + pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", received_qty=4, qty=2, rejected_warehouse=rejected_warehouse) return_pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", is_return=1, return_against=pr.name, received_qty = -4, qty=-2, rejected_warehouse=rejected_warehouse) @@ -269,7 +272,7 @@ class TestPurchaseReceipt(unittest.TestCase): if not frappe.db.exists("Item", item_code): item = make_item(item_code, dict(has_serial_no=1)) - serial_no = random_string(5) + serial_no = "12903812901" pr_doc = make_purchase_receipt(item_code=item_code, qty=1, serial_no = serial_no) @@ -282,7 +285,7 @@ class TestPurchaseReceipt(unittest.TestCase): new_pr_doc = make_purchase_receipt(item_code=item_code, qty=1) - serial_no = get_serial_nos(new_pr_doc[0].serial_no)[0] + serial_no = get_serial_nos(new_pr_doc.items[0].serial_no)[0] self.assertEqual(serial_no, frappe.db.get_value("Serial No", {"purchase_document_type": "Purchase Receipt", "purchase_document_no": new_pr_doc.name}, "name")) diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 855ab7a9662..f34b0472f0d 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -379,6 +379,7 @@ def auto_make_serial_nos(args): if sr.sales_order and args.get('voucher_type') == "Stock Entry" \ and not args.get('actual_qty', 0) > 0: sr.sales_order = None + sr.update_serial_no_reference() sr.save(ignore_permissions=True) elif args.get('actual_qty', 0) > 0: created_numbers.append(make_serial_no(serial_no, args)) From c7e523cee437f7af7821ea893d8f1fc46ea323d7 Mon Sep 17 00:00:00 2001 From: thefalconx33 Date: Sun, 9 Feb 2020 12:19:03 +0530 Subject: [PATCH 098/119] fix: mandatory warehouse wrror while updating items after submission --- erpnext/controllers/accounts_controller.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 7faf792d203..001da5b5ea8 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1135,6 +1135,7 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, child_item.reqd_by_date = p_doctype.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 return child_item From ec45c096a08983e10e2f57bddab1eb14f192b773 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Sun, 9 Feb 2020 19:45:42 +0530 Subject: [PATCH 099/119] fix: pricing rule not working on item groups (#20546) --- .../doctype/pricing_rule/test_pricing_rule.py | 48 +++++++++++++++++++ .../accounts/doctype/pricing_rule/utils.py | 2 +- .../setup/doctype/item_group/item_group.py | 12 ++--- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index 332a9007915..9c1fef69fac 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -9,6 +9,8 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.stock.get_item_details import get_item_details from frappe import MandatoryError +from erpnext.stock.doctype.item.test_item import make_item +from erpnext.healthcare.doctype.lab_test_template.lab_test_template import make_item_price class TestPricingRule(unittest.TestCase): def setUp(self): @@ -145,6 +147,52 @@ class TestPricingRule(unittest.TestCase): self.assertEquals(details.get("margin_type"), "Percentage") self.assertEquals(details.get("margin_rate_or_amount"), 10) + def test_mixed_conditions_for_item_group(self): + for item in ["Mixed Cond Item 1", "Mixed Cond Item 2"]: + make_item(item, {"item_group": "Products"}) + make_item_price(item, "_Test Price List", 100) + + test_record = { + "doctype": "Pricing Rule", + "title": "_Test Pricing Rule for Item Group", + "apply_on": "Item Group", + "item_groups": [ + { + "item_group": "Products", + }, + { + "item_group": "Seed", + }, + ], + "selling": 1, + "mixed_conditions": 1, + "currency": "USD", + "rate_or_discount": "Discount Percentage", + "discount_percentage": 10, + "applicable_for": "Customer Group", + "customer_group": "All Customer Groups", + "company": "_Test Company" + } + frappe.get_doc(test_record.copy()).insert() + + args = frappe._dict({ + "item_code": "Mixed Cond Item 1", + "item_group": "Products", + "company": "_Test Company", + "price_list": "_Test Price List", + "currency": "_Test Currency", + "doctype": "Sales Order", + "conversion_rate": 1, + "price_list_currency": "_Test Currency", + "plc_conversion_rate": 1, + "order_type": "Sales", + "customer": "_Test Customer", + "customer_group": "_Test Customer Group", + "name": None + }) + details = get_item_details(args) + self.assertEquals(details.get("discount_percentage"), 10) + def test_pricing_rule_for_variants(self): from erpnext.stock.get_item_details import get_item_details from frappe import MandatoryError diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index fe68fdb6c0f..e475563c77c 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -489,7 +489,7 @@ def get_pricing_rule_items(pr_doc): for d in pr_doc.get(pricing_rule_apply_on): if apply_on == 'item_group': - get_child_item_groups(d.get(apply_on)) + apply_on_data.extend(get_child_item_groups(d.get(apply_on))) else: apply_on_data.append(d.get(apply_on)) diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py index 9f258828660..43778404b60 100644 --- a/erpnext/setup/doctype/item_group/item_group.py +++ b/erpnext/setup/doctype/item_group/item_group.py @@ -174,15 +174,11 @@ def get_child_groups(item_group_name): and show_in_website = 1""", {"lft": item_group.lft, "rgt": item_group.rgt}) def get_child_item_groups(item_group_name): - child_item_groups = frappe.cache().hget("child_item_groups", item_group_name) + item_group = frappe.get_cached_value("Item Group", + item_group_name, ["lft", "rgt"], as_dict=1) - if not child_item_groups: - item_group = frappe.get_cached_doc("Item Group", item_group_name) - - child_item_groups = [d.name for d in frappe.get_all('Item Group', - filters= {'lft': ('>=', item_group.lft),'rgt': ('>=', item_group.rgt)})] - - frappe.cache().hset("child_item_groups", item_group_name, child_item_groups) + child_item_groups = [d.name for d in frappe.get_all('Item Group', + filters= {'lft': ('>=', item_group.lft),'rgt': ('<=', item_group.rgt)})] return child_item_groups or {} From 1343a4b7557266b2d8ec4d2b3b3c0498deb38ff5 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 10 Feb 2020 00:31:44 +0530 Subject: [PATCH 100/119] fix: patch for creating irs_1099 custom field (United States) --- erpnext/patches.txt | 1 + .../v12_0/create_irs_1099_field_united_states.py | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 erpnext/patches/v12_0/create_irs_1099_field_united_states.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 17c9a20766d..9fde54225ac 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -648,3 +648,4 @@ erpnext.patches.v12_0.update_owner_fields_in_acc_dimension_custom_fields erpnext.patches.v12_0.remove_denied_leaves_from_leave_ledger erpnext.patches.v12_0.update_price_or_product_discount erpnext.patches.v12_0.add_export_type_field_in_party_master +erpnext.patches.v12_0.create_irs_1099_field_united_states \ No newline at end of file diff --git a/erpnext/patches/v12_0/create_irs_1099_field_united_states.py b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py new file mode 100644 index 00000000000..3e4c87f434e --- /dev/null +++ b/erpnext/patches/v12_0/create_irs_1099_field_united_states.py @@ -0,0 +1,10 @@ +from __future__ import unicode_literals +import frappe +from erpnext.regional.united_states.setup import make_custom_fields + +def execute(): + company = frappe.get_all('Company', filters = {'country': 'United States'}) + if not company: + return + + make_custom_fields() \ No newline at end of file From 495ab6c7f241c7e6984ab516dc4ff4b31c5cb760 Mon Sep 17 00:00:00 2001 From: Ashish Shah Date: Mon, 10 Feb 2020 11:13:27 +0530 Subject: [PATCH 101/119] fix: backflush raw material based on - Material Transferred for Manufacture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi @nabinhait , Issue : Manufacturing setting > Backflush Raw Material Based on “Material Transferred for Manufacture” doesn't fetch the actual raw material transferred qty. It fetches qty based on "BOM" The issue is because @creamdory in PR #https://github.com/frappe/erpnext/pull/13384 commit : https://github.com/frappe/erpnext/pull/13384/files#diff-91f0ed661ef4b6e1f167fc7961b1a79b ``` changed from: if trans_qty and manufacturing_qty >= (produced_qty + flt(self.fg_completed_qty)): to : if trans_qty and manufacturing_qty > (produced_qty + flt(self.fg_completed_qty)): ``` **'='** was added by her in the condition, which was not there before her commit. Kindly except the fix for the issue. https://github.com/frappe/erpnext/blob/develop/erpnext/stock/doctype/stock_entry/stock_entry.py#L1057 https://github.com/frappe/erpnext/pull/13384 https://github.com/frappe/erpnext/pull/13384/files#diff-91f0ed661ef4b6e1f167fc7961b1a79b **before fix gif** : Stock Entry = Manufacture shows raw material quantity as per BOM. ![FetchTransQtyError](https://user-images.githubusercontent.com/29812965/74123824-ffdd8600-4bf5-11ea-8873-95de24a7ef09.gif) **after fix gi**f : Stock Entry = "Manufacture" shows raw material quantity as per "Material Transfer for Manufacture". ![FetchTransQtyFix](https://user-images.githubusercontent.com/29812965/74123836-0c61de80-4bf6-11ea-86fb-d9619fd9b02b.gif) --- erpnext/stock/doctype/stock_entry/stock_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 4b07f0aef9f..56cb3f06b94 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -1056,7 +1056,7 @@ class StockEntry(StockController): req_qty_each = flt(req_qty / manufacturing_qty) consumed_qty = flt(req_items[0].consumed_qty) - if trans_qty and manufacturing_qty >= (produced_qty + flt(self.fg_completed_qty)): + if trans_qty and manufacturing_qty > (produced_qty + flt(self.fg_completed_qty)): if qty >= req_qty: qty = (req_qty/trans_qty) * flt(self.fg_completed_qty) else: From a7c27596bb0607b749fcec1a2313405e01ddc674 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 10 Feb 2020 15:30:22 +0530 Subject: [PATCH 102/119] fix: added indexing on columns to fix performace issue --- .../accounts/doctype/gl_entry/gl_entry.json | 805 ++---------------- .../doctype/sales_invoice/sales_invoice.json | 7 +- 2 files changed, 63 insertions(+), 749 deletions(-) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json index a232a953f31..e64bc9e0c78 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.json +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json @@ -1,971 +1,286 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, "autoname": "ACC-GLE-.YYYY.-.#####", - "beta": 0, "creation": "2013-01-10 16:34:06", - "custom": 0, - "docstatus": 0, "doctype": "DocType", "document_type": "Document", - "editable_grid": 0, + "engine": "InnoDB", + "field_order": [ + "posting_date", + "transaction_date", + "account", + "party_type", + "party", + "cost_center", + "debit", + "credit", + "account_currency", + "debit_in_account_currency", + "credit_in_account_currency", + "against", + "against_voucher_type", + "against_voucher", + "voucher_type", + "voucher_no", + "voucher_detail_no", + "project", + "remarks", + "is_opening", + "is_advance", + "fiscal_year", + "company", + "finance_book", + "to_rename", + "due_date" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "posting_date", "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, "in_filter": 1, - "in_global_search": 0, "in_list_view": 1, - "in_standard_filter": 0, "label": "Posting Date", - "length": 0, - "no_copy": 0, "oldfieldname": "posting_date", "oldfieldtype": "Date", - "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": 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": "transaction_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": "Transaction Date", - "length": 0, - "no_copy": 0, "oldfieldname": "transaction_date", - "oldfieldtype": "Date", - "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 + "oldfieldtype": "Date" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "account", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, "in_filter": 1, - "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 1, "label": "Account", - "length": 0, - "no_copy": 0, "oldfieldname": "account", "oldfieldtype": "Link", "options": "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": 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": "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, - "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 + "search_index": 1 }, { - "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": 1, "label": "Party", - "length": 0, - "no_copy": 0, "options": "party_type", - "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": 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": "cost_center", "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, "in_filter": 1, - "in_global_search": 0, "in_list_view": 1, - "in_standard_filter": 0, "label": "Cost Center", - "length": 0, - "no_copy": 0, "oldfieldname": "cost_center", "oldfieldtype": "Link", - "options": "Cost Center", - "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": "Cost Center" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "debit", "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": "Debit Amount", - "length": 0, - "no_copy": 0, "oldfieldname": "debit", "oldfieldtype": "Currency", - "options": "Company:company:default_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 + "options": "Company:company:default_currency" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "credit", "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": "Credit Amount", - "length": 0, - "no_copy": 0, "oldfieldname": "credit", "oldfieldtype": "Currency", - "options": "Company:company:default_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 + "options": "Company:company:default_currency" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "account_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": "Account Currency", - "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 + "options": "Currency" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "debit_in_account_currency", "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": "Debit Amount in Account Currency", - "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 + "options": "currency" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "credit_in_account_currency", "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": "Credit Amount in Account Currency", - "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 + "options": "currency" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "against", "fieldtype": "Text", - "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": "Against", - "length": 0, - "no_copy": 0, "oldfieldname": "against", - "oldfieldtype": "Text", - "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 + "oldfieldtype": "Text" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "against_voucher_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": "Against Voucher Type", - "length": 0, - "no_copy": 0, "oldfieldname": "against_voucher_type", "oldfieldtype": "Data", "options": "DocType", - "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 + "search_index": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "against_voucher", "fieldtype": "Dynamic Link", - "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": "Against Voucher", - "length": 0, - "no_copy": 0, "oldfieldname": "against_voucher", "oldfieldtype": "Data", "options": "against_voucher_type", - "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": 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": "voucher_type", "fieldtype": "Link", - "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": "Voucher Type", - "length": 0, - "no_copy": 0, "oldfieldname": "voucher_type", "oldfieldtype": "Select", "options": "DocType", - "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 + "search_index": 1 }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "voucher_no", "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, "in_filter": 1, - "in_global_search": 0, - "in_list_view": 0, "in_standard_filter": 1, "label": "Voucher No", - "length": 0, - "no_copy": 0, "oldfieldname": "voucher_no", "oldfieldtype": "Data", "options": "voucher_type", - "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": 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": "voucher_detail_no", "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": "Voucher Detail No", - "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": "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 + "options": "Project" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "remarks", "fieldtype": "Text", - "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": "Remarks", - "length": 0, "no_copy": 1, "oldfieldname": "remarks", - "oldfieldtype": "Text", - "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 + "oldfieldtype": "Text" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "is_opening", "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": "Is Opening", - "length": 0, - "no_copy": 0, "oldfieldname": "is_opening", "oldfieldtype": "Select", - "options": "No\nYes", - "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": "No\nYes" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "is_advance", "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": "Is Advance", - "length": 0, - "no_copy": 0, "oldfieldname": "is_advance", "oldfieldtype": "Select", - "options": "No\nYes", - "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": "No\nYes" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "fieldname": "fiscal_year", "fieldtype": "Link", - "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": "Fiscal Year", - "length": 0, - "no_copy": 0, "oldfieldname": "fiscal_year", "oldfieldtype": "Select", - "options": "Fiscal Year", - "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": "Fiscal Year" }, { - "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": 0, - "ignore_xss_filter": 0, "in_filter": 1, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, "label": "Company", - "length": 0, - "no_copy": 0, "oldfieldname": "company", "oldfieldtype": "Link", "options": "Company", - "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": 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": "finance_book", "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": "Finance Book", - "length": 0, - "no_copy": 0, - "options": "Finance Book", - "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": "Finance Book" }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, "default": "1", "fieldname": "to_rename", "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": "To Rename", - "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 + "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": "due_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": "Due 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 + "label": "Due Date" } ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, "icon": "fa fa-list", "idx": 1, - "image_view": 0, "in_create": 1, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-05-01 07:05:00.366399", + "modified": "2020-02-10 04:54:57.777905", "modified_by": "Administrator", "module": "Accounts", "name": "GL Entry", "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": "Accounts User", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Accounts User" }, { - "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": "Accounts Manager", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Accounts Manager" }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 0, "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 0, "read": 1, "report": 1, - "role": "Auditor", - "set_user_permissions": 0, - "share": 0, - "submit": 0, - "write": 0 + "role": "Auditor" } ], "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, "search_fields": "voucher_no,account,posting_date,against_voucher", - "show_name_in_global_search": 0, "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 0, - "track_seen": 0, - "track_views": 0 + "sort_order": "DESC" } \ No newline at end of file diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 33ee7a2974e..52a0f4e081d 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -1,5 +1,4 @@ { - "actions": [], "allow_import": 1, "autoname": "naming_series:", "creation": "2013-05-24 19:29:05", @@ -373,7 +372,8 @@ "no_copy": 1, "options": "Sales Invoice", "print_hide": 1, - "read_only": 1 + "read_only": 1, + "search_index": 1 }, { "fieldname": "column_break_21", @@ -1568,8 +1568,7 @@ "icon": "fa fa-file-text", "idx": 181, "is_submittable": 1, - "links": [], - "modified": "2019-12-30 19:15:59.580414", + "modified": "2020-02-10 04:57:11.221180", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", From 57d33f9ce6a9e7cc9148d63bd6299d3f2705de82 Mon Sep 17 00:00:00 2001 From: Govind S Menokee Date: Tue, 11 Feb 2020 11:23:16 +0530 Subject: [PATCH 103/119] fix: get_students not respecting the program The get_students function is not taking into account the program for which the fee needs to be created. If a student is enrolled for multiple programs then the fee schedule pull up the wrong count of students. --- erpnext/education/doctype/fee_schedule/fee_schedule.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.py b/erpnext/education/doctype/fee_schedule/fee_schedule.py index a42800a80d5..bba101f2f1f 100644 --- a/erpnext/education/doctype/fee_schedule/fee_schedule.py +++ b/erpnext/education/doctype/fee_schedule/fee_schedule.py @@ -123,9 +123,11 @@ def get_students(student_group, academic_year, academic_term=None, student_categ students = frappe.db.sql(""" select pe.student, pe.student_name, pe.program, pe.student_batch_name - from `tabStudent Group Student` sgs, `tabProgram Enrollment` pe + from `tabStudent Group Student` sgs, `tabProgram Enrollment` pe, `tabStudent Group` sg where pe.student = sgs.student and pe.academic_year = %s + and sg.program = pe.program + and sg.name = sgs.parent and sgs.parent = %s and sgs.active = 1 {conditions} """.format(conditions=conditions), (academic_year, student_group), as_dict=1) From cde48a44cf5951228d20385461a22a1c296b82fb Mon Sep 17 00:00:00 2001 From: vishal Date: Tue, 11 Feb 2020 11:44:24 +0530 Subject: [PATCH 104/119] fix: filter serial no based on batch no --- erpnext/public/js/utils/serial_no_batch_selector.js | 5 +++-- erpnext/stock/doctype/serial_no/serial_no.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index 4ec12ce8e7f..23895ee4c02 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -90,7 +90,8 @@ erpnext.SerialNoBatchSelector = Class.extend({ args: { qty: qty, item_code: me.item_code, - warehouse: me.warehouse_details.name + warehouse: me.warehouse_details.name, + batch_no: me.item.batch_no || null } }); @@ -392,7 +393,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ delivery_document_no: "" } - if (this.has_batch) { + if (this.item.batch_no) { serial_no_filters["batch_no"] = this.item.batch_no; } diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 19eb398130c..c8e9b011be9 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -397,7 +397,6 @@ def make_serial_no(serial_no, args): sr.via_stock_ledger = args.get('via_stock_ledger') or True sr.asset = args.get('asset') sr.location = args.get('location') - if args.get('purchase_document_type'): sr.purchase_document_type = args.get('purchase_document_type') @@ -474,10 +473,11 @@ 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): +def auto_fetch_serial_number(qty, item_code, warehouse, batch_no=None): serial_numbers = frappe.get_list("Serial No", filters={ "item_code": item_code, "warehouse": warehouse, + "batch_no": batch_no, "delivery_document_no": "", "sales_invoice": "" }, limit=qty, order_by="creation") From fc4cc9ab42ae36c5e705517e4f327b528dd471c5 Mon Sep 17 00:00:00 2001 From: Er-Naren719 <49683121+Er-Naren719@users.noreply.github.com> Date: Mon, 10 Feb 2020 13:46:47 +0530 Subject: [PATCH 105/119] feat: column width increased for view attachments field (#314) --- erpnext/projects/doctype/project_user/project_user.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/projects/doctype/project_user/project_user.json b/erpnext/projects/doctype/project_user/project_user.json index f0a70dd1df9..2f452cc2d75 100644 --- a/erpnext/projects/doctype/project_user/project_user.json +++ b/erpnext/projects/doctype/project_user/project_user.json @@ -1,4 +1,5 @@ { + "actions": [], "creation": "2016-03-25 02:52:19.283003", "doctype": "DocType", "editable_grid": 1, @@ -46,6 +47,7 @@ "fetch_from": "user.full_name", "fieldname": "full_name", "fieldtype": "Read Only", + "in_list_view": 1, "label": "Full Name" }, { @@ -55,7 +57,7 @@ "label": "Welcome email sent" }, { - "columns": 1, + "columns": 2, "default": "0", "fieldname": "view_attachments", "fieldtype": "Check", @@ -74,7 +76,8 @@ } ], "istable": 1, - "modified": "2019-07-15 19:37:26.942294", + "links": [], + "modified": "2020-02-09 23:26:50.321417", "modified_by": "Administrator", "module": "Projects", "name": "Project User", From efbfeb2d89830c32720e3fd3feb1c2707046e862 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 17 Feb 2020 10:50:05 +0530 Subject: [PATCH 106/119] fix: filters for quality_procedure tree --- .../doctype/quality_procedure/quality_procedure_tree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js index dbdbbab3925..6df6f656aa1 100644 --- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js +++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js @@ -4,7 +4,7 @@ frappe.treeview_settings["Quality Procedure"] = { add_tree_node: 'erpnext.quality_management.doctype.quality_procedure.quality_procedure.add_node', filters: [ { - fieldname: "quality_procedure", + fieldname: "parent_quality_procedure", fieldtype: "Link", options: "Quality Procedure", label: __("Quality Procedure"), From 5bfebaf1c0417141340c12f8a9f7a78139e42617 Mon Sep 17 00:00:00 2001 From: thefalconx33 Date: Mon, 17 Feb 2020 14:15:20 +0530 Subject: [PATCH 107/119] fix: disabled mode of payments fetches in sales invoices --- .../doctype/mode_of_payment/mode_of_payment.py | 13 +++++++++++++ erpnext/accounts/doctype/sales_invoice/pos.py | 7 +++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py index fcf94ce98a9..d54a47e3c96 100644 --- a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py +++ b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py @@ -11,6 +11,7 @@ class ModeofPayment(Document): def validate(self): self.validate_accounts() self.validate_repeating_companies() + self.validate_pos_mode_of_payment() def validate_repeating_companies(self): """Error when Same Company is entered multiple times in accounts""" @@ -27,3 +28,15 @@ class ModeofPayment(Document): if frappe.db.get_value("Account", entry.default_account, "company") != entry.company: frappe.throw(_("Account {0} does not match with Company {1} in Mode of Account: {2}") .format(entry.default_account, entry.company, self.name)) + + def validate_pos_mode_of_payment(self): + if not self.enabled: + pos_profiles = frappe.db.sql("""SELECT sip.parent FROM `tabSales Invoice Payment` sip + WHERE sip.parenttype = 'POS Profile' and sip.mode_of_payment = %s""", (self.name)) + pos_profiles = list(map(lambda x: x[0], pos_profiles)) + + if pos_profiles: + message = "POS Profile " + frappe.bold(", ".join(pos_profiles)) + " contains \ + Mode of Payment " + frappe.bold(str(self.name)) + ". Please remove them to disable this mode." + frappe.throw(_(message), title="Not Allowed") + diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py index a48d2244893..749816f7814 100755 --- a/erpnext/accounts/doctype/sales_invoice/pos.py +++ b/erpnext/accounts/doctype/sales_invoice/pos.py @@ -152,8 +152,11 @@ def update_multi_mode_option(doc, pos_profile): def get_mode_of_payment(doc): - return frappe.db.sql(""" select mpa.default_account, mpa.parent, mp.type as type from `tabMode of Payment Account` mpa, \ - `tabMode of Payment` mp where mpa.parent = mp.name and mpa.company = %(company)s""", {'company': doc.company}, as_dict=1) + return frappe.db.sql(""" + select mpa.default_account, mpa.parent, mp.type as type + from `tabMode of Payment Account` mpa,`tabMode of Payment` mp + where mpa.parent = mp.name and mpa.company = %(company)s and mp.enabled = 1""", + {'company': doc.company}, as_dict=1) def update_tax_table(doc): From 660b4d1e2fbef983e99bf4ad5710412b98ac0f02 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 17 Feb 2020 15:58:31 +0530 Subject: [PATCH 108/119] feat: show numeric values in item configurator (#20430) --- erpnext/portal/product_configurator/utils.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/erpnext/portal/product_configurator/utils.py b/erpnext/portal/product_configurator/utils.py index 336b9319c1d..ce507a39486 100644 --- a/erpnext/portal/product_configurator/utils.py +++ b/erpnext/portal/product_configurator/utils.py @@ -1,4 +1,5 @@ import frappe +import numpy as np from erpnext.portal.product_configurator.item_variants_cache import ItemVariantsCacheManager def get_field_filter_data(): @@ -172,6 +173,7 @@ def get_attributes_and_values(item_code): item_attribute_values = frappe.db.get_all('Item Attribute Value', ['parent', 'attribute_value', 'idx'], order_by='parent asc, idx asc') + item_attribute_values += get_numeric_values() ordered_attribute_value_map = frappe._dict() for iv in item_attribute_values: ordered_attribute_value_map.setdefault(iv.parent, []).append(iv.attribute_value) @@ -184,6 +186,23 @@ def get_attributes_and_values(item_code): return attributes +def get_numeric_values(): + attribute_values_list = [] + numeric_attributes = frappe.get_list("Item Attribute", fields=['name', 'from_range', 'to_range', 'increment'], filters={"numeric_values": 1}) + for attribute in numeric_attributes: + from_range = attribute["from_range"] + to_range = attribute['to_range'] + attribute['increment'] + increment = attribute['increment'] + values = list(np.arange(from_range, to_range, increment)) + + for idx, val in enumerate(values): + attribute_values_list.append(frappe._dict({ + "parent": attribute.get("name"), + "attribute_value": str(int(val)) if val.is_integer() else str(val), + "idx": idx + })) + return attribute_values_list + @frappe.whitelist(allow_guest=True) def get_next_attribute_and_values(item_code, selected_attributes): From f95ac99baa6c60a270b3a4ff52fab3b957b6c12e Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Wed, 27 Nov 2019 14:53:58 +0530 Subject: [PATCH 109/119] fix(travis): add lib cups for updated frappe requirements --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 40afeee8d46..365eb67f3dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -63,6 +63,7 @@ install: - tar -xf /tmp/wkhtmltox.tar.xz -C /tmp - sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf - sudo chmod o+x /usr/local/bin/wkhtmltopdf + - sudo apt-get install libcups2-dev - cd ~/frappe-bench From 6f28383531a78bb452722f3e454b99c1807343b7 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 18 Feb 2020 10:51:54 +0530 Subject: [PATCH 110/119] fix: Stock Quantity not calculated on client side in Material Request Items. --- erpnext/public/js/controllers/transaction.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 512bcf9f4fb..8c022e95fb5 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -941,15 +941,19 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ }, conversion_factor: function(doc, cdt, cdn, dont_fetch_price_list_rate) { - if(doc.doctype != 'Material Request' && frappe.meta.get_docfield(cdt, "stock_qty", cdn)) { + if(frappe.meta.get_docfield(cdt, "stock_qty", cdn)) { var item = frappe.get_doc(cdt, cdn); frappe.model.round_floats_in(item, ["qty", "conversion_factor"]); item.stock_qty = flt(item.qty * item.conversion_factor, precision("stock_qty", item)); - item.total_weight = flt(item.stock_qty * item.weight_per_unit); refresh_field("stock_qty", item.name, item.parentfield); - refresh_field("total_weight", item.name, item.parentfield); this.toggle_conversion_factor(item); - this.calculate_net_weight(); + + if(doc.doctype != "Material Request") { + item.total_weight = flt(item.stock_qty * item.weight_per_unit); + refresh_field("total_weight", item.name, item.parentfield); + this.calculate_net_weight(); + } + if (!dont_fetch_price_list_rate && frappe.meta.has_field(doc.doctype, "price_list_currency")) { this.apply_price_list(item, true); From b63c041aa429725de0251dd8878c58a2cd2dd8d7 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Tue, 18 Feb 2020 16:09:37 +0530 Subject: [PATCH 111/119] feat: Group by AR/AP report (#20574) * feat: Group by AR/AP report * fix: Do not consider total row in charts * fix: Subtotal row for last party --- .../accounts_payable/accounts_payable.js | 15 ++++ .../accounts_receivable.js | 16 +++- .../accounts_receivable.py | 75 ++++++++++++++++--- 3 files changed, 96 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js index b1f427ca7f6..df700ec9d3c 100644 --- a/erpnext/accounts/report/accounts_payable/accounts_payable.js +++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js @@ -100,6 +100,11 @@ frappe.query_reports["Accounts Payable"] = { "fieldtype": "Link", "options": "Supplier Group" }, + { + "fieldname": "group_by_party", + "label": __("Group By Supplier"), + "fieldtype": "Check" + }, { "fieldname":"based_on_payment_terms", "label": __("Based On Payment Terms"), @@ -112,6 +117,16 @@ frappe.query_reports["Accounts Payable"] = { "hidden": 1 } ], + + "formatter": function(value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + if (data && data.bold) { + value = value.bold(); + + } + return value; + }, + onload: function(report) { report.page.add_inner_button(__("Accounts Payable Summary"), function() { var filters = report.get_values(); diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js index 9b4dda2f696..5d0154f597e 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js @@ -87,7 +87,7 @@ frappe.query_reports["Accounts Receivable"] = { frappe.query_report.set_filter_value('payment_terms', value["payment_terms"]); }); - frappe.db.get_value('Customer Credit Limit', {'parent': customer, 'company': company}, + frappe.db.get_value('Customer Credit Limit', {'parent': customer, 'company': company}, ["credit_limit"], function(value) { if (value) { frappe.query_report.set_filter_value('credit_limit', value["credit_limit"]); @@ -131,6 +131,11 @@ frappe.query_reports["Accounts Receivable"] = { "fieldtype": "Link", "options": "Sales Person" }, + { + "fieldname": "group_by_party", + "label": __("Group By Customer"), + "fieldtype": "Check" + }, { "fieldname":"based_on_payment_terms", "label": __("Based On Payment Terms"), @@ -177,6 +182,15 @@ frappe.query_reports["Accounts Receivable"] = { } ], + "formatter": function(value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + if (data && data.bold) { + value = value.bold(); + + } + return value; + }, + onload: function(report) { report.page.add_inner_button(__("Accounts Receivable Summary"), function() { var filters = report.get_values(); diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index f82146a1df8..0438f6d09e1 100755 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -46,7 +46,7 @@ class ReceivablePayableReport(object): self.get_columns() self.get_data() self.get_chart_data() - return self.columns, self.data, None, self.chart + return self.columns, self.data, None, self.chart, None, self.skip_total_row def set_defaults(self): if not self.filters.get("company"): @@ -57,6 +57,12 @@ class ReceivablePayableReport(object): self.party_type = self.filters.party_type self.party_details = {} self.invoices = set() + self.skip_total_row = 0 + + if self.filters.get('group_by_party'): + self.previous_party='' + self.total_row_map = {} + self.skip_total_row = 1 def get_data(self): self.get_gl_entries() @@ -102,6 +108,12 @@ class ReceivablePayableReport(object): ) self.get_invoices(gle) + if self.filters.get('group_by_party'): + self.init_subtotal_row(gle.party) + + if self.filters.get('group_by_party'): + self.init_subtotal_row('Total') + def get_invoices(self, gle): if gle.voucher_type in ('Sales Invoice', 'Purchase Invoice'): if self.filters.get("sales_person"): @@ -111,6 +123,20 @@ class ReceivablePayableReport(object): else: self.invoices.add(gle.voucher_no) + def init_subtotal_row(self, party): + if not self.total_row_map.get(party): + self.total_row_map.setdefault(party, { + 'party': party, + 'bold': 1 + }) + + for field in self.get_currency_fields(): + self.total_row_map[party][field] = 0.0 + + def get_currency_fields(self): + return ['invoiced', 'paid', 'credit_note', 'outstanding', 'range1', + 'range2', 'range3', 'range4', 'range5'] + def update_voucher_balance(self, gle): # get the row where this balance needs to be updated # if its a payment, it will return the linked invoice or will be considered as advance @@ -135,6 +161,18 @@ class ReceivablePayableReport(object): # advance / unlinked payment or other adjustment row.paid -= gle_balance + def update_sub_total_row(self, row, party): + total_row = self.total_row_map.get(party) + + for field in self.get_currency_fields(): + total_row[field] += row.get(field, 0.0) + + def append_subtotal_row(self, party): + sub_total_row = self.total_row_map.get(party) + self.data.append(sub_total_row) + self.data.append({}) + self.update_sub_total_row(sub_total_row, 'Total') + def get_voucher_balance(self, gle): if self.filters.get("sales_person"): against_voucher = gle.against_voucher or gle.voucher_no @@ -192,11 +230,22 @@ class ReceivablePayableReport(object): else: self.append_row(row) + if self.filters.get('group_by_party'): + self.append_subtotal_row(self.previous_party) + self.data.append(self.total_row_map.get('Total')) + def append_row(self, row): self.allocate_future_payments(row) self.set_invoice_details(row) self.set_party_details(row) self.set_ageing(row) + + if self.filters.get('group_by_party'): + self.update_sub_total_row(row, row.party) + if self.previous_party and (self.previous_party != row.party): + self.append_subtotal_row(self.previous_party) + self.previous_party = row.party + self.data.append(row) def set_invoice_details(self, row): @@ -503,6 +552,7 @@ class ReceivablePayableReport(object): # get all the GL entries filtered by the given filters conditions, values = self.prepare_conditions() + order_by = self.get_order_by_condition() if self.filters.get(scrub(self.party_type)): select_fields = "debit_in_account_currency as debit, credit_in_account_currency as credit" @@ -520,9 +570,8 @@ class ReceivablePayableReport(object): and party_type=%s and (party is not null and party != '') and posting_date <= %s - {1} - order by posting_date, party""" - .format(select_fields, conditions), values, as_dict=True) + {1} {2}""" + .format(select_fields, conditions, order_by), values, as_dict=True) def get_sales_invoices_or_customers_based_on_sales_person(self): if self.filters.get("sales_person"): @@ -557,6 +606,12 @@ class ReceivablePayableReport(object): return " and ".join(conditions), values + def get_order_by_condition(self): + if self.filters.get('group_by_party'): + return "order by party, posting_date" + else: + return "order by posting_date, party" + def add_common_filters(self, conditions, values, party_type_field): if self.filters.company: conditions.append("company=%s") @@ -736,11 +791,13 @@ class ReceivablePayableReport(object): def get_chart_data(self): rows = [] for row in self.data: - values = [row.range1, row.range2, row.range3, row.range4, row.range5] - precision = cint(frappe.db.get_default("float_precision")) or 2 - rows.append({ - 'values': [flt(val, precision) for val in values] - }) + row = frappe._dict(row) + if not cint(row.bold): + values = [row.range1, row.range2, row.range3, row.range4, row.range5] + precision = cint(frappe.db.get_default("float_precision")) or 2 + rows.append({ + 'values': [flt(val, precision) for val in values] + }) self.chart = { "data": { From 1ed737cf6488389114abd833d6660b4178b1b101 Mon Sep 17 00:00:00 2001 From: marination Date: Tue, 18 Feb 2020 21:35:59 +0530 Subject: [PATCH 112/119] fix: Set Query on warehouse fields in Stock Settings --- erpnext/stock/doctype/stock_settings/stock_settings.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.js b/erpnext/stock/doctype/stock_settings/stock_settings.js index 49ce3d8ef7a..755c4307187 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.js +++ b/erpnext/stock/doctype/stock_settings/stock_settings.js @@ -3,6 +3,15 @@ frappe.ui.form.on('Stock Settings', { refresh: function(frm) { + let filters = function() { + return { + filters : { + is_group : 0 + } + }; + } + frm.set_query("default_warehouse", filters); + frm.set_query("sample_retention_warehouse", filters); } }); From 0119d15adb491d87dc8739c4cfa7a39c3e4caafe Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 19 Feb 2020 11:05:58 +0530 Subject: [PATCH 113/119] fix: Server side validation for Warehouses --- erpnext/stock/doctype/stock_settings/stock_settings.js | 6 +++--- erpnext/stock/doctype/stock_settings/stock_settings.py | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.js b/erpnext/stock/doctype/stock_settings/stock_settings.js index 755c4307187..cc0e2cfc425 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.js +++ b/erpnext/stock/doctype/stock_settings/stock_settings.js @@ -5,11 +5,11 @@ frappe.ui.form.on('Stock Settings', { refresh: function(frm) { let filters = function() { return { - filters : { + filters : { is_group : 0 - } + } }; - } + }; frm.set_query("default_warehouse", filters); frm.set_query("sample_retention_warehouse", filters); diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py index 65de2e58d3a..93b5eee75c2 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.py +++ b/erpnext/stock/doctype/stock_settings/stock_settings.py @@ -30,9 +30,17 @@ class StockSettings(Document): frappe.make_property_setter({'fieldname': name, 'property': 'hidden', 'value': 0 if self.show_barcode_field else 1}) + self.validate_warehouses() self.cant_change_valuation_method() self.validate_clean_description_html() + def validate_warehouses(self): + warehouse_fields = ["default_warehouse", "sample_retention_warehouse"] + for field in warehouse_fields: + if frappe.db.get_value("Warehouse", self.get(field), "is_group"): + frappe.throw(_("Group Warehouses cannot be used in transactions. Please change the value of {0}") \ + .format(frappe.bold(self.meta.get_field(field).label)), title =_("Incorrect Warehouse")) + def cant_change_valuation_method(self): db_valuation_method = frappe.db.get_single_value("Stock Settings", "valuation_method") From f6d7090f07c29c360ba9040b2ddcd83fec1fd3a5 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 19 Feb 2020 19:16:40 +0530 Subject: [PATCH 114/119] fix: earned leaves creation for zero maximum leaves (#20677) --- .../doctype/leave_application/test_leave_application.py | 9 ++++++++- erpnext/hr/utils.py | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.py b/erpnext/hr/doctype/leave_application/test_leave_application.py index 5dfcad6a294..4c21edb2c02 100644 --- a/erpnext/hr/doctype/leave_application/test_leave_application.py +++ b/erpnext/hr/doctype/leave_application/test_leave_application.py @@ -409,7 +409,7 @@ class TestLeaveApplication(unittest.TestCase): self.assertEqual(get_leave_balance_on(employee.name, leave_type.name, nowdate(), add_days(nowdate(), 8)), 21) - def test_earned_leave(self): + def test_earned_leaves_creation(self): leave_period = get_leave_period() employee = get_employee() leave_type = 'Test Earned Leave Type' @@ -437,6 +437,13 @@ class TestLeaveApplication(unittest.TestCase): i += 1 self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 6) + # validate earned leaves creation without maximum leaves + frappe.db.set_value('Leave Type', leave_type, 'max_leaves_allowed', 0) + while(i<14): + allocate_earned_leaves() + i += 1 + self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 14) + # test to not consider current leave in leave balance while submitting def test_current_leave_on_submit(self): employee = get_employee() diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py index 9b0ca4e9a1a..4f5653dc67e 100644 --- a/erpnext/hr/utils.py +++ b/erpnext/hr/utils.py @@ -316,7 +316,9 @@ def allocate_earned_leaves(): allocation = frappe.get_doc('Leave Allocation', allocation.name) new_allocation = flt(allocation.total_leaves_allocated) + flt(earned_leaves) - new_allocation = new_allocation if new_allocation <= e_leave_type.max_leaves_allowed else e_leave_type.max_leaves_allowed + + if new_allocation > e_leave_type.max_leaves_allowed and e_leave_type.max_leaves_allowed > 0: + new_allocation = e_leave_type.max_leaves_allowed if new_allocation == allocation.total_leaves_allocated: continue From cd6b60df70ac8c8712966a8599c925eb1e002450 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 20 Feb 2020 12:18:21 +0530 Subject: [PATCH 115/119] core: Added change log --- erpnext/change_log/v12/v12_5_0.md | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 erpnext/change_log/v12/v12_5_0.md diff --git a/erpnext/change_log/v12/v12_5_0.md b/erpnext/change_log/v12/v12_5_0.md new file mode 100644 index 00000000000..e398bd7c450 --- /dev/null +++ b/erpnext/change_log/v12/v12_5_0.md @@ -0,0 +1,53 @@ +## Version 12.4.0 Release Note + +### New Features: +- **Group by Customer / Customer Group / Item / Item Group / Territory / Invoice** option in Itemised Sales Register report [#20251](https://github.com/frappe/erpnext/pull/20251) + +- **Group by Supplier / Item / Item Group / Invoice** option in Itemised Purchase Register report + +- **Group by Customer / Supplier** option in Accounts Receivable / Payable report + +- Enhanced Fixed Asset Register report [#20332](https://github.com/frappe/erpnext/pull/20332) + +- Added tax category in pos profile [#20413](https://github.com/frappe/erpnext/pull/20413) + + +### Fixes +- GL Entries were not creating on manual asset creation [#20265](https://github.com/frappe/erpnext/pull/20265) + +- Payment Entry should not be allowed against blocked Purchase Invoice until release date [#20270](https://github.com/frappe/erpnext/pull/20270) + +- Incorrect number of GL Entries error in stock entry due to precision issue [#20297](https://github.com/frappe/erpnext/pull/20297) + +- Wrong outstanding invoices fetched against employee [#20373](https://github.com/frappe/erpnext/pull/20373) + +- Finance book filtering logic in financial statements and other accounting reports [#20411](https://github.com/frappe/erpnext/pull/20410) + +- Additional discount was not appling on sales invoice created by subscription [#20432](https://github.com/frappe/erpnext/pull/20432) + +- Deprecated fetching item price based on minimum qty [#20346](https://github.com/frappe/erpnext/pull/20346) + +- Calculation of carry forwarded leaves [#20341](https://github.com/frappe/erpnext/pull/20341) + +- Quotation status will be expired based on validity only if it is not Ordered or Lost [#20365](https://github.com/frappe/erpnext/pull/20354) + +- Delete auto created batch on cancellation of Purchase Receipt / Stock Entry [#20392](https://github.com/frappe/erpnext/pull/20392) + +- Show product bundle item's availability on website based on availability of all bundled items [#20384](https://github.com/frappe/erpnext/pull/20384) + +- Show relevant suppliers on "Create Purchase Order" popup in Material Request [#20232](https://github.com/frappe/erpnext/pull/20232) + +- Cannot complete task if dependent task are not completed / cancelled [#20434](https://github.com/frappe/erpnext/pull/20434) + +- Show numeric values in item configurator [#20430](https://github.com/frappe/erpnext/pull/20430) + +- Filter serial no based on batch no [#20566](https://github.com/frappe/erpnext/pull/20566) + +- Pricing rule was not working on item groups [#20546](https://github.com/frappe/erpnext/pull/20546) + +- Disabled quick entry for doctypes with tree view [#20453](https://github.com/frappe/erpnext/pull/20453) + +### Optimisation +- Handling of large number of serial no creation via Purchase Receipt / Stock Entry (10 times faster than before!) [#20540](https://github.com/frappe/erpnext/pull/20540) + +- Update outstanding amount on Sales Invoice on submission of invoice / payment [#20557](https://github.com/frappe/erpnext/pull/20557) \ No newline at end of file From 2d2aa7d664d4c312e84a75676f5e885cca5558c0 Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 20 Feb 2020 12:22:01 +0530 Subject: [PATCH 116/119] fix: check for available stock in product bundle's website warehouse (#20679) * fix: check for available stock in product bundle's website warehouse * test: earned leaves creation * fix: minor change Co-authored-by: Mangesh-Khairnar --- .../hr/doctype/leave_application/test_leave_application.py | 7 ++++--- erpnext/utilities/product.py | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.py b/erpnext/hr/doctype/leave_application/test_leave_application.py index 4c21edb2c02..dde913a9b62 100644 --- a/erpnext/hr/doctype/leave_application/test_leave_application.py +++ b/erpnext/hr/doctype/leave_application/test_leave_application.py @@ -439,10 +439,11 @@ class TestLeaveApplication(unittest.TestCase): # validate earned leaves creation without maximum leaves frappe.db.set_value('Leave Type', leave_type, 'max_leaves_allowed', 0) - while(i<14): + i = 0 + while(i<6): allocate_earned_leaves() i += 1 - self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 14) + self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 9) # test to not consider current leave in leave balance while submitting def test_current_leave_on_submit(self): @@ -623,4 +624,4 @@ def allocate_leaves(employee, leave_period, leave_type, new_leaves_allocated, el "docstatus": 1 }).insert() - allocate_leave.submit() \ No newline at end of file + allocate_leave.submit() diff --git a/erpnext/utilities/product.py b/erpnext/utilities/product.py index 1c0d4c38c73..c23c1f7096d 100644 --- a/erpnext/utilities/product.py +++ b/erpnext/utilities/product.py @@ -129,6 +129,7 @@ def get_non_stock_item_status(item_code, item_warehouse_field): #if item belongs to product bundle, check if bundle items are in stock if frappe.db.exists("Product Bundle", item_code): items = frappe.get_doc("Product Bundle", item_code).get_all_children() - return all([ get_qty_in_stock(d.item_code, item_warehouse_field).in_stock for d in items ]) + bundle_warehouse = frappe.db.get_value('Item', item_code, item_warehouse_field) + return all([ get_qty_in_stock(d.item_code, item_warehouse_field, bundle_warehouse).in_stock for d in items ]) else: return 1 From 8903258362c8023fc8dd1cffd57ae526dd2f4c5d Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 20 Feb 2020 12:30:35 +0530 Subject: [PATCH 117/119] fix: mandatory on hold comment for purchase invoice (#20668) Co-authored-by: Nabin Hait --- erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index d4676ff0375..737c18a8a98 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -1015,7 +1015,7 @@ def unblock_invoice(name): @frappe.whitelist() -def block_invoice(name, hold_comment, release_date): +def block_invoice(name, release_date, hold_comment=None): if frappe.db.exists('Purchase Invoice', name): pi = frappe.get_doc('Purchase Invoice', name) pi.block_invoice(hold_comment, release_date) From b203406d4cb741a2cfe54587f89cd36922dc6902 Mon Sep 17 00:00:00 2001 From: sahil28297 <37302950+sahil28297@users.noreply.github.com> Date: Thu, 20 Feb 2020 18:20:33 +0530 Subject: [PATCH 118/119] fix: proper release note version --- erpnext/change_log/v12/v12_5_0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/change_log/v12/v12_5_0.md b/erpnext/change_log/v12/v12_5_0.md index e398bd7c450..77499e61baf 100644 --- a/erpnext/change_log/v12/v12_5_0.md +++ b/erpnext/change_log/v12/v12_5_0.md @@ -1,4 +1,4 @@ -## Version 12.4.0 Release Note +## Version 12.5.0 Release Note ### New Features: - **Group by Customer / Customer Group / Item / Item Group / Territory / Invoice** option in Itemised Sales Register report [#20251](https://github.com/frappe/erpnext/pull/20251) @@ -50,4 +50,4 @@ ### Optimisation - Handling of large number of serial no creation via Purchase Receipt / Stock Entry (10 times faster than before!) [#20540](https://github.com/frappe/erpnext/pull/20540) -- Update outstanding amount on Sales Invoice on submission of invoice / payment [#20557](https://github.com/frappe/erpnext/pull/20557) \ No newline at end of file +- Update outstanding amount on Sales Invoice on submission of invoice / payment [#20557](https://github.com/frappe/erpnext/pull/20557) From 1b78d20d3c09b02ba470be952f1b5744cd0240ad Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Thu, 20 Feb 2020 18:46:57 +0550 Subject: [PATCH 119/119] bumped to version 12.5.0 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 12177f81da9..718552ad8ef 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '12.4.3' +__version__ = '12.5.0' def get_default_company(user=None): '''Get default company for user'''