From e9f2ab5caf90237dad9a31db713d566712c4b84f Mon Sep 17 00:00:00 2001 From: Ashish Shah Date: Wed, 10 May 2023 10:51:20 +0530 Subject: [PATCH 01/12] refactor: use 'flt' for base_total_taxes_and_charges difference_amount calculation is broken, as calculation gives NaN. Fix is make frm.doc.base_total_taxes_and_charges as flt(frm.doc.base_total_taxes_and_charges) (cherry picked from commit ae4e56747c63f0335259cb0949ae1d429d2de2a0) --- erpnext/accounts/doctype/payment_entry/payment_entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 969027dd97c..cc72c313238 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -905,7 +905,7 @@ frappe.ui.form.on('Payment Entry', { function(d) { return flt(d.amount) })); frm.set_value("difference_amount", difference_amount - total_deductions + - frm.doc.base_total_taxes_and_charges); + flt(frm.doc.base_total_taxes_and_charges)); frm.events.hide_unhide_fields(frm); }, From aa7fede0dc92509394b2f5d8643b604df315f033 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Tue, 16 May 2023 15:12:47 +0530 Subject: [PATCH 02/12] fix(ux): SCR consumed-qty read-only property (cherry picked from commit adf2474d9ded01ed89aedddd1fd3da3514cd68b0) --- .../subcontracting_receipt.js | 18 ++++-------------- .../subcontracting_receipt.py | 8 ++++++++ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js index 45289b1dab5..4bf008ac406 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js @@ -76,26 +76,14 @@ frappe.ui.form.on('Subcontracting Receipt', { } }); - let batch_no_field = frm.get_docfield("items", "batch_no"); + let batch_no_field = frm.get_docfield('items', 'batch_no'); if (batch_no_field) { batch_no_field.get_route_options_for_new_doc = function(row) { return { - "item": row.doc.item_code + 'item': row.doc.item_code } }; } - - frappe.db.get_single_value('Buying Settings', 'backflush_raw_materials_of_subcontract_based_on').then(val => { - if (val == 'Material Transferred for Subcontract') { - frm.fields_dict['supplied_items'].grid.grid_rows.forEach((grid_row) => { - grid_row.docfields.forEach((df) => { - if (df.fieldname == 'consumed_qty') { - df.read_only = 0; - } - }); - }); - } - }); }, refresh: (frm) => { @@ -157,6 +145,8 @@ frappe.ui.form.on('Subcontracting Receipt', { } }); }, __('Get Items From')); + + frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty', 'read_only', frm.doc.__onload && frm.doc.__onload.backflush_based_on === 'BOM'); } }, diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index 2c842622730..416f4f80a21 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -28,6 +28,14 @@ class SubcontractingReceipt(SubcontractingController): }, ] + def onload(self): + self.set_onload( + "backflush_based_on", + frappe.db.get_single_value( + "Buying Settings", "backflush_raw_materials_of_subcontract_based_on" + ), + ) + def update_status_updater_args(self): if cint(self.is_return): self.status_updater.extend( From 15c1af3d8a44ad25b1d681cfe30de75faf1c10bd Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 16:17:21 +0530 Subject: [PATCH 03/12] fix: consider 0 if rate/qty are null (backport #35338) (#35340) fix: consider 0 if rate/qty are null (#35338) [skip ci] (cherry picked from commit e5c86bc2e82202522bd803f66dc1bdc00f8e4432) Co-authored-by: Ankush Menat --- .../patches/v13_0/update_amt_in_work_order_required_items.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/patches/v13_0/update_amt_in_work_order_required_items.py b/erpnext/patches/v13_0/update_amt_in_work_order_required_items.py index e37f291233e..64170edb718 100644 --- a/erpnext/patches/v13_0/update_amt_in_work_order_required_items.py +++ b/erpnext/patches/v13_0/update_amt_in_work_order_required_items.py @@ -7,4 +7,6 @@ def execute(): frappe.reload_doc("manufacturing", "doctype", "work_order") frappe.reload_doc("manufacturing", "doctype", "work_order_item") - frappe.db.sql("""UPDATE `tabWork Order Item` SET amount = rate * required_qty""") + frappe.db.sql( + """UPDATE `tabWork Order Item` SET amount = ifnull(rate, 0.0) * ifnull(required_qty, 0.0)""" + ) From 48884366ea6ca177813f2101a6347e0c2237d9f3 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Thu, 11 May 2023 12:47:47 +0530 Subject: [PATCH 04/12] fix: Pick List Status (cherry picked from commit 9fb8b1827daa126087d3e237d135a96e73841e70) --- erpnext/stock/doctype/pick_list/pick_list.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index 46d6e9e7578..74927c779cc 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -29,6 +29,7 @@ class PickList(Document): self.validate_for_qty() def before_save(self): + self.update_status() self.set_item_locations() # set percentage picked in SO @@ -89,20 +90,20 @@ class PickList(Document): self.update_reference_qty() self.update_sales_order_picking_status() - def update_status(self, status=None, update_modified=True): + def update_status(self, status=None): if not status: if self.docstatus == 0: status = "Draft" elif self.docstatus == 1: - if self.status == "Draft": - status = "Open" - elif target_document_exists(self.name, self.purpose): + if target_document_exists(self.name, self.purpose): status = "Completed" + else: + status = "Open" elif self.docstatus == 2: status = "Cancelled" if status: - frappe.db.set_value("Pick List", self.name, "status", status, update_modified=update_modified) + self.db_set("status", status) def update_reference_qty(self): packed_items = [] From 0a080efce26e99198a326009caa5d353a8fae862 Mon Sep 17 00:00:00 2001 From: Anand Baburajan Date: Wed, 17 May 2023 22:21:00 +0530 Subject: [PATCH 05/12] fix: depreciation schedule for existing assets [v14] (#35255) * fix: depreciation schedule for existing assets * chore: correct logic for existing assets and fix test --- erpnext/assets/doctype/asset/asset.py | 10 ++++++---- erpnext/assets/doctype/asset/test_asset.py | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index fe1fd98aa09..39e65a7b97b 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -425,7 +425,7 @@ class Asset(AccountsController): depreciation_amount += value_after_depreciation - finance_book.expected_value_after_useful_life skip_row = True - if depreciation_amount > 0: + if flt(depreciation_amount, self.precision("gross_purchase_amount")) > 0: self._add_depreciation_row( schedule_date, depreciation_amount, @@ -1287,9 +1287,11 @@ def get_straight_line_or_manual_depr_amount(asset, row): ) # if the Depreciation Schedule is being prepared for the first time else: - return (flt(asset.gross_purchase_amount) - flt(row.expected_value_after_useful_life)) / flt( - row.total_number_of_depreciations - ) + return ( + flt(asset.gross_purchase_amount) + - flt(asset.opening_accumulated_depreciation) + - flt(row.expected_value_after_useful_life) + ) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked) def get_wdv_or_dd_depr_amount( diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 8a1df6f71ce..1968154383d 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -649,7 +649,7 @@ class TestDepreciationMethods(AssetSetup): ) self.assertEqual(asset.status, "Draft") - expected_schedules = [["2032-12-31", 30000.0, 77095.89], ["2033-06-06", 12904.11, 90000.0]] + expected_schedules = [["2032-12-31", 42904.11, 90000.0]] schedules = [ [cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount] for d in asset.get("schedules") From 2631224e497d173684c25eb683ac3c86539b2ac3 Mon Sep 17 00:00:00 2001 From: vishnu Date: Sun, 14 May 2023 09:35:38 +0000 Subject: [PATCH 06/12] fix: Creating landed cost voucher from connections (cherry picked from commit f2ceb003797332cb6c1fee7a5c3e67a2b2b8e3d1) --- erpnext/public/js/controllers/accounts.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js index d943126018a..47b88a002bc 100644 --- a/erpnext/public/js/controllers/accounts.js +++ b/erpnext/public/js/controllers/accounts.js @@ -91,6 +91,12 @@ frappe.ui.form.on("Sales Invoice", { }); frappe.ui.form.on('Purchase Invoice', { + setup: (frm) => { + frm.make_methods = { + 'Landed Cost Voucher': function () { frm.trigger('create_landedcost_voucher') }, + } + }, + mode_of_payment: function(frm) { get_payment_mode_account(frm, frm.doc.mode_of_payment, function(account){ frm.set_value('cash_bank_account', account); @@ -99,6 +105,20 @@ frappe.ui.form.on('Purchase Invoice', { payment_terms_template: function() { cur_frm.trigger("disable_due_date"); + }, + + create_landedcost_voucher: function (frm) { + let lcv = frappe.model.get_new_doc('Landed Cost Voucher'); + lcv.company = frm.doc.company; + + let lcv_receipt = frappe.model.get_new_doc('Landed Cost Purchase Invoice'); + lcv_receipt.receipt_document_type = 'Purchase Invoice'; + lcv_receipt.receipt_document = frm.doc.name; + lcv_receipt.supplier = frm.doc.supplier; + lcv_receipt.grand_total = frm.doc.grand_total; + lcv.purchase_receipts = [lcv_receipt]; + + frappe.set_route("Form", lcv.doctype, lcv.name); } }); From bdf81a43c646703d05dc0a720fa0078331a03142 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 17 May 2023 13:40:33 +0530 Subject: [PATCH 07/12] fix: tds incorrectly calculated for invoice that are below threshold Two purchase invoices for the same supplier, using different tax withholding categories have this issue. | Category | single | cumulative | |----------+--------+------------| | cat1 | 100 | 500 | | cat2 | 1000 | 5000 | 1. PINV1 of net total: 105/- uses cat1. TDS is calculated as it breached single threshold 2. PINV2 of net total: 200/- uses cat2. TDS incorrectly calculated as PINV1 already has TDS calculated and 'consider_party_ledger_amount' is enabled. (cherry picked from commit 84b7c1bba09f89a390a17898b4d8fa665adcbc8f) --- .../tax_withholding_category/tax_withholding_category.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py index ad3477ef3d3..1f2d9803739 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py @@ -302,7 +302,7 @@ def get_invoice_vouchers(parties, tax_details, company, party_type="Supplier"): "docstatus": 1, } - if not tax_details.get("consider_party_ledger_amount") and doctype != "Sales Invoice": + if doctype != "Sales Invoice": filters.update( {"apply_tds": 1, "tax_withholding_category": tax_details.get("tax_withholding_category")} ) From 879946e2c80de336fd81a063c5699cce48d7ca10 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 18 May 2023 12:00:59 +0530 Subject: [PATCH 08/12] fix(test): cumulative threshold checks (cherry picked from commit 132846bbd107a921dfbfde9240f368bea9382cf7) --- .../test_tax_withholding_category.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py index 1e86cf5d2ef..bc4f6709fca 100644 --- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py +++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py @@ -110,9 +110,9 @@ class TestTaxWithholdingCategory(unittest.TestCase): invoices.append(pi1) # Cumulative threshold is 30000 - # Threshold calculation should be on both the invoices - # TDS should be applied only on 1000 - self.assertEqual(pi1.taxes[0].tax_amount, 1000) + # Threshold calculation should be only on the Second invoice + # Second didn't breach, no TDS should be applied + self.assertEqual(pi1.taxes, []) for d in reversed(invoices): d.cancel() From d23b93a46246499ac07b4ccadfe8330a9b86157a Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 18 May 2023 12:47:38 +0530 Subject: [PATCH 09/12] fix: possible type error on quotation -> sales order creation (cherry picked from commit b2290c6f57cfe8a9ddade44f673039a4600313c9) --- erpnext/selling/doctype/quotation/quotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 693fc92ce93..61969fe8a91 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -288,7 +288,7 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False): ) # sales team - for d in customer.get("sales_team"): + for d in customer.get("sales_team") or []: target.append( "sales_team", { From 3a0cdf30ce0e841f5867a4022d99bda85a2afcc5 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 19 May 2023 18:53:40 +0530 Subject: [PATCH 10/12] feat: provision to make reposting entries from Stock and Account Value Comparison Report (cherry picked from commit 7b818e9d34c87ad2fd80493454bd86674ddb54c5) --- .../stock_and_account_value_comparison.js | 37 ++++++++++++++++++- .../stock_and_account_value_comparison.py | 33 +++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.js b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.js index 7a170beec37..50a78a82588 100644 --- a/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.js +++ b/erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.js @@ -33,5 +33,40 @@ frappe.query_reports["Stock and Account Value Comparison"] = { "fieldtype": "Date", "default": frappe.datetime.get_today(), }, - ] + ], + + get_datatable_options(options) { + return Object.assign(options, { + checkboxColumn: true, + }); + }, + + onload(report) { + report.page.add_inner_button(__("Create Reposting Entries"), function() { + let message = `
+

+ Reposting Entries will change the value of + accounts Stock In Hand, and Stock Expenses + in the Trial Balance report and will also change + the Balance Value in the Stock Balance report. +

+

Are you sure you want to create Reposting Entries?

+
+ `; + + frappe.confirm(__(message), () => { + let indexes = frappe.query_report.datatable.rowmanager.getCheckedRows(); + let selected_rows = indexes.map(i => frappe.query_report.data[i]); + + frappe.call({ + method: "erpnext.stock.report.stock_and_account_value_comparison.stock_and_account_value_comparison.create_reposting_entries", + args: { + rows: selected_rows, + company: frappe.query_report.get_filter_values().company + } + }); + + }); + }); + } }; 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 106e877c4cd..b1da3ec1bd1 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 @@ -4,6 +4,7 @@ import frappe from frappe import _ +from frappe.utils import get_link_to_form, parse_json import erpnext from erpnext.accounts.utils import get_currency_precision, get_stock_accounts @@ -134,3 +135,35 @@ def get_columns(filters): "width": "120", }, ] + + +@frappe.whitelist() +def create_reposting_entries(rows, company): + if isinstance(rows, str): + rows = parse_json(rows) + + entries = [] + for row in rows: + row = frappe._dict(row) + + try: + doc = frappe.get_doc( + { + "doctype": "Repost Item Valuation", + "based_on": "Transaction", + "status": "Queued", + "voucher_type": row.voucher_type, + "voucher_no": row.voucher_no, + "posting_date": row.posting_date, + "company": company, + "allow_nagative_stock": 1, + } + ).submit() + + entries.append(get_link_to_form("Repost Item Valuation", doc.name)) + except frappe.DuplicateEntryError: + pass + + if entries: + entries = ", ".join(entries) + frappe.msgprint(_(f"Reposting entries created: {entries}")) From abfd975eb6ff755f46b4879d6f962e49bf237ca7 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sat, 20 May 2023 19:45:59 +0530 Subject: [PATCH 11/12] chore: drop outdated navigation video new stuff is in work, this one is actually counter-productive rn. (cherry picked from commit ba61865ee647891f91d38b6a6cd4c2350a05962e) --- erpnext/setup/module_onboarding/home/home.json | 7 ++----- .../create_a_customer/create_a_customer.json | 2 +- .../create_a_supplier/create_a_supplier.json | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/erpnext/setup/module_onboarding/home/home.json b/erpnext/setup/module_onboarding/home/home.json index 516f12229c5..1fd96796cb2 100644 --- a/erpnext/setup/module_onboarding/home/home.json +++ b/erpnext/setup/module_onboarding/home/home.json @@ -25,15 +25,12 @@ "documentation_url": "https://docs.erpnext.com/docs/v14/user/manual/en/setting-up/company-setup", "idx": 0, "is_complete": 0, - "modified": "2023-05-16 13:13:24.043792", + "modified": "2023-05-20 19:45:03.936741", "modified_by": "Administrator", "module": "Setup", "name": "Home", "owner": "Administrator", "steps": [ - { - "step": "Navigation Help" - }, { "step": "Create an Item" }, @@ -47,7 +44,7 @@ "step": "Create a Quotation" } ], - "subtitle": "Item, Customer, Supplier, Navigation Help and Quotation", + "subtitle": "Item, Customer, Supplier and Quotation", "success_message": "You're ready to start your journey with ERPNext", "title": "Let's begin your journey with ERPNext" } \ No newline at end of file diff --git a/erpnext/setup/onboarding_step/create_a_customer/create_a_customer.json b/erpnext/setup/onboarding_step/create_a_customer/create_a_customer.json index e1a8f908663..5b0fd419c25 100644 --- a/erpnext/setup/onboarding_step/create_a_customer/create_a_customer.json +++ b/erpnext/setup/onboarding_step/create_a_customer/create_a_customer.json @@ -9,7 +9,7 @@ "is_complete": 0, "is_single": 0, "is_skipped": 0, - "modified": "2023-05-16 12:54:54.112364", + "modified": "2023-05-16 20:01:34.202622", "modified_by": "Administrator", "name": "Create a Customer", "owner": "Administrator", diff --git a/erpnext/setup/onboarding_step/create_a_supplier/create_a_supplier.json b/erpnext/setup/onboarding_step/create_a_supplier/create_a_supplier.json index ef493fe00d1..4ac26e2879c 100644 --- a/erpnext/setup/onboarding_step/create_a_supplier/create_a_supplier.json +++ b/erpnext/setup/onboarding_step/create_a_supplier/create_a_supplier.json @@ -9,7 +9,7 @@ "is_complete": 0, "is_single": 0, "is_skipped": 0, - "modified": "2023-05-16 12:55:08.610113", + "modified": "2023-05-19 15:32:55.069257", "modified_by": "Administrator", "name": "Create a Supplier", "owner": "Administrator", From 633a1703dcbfb54bab897259c023862791cfbff4 Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Sun, 21 May 2023 15:07:38 +0530 Subject: [PATCH 12/12] fix: don't recalculate rate for SCR rejected warehouse SLE (cherry picked from commit 57ee473fa40981ccb89acc91c608b6387a6b8278) --- erpnext/controllers/subcontracting_controller.py | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index c3fa894e895..1e9c4dc8478 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -689,7 +689,6 @@ class SubcontractingController(StockController): "actual_qty": flt(item.rejected_qty) * flt(item.conversion_factor), "serial_no": cstr(item.rejected_serial_no).strip(), "incoming_rate": 0.0, - "recalculate_rate": 1, }, ) )