From bd4e296336226f38067c5822d70580b35de3539e Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Thu, 24 Oct 2019 15:45:32 +0530 Subject: [PATCH 01/11] fix: sync delivery note status in both list view and form view --- erpnext/stock/doctype/delivery_note/delivery_note_list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js index 6fc51ecdd9d..0ae7c37b3f8 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js @@ -6,9 +6,9 @@ frappe.listview_settings['Delivery Note'] = { return [__("Return"), "darkgrey", "is_return,=,Yes"]; } else if (doc.status === "Closed") { return [__("Closed"), "green", "status,=,Closed"]; - } else if (doc.grand_total !== 0 && flt(doc.per_billed, 2) < 100) { + } else if (flt(doc.per_billed, 2) < 100) { return [__("To Bill"), "orange", "per_billed,<,100"]; - } else if (doc.grand_total === 0 || flt(doc.per_billed, 2) == 100) { + } else if (flt(doc.per_billed, 2) == 100) { return [__("Completed"), "green", "per_billed,=,100"]; } }, From 10b226af10ef4e2b2df5d46ae057b8e43998b346 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 28 Oct 2019 15:48:10 +0530 Subject: [PATCH 02/11] fix: Search field entries included in Item Link field query --- erpnext/controllers/queries.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 241d3ab7c98..02d0b12739a 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -152,6 +152,17 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters): def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False): conditions = [] + #Get searchfields from meta and use in Item Link field query + meta = frappe.get_meta("Item") + searchfields = meta.get_search_fields() + + fields = [f for f in searchfields if not f in ["name", "item_group", "description"]] + fields = ", ".join(fields) + + searchfields = searchfields + [f for f in [searchfield or "name", "item_code", "item_group", "item_name"] + if not f in searchfields] + searchfields = " or ".join([field + " like %(txt)s" for field in searchfields]) + description_cond = '' if frappe.db.count('Item', cache=True) < 50000: # scan description only if items are less than 50000 @@ -162,17 +173,14 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name, tabItem.item_group, if(length(tabItem.description) > 40, \ - concat(substr(tabItem.description, 1, 40), "..."), description) as decription + concat(substr(tabItem.description, 1, 40), "..."), description) as description, + {fields} from tabItem where tabItem.docstatus < 2 and tabItem.has_variants=0 and tabItem.disabled=0 and (tabItem.end_of_life > %(today)s or ifnull(tabItem.end_of_life, '0000-00-00')='0000-00-00') - and (tabItem.`{key}` LIKE %(txt)s - or tabItem.item_code LIKE %(txt)s - or tabItem.item_group LIKE %(txt)s - or tabItem.item_name LIKE %(txt)s - or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s) + and ({scond} or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s) {description_cond}) {fcond} {mcond} order by @@ -182,6 +190,8 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals name, item_name limit %(start)s, %(page_len)s """.format( key=searchfield, + fields=fields, + scond=searchfields, fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'), mcond=get_match_cond(doctype).replace('%', '%%'), description_cond = description_cond), From 91f81b07d9391abc2e7a5739540b93096f08c9fa Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 30 Oct 2019 13:30:28 +0530 Subject: [PATCH 03/11] fix: not able to select the zero qty batch while making the sales return entry (#19436) --- erpnext/controllers/queries.py | 39 ++++++++++++-------- erpnext/public/js/controllers/transaction.js | 5 +++ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 241d3ab7c98..f21ce78d71f 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -280,22 +280,31 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters): "page_len": page_len } + having_clause = "having sum(sle.actual_qty) > 0" + if filters.get("is_return"): + having_clause = "" + if args.get('warehouse'): - batch_nos = frappe.db.sql("""select sle.batch_no, round(sum(sle.actual_qty),2), sle.stock_uom, concat('MFG-',batch.manufacturing_date), concat('EXP-',batch.expiry_date) - from `tabStock Ledger Entry` sle - INNER JOIN `tabBatch` batch on sle.batch_no = batch.name - where - batch.disabled = 0 - and sle.item_code = %(item_code)s - and sle.warehouse = %(warehouse)s - and (sle.batch_no like %(txt)s - or batch.manufacturing_date like %(txt)s) - and batch.docstatus < 2 - {0} - {match_conditions} - group by batch_no having sum(sle.actual_qty) > 0 - order by batch.expiry_date, sle.batch_no desc - limit %(start)s, %(page_len)s""".format(cond, match_conditions=get_match_cond(doctype)), args) + batch_nos = frappe.db.sql("""select sle.batch_no, round(sum(sle.actual_qty),2), sle.stock_uom, + concat('MFG-',batch.manufacturing_date), concat('EXP-',batch.expiry_date) + from `tabStock Ledger Entry` sle + INNER JOIN `tabBatch` batch on sle.batch_no = batch.name + where + batch.disabled = 0 + and sle.item_code = %(item_code)s + and sle.warehouse = %(warehouse)s + and (sle.batch_no like %(txt)s + or batch.manufacturing_date like %(txt)s) + and batch.docstatus < 2 + {cond} + {match_conditions} + group by batch_no {having_clause} + order by batch.expiry_date, sle.batch_no desc + limit %(start)s, %(page_len)s""".format( + cond=cond, + match_conditions=get_match_cond(doctype), + having_clause = having_clause + ), args) return batch_nos else: diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 17fad54453b..d29750950d7 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -1422,6 +1422,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ 'item_code': item.item_code, 'posting_date': me.frm.doc.posting_date || frappe.datetime.nowdate(), } + + if (doc.is_return) { + filters["is_return"] = 1; + } + if (item.warehouse) filters["warehouse"] = item.warehouse; return { From 3f4cdcc7a4e0dd7dea1d6b1e11bfd544f73de13e Mon Sep 17 00:00:00 2001 From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com> Date: Wed, 30 Oct 2019 14:18:20 +0530 Subject: [PATCH 04/11] fix: On Specific case if no item code in name (#19420) --- erpnext/manufacturing/doctype/bom/bom.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 437f1694b91..0ed2c86b4c4 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -38,9 +38,11 @@ class BOM(WebsiteGenerator): names = [d[-1][1:] for d in filter(lambda x: len(x) > 1 and x[-1], names)] # split by (-) if cancelled - names = [cint(name.split('-')[-1]) for name in names] - - idx = max(names) + 1 + if names: + names = [cint(name.split('-')[-1]) for name in names] + idx = max(names) + 1 + else: + idx = 1 else: idx = 1 From 112902a9c42ebf57edea8634f732a3588bb758b9 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 30 Oct 2019 14:22:49 +0530 Subject: [PATCH 05/11] fix: not able to select the project in the work order --- erpnext/manufacturing/doctype/work_order/work_order.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js index 22d74e8ee6e..f4be3119e98 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.js +++ b/erpnext/manufacturing/doctype/work_order/work_order.js @@ -318,7 +318,7 @@ frappe.ui.form.on("Work Order", { }, project: function(frm) { - if(!erpnext.in_production_item_onchange) { + if(!erpnext.in_production_item_onchange && !frm.doc.bom_no) { frm.trigger("production_item"); } }, From b02db3c3e8ce0fcc86b7bfdef060f2136ce1a96e Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Wed, 30 Oct 2019 15:20:43 +0530 Subject: [PATCH 06/11] chore: moves email digest to long job from regular --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index a067e28747e..0753c58566e 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -233,7 +233,6 @@ scheduler_events = { ], "daily": [ "erpnext.stock.reorder_item.reorder_item", - "erpnext.setup.doctype.email_digest.email_digest.send", "erpnext.support.doctype.issue.issue.auto_close_tickets", "erpnext.crm.doctype.opportunity.opportunity.auto_close_opportunity", "erpnext.controllers.accounts_controller.update_invoice_status", @@ -252,6 +251,7 @@ scheduler_events = { "erpnext.projects.doctype.project.project.send_project_status_email_to_users" ], "daily_long": [ + "erpnext.setup.doctype.email_digest.email_digest.send", "erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms" ], "monthly_long": [ From 7aa993b14b68e2fd3553ce598c26c53bc9f04b78 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 30 Oct 2019 18:33:44 +0530 Subject: [PATCH 07/11] fix: Fetching catched meta and removed description fetch from Search Fields Description is conditionally fetched and also used in WHERE clause, that is maintained. Improved naming --- erpnext/controllers/queries.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 02d0b12739a..db230033727 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -153,14 +153,17 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals conditions = [] #Get searchfields from meta and use in Item Link field query - meta = frappe.get_meta("Item") + meta = frappe.get_meta("Item", cached=True) searchfields = meta.get_search_fields() - fields = [f for f in searchfields if not f in ["name", "item_group", "description"]] - fields = ", ".join(fields) + if "description" in searchfields: + searchfields.remove("description") - searchfields = searchfields + [f for f in [searchfield or "name", "item_code", "item_group", "item_name"] - if not f in searchfields] + columns = [field for field in searchfields if not field in ["name", "item_group", "description"]] + columns = ", ".join(columns) + + searchfields = searchfields + [field for field in[searchfield or "name", "item_code", "item_group", "item_name"] + if not field in searchfields] searchfields = " or ".join([field + " like %(txt)s" for field in searchfields]) description_cond = '' @@ -174,7 +177,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals tabItem.item_group, if(length(tabItem.description) > 40, \ concat(substr(tabItem.description, 1, 40), "..."), description) as description, - {fields} + {columns} from tabItem where tabItem.docstatus < 2 and tabItem.has_variants=0 @@ -190,7 +193,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals name, item_name limit %(start)s, %(page_len)s """.format( key=searchfield, - fields=fields, + columns=columns, scond=searchfields, fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'), mcond=get_match_cond(doctype).replace('%', '%%'), From 170dd37b86c7e849e43cd911207f35e14039610c Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Thu, 31 Oct 2019 15:56:05 +0530 Subject: [PATCH 08/11] fix: purchase order issue, margin_rate_or_amount not there in the purchase documents (#19465) --- erpnext/controllers/accounts_controller.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 4d6e22e1915..013e56db0e3 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1097,6 +1097,8 @@ def get_supplier_block_status(party_name): @frappe.whitelist() def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name): data = json.loads(trans_items) + sales_doctypes = ['Sales Order', 'Sales Invoice', 'Delivery Note', 'Quotation'] + for d in data: child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname")) @@ -1118,18 +1120,22 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name): # if rate is greater than price_list_rate, set margin # or set discount child_item.discount_percentage = 0 - child_item.margin_type = "Amount" - child_item.margin_rate_or_amount = flt(child_item.rate - child_item.price_list_rate, - child_item.precision("margin_rate_or_amount")) - child_item.rate_with_margin = child_item.rate + + if parent_doctype in sales_doctypes: + child_item.margin_type = "Amount" + child_item.margin_rate_or_amount = flt(child_item.rate - child_item.price_list_rate, + child_item.precision("margin_rate_or_amount")) + child_item.rate_with_margin = child_item.rate else: child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, child_item.precision("discount_percentage")) child_item.discount_amount = flt( child_item.price_list_rate) - flt(child_item.rate) - child_item.margin_type = "" - child_item.margin_rate_or_amount = 0 - child_item.rate_with_margin = 0 + + if parent_doctype in sales_doctypes: + child_item.margin_type = "" + child_item.margin_rate_or_amount = 0 + child_item.rate_with_margin = 0 child_item.flags.ignore_validate_update_after_submit = True child_item.save() From a985bfc29a0c7081b1e9e779818054e5e420cdf5 Mon Sep 17 00:00:00 2001 From: Maxwell Morais Date: Fri, 1 Nov 2019 18:31:56 -0300 Subject: [PATCH 09/11] Wrong datafield type in Task The field `depends_on_tasks` is set as `Data`, but it stores a list of strings joined by comma, so with more than 5 tasks, we reach the field size limit of 144 chars and data get trunked, what make us lose data! --- erpnext/projects/doctype/task/task.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json index b7f547dbcaf..e1ef1366c35 100644 --- a/erpnext/projects/doctype/task/task.json +++ b/erpnext/projects/doctype/task/task.json @@ -713,7 +713,7 @@ "depends_on": "", "fetch_if_empty": 0, "fieldname": "depends_on_tasks", - "fieldtype": "Data", + "fieldtype": "Long Text", "hidden": 1, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -1433,4 +1433,4 @@ "track_changes": 0, "track_seen": 1, "track_views": 0 -} \ No newline at end of file +} From bc01dafbba0cdaed5db7bb3cdf1b4d9ed2978416 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Sun, 3 Nov 2019 14:02:52 +0530 Subject: [PATCH 10/11] fix: calculate total tax in sales register report --- erpnext/accounts/report/sales_register/sales_register.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index 3cc2f915268..caf1c5f9eec 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -70,6 +70,7 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No if tax_acc not in income_accounts: tax_amount_precision = get_field_precision(frappe.get_meta("Sales Taxes and Charges").get_field("tax_amount"), currency=company_currency) or 2 tax_amount = flt(invoice_tax_map.get(inv.name, {}).get(tax_acc), tax_amount_precision) + total_tax += tax_amount row.append(tax_amount) # total tax, grand total, outstanding amount & rounded total From 8ce7893bf0d98cf1c10fcd6c3be2aa26df6d89c7 Mon Sep 17 00:00:00 2001 From: Diksha Date: Mon, 4 Nov 2019 12:19:23 +0530 Subject: [PATCH 11/11] fix(sales order): rename delivery to delivery note on sales order make button --- erpnext/selling/doctype/sales_order/sales_order.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index 98d62369ff2..bbfa9746de2 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -142,7 +142,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( // delivery note if(flt(doc.per_delivered, 6) < 100 && allow_delivery) { - this.frm.add_custom_button(__('Delivery'), + this.frm.add_custom_button(__('Delivery Note'), function() { me.make_delivery_note_based_on_delivery_date(); }, __("Make")); if(["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1){