From d6d8903d13e0011b34eda548bad249ec9ed66cf8 Mon Sep 17 00:00:00 2001 From: Assem Bahnasy Date: Thu, 14 Aug 2025 16:05:09 +0300 Subject: [PATCH 01/25] style: Apply ruff formatting --- erpnext/accounts/doctype/pricing_rule/utils.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index de63ec3a8c4..fde3b9e48dd 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -583,11 +583,7 @@ def apply_pricing_rule_on_transaction(doc): if not d.get(pr_field): continue - if ( - d.validate_applied_rule - and doc.get(field) is not None - and doc.get(field) < d.get(pr_field) - ): + if d.validate_applied_rule and (doc.get(field) or 0) < d.get(pr_field): frappe.msgprint(_("User has not applied rule on the invoice {0}").format(doc.name)) else: if not d.coupon_code_based: From 6a31b7b1182e87c1748c657589c01637f89e41f4 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Tue, 19 Aug 2025 14:29:59 +0200 Subject: [PATCH 02/25] fix: set missing due date in Purchase Invoice and POS Invoice (#49232) (cherry picked from commit 77478303fefbb7246c66c125278a267a73d01961) --- erpnext/accounts/doctype/pos_invoice/pos_invoice.py | 8 +++++++- .../accounts/doctype/purchase_invoice/purchase_invoice.py | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index 87360543efd..0196b2b6189 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -668,7 +668,13 @@ class POSInvoice(SalesInvoice): "Account", self.debit_to, "account_currency" ) if not self.due_date and self.customer: - self.due_date = get_due_date(self.posting_date, "Customer", self.customer, self.company) + self.due_date = get_due_date( + self.posting_date, + "Customer", + self.customer, + self.company, + template_name=self.payment_terms_template, + ) super(SalesInvoice, self).set_missing_values(for_validate) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 4f0d6a64c36..8be04ab67a1 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -340,7 +340,12 @@ class PurchaseInvoice(BuyingController): ) if not self.due_date: self.due_date = get_due_date( - self.posting_date, "Supplier", self.supplier, self.company, self.bill_date + self.posting_date, + "Supplier", + self.supplier, + self.company, + self.bill_date, + template_name=self.payment_terms_template, ) tds_category = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category") From 7bb180e5da334d3b2abcd0032907764cb42b4288 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 26 Aug 2025 12:43:47 +0530 Subject: [PATCH 03/25] fix: source warehouse in manufacture entry and reqd prop of scrap warehouse (cherry picked from commit fe0722c4f183cea687494f6681d7e042cf35a907) --- .../manufacturing/doctype/work_order/work_order.js | 14 ++++++++++++++ erpnext/stock/doctype/stock_entry/stock_entry.py | 11 ++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js index 92080c05baf..2f189ba4c46 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.js +++ b/erpnext/manufacturing/doctype/work_order/work_order.js @@ -116,6 +116,20 @@ frappe.ui.form.on("Work Order", { frm.set_indicator_formatter("operation", function (doc) { return frm.doc.qty == doc.completed_qty ? "green" : "orange"; }); + + if (frm.doc.docstatus == 0 && frm.doc.bom_no) { + frappe.call({ + method: "erpnext.manufacturing.doctype.work_order.work_order.check_if_scrap_warehouse_mandatory", + args: { + bom_no: frm.doc.bom_no, + }, + callback: function (r) { + if (r.message["set_scrap_wh_mandatory"]) { + frm.toggle_reqd("scrap_warehouse", true); + } + }, + }); + } }, onload: function (frm) { diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index a1260c5ffdd..0d1175b2fe0 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -2123,7 +2123,16 @@ class StockEntry(StockController): "Work Order", self.work_order, "allow_alternative_item" ) - item.from_warehouse = self.from_warehouse or item.source_warehouse or item.default_warehouse + item.from_warehouse = ( + frappe.get_value( + "Work Order Item", + {"parent": self.work_order, "item_code": item.item_code}, + "source_warehouse", + ) + if frappe.get_value("Work Order", self.work_order, "skip_transfer") + and not frappe.get_value("Work Order", self.work_order, "from_wip_warehouse") + else self.from_warehouse or item.source_warehouse or item.default_warehouse + ) if item.item_code in used_alternative_items: alternative_item_data = used_alternative_items.get(item.item_code) item.item_code = alternative_item_data.item_code From 7926cfd8c408214c95ab63a7ad2bdf332988c539 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 14:13:39 +0200 Subject: [PATCH 04/25] fix: add option to disable Transaction Log (backport #49342) (#49344) Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com> fix: add option to disable Transaction Log (#49342) --- erpnext/regional/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/regional/__init__.py b/erpnext/regional/__init__.py index bd5d5401035..e2c791071af 100644 --- a/erpnext/regional/__init__.py +++ b/erpnext/regional/__init__.py @@ -19,6 +19,9 @@ def create_transaction_log(doc, method): Appends the transaction to a chain of hashed logs for legal resons. Called on submit of Sales Invoice and Payment Entry. """ + if frappe.conf.get("disable_transaction_log", False): + return + region = get_region() if region not in ["Germany"]: return From c875ff972f4596b1ed0c1160de51969e5544d4a6 Mon Sep 17 00:00:00 2001 From: 0xD0M1M0 <76812428+0xD0M1M0@users.noreply.github.com> Date: Wed, 27 Aug 2025 18:31:54 +0200 Subject: [PATCH 05/25] feat: optional fixed outgoing email for RfQ (#49258) * feat: optional fixed outgoing email for RfQ * fix: linters * fix: select only outgoing account * fix: linters (cherry picked from commit 2bf0ba9802a02f3bece8f88207c0704725e63910) --- .../buying_settings/buying_settings.json | 19 +++++++++++++++++-- .../buying_settings/buying_settings.py | 1 + .../request_for_quotation.py | 6 +++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.json b/erpnext/buying/doctype/buying_settings/buying_settings.json index 9a2d07dbec2..170a68fb394 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.json +++ b/erpnext/buying/doctype/buying_settings/buying_settings.json @@ -39,7 +39,9 @@ "section_break_xcug", "auto_create_subcontracting_order", "column_break_izrr", - "auto_create_purchase_receipt" + "auto_create_purchase_receipt", + "request_for_quotation_tab", + "fixed_email" ], "fields": [ { @@ -255,6 +257,19 @@ "fieldname": "set_valuation_rate_for_rejected_materials", "fieldtype": "Check", "label": "Set Valuation Rate for Rejected Materials" + }, + { + "fieldname": "request_for_quotation_tab", + "fieldtype": "Tab Break", + "label": "Request for Quotation" + }, + { + "description": "If set, the system does not use the user's Email or the standard outgoing Email account for sending request for quotations.", + "fieldname": "fixed_email", + "fieldtype": "Link", + "label": "Fixed Outgoing Email Account", + "link_filters": "[[\"Email Account\",\"enable_outgoing\",\"=\",1]]", + "options": "Email Account" } ], "grid_page_length": 50, @@ -263,7 +278,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2025-05-16 15:56:38.321369", + "modified": "2025-08-20 22:13:38.506889", "modified_by": "Administrator", "module": "Buying", "name": "Buying Settings", diff --git a/erpnext/buying/doctype/buying_settings/buying_settings.py b/erpnext/buying/doctype/buying_settings/buying_settings.py index f3b3dbefff4..8b83418f6f8 100644 --- a/erpnext/buying/doctype/buying_settings/buying_settings.py +++ b/erpnext/buying/doctype/buying_settings/buying_settings.py @@ -30,6 +30,7 @@ class BuyingSettings(Document): blanket_order_allowance: DF.Float buying_price_list: DF.Link | None disable_last_purchase_rate: DF.Check + fixed_email: DF.Link | None maintain_same_rate: DF.Check maintain_same_rate_action: DF.Literal["Stop", "Warn"] over_transfer_allowance: DF.Float diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py index d11424b555f..e8c5690cf6f 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -289,7 +289,11 @@ class RequestforQuotation(BuyingController): email_template = frappe.get_doc("Email Template", self.email_template) message = frappe.render_template(email_template.response_, doc_args) subject = frappe.render_template(email_template.subject, doc_args) - sender = frappe.session.user not in STANDARD_USERS and frappe.session.user or None + fixed_procurement_email = frappe.db.get_single_value("Buying Settings", "fixed_email") + if fixed_procurement_email: + sender = frappe.db.get_value("Email Account", fixed_procurement_email, "email_id") + else: + sender = frappe.session.user not in STANDARD_USERS and frappe.session.user or None if preview: return {"message": message, "subject": subject} From 0b3fac3a0e9b98d0a3ac2a4cb5dedaf6864b76d1 Mon Sep 17 00:00:00 2001 From: "El-Shafei H." Date: Wed, 20 Aug 2025 10:15:27 +0300 Subject: [PATCH 06/25] fix: convert NaN to numerical (cherry picked from commit fac8013dba8d2302f37e9bc95bfc3c3f3042df50) --- erpnext/public/js/bank_reconciliation_tool/number_card.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/bank_reconciliation_tool/number_card.js b/erpnext/public/js/bank_reconciliation_tool/number_card.js index d39884c381e..381d94ed785 100644 --- a/erpnext/public/js/bank_reconciliation_tool/number_card.js +++ b/erpnext/public/js/bank_reconciliation_tool/number_card.js @@ -26,7 +26,7 @@ erpnext.accounts.bank_reconciliation.NumberCardManager = class NumberCardManager currency: this.currency, }, { - value: this.bank_statement_closing_balance - this.cleared_balance, + value: flt(this.bank_statement_closing_balance) - flt(this.cleared_balance), label: __("Difference"), datatype: "Currency", currency: this.currency, From caa1681c5fc556836eca5b0d7fc6bf35e26e5317 Mon Sep 17 00:00:00 2001 From: anwarpatelnoori Date: Wed, 20 Aug 2025 14:18:35 +0000 Subject: [PATCH 07/25] fix: show create purchase receipt button only when update stock is not checked (cherry picked from commit ed550bb63382a97cbbd55d5c90d361a61c26a529) --- erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 17fad2eca43..ad367f3c9cb 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -644,7 +644,7 @@ frappe.ui.form.on("Purchase Invoice", { }, add_custom_buttons: function (frm) { - if (frm.doc.docstatus == 1 && frm.doc.per_received < 100) { + if (frm.doc.docstatus == 1 && frm.doc.per_received < 100 && frm.doc.update_stock == 0) { frm.add_custom_button( __("Purchase Receipt"), () => { From 064ce4bf6d933d6e803d0980ce2274402a22a458 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 16:51:19 +0000 Subject: [PATCH 08/25] fix: hide is_cumulative for apply_on is set to Transaction (backport #49243) (#49257) * fix: hide is_cumulative for apply_on is set to Transaction (cherry picked from commit 699d42b26c77166dc11d1d5e499f1c5f51d447fa) # Conflicts: # erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json * chore: update modified date for promotional_scheme.json --------- Co-authored-by: Navin-S-R Co-authored-by: Mihir Kandoi --- erpnext/accounts/doctype/pricing_rule/pricing_rule.json | 3 ++- .../doctype/promotional_scheme/promotional_scheme.json | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json index c4825a6d519..7a5c6d7713b 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json @@ -174,6 +174,7 @@ }, { "default": "0", + "depends_on": "eval:doc.apply_on != 'Transaction'", "fieldname": "is_cumulative", "fieldtype": "Check", "label": "Is Cumulative" @@ -656,7 +657,7 @@ "icon": "fa fa-gift", "idx": 1, "links": [], - "modified": "2025-02-17 18:15:39.824639", + "modified": "2025-08-20 11:40:07.096854", "modified_by": "Administrator", "module": "Accounts", "name": "Pricing Rule", diff --git a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json index 1d68b23d6c7..c55b0a7d7ff 100644 --- a/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json +++ b/erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json @@ -93,12 +93,14 @@ }, { "default": "0", + "depends_on": "eval:doc.apply_on != 'Transaction'", "fieldname": "mixed_conditions", "fieldtype": "Check", "label": "Mixed Conditions" }, { "default": "0", + "depends_on": "eval:doc.apply_on != 'Transaction'", "fieldname": "is_cumulative", "fieldtype": "Check", "label": "Is Cumulative" @@ -278,7 +280,7 @@ } ], "links": [], - "modified": "2021-05-06 16:20:22.039078", + "modified": "2025-08-20 11:48:23.231081", "modified_by": "Administrator", "module": "Accounts", "name": "Promotional Scheme", @@ -336,4 +338,4 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 1 -} \ No newline at end of file +} From 17f7351f8534ccf14b0b02ad39657beea8403980 Mon Sep 17 00:00:00 2001 From: Imesha Sudasingha Date: Thu, 28 Aug 2025 01:48:21 +0530 Subject: [PATCH 09/25] fix: remove defunct payment gateway links from ERPNext Integrations workspace - Remove GoCardless Settings link (DocType deleted in v15.0) - Remove Mpesa Settings link (DocType deleted in v15.0) - Update Payments card link_count from 3 to 1 - Only Plaid Settings remains in Payments section Fixes broken links that resulted in errors when clicked. Closes #49352 --- .../erpnext_integrations.json | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json b/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json index 510317f5c2e..6b236f2cc60 100644 --- a/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json +++ b/erpnext/erpnext_integrations/workspace/erpnext_integrations/erpnext_integrations.json @@ -188,30 +188,10 @@ "hidden": 0, "is_query_report": 0, "label": "Payments", - "link_count": 3, + "link_count": 1, "onboard": 0, "type": "Card Break" }, - { - "hidden": 0, - "is_query_report": 0, - "label": "GoCardless Settings", - "link_count": 0, - "link_to": "GoCardless Settings", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, - { - "hidden": 0, - "is_query_report": 0, - "label": "Mpesa Settings", - "link_count": 0, - "link_to": "Mpesa Settings", - "link_type": "DocType", - "onboard": 0, - "type": "Link" - }, { "hidden": 0, "is_query_report": 0, From c06f72f9f7885be13cc173362349b381b882f2c4 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 28 Aug 2025 23:42:35 +0530 Subject: [PATCH 10/25] =?UTF-8?q?fix:=20:bug:=20fixing=20buying=20controll?= =?UTF-8?q?er=20to=20include=20transaction=20controller=E2=80=A6=20(backpo?= =?UTF-8?q?rt=20#49140)=20(#49370)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: :bug: fixing buying controller to include transaction controller… (#49140) * fix: :bug: fixing buying controller to include transaction controller function * refactor: fixed formatting --------- Co-authored-by: Mihir Kandoi (cherry picked from commit aedb171dd4d3b30d419f94c80ac5ef4555cf3ea8) # Conflicts: # erpnext/public/js/controllers/buying.js * chore: resolve conflicts --------- Co-authored-by: jll-02 <63648645+jll-02@users.noreply.github.com> Co-authored-by: Mihir Kandoi --- erpnext/public/js/controllers/buying.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index a1675be8954..e7ee7d505a1 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -159,8 +159,9 @@ erpnext.buying = { }); } - company(){ - if(!frappe.meta.has_field(this.frm.doc.doctype, "billing_address")) return; + company() { + super.company(); + if (!frappe.meta.has_field(this.frm.doc.doctype, "billing_address")) return; frappe.call({ method: "erpnext.setup.doctype.company.company.get_billing_shipping_address", From e8025365cdd5ac35ac090a96266f6d20f7b5d981 Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Fri, 29 Aug 2025 14:55:49 +0530 Subject: [PATCH 11/25] fix(repost item valuation): reorder function call (cherry picked from commit aaa4f0ae26e2f503a3714f4e14322b51d2f909ce) --- .../repost_item_valuation.js | 15 +++++++++++++++ .../repost_item_valuation.py | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js index 6f2548ac8ea..7b7c2e69cce 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js @@ -132,4 +132,19 @@ frappe.ui.form.on("Repost Item Valuation", { }, }); }, + + voucher_type: function (frm) { + console.log(frm.doc); + frm.trigger("set_company_on_transaction"); + }, + + voucher_no: function (frm) { + frm.trigger("set_company_on_transaction"); + }, + + set_company_on_transaction(frm) { + if (frm.doc.voucher_no && frm.doc.voucher_no) { + frm.call("set_company"); + } + }, }); diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index 06598aa285b..303f28252d8 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -70,10 +70,10 @@ class RepostItemValuation(Document): ) def validate(self): + self.set_company() self.validate_period_closing_voucher() self.set_status(write=False) self.reset_field_values() - self.set_company() self.validate_accounts_freeze() self.reset_recreate_stock_ledgers() @@ -167,6 +167,7 @@ class RepostItemValuation(Document): def on_trash(self): self.clear_attachment() + @frappe.whitelist() def set_company(self): if self.based_on == "Transaction": self.company = frappe.get_cached_value(self.voucher_type, self.voucher_no, "company") From f43ed2e50e96dce6a804ffeae2c8b4186b1c53a3 Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Fri, 29 Aug 2025 15:31:47 +0530 Subject: [PATCH 12/25] chore: remove console log (cherry picked from commit d11741107030463878de054bb844bd6e9a8f2d62) --- .../stock/doctype/repost_item_valuation/repost_item_valuation.js | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js index 7b7c2e69cce..06b24071827 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js @@ -134,7 +134,6 @@ frappe.ui.form.on("Repost Item Valuation", { }, voucher_type: function (frm) { - console.log(frm.doc); frm.trigger("set_company_on_transaction"); }, From 45cdb39eddcd96fdec2e1bcb7e8dede2ba8159f3 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 29 Aug 2025 22:50:31 +0530 Subject: [PATCH 13/25] fix: Issue with Barcode Scanning in Stock Entry (cherry picked from commit 13e3db3730eaf5c90b151ea9e65cf8dd52587abd) --- erpnext/public/js/utils/barcode_scanner.js | 8 ++------ erpnext/stock/doctype/stock_entry/stock_entry.js | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/erpnext/public/js/utils/barcode_scanner.js b/erpnext/public/js/utils/barcode_scanner.js index b8d1b4afa2a..1c3d5d160e6 100644 --- a/erpnext/public/js/utils/barcode_scanner.js +++ b/erpnext/public/js/utils/barcode_scanner.js @@ -459,12 +459,8 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner { const item_scanned = row.has_item_scanned; let warehouse_match = true; - if (has_warehouse_field) { - if (warehouse) { - warehouse_match = row[warehouse_field] === warehouse; - } else { - warehouse_match = !row[warehouse_field]; - } + if (has_warehouse_field && warehouse && row[warehouse_field]) { + warehouse_match = row[warehouse_field] === warehouse; } return ( diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 67918ee1dfd..ea2ec897d1d 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -1006,7 +1006,7 @@ erpnext.stock.StockEntry = class StockEntry extends erpnext.stock.StockControlle this.barcode_scanner = new erpnext.utils.BarcodeScanner({ frm: this.frm, warehouse_field: (doc) => { - return doc.purpose === "Material Transfer" ? "t_warehouse" : "s_warehouse"; + return doc.purpose === "Material Receipt" ? "t_warehouse" : "s_warehouse"; }, }); From 6761a023d02b2609fd4fe04d00c12d2e6cbca091 Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Fri, 29 Aug 2025 23:27:14 +0530 Subject: [PATCH 14/25] fix(repost item valuation): validate voucher type in transaction (cherry picked from commit 5663c2a1ca2d2efcd97a60c8a43f9fa42580dbb5) --- .../doctype/repost_item_valuation/repost_item_valuation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js index 06b24071827..e6547ad6f35 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.js @@ -142,7 +142,7 @@ frappe.ui.form.on("Repost Item Valuation", { }, set_company_on_transaction(frm) { - if (frm.doc.voucher_no && frm.doc.voucher_no) { + if (frm.doc.voucher_no && frm.doc.voucher_type) { frm.call("set_company"); } }, From 6f20a2c6e5ee5e88be8405274a4312b86add5140 Mon Sep 17 00:00:00 2001 From: Fawaz Alhafiz <48890670+fawaaaz111@users.noreply.github.com> Date: Sun, 31 Aug 2025 09:43:01 +0300 Subject: [PATCH 15/25] chore: remove unused import (Order) module (cherry picked from commit 4e86a46008ad4ca05bb7c039f4a77e256a2c1c9f) --- .../report/item_wise_sales_register/item_wise_sales_register.py | 1 - 1 file changed, 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 d6ffd3db5ac..d234e5bc328 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 @@ -9,7 +9,6 @@ from frappe.query_builder import functions as fn from frappe.utils import cstr, flt from frappe.utils.nestedset import get_descendants_of from frappe.utils.xlsxutils import handle_html -from pypika import Order from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments from erpnext.accounts.report.utils import get_values_for_columns From e6a305e97219582c19a64f94bb73340f08321537 Mon Sep 17 00:00:00 2001 From: Bhavan23 Date: Mon, 25 Aug 2025 11:14:44 +0000 Subject: [PATCH 16/25] fix(budget): always set fiscal year before fetching company approver role (cherry picked from commit 770d6dd8e26436f8736379a5fed0c0bf308fb143) --- erpnext/accounts/doctype/budget/budget.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py index d31f72f062e..32225fff93d 100644 --- a/erpnext/accounts/doctype/budget/budget.py +++ b/erpnext/accounts/doctype/budget/budget.py @@ -142,8 +142,10 @@ def validate_expense_against_budget(args, expense_amount=0): if not frappe.get_all("Budget", limit=1): return - if args.get("company") and not args.fiscal_year: + if not args.fiscal_year: args.fiscal_year = get_fiscal_year(args.get("posting_date"), company=args.get("company"))[0] + + if args.get("company"): frappe.flags.exception_approver_role = frappe.get_cached_value( "Company", args.get("company"), "exception_budget_approver_role" ) From 9d34eb686c912cc65d3e82234086eb071497dc55 Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Tue, 26 Aug 2025 18:22:49 +0530 Subject: [PATCH 17/25] fix: run config with force (cherry picked from commit e8288a2f63a4f0c0b2cdf7a755b335d1a838a2ae) --- erpnext/patches.txt | 2 +- erpnext/patches/v15_0/sync_auto_reconcile_config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index ae52e1e3a09..fd3dc3ad3cd 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -390,7 +390,7 @@ erpnext.patches.v15_0.enable_allow_existing_serial_no erpnext.patches.v15_0.update_cc_in_process_statement_of_accounts erpnext.patches.v15_0.update_asset_status_to_work_in_progress erpnext.patches.v15_0.rename_manufacturing_settings_field -erpnext.patches.v15_0.sync_auto_reconcile_config +erpnext.patches.v15_0.sync_auto_reconcile_config #2025-08-26 execute:frappe.db.set_single_value("Accounts Settings", "exchange_gain_loss_posting_date", "Payment") erpnext.patches.v14_0.disable_add_row_in_gross_profit erpnext.patches.v15_0.set_difference_amount_in_asset_value_adjustment diff --git a/erpnext/patches/v15_0/sync_auto_reconcile_config.py b/erpnext/patches/v15_0/sync_auto_reconcile_config.py index be92ad99536..f7ece3ca43e 100644 --- a/erpnext/patches/v15_0/sync_auto_reconcile_config.py +++ b/erpnext/patches/v15_0/sync_auto_reconcile_config.py @@ -11,7 +11,7 @@ def execute(): frappe.db.set_single_value("Accounts Settings", "reconciliation_queue_size", 5) # Create Scheduler Event record if it doesn't exist - if frappe.reload_doc("core", "doctype", "scheduler_event"): + if frappe.reload_doc("core", "doctype", "scheduler_event", force=True): method = "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.trigger_reconciliation_for_queued_docs" if not frappe.db.get_all( "Scheduler Event", {"scheduled_against": "Process Payment Reconciliation", "method": method} From ecb785806299524212c490b931e67f9cb9543749 Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Tue, 26 Aug 2025 20:29:24 +0530 Subject: [PATCH 18/25] fix: show company currency symbol (cherry picked from commit 49bb095152036e6a3c765667b063cf070e06cd42) # Conflicts: # erpnext/selling/doctype/quotation_item/quotation_item.json --- erpnext/selling/doctype/quotation_item/quotation_item.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json index 2818b49913d..74c4670063e 100644 --- a/erpnext/selling/doctype/quotation_item/quotation_item.json +++ b/erpnext/selling/doctype/quotation_item/quotation_item.json @@ -365,6 +365,7 @@ "fieldname": "base_net_rate", "fieldtype": "Currency", "label": "Net Rate (Company Currency)", + "options": "Company:company:default_currency", "print_hide": 1, "read_only": 1 }, @@ -698,7 +699,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2024-12-12 13:49:18.765883", + "modified": "2025-08-26 20:31:47.775890", "modified_by": "Administrator", "module": "Selling", "name": "Quotation Item", From 9f0d743e1b3a74a8b76ac900c7a7928d49e8f1fe Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 1 Sep 2025 13:39:35 +0530 Subject: [PATCH 19/25] fix: validation for Recreate Stock Ledgers (cherry picked from commit 785845a4257fcb113a162af0546a946e1c4b88ba) --- .../purchase_receipt/test_purchase_receipt.py | 30 +++++++++++++++++++ .../repost_item_valuation.py | 21 +++++++++++++ 2 files changed, 51 insertions(+) diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 7df84379c22..b7014b19c4a 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -4146,6 +4146,36 @@ class TestPurchaseReceipt(FrappeTestCase): self.assertTrue(sles) + def test_validate_recreate_stock_ledgers_for_sn_item(self): + item_code = "Test SN Item for Recreate Stock Ledgers" + make_item(item_code, {"has_serial_no": 1, "serial_no_series": "SN-TRSLR-.#####"}) + + pr = make_purchase_receipt(item_code=item_code, qty=10, rate=100) + pr.submit() + + sles = frappe.get_all( + "Stock Ledger Entry", + filters={"voucher_type": pr.doctype, "voucher_no": pr.name}, + pluck="name", + ) + + self.assertTrue(sles) + + repost_doc = frappe.get_doc( + { + "doctype": "Repost Item Valuation", + "based_on": "Transaction", + "voucher_type": pr.doctype, + "voucher_no": pr.name, + "posting_date": pr.posting_date, + "posting_time": pr.posting_time, + "company": pr.company, + "recreate_stock_ledgers": 1, + } + ) + + self.assertRaises(frappe.ValidationError, repost_doc.save) + def test_internal_pr_qty_change_only_single_batch(self): from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index 303f28252d8..49ba0bf8358 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -76,6 +76,27 @@ class RepostItemValuation(Document): self.reset_field_values() self.validate_accounts_freeze() self.reset_recreate_stock_ledgers() + self.validate_recreate_stock_ledgers() + + def validate_recreate_stock_ledgers(self): + if not self.recreate_stock_ledgers: + return + + items = [] + if self.based_on == "Item and Warehouse": + items.append(self.item_code) + else: + items = get_items_to_be_repost(self.voucher_type, self.voucher_no) + items = list(set([d.item_code for d in items])) + + if serial_batch_items := frappe.get_all( + "Item", or_filters={"has_serial_no": 1, "has_batch_no": 1}, filters={"name": ("in", items)} + ): + item_list = ", ".join([d.name for d in serial_batch_items]) + msg = _( + "Since {0} are Serial No/Batch No items, you cannot enable 'Recreate Stock Ledgers' in Repost Item Valuation." + ).format(item_list) + frappe.throw(msg) def validate_period_closing_voucher(self): # Period Closing Voucher From 835b9c3378c3cc7b2418dca219455ddd7f4e2824 Mon Sep 17 00:00:00 2001 From: l0gesh29 Date: Thu, 28 Aug 2025 19:16:10 +0530 Subject: [PATCH 20/25] fix: ignore cancelled gl and add company filter (cherry picked from commit afb067ce50a55116f6351a4bafeb47c69b3b2009) --- .../trial_balance_simple/trial_balance_simple.json | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json b/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json index fab3a76a0c4..6b926649ca6 100644 --- a/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json +++ b/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json @@ -4,15 +4,25 @@ "disabled": 0, "docstatus": 0, "doctype": "Report", + "filters": [ + { + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "mandatory": 1, + "options": "Company", + "wildcard_filter": 0 + } + ], "idx": 0, "is_standard": "Yes", - "modified": "2019-01-17 17:20:42.374958", + "modified": "2025-08-28 19:06:54.273322", "modified_by": "Administrator", "module": "Accounts", "name": "Trial Balance (Simple)", "owner": "Administrator", "prepared_report": 0, - "query": "select fiscal_year as \"Fiscal Year:Data:80\",\n\tcompany as \"Company:Data:220\",\n\tposting_date as \"Posting Date:Date:100\",\n\taccount as \"Account:Data:380\",\n\tsum(debit) as \"Debit:Currency:140\",\n\tsum(credit) as \"Credit:Currency:140\",\n\tfinance_book as \"Finance Book:Link/Finance Book:140\"\nfrom `tabGL Entry`\ngroup by fiscal_year, company, posting_date, account\norder by fiscal_year, company, posting_date, account", + "query": "select fiscal_year as \"Fiscal Year:Data:80\",\n\tcompany as \"Company:Data:220\",\n\tposting_date as \"Posting Date:Date:100\",\n\taccount as \"Account:Data:380\",\n\tsum(debit) as \"Debit:Currency:140\",\n\tsum(credit) as \"Credit:Currency:140\",\n\tfinance_book as \"Finance Book:Link/Finance Book:140\"\nfrom `tabGL Entry`\nwhere is_cancelled = 0 and company = %(company)s\ngroup by fiscal_year, company, posting_date, account\norder by fiscal_year, company, posting_date, account", "ref_doctype": "GL Entry", "report_name": "Trial Balance (Simple)", "report_type": "Query Report", From f2c4baeb0e1e982342099e4a2fca9a6737952575 Mon Sep 17 00:00:00 2001 From: l0gesh29 Date: Fri, 29 Aug 2025 16:30:29 +0530 Subject: [PATCH 21/25] fix: add is_cancelled in condition (cherry picked from commit 77a9cf639857b8e274d9c5adcaabd084d1524c7b) --- erpnext/accounts/doctype/gl_entry/gl_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py index 2e4f9db3539..37ac27f3722 100644 --- a/erpnext/accounts/doctype/gl_entry/gl_entry.py +++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py @@ -311,7 +311,7 @@ def validate_balance_type(account, adv_adj=False): if balance_must_be: balance = frappe.db.sql( """select sum(debit) - sum(credit) - from `tabGL Entry` where account = %s""", + from `tabGL Entry` where is_cancelled = 0 and account = %s""", account, )[0][0] From a3605d83703ea91f177f9fcd287f7d0fdaa73f42 Mon Sep 17 00:00:00 2001 From: diptanilsaha Date: Mon, 1 Sep 2025 15:15:42 +0530 Subject: [PATCH 22/25] fix(perf): applying consistent index to fetch gl entries for financial statements (cherry picked from commit 3e2fb85ae6716e9e36a875866ea6fac1998265c4) --- erpnext/accounts/report/financial_statements.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 71e541692f8..04068dc08a1 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -532,6 +532,7 @@ def get_accounting_entries( query = query.select(gl_entry.posting_date, gl_entry.is_opening, gl_entry.fiscal_year) query = query.where(gl_entry.is_cancelled == 0) query = query.where(gl_entry.posting_date <= to_date) + query = query.force_index("posting_date_company_index") if ignore_opening_entries and not ignore_is_opening: query = query.where(gl_entry.is_opening == "No") From fc47fbeaa1f02cd5ef48407c3e56506f8d3052d7 Mon Sep 17 00:00:00 2001 From: Vignesh Sekar Date: Tue, 26 Aug 2025 00:14:15 +0530 Subject: [PATCH 23/25] perf: check PCV (smaller) table before checking GL Entries (cherry picked from commit 4d3ddeae8dec6d5ec23657f7e2ed35c626306733) --- .../period_closing_voucher.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index 7f51f2add59..fba261a1484 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -75,6 +75,17 @@ class PeriodClosingVoucher(AccountsController): return previous_fiscal_year_start_date = previous_fiscal_year[0][1] + previous_fiscal_year_closed = frappe.db.exists( + "Period Closing Voucher", + { + "period_end_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), + "docstatus": 1, + "company": self.company, + }, + ) + if previous_fiscal_year_closed: + return + gle_exists_in_previous_year = frappe.db.exists( "GL Entry", { @@ -86,16 +97,7 @@ class PeriodClosingVoucher(AccountsController): if not gle_exists_in_previous_year: return - previous_fiscal_year_closed = frappe.db.exists( - "Period Closing Voucher", - { - "period_end_date": ("between", [previous_fiscal_year_start_date, last_year_closing]), - "docstatus": 1, - "company": self.company, - }, - ) - if not previous_fiscal_year_closed: - frappe.throw(_("Previous Year is not closed, please close it first")) + frappe.throw(_("Previous Year is not closed, please close it first")) def block_if_future_closing_voucher_exists(self): future_closing_voucher = self.get_future_closing_voucher() From 1d28135898e9ba28f9eae93b4f7ec06423324c6a Mon Sep 17 00:00:00 2001 From: ravibharathi656 Date: Mon, 25 Aug 2025 21:12:26 +0530 Subject: [PATCH 24/25] fix(exchange rate revaluation): add check for gain_loss (cherry picked from commit e5affb16c766b4a21b725fa2edd4f9547fda69f8) --- .../exchange_rate_revaluation/exchange_rate_revaluation.py | 3 ++- erpnext/setup/doctype/company/company.json | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py index c08bd3878d5..2c4e3eb8996 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py @@ -134,7 +134,8 @@ class ExchangeRateRevaluation(Document): accounts = self.get_accounts_data() if accounts: for acc in accounts: - self.append("accounts", acc) + if acc.get("gain_loss"): + self.append("accounts", acc) @frappe.whitelist() def get_accounts_data(self): diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index ae473e15917..8c4f85ff19f 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -766,6 +766,7 @@ }, { "default": "0", + "description": "Upon enabling this, the JV will be submitted for a different exchange rate.", "fieldname": "submit_err_jv", "fieldtype": "Check", "label": "Submit ERR Journals?" @@ -857,7 +858,7 @@ "image_field": "company_logo", "is_tree": 1, "links": [], - "modified": "2025-01-09 20:12:25.471544", + "modified": "2025-08-25 18:34:03.602046", "modified_by": "Administrator", "module": "Setup", "name": "Company", @@ -919,6 +920,7 @@ "select": 1 } ], + "row_format": "Dynamic", "show_name_in_global_search": 1, "sort_field": "modified", "sort_order": "ASC", From b57dabd8ef0f816816fae44586c5a1ee384d31c2 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 2 Sep 2025 15:02:56 +0530 Subject: [PATCH 25/25] fix: valuation for batch items --- erpnext/stock/serial_batch_bundle.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py index 21180accf83..2a1fe92ae28 100644 --- a/erpnext/stock/serial_batch_bundle.py +++ b/erpnext/stock/serial_batch_bundle.py @@ -770,12 +770,15 @@ class BatchNoValuation(DeprecatedBatchNoValuation): self.non_batchwise_valuation_batches = self.batches return - batches = frappe.get_all( - "Batch", filters={"name": ("in", self.batches), "use_batchwise_valuation": 1}, fields=["name"] - ) + if get_valuation_method(self.sle.item_code) == "FIFO": + self.batchwise_valuation_batches = self.batches + else: + batches = frappe.get_all( + "Batch", filters={"name": ("in", self.batches), "use_batchwise_valuation": 1}, fields=["name"] + ) - for batch in batches: - self.batchwise_valuation_batches.append(batch.name) + for batch in batches: + self.batchwise_valuation_batches.append(batch.name) self.non_batchwise_valuation_batches = list(set(self.batches) - set(self.batchwise_valuation_batches))