From a306af8c089a07d3ac8f65439868997a5cd5f37c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Thu, 6 Aug 2020 20:52:02 +0530 Subject: [PATCH 01/16] fix: Add help link in navbar settings --- erpnext/patches.txt | 1 + .../v13_0/add_standard_navbar_items.py | 7 +++ erpnext/public/js/conf.js | 26 ----------- erpnext/setup/install.py | 45 ++++++++++++++++++- 4 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 erpnext/patches/v13_0/add_standard_navbar_items.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 3bd416952f8..3f63bf651bb 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -718,3 +718,4 @@ erpnext.patches.v13_0.delete_report_requested_items_to_order erpnext.patches.v12_0.update_item_tax_template_company erpnext.patches.v13_0.move_branch_code_to_bank_account erpnext.patches.v13_0.healthcare_lab_module_rename_doctypes +erpnext.patches.v13_0.add_standard_navbar_items #4 diff --git a/erpnext/patches/v13_0/add_standard_navbar_items.py b/erpnext/patches/v13_0/add_standard_navbar_items.py new file mode 100644 index 00000000000..5de99a5abc4 --- /dev/null +++ b/erpnext/patches/v13_0/add_standard_navbar_items.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals +import frappe +from erpnext.setup.install import add_standard_navbar_items + +def execute(): + # Add standard navbar items for ERPNext in Navbar Settings + add_standard_navbar_items() \ No newline at end of file diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js index 9870f819105..2af9140f9e2 100644 --- a/erpnext/public/js/conf.js +++ b/erpnext/public/js/conf.js @@ -3,32 +3,6 @@ frappe.provide('erpnext'); -// add toolbar icon -$(document).bind('toolbar_setup', function() { - frappe.app.name = "ERPNext"; - - frappe.help_feedback_link = '

Feedback

' - - - $('[data-link="docs"]').attr("href", "https://erpnext.com/docs") - $('[data-link="issues"]').attr("href", "https://github.com/frappe/erpnext/issues") - - - // default documentation goes to erpnext - // $('[data-link-type="documentation"]').attr('data-path', '/erpnext/manual/index'); - - // additional help links for erpnext - var $help_menu = $('.dropdown-help ul .documentation-links'); - $('
  • '+__('Documentation')+'
  • ').insertBefore($help_menu); - $('
  • '+__('User Forum')+'
  • ').insertBefore($help_menu); - $('
  • '+__('Report an Issue')+'
  • ').insertBefore($help_menu); - -}); - // preferred modules for breadcrumbs $.extend(frappe.breadcrumbs.preferred, { "Item Group": "Stock", diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index aa9fbc0a92c..b2f0fa2ed6e 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -25,12 +25,13 @@ def after_install(): create_default_success_action() create_default_energy_point_rules() add_company_to_session_defaults() + add_standard_navbar_items() frappe.db.commit() def check_setup_wizard_not_completed(): if frappe.db.get_default('desktop:home_page') != 'setup-wizard': - message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. + message = """ERPNext can only be installed on a fresh site where the setup wizard is not completed. You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall""" frappe.throw(message) @@ -103,3 +104,45 @@ def add_company_to_session_defaults(): "ref_doctype": "Company" }) settings.save() + +def add_standard_navbar_items(): + navbar_settings = frappe.get_single("Navbar Settings") + + erpnext_navbar_items = [ + { + 'item_label': 'Documentation', + 'item_type': 'Route', + 'route': 'https://erpnext.com/docs/user/manual', + 'is_standard': 1 + }, + { + 'item_label': 'User Forum', + 'item_type': 'Route', + 'route': 'https://discuss.erpnext.com', + 'is_standard': 1 + }, + { + 'item_label': 'Report an Issue', + 'item_type': 'Route', + 'route': 'https://github.com/frappe/erpnext/issues', + 'is_standard': 1 + } + ] + + current_nabvar_items = navbar_settings.help_dropdown + navbar_settings.set('help_dropdown', []) + + for item in erpnext_navbar_items: + navbar_settings.append('help_dropdown', item) + + for item in current_nabvar_items: + navbar_settings.append('help_dropdown', { + 'item_label': item.item_label, + 'item_type': item.item_type, + 'route': item.route, + 'action': item.action, + 'is_standard': item.is_standard, + 'hidden': item.hidden + }) + + navbar_settings.save() From 2c26144a6b5f22e8c2f2fd9a2e8930e440ae76a1 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Wed, 19 Aug 2020 18:55:06 +0200 Subject: [PATCH 02/16] Update erpnext/patches/v13_0/add_standard_navbar_items.py --- erpnext/patches/v13_0/add_standard_navbar_items.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v13_0/add_standard_navbar_items.py b/erpnext/patches/v13_0/add_standard_navbar_items.py index 5de99a5abc4..d05b258db0c 100644 --- a/erpnext/patches/v13_0/add_standard_navbar_items.py +++ b/erpnext/patches/v13_0/add_standard_navbar_items.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -import frappe +# import frappe from erpnext.setup.install import add_standard_navbar_items def execute(): # Add standard navbar items for ERPNext in Navbar Settings - add_standard_navbar_items() \ No newline at end of file + add_standard_navbar_items() From 9766adbf4eaf6abf990746bbbabfabf928dd4819 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Wed, 26 Aug 2020 14:53:23 +0530 Subject: [PATCH 03/16] fix: don't overwrite appointment duration if already specified --- .../doctype/patient_appointment/patient_appointment.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js index f7ed31bfeab..2d6b64532b1 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js @@ -226,7 +226,9 @@ let check_and_set_availability = function(frm) { primary_action_label: __('Book'), primary_action: function() { frm.set_value('appointment_time', selected_slot); - frm.set_value('duration', duration); + if (!frm.doc.duration) { + frm.set_value('duration', duration); + } frm.set_value('practitioner', d.get_value('practitioner')); frm.set_value('department', d.get_value('department')); frm.set_value('appointment_date', d.get_value('appointment_date')); From c7830f71072509cb7fb751b9836bd8f4d6a9e65d Mon Sep 17 00:00:00 2001 From: Anupam K Date: Wed, 26 Aug 2020 15:28:22 +0530 Subject: [PATCH 04/16] feat: Added phone field in product Inquiry --- erpnext/templates/generators/item/item_inquiry.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/erpnext/templates/generators/item/item_inquiry.js b/erpnext/templates/generators/item/item_inquiry.js index 52ddae2624c..e7db3a368df 100644 --- a/erpnext/templates/generators/item/item_inquiry.js +++ b/erpnext/templates/generators/item/item_inquiry.js @@ -20,6 +20,13 @@ frappe.ready(() => { options: 'Email', reqd: 1 }, + { + fieldtype: 'Data', + label: __('Phone Number'), + fieldname: 'phone', + options: 'Phone', + reqd: 1 + }, { fieldtype: 'Data', label: __('Subject'), From 733fd5f03c7c855457c27600285fd2d0ace4bad6 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 26 Aug 2020 18:23:12 +0530 Subject: [PATCH 05/16] fix: get_applied_pricing_rule in taxes_and_totals --- erpnext/controllers/taxes_and_totals.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 2a14be85325..92cfdb7f1a1 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -9,6 +9,7 @@ from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction from erpnext.controllers.accounts_controller import validate_conversion_rate, \ validate_taxes_and_charges, validate_inclusive_tax from erpnext.stock.get_item_details import _get_item_tax_template +from erpnext.accounts.doctype.pricing_rule.utils import get_applied_pricing_rules class calculate_taxes_and_totals(object): def __init__(self, doc): @@ -209,7 +210,7 @@ class calculate_taxes_and_totals(object): elif tax.charge_type == "On Previous Row Total": current_tax_fraction = (tax_rate / 100.0) * \ self.doc.get("taxes")[cint(tax.row_id) - 1].grand_total_fraction_for_current_item - + elif tax.charge_type == "On Item Quantity": inclusive_tax_amount_per_qty = flt(tax_rate) @@ -607,7 +608,7 @@ class calculate_taxes_and_totals(object): base_rate_with_margin = 0.0 if item.price_list_rate: if item.pricing_rules and not self.doc.ignore_pricing_rule: - for d in json.loads(item.pricing_rules): + for d in get_applied_pricing_rules(item.pricing_rules): pricing_rule = frappe.get_cached_doc('Pricing Rule', d) if (pricing_rule.margin_type == 'Amount' and pricing_rule.currency == self.doc.currency)\ From bb5d886930da4caf37ba0ea5de38ede957155752 Mon Sep 17 00:00:00 2001 From: bhavesh95863 <34086262+bhavesh95863@users.noreply.github.com> Date: Wed, 26 Aug 2020 18:23:21 +0530 Subject: [PATCH 06/16] fix: account & cost center filter by company --- .../doctype/shipping_rule/shipping_rule.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js index 53ee08a773e..d0904eec3e3 100644 --- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.js +++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.js @@ -3,6 +3,22 @@ frappe.ui.form.on('Shipping Rule', { refresh: function(frm) { + frm.set_query("cost_center", function() { + return { + filters: { + company: frm.doc.company + } + } + }) + + frm.set_query("account", function() { + return { + filters: { + company: frm.doc.company + } + } + }) + frm.trigger('toggle_reqd'); }, calculate_based_on: function(frm) { @@ -12,4 +28,4 @@ frappe.ui.form.on('Shipping Rule', { frm.toggle_reqd("shipping_amount", frm.doc.calculate_based_on === 'Fixed'); frm.toggle_reqd("conditions", frm.doc.calculate_based_on !== 'Fixed'); } -}); \ No newline at end of file +}); From 1bd83e69eeb3cb62afa2b6bbd80f5af80b6658c8 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 27 Aug 2020 13:06:52 +0530 Subject: [PATCH 07/16] feat: added Installation Note and Warranty Claim links to Customer dashboard (#23183) --- erpnext/selling/doctype/customer/customer_dashboard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py index cf234650c8b..532c11b86e4 100644 --- a/erpnext/selling/doctype/customer/customer_dashboard.py +++ b/erpnext/selling/doctype/customer/customer_dashboard.py @@ -33,7 +33,7 @@ def get_data(): }, { 'label': _('Support'), - 'items': ['Issue', 'Maintenance Visit'] + 'items': ['Issue', 'Maintenance Visit', 'Installation Note', 'Warranty Claim'] }, { 'label': _('Projects'), From ead2f6abf0a8d11700ad16f022abdd99273666c1 Mon Sep 17 00:00:00 2001 From: michellealva Date: Thu, 27 Aug 2020 13:57:15 +0530 Subject: [PATCH 08/16] fix: Chage fiedtype of Customer's PO in Sales Invoice --- erpnext/accounts/doctype/sales_invoice/sales_invoice.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 31613e50b04..2397b7d0cb4 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -447,7 +447,7 @@ { "allow_on_submit": 1, "fieldname": "po_no", - "fieldtype": "Small Text", + "fieldtype": "Data", "hide_days": 1, "hide_seconds": 1, "label": "Customer's Purchase Order", @@ -1946,7 +1946,7 @@ "idx": 181, "is_submittable": 1, "links": [], - "modified": "2020-08-03 23:31:12.675040", + "modified": "2020-08-27 01:56:28.532140", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", From c8eea556d178607f2b4f09f1b683c64eed7f2bfc Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 27 Aug 2020 18:54:25 +0530 Subject: [PATCH 09/16] fix: BOM Update Tool failing due to Too Many Writes error --- .../manufacturing/doctype/bom_update_tool/bom_update_tool.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py index e6c10ad12b0..742d18c4cda 100644 --- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py +++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py @@ -90,6 +90,7 @@ def update_latest_price_in_all_boms(): update_cost() def replace_bom(args): + frappe.db.auto_commit_on_many_writes = 1 args = frappe._dict(args) doc = frappe.get_doc("BOM Update Tool") @@ -97,6 +98,8 @@ def replace_bom(args): doc.new_bom = args.new_bom doc.replace_bom() + frappe.db.auto_commit_on_many_writes = 0 + def update_cost(): frappe.db.auto_commit_on_many_writes = 1 bom_list = get_boms_in_bottom_up_order() From 33f984c7af1f6b140b8306f0c8d5ee690bdf4805 Mon Sep 17 00:00:00 2001 From: bhavesh95863 <34086262+bhavesh95863@users.noreply.github.com> Date: Thu, 27 Aug 2020 21:49:21 +0530 Subject: [PATCH 10/16] fix: can't multiply sequence by non-int of type 'float --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index c23a6ad58f9..62fc4163e15 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -356,7 +356,7 @@ erpnext.PointOfSale.ItemCart = class { onchange: function() { if (this.value || this.value == 0) { const frm = me.events.get_frm(); - frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', this.value); + frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', parseFloat(this.value)); me.hide_discount_control(this.value); } }, @@ -948,4 +948,4 @@ erpnext.PointOfSale.ItemCart = class { show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none'); } -} \ No newline at end of file +} From 3e9f493f15b05c364a6a2df11b11113899d0006c Mon Sep 17 00:00:00 2001 From: bhavesh95863 <34086262+bhavesh95863@users.noreply.github.com> Date: Fri, 28 Aug 2020 11:15:02 +0530 Subject: [PATCH 11/16] fix: change parseFloat to flt --- erpnext/selling/page/point_of_sale/pos_item_cart.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js index 62fc4163e15..eadeb8fde88 100644 --- a/erpnext/selling/page/point_of_sale/pos_item_cart.js +++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js @@ -356,7 +356,7 @@ erpnext.PointOfSale.ItemCart = class { onchange: function() { if (this.value || this.value == 0) { const frm = me.events.get_frm(); - frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', parseFloat(this.value)); + frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', flt(this.value)); me.hide_discount_control(this.value); } }, From 6887382937874ee962336c43674acf715852cce8 Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Fri, 28 Aug 2020 11:52:00 +0530 Subject: [PATCH 12/16] fix: Ignore cpmpany and bank account doctype while deleting company transactions (#22953) --- erpnext/setup/doctype/company/delete_company_transactions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py index 8ecc13b2fb7..c94831ef937 100644 --- a/erpnext/setup/doctype/company/delete_company_transactions.py +++ b/erpnext/setup/doctype/company/delete_company_transactions.py @@ -26,7 +26,8 @@ def delete_company_transactions(company_name): tabDocField where fieldtype='Link' and options='Company'"""): if doctype not in ("Account", "Cost Center", "Warehouse", "Budget", "Party Account", "Employee", "Sales Taxes and Charges Template", - "Purchase Taxes and Charges Template", "POS Profile", 'BOM'): + "Purchase Taxes and Charges Template", "POS Profile", "BOM", + "Company", "Bank Account"): delete_for_doctype(doctype, company_name) # reset company values From e9274283bd27415bfb410d5b1991730ea147272d Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 28 Aug 2020 12:21:10 +0530 Subject: [PATCH 13/16] fix: Raise Error on over receipt/consumption for sub-contrcated PR --- erpnext/controllers/buying_controller.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index f982700c01b..ac567b7deae 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -276,6 +276,9 @@ class BuyingController(StockController): qty_to_be_received_map = get_qty_to_be_received(purchase_orders) for item in self.get('items'): + if not item.purchase_order: + continue + # reset raw_material cost item.rm_supp_cost = 0 @@ -288,6 +291,12 @@ class BuyingController(StockController): fg_yet_to_be_received = qty_to_be_received_map.get(item_key) + if not fg_yet_to_be_received: + frappe.throw(_("Row #{0}: Item {1} is already fully received in Purchase Order {2}") + .format(item.idx, frappe.bold(item.item_code), + frappe.utils.get_link_to_form("Purchase Order", item.purchase_order)), + title=_("Limit Crossed")) + transferred_batch_qty_map = get_transferred_batch_qty_map(item.purchase_order, item.item_code) backflushed_batch_qty_map = get_backflushed_batch_qty_map(item.purchase_order, item.item_code) From 731bae170e58da232972f621d9436b397c909411 Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 28 Aug 2020 14:09:02 +0530 Subject: [PATCH 14/16] fix: Test for Over Receipt via PRs on a PO --- .../purchase_receipt/test_purchase_receipt.py | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 4a8236dd111..67161aa6dd9 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import unittest +import json import frappe, erpnext import frappe.defaults from frappe.utils import cint, flt, cstr, today, random_string @@ -152,13 +153,78 @@ class TestPurchaseReceipt(unittest.TestCase): qty=100, basic_rate=100, company="_Test Company with perpetual inventory") pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=0, is_subcontracted="Yes", company="_Test Company with perpetual inventory", warehouse='Stores - TCP1', supplier_warehouse='Work In Progress - TCP1') - + gl_entries = get_gl_entries("Purchase Receipt", pr.name) self.assertFalse(gl_entries) set_perpetual_inventory(0) + def test_subcontracting_over_receipt(self): + """ + Behaviour: Raise multiple PRs against one PO that in total + receive more than the required qty in the PO. + Expected Result: Error Raised for Over Receipt against PO. + """ + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry + from erpnext.buying.doctype.purchase_order.test_purchase_order import (update_backflush_based_on, + make_subcontracted_item, create_purchase_order) + from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, + make_rm_stock_entry as make_subcontract_transfer_entry) + + update_backflush_based_on("Material Transferred for Subcontract") + item_code = "_Test Subcontracted FG Item 1" + make_subcontracted_item(item_code) + + po = create_purchase_order(item_code=item_code, qty=1, + is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") + + #stock raw materials in a warehouse before transfer + make_stock_entry(target="_Test Warehouse - _TC", + item_code="_Test Item Home Desktop 100", qty=1, basic_rate=100) + make_stock_entry(target="_Test Warehouse - _TC", + item_code = "Test Extra Item 1", qty=1, basic_rate=100) + make_stock_entry(target="_Test Warehouse - _TC", + item_code = "_Test Item", qty=1, basic_rate=100) + + rm_items = [ + { + "item_code": item_code, + "rm_item_code": po.supplied_items[0].rm_item_code, + "item_name": "_Test Item", + "qty": po.supplied_items[0].required_qty, + "warehouse": "_Test Warehouse - _TC", + "stock_uom": "Nos" + }, + { + "item_code": item_code, + "rm_item_code": po.supplied_items[1].rm_item_code, + "item_name": "Test Extra Item 1", + "qty": po.supplied_items[1].required_qty, + "warehouse": "_Test Warehouse - _TC", + "stock_uom": "Nos" + }, + { + "item_code": item_code, + "rm_item_code": po.supplied_items[2].rm_item_code, + "item_name": "_Test Item Home Desktop 100", + "qty": po.supplied_items[2].required_qty, + "warehouse": "_Test Warehouse - _TC", + "stock_uom": "Nos" + } + ] + rm_item_string = json.dumps(rm_items) + se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string)) + se.to_warehouse = "_Test Warehouse 1 - _TC" + se.save() + se.submit() + + pr1 = make_purchase_receipt(po.name) + pr2 = make_purchase_receipt(po.name) + + pr1.submit() + self.assertRaises(frappe.ValidationError, pr2.submit) + def test_serial_no_supplier(self): pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1) self.assertEqual(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"), From b23840bf7b668971364ac05cb2425d396b617dd5 Mon Sep 17 00:00:00 2001 From: Syed Mujeer Hashmi Date: Sat, 29 Aug 2020 12:48:48 +0530 Subject: [PATCH 15/16] fix: Filter out cancelled entries in customer ledger summary Signed-off-by: Syed Mujeer Hashmi --- .../report/customer_ledger_summary/customer_ledger_summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py index 2cb10b11e1b..10b32fea562 100644 --- a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py +++ b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py @@ -173,7 +173,7 @@ class PartyLedgerSummaryReport(object): from `tabGL Entry` gle {join} where - gle.docstatus < 2 and gle.party_type=%(party_type)s and ifnull(gle.party, '') != '' + gle.docstatus < 2 and gle.is_cancelled = 0 and gle.party_type=%(party_type)s and ifnull(gle.party, '') != '' and gle.posting_date <= %(to_date)s {conditions} order by gle.posting_date """.format(join=join, join_field=join_field, conditions=conditions), self.filters, as_dict=True) @@ -248,7 +248,7 @@ class PartyLedgerSummaryReport(object): from `tabGL Entry` where - docstatus < 2 + docstatus < 2 and is_cancelled = 0 and (voucher_type, voucher_no) in ( select voucher_type, voucher_no from `tabGL Entry` gle, `tabAccount` acc where acc.name = gle.account and acc.account_type = '{income_or_expense}' From e268d294b3390daad2a6031db22bdc264a3fda53 Mon Sep 17 00:00:00 2001 From: marination Date: Sun, 30 Aug 2020 21:01:34 +0530 Subject: [PATCH 16/16] fix: Better error feedback on creating SO from Quotation --- erpnext/selling/doctype/quotation/quotation.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index ab095ebfe08..20ae19f5dbe 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -285,9 +285,17 @@ def _make_customer(source_name, ignore_permissions=False): return customer else: raise - except frappe.MandatoryError: + except frappe.MandatoryError as e: + mandatory_fields = e.args[0].split(':')[1].split(',') + mandatory_fields = [customer.meta.get_label(field.strip()) for field in mandatory_fields] + frappe.local.message_log = [] - frappe.throw(_("Please create Customer from Lead {0}").format(lead_name)) + lead_link = frappe.utils.get_link_to_form("Lead", lead_name) + message = _("Could not auto create Customer due to the following missing mandatory field(s):") + "
    " + message += "
    • " + "
    • ".join(mandatory_fields) + "
    " + message += _("Please create Customer from Lead {0}.").format(lead_link) + + frappe.throw(message, title=_("Mandatory Missing")) else: return customer_name else: