From e67195b0b9ff1cd260f97e44d3d92e3d07581a35 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 17 Jun 2020 19:06:56 +0530 Subject: [PATCH 01/10] fix: Typo --- erpnext/controllers/item_variant.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py index 50b17abbe6d..1f95e004244 100644 --- a/erpnext/controllers/item_variant.py +++ b/erpnext/controllers/item_variant.py @@ -102,7 +102,7 @@ def validate_item_attribute_value(attributes_list, attribute, attribute_value, i frappe.throw(_("{0} is not a valid Value for Attribute {1} of Item {2}.").format( frappe.bold(attribute_value), frappe.bold(attribute), frappe.bold(item)), InvalidItemAttributeValueError, title=_("Invalid Value")) else: - msg = _("The value {0} is already assigned to an exisiting Item {1}.").format( + msg = _("The value {0} is already assigned to an existing Item {1}.").format( frappe.bold(attribute_value), frappe.bold(item)) msg += "
" + _("To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings.").format(frappe.bold("Allow Rename Attribute Value")) From 59938a46eb01093e114c0d4a065bfa350313f9b1 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2020 09:46:03 +0530 Subject: [PATCH 02/10] fix: typo for language in Terms description (#22270) (#22272) (cherry picked from commit c159556c24dd90f18d2b5dafacd94abfacfff4d8) Co-authored-by: Kenneth Sequeira <33246109+kennethsequeira@users.noreply.github.com> --- .../doctype/terms_and_conditions/terms_and_conditions.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.json b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.json index aba6a791a4e..28d1d16a051 100644 --- a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.json +++ b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.json @@ -1,4 +1,5 @@ { + "actions": [], "allow_import": 1, "allow_rename": 1, "autoname": "field:title", @@ -49,7 +50,7 @@ "fieldname": "terms_and_conditions_help", "fieldtype": "HTML", "label": "Terms and Conditions Help", - "options": "

Standard Terms and Conditions Example

\n\n
Delivery Terms for Order number {{ name }}\n\n-Order Date : {{ transaction_date }} \n-Expected Delivery Date : {{ delivery_date }}\n
\n\n

How to get fieldnames

\n\n

The fieldnames you can use in your email template are the fields in the document from which you are sending the email. You can find out the fields of any documents via Setup > Customize Form View and selecting the document type (e.g. Sales Invoice)

\n\n

Templating

\n\n

Templates are compiled using the Jinja Templating Langauge. To learn more about Jinja, read this documentation.

" + "options": "

Standard Terms and Conditions Example

\n\n
Delivery Terms for Order number {{ name }}\n\n-Order Date : {{ transaction_date }} \n-Expected Delivery Date : {{ delivery_date }}\n
\n\n

How to get fieldnames

\n\n

The fieldnames you can use in your email template are the fields in the document from which you are sending the email. You can find out the fields of any documents via Setup > Customize Form View and selecting the document type (e.g. Sales Invoice)

\n\n

Templating

\n\n

Templates are compiled using the Jinja Templating Language. To learn more about Jinja, read this documentation.

" }, { "fieldname": "applicable_modules_section", @@ -81,7 +82,8 @@ ], "icon": "icon-legal", "idx": 1, - "modified": "2019-07-04 13:31:30.393425", + "links": [], + "modified": "2020-06-16 22:54:38.094844", "modified_by": "Administrator", "module": "Setup", "name": "Terms and Conditions", From 5d042ad4960266e372eab783a0d22a4e33aa8637 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2020 09:47:15 +0530 Subject: [PATCH 03/10] fix: update shopify api version (#22284) (#22299) Co-authored-by: Saurabh (cherry picked from commit 53b601523b81c32a0b5c10c721f99c184d09bcd8) Co-authored-by: Mangesh-Khairnar --- .../shopify_settings/shopify_settings.py | 24 +++++++++++++------ .../doctype/shopify_settings/sync_product.py | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py index 64c3b2d2730..25ffd281099 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py @@ -8,6 +8,7 @@ import json from frappe import _ from frappe.model.document import Document from frappe.utils import get_request_session +from requests.exceptions import HTTPError from frappe.custom.doctype.custom_field.custom_field import create_custom_fields from erpnext.erpnext_integrations.utils import get_webhook_address from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log @@ -29,19 +30,24 @@ class ShopifySettings(Document): webhooks = ["orders/create", "orders/paid", "orders/fulfilled"] # url = get_shopify_url('admin/webhooks.json', self) created_webhooks = [d.method for d in self.webhooks] - url = get_shopify_url('admin/api/2019-04/webhooks.json', self) + url = get_shopify_url('admin/api/2020-04/webhooks.json', self) for method in webhooks: session = get_request_session() try: - d = session.post(url, data=json.dumps({ + res = session.post(url, data=json.dumps({ "webhook": { "topic": method, "address": get_webhook_address(connector_name='shopify_connection', method='store_request_data'), "format": "json" } }), headers=get_header(self)) - d.raise_for_status() - self.update_webhook_table(method, d.json()) + res.raise_for_status() + self.update_webhook_table(method, res.json()) + + except HTTPError as e: + error_message = res.json().get('errors', e) + make_shopify_log(status="Warning", exception=error_message, rollback=True) + except Exception as e: make_shopify_log(status="Warning", exception=e, rollback=True) @@ -50,13 +56,18 @@ class ShopifySettings(Document): deleted_webhooks = [] for d in self.webhooks: - url = get_shopify_url('admin/api/2019-04/webhooks/{0}.json'.format(d.webhook_id), self) + url = get_shopify_url('admin/api/2020-04/webhooks/{0}.json'.format(d.webhook_id), self) try: res = session.delete(url, headers=get_header(self)) res.raise_for_status() deleted_webhooks.append(d) + + except HTTPError as e: + error_message = res.json().get('errors', e) + make_shopify_log(status="Warning", exception=error_message, rollback=True) + except Exception as e: - frappe.log_error(message=frappe.get_traceback(), title=e) + frappe.log_error(message=e, title='Shopify Webhooks Issue') for d in deleted_webhooks: self.remove(d) @@ -125,4 +136,3 @@ def setup_custom_fields(): } create_custom_fields(custom_fields) - diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py b/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py index bde101123db..f9f0bb3cecc 100644 --- a/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py +++ b/erpnext/erpnext_integrations/doctype/shopify_settings/sync_product.py @@ -8,7 +8,7 @@ from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings impo shopify_variants_attr_list = ["option1", "option2", "option3"] def sync_item_from_shopify(shopify_settings, item): - url = get_shopify_url("admin/api/2019-04/products/{0}.json".format(item.get("product_id")), shopify_settings) + url = get_shopify_url("admin/api/2020-04/products/{0}.json".format(item.get("product_id")), shopify_settings) session = get_request_session() try: From c75236579f307c638264f54bfbec712dc3b1ba56 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 18 Jun 2020 13:59:19 +0530 Subject: [PATCH 04/10] fix: incorrect variable used while adding items in the submitted sales order --- erpnext/controllers/accounts_controller.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index a4bed51f479..3e6c7dc788f 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1194,11 +1194,11 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil action = "add" if perm_type == 'create' else "update" frappe.throw(_("You do not have permissions to {} items in a Sales Order.").format(action), title=_("Insufficient Permissions")) - def get_new_child_item(): + def get_new_child_item(item_row): if parent_doctype == "Sales Order": - return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d) + return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row) if parent_doctype == "Purchase Order": - return set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d) + return set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row) def validate_quantity(child_item, d): if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty): @@ -1219,7 +1219,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil if not d.get("docname"): new_child_flag = True check_permissions(parent, 'create') - child_item = get_new_child_item() + child_item = get_new_child_item(d) else: check_permissions(parent, 'write') child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname")) From af6a0f3a9d091713fdc90574acb5275b0d89c061 Mon Sep 17 00:00:00 2001 From: Kenneth Sequeira <33246109+kennethsequeira@users.noreply.github.com> Date: Thu, 18 Jun 2020 14:34:11 +0530 Subject: [PATCH 05/10] fix(HR): typo in error message in Employee Balance Report (#22306) * fix: typo in date error message * fix: error message cleanup in Leave Balance report --- .../report/employee_leave_balance/employee_leave_balance.py | 4 ++-- .../employee_leave_balance_summary.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py index d5050e73d46..0a6386f103f 100644 --- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py +++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py @@ -49,7 +49,7 @@ def get_data(filters, leave_types): conditions = get_conditions(filters) if filters.to_date <= filters.from_date: - frappe.throw(_("From date can not be greater than than To date")) + frappe.throw(_("'From Date should be less than To Date")) active_employees = frappe.get_all("Employee", filters=conditions, @@ -160,4 +160,4 @@ def get_department_leave_approver_map(department=None): for k, v in approver_list: approvers.setdefault(k, []).append(v) - return approvers \ No newline at end of file + return approvers diff --git a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py index 21646425bb6..70510492be9 100644 --- a/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py +++ b/erpnext/hr/report/employee_leave_balance_summary/employee_leave_balance_summary.py @@ -10,7 +10,7 @@ from erpnext.hr.report.employee_leave_balance.employee_leave_balance import calc def execute(filters=None): if filters.to_date <= filters.from_date: - frappe.throw(_('From date can not be greater than than To date')) + frappe.throw(_('From Date should be less than To Date')) columns = get_columns() data = get_data(filters) From 0c08324fab230968b7e0b375363800c76374a6f2 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2020 15:29:46 +0530 Subject: [PATCH 06/10] chore: add standard queries hooks to whitelist (#21939) (#22305) standard queries are used within the search widget, and now require to be whitelisted before they can be executed through the search widget. Signed-off-by: Chinmay D. Pai Co-authored-by: sahil28297 <37302950+sahil28297@users.noreply.github.com> (cherry picked from commit 96100e95077db9d9a2a27b384030460109cdd0f2) Co-authored-by: Chinmay Pai --- .../doctype/healthcare_practitioner/healthcare_practitioner.py | 1 + erpnext/selling/doctype/customer/customer.py | 1 + 2 files changed, 2 insertions(+) diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py index ad32e946312..40f31016bc4 100644 --- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py +++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py @@ -67,6 +67,7 @@ def validate_service_item(item, msg): if frappe.db.get_value("Item", item, "is_stock_item") == 1: frappe.throw(_(msg)) +@frappe.whitelist() def get_practitioner_list(doctype, txt, searchfield, start, page_len, filters=None): fields = ["name", "first_name", "mobile_phone"] diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 9a5d2ebd910..53c43fb2b60 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -299,6 +299,7 @@ def get_loyalty_programs(doc): return lp_details +@frappe.whitelist() def get_customer_list(doctype, txt, searchfield, start, page_len, filters=None): from erpnext.controllers.queries import get_fields From 1ca4370033fd8e8cfb65c236ee6270aa63f15750 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2020 15:39:13 +0530 Subject: [PATCH 07/10] fix: asset maintenance fixes (#21277) (#22294) * fix: asset maintenance fixes * fix: tests (cherry picked from commit 9c494d3e72d95c6b95f379a0d00545a225f35c33) Co-authored-by: Saqib --- .../asset_maintenance/asset_maintenance.js | 39 ------------------- .../asset_maintenance/asset_maintenance.py | 7 ++-- .../test_asset_maintenance.py | 6 ++- 3 files changed, 7 insertions(+), 45 deletions(-) diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js index 3c135d466c1..001fc26ffe7 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js @@ -24,26 +24,6 @@ frappe.ui.form.on('Asset Maintenance', { return indicator; } ); - - frm.set_query('select_serial_no', function(doc){ - return { - asset: frm.doc.asset_name - } - }) - }, - - select_serial_no: (frm) => { - let serial_nos = frm.doc.serial_no || frm.doc.select_serial_no; - if (serial_nos) { - serial_nos = serial_nos.split('\n'); - serial_nos.push(frm.doc.select_serial_no); - - const unique_sn = serial_nos.filter(function(elem, index, self) { - return index === self.indexOf(elem); - }); - - frm.set_value("serial_no", unique_sn.join('\n')); - } }, refresh: (frm) => { @@ -93,25 +73,6 @@ frappe.ui.form.on('Asset Maintenance Task', { }, end_date: (frm, cdt, cdn) => { get_next_due_date(frm, cdt, cdn); - }, - assign_to: (frm, cdt, cdn) => { - var d = locals[cdt][cdn]; - if (frm.doc.__islocal) { - frappe.model.set_value(cdt, cdn, "assign_to", ""); - frappe.model.set_value(cdt, cdn, "assign_to_name", ""); - frappe.throw(__("Please save before assigning task.")); - } - if (d.assign_to) { - return frappe.call({ - method: 'erpnext.assets.doctype.asset_maintenance.asset_maintenance.assign_tasks', - args: { - asset_maintenance_name: frm.doc.name, - assign_to_member: d.assign_to, - maintenance_task: d.maintenance_task, - next_due_date: d.next_due_date - } - }); - } } }); diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py index ba63dd661d7..d6adde6a371 100644 --- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py +++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py @@ -16,12 +16,11 @@ class AssetMaintenance(Document): throw(_("Start date should be less than end date for task {0}").format(task.maintenance_task)) if getdate(task.next_due_date) < getdate(nowdate()): task.maintenance_status = "Overdue" + if not task.assign_to and self.docstatus == 0: + throw(_("Row #{}: Please asign task to a member.").format(task.idx)) def on_update(self): for task in self.get('asset_maintenance_tasks'): - if not task.assign_to: - task.db_set("assign_to", self.maintenance_manager) - task.db_set("assign_to_name", self.maintenance_manager_name) assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date) self.sync_maintenance_tasks() @@ -108,7 +107,7 @@ def update_maintenance_log(asset_maintenance, item_code, item_name, task): @frappe.whitelist() def get_team_members(doctype, txt, searchfield, start, page_len, filters): - return frappe.db.get_values('Maintenance Team Member', {'parent':filters.get("maintenance_team")}) + return frappe.db.get_values('Maintenance Team Member', { 'parent': filters.get("maintenance_team") }) @frappe.whitelist() def get_maintenance_log(asset_name): diff --git a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py index 6c2fd67a9af..392fbdd2af7 100644 --- a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py +++ b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py @@ -125,13 +125,15 @@ def get_maintenance_tasks(): "start_date": nowdate(), "periodicity": "Monthly", "maintenance_type": "Preventive Maintenance", - "maintenance_status": "Planned" + "maintenance_status": "Planned", + "assign_to": "marcus@abc.com" }, {"maintenance_task": "Check Gears", "start_date": nowdate(), "periodicity": "Yearly", "maintenance_type": "Calibration", - "maintenance_status": "Planned" + "maintenance_status": "Planned", + "assign_to": "thalia@abc.com" } ] From f9dbcef5c9170e076610f1c082ccfa1e711ab9c8 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 18 Jun 2020 16:45:16 +0530 Subject: [PATCH 08/10] fix: Do not copy Item Tax template from SO to PO --- erpnext/selling/doctype/sales_order/sales_order.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 05e4aa892b0..ffb66354fa0 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -868,7 +868,8 @@ def make_purchase_order(source_name, for_supplier=None, selected_items=[], targe ], "field_no_map": [ "rate", - "price_list_rate" + "price_list_rate", + "item_tax_template" ], "postprocess": update_item, "condition": lambda doc: doc.ordered_qty < doc.qty and doc.supplier == supplier and doc.item_code in selected_items From 531ef15e30b91eaab139b0e587afb25e2ec3da15 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2020 17:04:36 +0530 Subject: [PATCH 09/10] refactor: handle exceptions when updating addresses (#22307) (#22315) * refactor: handle exceptions when updating addresses * refactor: fold common statements in a loop (cherry picked from commit 34d2bfbb3e6ce28de2690812191b8885b4f8f6ab) Co-authored-by: Shivam Mishra --- .../connectors/woocommerce_connection.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py index 1b0c9f60b6e..6dedaa8c530 100644 --- a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py +++ b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py @@ -73,10 +73,16 @@ def link_customer_and_address(raw_billing_data, raw_shipping_data, customer_name if customer_exists: frappe.rename_doc("Customer", old_name, customer_name) - billing_address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": "Billing"}) - shipping_address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": "Shipping"}) - rename_address(billing_address, customer) - rename_address(shipping_address, customer) + for address_type in ("Billing", "Shipping",): + try: + address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": address_type}) + rename_address(address, customer) + except ( + frappe.DoesNotExistError, + frappe.DuplicateEntryError, + frappe.ValidationError, + ): + pass else: create_address(raw_billing_data, customer, "Billing") create_address(raw_shipping_data, customer, "Shipping") From cce1116b4e2adad6e061f1965e13bc960a756aa2 Mon Sep 17 00:00:00 2001 From: Marica Date: Thu, 18 Jun 2020 19:15:49 +0530 Subject: [PATCH 10/10] fix: Quality procedure fixes (#22287) * fix: Quality Procedure Fixes - Dont prompt error message if parent is the same in child - filter child procedure field - Disable New button in tree view - Editable grid for Quality Procedure Proces table. * chore: Remove unnecessary get_doc * fix: Codacy Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> --- .../quality_procedure/quality_procedure.js | 9 +++++++ .../quality_procedure/quality_procedure.json | 3 ++- .../quality_procedure/quality_procedure.py | 25 +++++++++++-------- .../quality_procedure_tree.js | 1 + .../quality_procedure_process.json | 5 +++- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.js b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.js index ded3a51dd60..cf2644e0053 100644 --- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.js +++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.js @@ -2,4 +2,13 @@ // For license information, please see license.txt frappe.ui.form.on('Quality Procedure', { + refresh: function(frm) { + frm.set_query("procedure","processes", (frm) =>{ + return { + filters: { + name: ["not in", [frm.parent_quality_procedure, frm.name]] + } + }; + }); + } }); \ No newline at end of file diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json index e44e0733967..b3c0d948909 100644 --- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json +++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json @@ -1,5 +1,6 @@ { "actions": [], + "allow_rename": 1, "autoname": "format:PRC-{quality_procedure_name}", "creation": "2018-10-06 00:06:29.756804", "doctype": "DocType", @@ -72,7 +73,7 @@ ], "is_tree": 1, "links": [], - "modified": "2020-03-18 18:26:05.511984", + "modified": "2020-06-17 17:25:03.434953", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality Procedure", diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py index 3ce5ea015f5..1952e578673 100644 --- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py +++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py @@ -10,13 +10,8 @@ from frappe import _ class QualityProcedure(NestedSet): nsm_parent_field = 'parent_quality_procedure' - def on_save(self): - for process in self.processes: - if process.procedure: - doc = frappe.get_doc("Quality Procedure", process.procedure) - if doc.parent_quality_procedure: - frappe.throw(_("{0} already has a Parent Procedure {1}.".format(process.procedure, doc.parent_quality_procedure))) - self.is_group = 1 + def before_save(self): + self.check_for_incorrect_child() def on_update(self): self.set_parent() @@ -47,11 +42,21 @@ class QualityProcedure(NestedSet): doc.save(ignore_permissions=True) def set_parent(self): + for process in self.processes: + # Set parent for only those children who don't have a parent + parent_quality_procedure = frappe.db.get_value("Quality Procedure", process.procedure, "parent_quality_procedure") + if not parent_quality_procedure and process.procedure: + frappe.db.set_value(self.doctype, process.procedure, "parent_quality_procedure", self.name) + + def check_for_incorrect_child(self): for process in self.processes: if process.procedure: - doc = frappe.get_doc("Quality Procedure", process.procedure) - doc.parent_quality_procedure = self.name - doc.save(ignore_permissions=True) + # Check if any child process belongs to another parent. + parent_quality_procedure = frappe.db.get_value("Quality Procedure", process.procedure, "parent_quality_procedure") + if parent_quality_procedure and parent_quality_procedure != self.name: + frappe.throw(_("{0} already has a Parent Procedure {1}.".format(frappe.bold(process.procedure), frappe.bold(parent_quality_procedure))), + title=_("Invalid Child Procedure")) + self.is_group = 1 @frappe.whitelist() def get_children(doctype, parent=None, parent_quality_procedure=None, is_root=False): 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 6df6f656aa1..ef48ab6c6e2 100644 --- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js +++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js @@ -16,6 +16,7 @@ frappe.treeview_settings["Quality Procedure"] = { }, ], breadcrumb: "Setup", + disable_add_node: true, root_label: "All Quality Procedures", get_tree_root: false, menu_items: [ diff --git a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json index 0a67fa505ee..3925dbb8aca 100644 --- a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json +++ b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json @@ -1,6 +1,8 @@ { + "actions": [], "creation": "2019-05-26 00:10:00.248885", "doctype": "DocType", + "editable_grid": 1, "engine": "InnoDB", "field_order": [ "process_description", @@ -23,7 +25,8 @@ } ], "istable": 1, - "modified": "2019-05-26 22:05:49.007189", + "links": [], + "modified": "2020-06-17 15:44:38.937915", "modified_by": "Administrator", "module": "Quality Management", "name": "Quality Procedure Process",