From b844afe0ec4c27f7c01dca8764f08df049ce37df Mon Sep 17 00:00:00 2001 From: Navin-S-R Date: Wed, 11 Feb 2026 17:29:20 +0530 Subject: [PATCH 01/31] feat: show formatted currency symbol on ledger preview (cherry picked from commit 5c8cb1e7ec0aa194ccd41e6581301a0894ad6814) --- erpnext/controllers/stock_controller.py | 2 +- erpnext/public/js/utils/ledger_preview.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index f2e93a4e933..7ff2c4061f2 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -2017,7 +2017,7 @@ def get_gl_entries_for_preview(doctype, docname, fields): def get_columns(raw_columns, fields): return [ - {"name": d.get("label"), "editable": False, "width": 110} + {"name": d.get("label"), "editable": False, "width": 110, "fieldtype": d.get("fieldtype")} for d in raw_columns if not d.get("hidden") and d.get("fieldname") in fields ] diff --git a/erpnext/public/js/utils/ledger_preview.js b/erpnext/public/js/utils/ledger_preview.js index 84d57efb1eb..a86e0076629 100644 --- a/erpnext/public/js/utils/ledger_preview.js +++ b/erpnext/public/js/utils/ledger_preview.js @@ -84,6 +84,14 @@ erpnext.accounts.ledger_preview = { }, get_datatable(columns, data, wrapper) { + columns.forEach((col) => { + if (col.fieldtype === "Currency") { + col.format = (value) => { + return format_currency(value); + }; + } + }); + const datatable_options = { columns: columns, data: data, From 1d444e53eb16d5859295916daaa9a51561d9e0c4 Mon Sep 17 00:00:00 2001 From: Roxxane Date: Mon, 9 Feb 2026 22:25:11 +0800 Subject: [PATCH 02/31] fix(stock): remove hardcoded letter_head from report The 'Incorrect Serial and Batch Bundle' report had a hardcoded letter_head value of 'Test', preventing users from deleting a Letter Head named 'Test' due to link check. Standard reports should not reference specific Letter Head names. Fixes #52569 (cherry picked from commit 99cd29d88f876702afa2d6f43bf12beb38ba8920) --- .../incorrect_serial_and_batch_bundle.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.json b/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.json index 11e6e4ea3d4..0833ab5eb3a 100644 --- a/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.json +++ b/erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.json @@ -9,7 +9,7 @@ "idx": 0, "is_standard": "Yes", "json": "{}", - "letter_head": "Test", + "letter_head": null, "letterhead": null, "modified": "2025-02-03 15:39:47.613040", "modified_by": "Administrator", From f98e53692e388be76b089ed773b719b877fa25a4 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 12 Feb 2026 12:02:44 +0530 Subject: [PATCH 03/31] refactor: use query builder for sales person commission summary (cherry picked from commit 7105e3fb69b0b2e2ed28fbdcc674231e7aecc3c0) --- .../sales_person_commission_summary.py | 71 +++++++++++-------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py index 16b2d499af2..b0e611589eb 100644 --- a/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py +++ b/erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py @@ -3,7 +3,8 @@ import frappe -from frappe import _, msgprint +from frappe import _, msgprint, qb +from frappe.query_builder import Criterion def execute(filters=None): @@ -97,45 +98,53 @@ def get_columns(filters): def get_entries(filters): - date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date" + dt = qb.DocType(filters["doc_type"]) + st = qb.DocType("Sales Team") + date_field = dt["transaction_date"] if filters["doc_type"] == "Sales Order" else dt["posting_date"] - conditions, values = get_conditions(filters, date_field) - entries = frappe.db.sql( - """ - select - dt.name, dt.customer, dt.territory, dt.{} as posting_date,dt.base_net_total as base_net_amount, - st.commission_rate,st.sales_person, st.allocated_percentage, st.allocated_amount, st.incentives - from - `tab{}` dt, `tabSales Team` st - where - st.parent = dt.name and st.parenttype = {} - and dt.docstatus = 1 {} order by dt.name desc,st.sales_person - """.format(date_field, filters["doc_type"], "%s", conditions), - tuple([filters["doc_type"], *values]), - as_dict=1, + conditions = get_conditions(dt, st, filters, date_field) + entries = ( + qb.from_(dt) + .join(st) + .on(st.parent.eq(dt.name) & st.parenttype.eq(filters["doc_type"])) + .select( + dt.name, + dt.customer, + dt.territory, + date_field.as_("posting_date"), + dt.base_net_total.as_("base_net_amount"), + st.commission_rate, + st.sales_person, + st.allocated_percentage, + st.allocated_amount, + st.incentives, + ) + .where(Criterion.all(conditions)) + .orderby(dt.name, st.sales_person) + .run(as_dict=True) ) return entries -def get_conditions(filters, date_field): - conditions = [""] - values = [] +def get_conditions(dt, st, filters, date_field): + conditions = [] + + conditions.append(dt.docstatus.eq(1)) + from_dt = filters.get("from_date") + to_dt = filters.get("to_date") + if from_dt and to_dt: + conditions.append(date_field.between(from_dt, to_dt)) + elif from_dt and not to_dt: + conditions.append(date_field.gte(from_dt)) + elif not from_dt and to_dt: + conditions.append(date_field.lte(to_dt)) for field in ["company", "customer", "territory"]: if filters.get(field): - conditions.append(f"dt.{field}=%s") - values.append(filters[field]) + conditions.append(dt[field].eq(filters.get(field))) if filters.get("sales_person"): - conditions.append("st.sales_person = '{}'".format(filters.get("sales_person"))) + conditions.append(st["sales_person"].eq(filters.get("sales_person"))) - if filters.get("from_date"): - conditions.append(f"dt.{date_field}>=%s") - values.append(filters["from_date"]) - - if filters.get("to_date"): - conditions.append(f"dt.{date_field}<=%s") - values.append(filters["to_date"]) - - return " and ".join(conditions), values + return conditions From 543e0131b5e06d44c5f100353289ed467dedf6bd Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Thu, 12 Feb 2026 13:36:26 +0530 Subject: [PATCH 04/31] refactor: use query builder for profitability analysis (cherry picked from commit 5e34325604acae2cf7c112b64d1ef052612fe1ac) --- .../profitability_analysis.py | 68 ++++++++++++------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py index 5f3215fe7e2..4d057636a69 100644 --- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py +++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py @@ -3,7 +3,8 @@ import frappe -from frappe import _ +from frappe import _, qb +from frappe.query_builder import Criterion from frappe.utils import cstr, flt from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_dimensions @@ -33,11 +34,19 @@ def execute(filters=None): def get_accounts_data(based_on, company): if based_on == "Cost Center": - return frappe.db.sql( - """select name, parent_cost_center as parent_account, cost_center_name as account_name, lft, rgt - from `tabCost Center` where company=%s order by name""", - company, - as_dict=True, + cc = qb.DocType("Cost Center") + return ( + qb.from_(cc) + .select( + cc.name, + cc.parent_cost_center.as_("parent_account"), + cc.cost_center_name.as_("account_name"), + cc.lft, + cc.rgt, + ) + .where(cc.company.eq(company)) + .orderby(cc.name) + .run(as_dict=True) ) elif based_on == "Project": return frappe.get_all("Project", fields=["name"], filters={"company": company}, order_by="name") @@ -206,27 +215,38 @@ def set_gl_entries_by_account( company, from_date, to_date, based_on, gl_entries_by_account, ignore_closing_entries=False ): """Returns a dict like { "account": [gl entries], ... }""" - additional_conditions = [] + gl = qb.DocType("GL Entry") + acc = qb.DocType("Account") + + conditions = [] + conditions.append(gl.company.eq(company)) + conditions.append(gl[based_on].notnull()) + conditions.append(gl.is_cancelled.eq(0)) + + if from_date and to_date: + conditions.append(gl.posting_date.between(from_date, to_date)) + elif from_date and not to_date: + conditions.append(gl.posting_date.gte(from_date)) + elif not from_date and to_date: + conditions.append(gl.posting_date.lte(to_date)) if ignore_closing_entries: - additional_conditions.append("and voucher_type !='Period Closing Voucher'") + conditions.append(gl.voucher_type.ne("Period Closing Voucher")) - if from_date: - additional_conditions.append("and posting_date >= %(from_date)s") - - gl_entries = frappe.db.sql( - """select posting_date, {based_on} as based_on, debit, credit, - is_opening, (select root_type from `tabAccount` where name = account) as type - from `tabGL Entry` where company=%(company)s - {additional_conditions} - and posting_date <= %(to_date)s - and {based_on} is not null - and is_cancelled = 0 - order by {based_on}, posting_date""".format( - additional_conditions="\n".join(additional_conditions), based_on=based_on - ), - {"company": company, "from_date": from_date, "to_date": to_date}, - as_dict=True, + root_subquery = qb.from_(acc).select(acc.root_type).where(acc.name.eq(gl.account)) + gl_entries = ( + qb.from_(gl) + .select( + gl.posting_date, + gl[based_on].as_("based_on"), + gl.debit, + gl.credit, + gl.is_opening, + root_subquery.as_("type"), + ) + .where(Criterion.all(conditions)) + .orderby(gl[based_on], gl.posting_date) + .run(as_dict=True) ) for entry in gl_entries: From 38679d6d147b098adf83ab7466697d5752cef9ea Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Thu, 12 Feb 2026 13:22:17 +0530 Subject: [PATCH 05/31] fix: consider table multiselect in delete transaction (cherry picked from commit be3d2422a7e1116fb5c4ad35edd2c3d679d94115) --- .../transaction_deletion_record.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py index b308453c847..245befce842 100644 --- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py +++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py @@ -317,7 +317,9 @@ class TransactionDeletionRecord(Document): list: List of child table DocType names (Table field options) """ return frappe.get_all( - "DocField", filters={"parent": doctype_name, "fieldtype": "Table"}, pluck="options" + "DocField", + filters={"parent": doctype_name, "fieldtype": ["in", ["Table", "Table MultiSelect"]]}, + pluck="options", ) def _get_to_delete_row_infos(self, doctype_name, company_field=None, company=None): From 3c33a19634cca72e206db05953f97e662ed2969c Mon Sep 17 00:00:00 2001 From: SowmyaArunachalam Date: Thu, 12 Feb 2026 13:26:47 +0530 Subject: [PATCH 06/31] fix: removed lost reason detail (cherry picked from commit 9bb60405e70bdc6c76ebcc5bc739cdf658e108a4) # Conflicts: # erpnext/patches.txt --- erpnext/patches.txt | 1 + .../v15_0/delete_quotation_lost_record_detail.py | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 erpnext/patches/v15_0/delete_quotation_lost_record_detail.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 838c837321e..e6d090dac21 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -464,3 +464,4 @@ erpnext.patches.v16_0.set_ordered_qty_in_quotation_item erpnext.patches.v16_0.migrate_transaction_deletion_task_flags_to_status # 2 erpnext.patches.v16_0.update_company_custom_field_in_bin erpnext.patches.v15_0.replace_http_with_https_in_sales_partner +erpnext.patches.v15_0.delete_quotation_lost_record_detail diff --git a/erpnext/patches/v15_0/delete_quotation_lost_record_detail.py b/erpnext/patches/v15_0/delete_quotation_lost_record_detail.py new file mode 100644 index 00000000000..2dc37486e1c --- /dev/null +++ b/erpnext/patches/v15_0/delete_quotation_lost_record_detail.py @@ -0,0 +1,11 @@ +import frappe +from frappe.query_builder import DocType + + +def execute(): + qlr = DocType("Quotation Lost Reason Detail") + quotation = DocType("Quotation") + + sub_query = frappe.qb.from_(quotation).select(quotation.name) + query = frappe.qb.from_(qlr).delete().where(qlr.parent.notin(sub_query)) + query.run() From 485c1b025a6d32877b7c4d4c97e10908bcfee5ad Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 15 Feb 2026 12:29:28 +0530 Subject: [PATCH 07/31] Revert "fix: Workspace sidebar links for Debit/Credit Notes (backport #51594)" --- erpnext/workspace_sidebar/invoicing.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/workspace_sidebar/invoicing.json b/erpnext/workspace_sidebar/invoicing.json index 9a80f8237a6..99a6b367953 100644 --- a/erpnext/workspace_sidebar/invoicing.json +++ b/erpnext/workspace_sidebar/invoicing.json @@ -314,7 +314,7 @@ "type": "Link" } ], - "modified": "2026-01-27 21:23:15.665712", + "modified": "2026-01-26 21:23:15.665712", "modified_by": "Administrator", "module": "Accounts", "name": "Invoicing", From e2183ebde9034d826e985706090ff06705529540 Mon Sep 17 00:00:00 2001 From: ervishnucs Date: Fri, 13 Feb 2026 11:58:54 +0530 Subject: [PATCH 08/31] fix: allow non-stock items while updating items (cherry picked from commit 07db5941aa0e451c33b71db131de4a968a4663e5) --- erpnext/public/js/utils.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 08b745d2c32..578846f0937 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -646,7 +646,11 @@ erpnext.utils.update_child_items = function (opts) { get_query: function () { let filters; if (frm.doc.doctype == "Sales Order") { - filters = { is_sales_item: 1, is_stock_item: !frm.doc.is_subcontracted }; + if (frm.doc.is_subcontracted) { + filters = { is_sales_item: 1, is_stock_item: 0 }; + } else { + filters = { is_sales_item: 1 }; + } } else if (frm.doc.doctype == "Purchase Order") { if (frm.doc.is_subcontracted) { if (frm.doc.is_old_subcontracting_flow) { From 46b588442071cf8ef43e4639a61f1fe17968216e Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 15 Feb 2026 13:06:37 +0530 Subject: [PATCH 09/31] fix: total weight does not update when updating items (cherry picked from commit 63323a2611f6e57e02c68873b7b2f612eac38b3d) --- erpnext/controllers/accounts_controller.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index a97fb4000fb..25959c651cf 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -4079,6 +4079,12 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil flt(d.get("conversion_factor"), conv_fac_precision) or conversion_factor ) + if child_item.get("total_weight") and child_item.get("weight_per_unit"): + child_item.total_weight = flt( + child_item.weight_per_unit * child_item.qty * child_item.conversion_factor, + child_item.precision("total_weight"), + ) + if d.get("delivery_date") and parent_doctype == "Sales Order": child_item.delivery_date = d.get("delivery_date") From 4a4e9956e255c70cbe4079015e87c17eb8025e74 Mon Sep 17 00:00:00 2001 From: MochaMind Date: Sun, 15 Feb 2026 18:30:35 +0530 Subject: [PATCH 10/31] chore: update POT file (#52674) --- erpnext/locale/main.pot | 347 ++++++++++++++++++++++------------------ 1 file changed, 192 insertions(+), 155 deletions(-) diff --git a/erpnext/locale/main.pot b/erpnext/locale/main.pot index eab1b559dde..77c3cdac6aa 100644 --- a/erpnext/locale/main.pot +++ b/erpnext/locale/main.pot @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ERPNext VERSION\n" "Report-Msgid-Bugs-To: hello@frappe.io\n" -"POT-Creation-Date: 2026-02-08 09:43+0000\n" -"PO-Revision-Date: 2026-02-08 09:43+0000\n" +"POT-Creation-Date: 2026-02-15 09:44+0000\n" +"PO-Revision-Date: 2026-02-15 09:44+0000\n" "Last-Translator: hello@frappe.io\n" "Language-Team: hello@frappe.io\n" "MIME-Version: 1.0\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1466 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1469 msgid "" "\n" "\t\t\tThe Batch {0} of an item {1} has negative stock in the warehouse {2}. Please add a stock quantity of {3} to proceed with this entry." @@ -3782,7 +3782,7 @@ msgstr "" #: erpnext/accounts/doctype/process_payment_reconciliation_log_allocations/process_payment_reconciliation_log_allocations.json #: erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json #: erpnext/accounts/doctype/unreconcile_payment_entries/unreconcile_payment_entries.json -#: erpnext/accounts/report/gross_profit/gross_profit.py:398 +#: erpnext/accounts/report/gross_profit/gross_profit.py:409 #: erpnext/public/js/utils/unreconcile.js:87 msgid "Allocated Amount" msgstr "" @@ -3952,11 +3952,17 @@ msgstr "" #: erpnext/stock/doctype/item/item.json #: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json #: erpnext/stock/doctype/stock_settings/stock_settings.json -#: erpnext/stock/doctype/stock_settings/stock_settings.py:178 -#: erpnext/stock/doctype/stock_settings/stock_settings.py:190 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:179 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:191 msgid "Allow Negative Stock" msgstr "" +#. Label of the allow_negative_stock_for_batch (Check) field in DocType 'Stock +#. Settings' +#: erpnext/stock/doctype/stock_settings/stock_settings.json +msgid "Allow Negative Stock for Batch" +msgstr "" + #. Label of the allow_negative_rates_for_items (Check) field in DocType #. 'Selling Settings' #: erpnext/selling/doctype/selling_settings/selling_settings.json @@ -4472,7 +4478,7 @@ msgstr "" #: erpnext/selling/report/sales_order_analysis/sales_order_analysis.py:290 #: erpnext/selling/report/sales_partner_commission_summary/sales_partner_commission_summary.py:53 #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.py:69 -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:67 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:68 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:109 #: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json #: erpnext/stock/doctype/landed_cost_item/landed_cost_item.json @@ -5152,7 +5158,7 @@ msgstr "" msgid "As there are existing submitted transactions against item {0}, you can not change the value of {1}." msgstr "" -#: erpnext/stock/doctype/stock_settings/stock_settings.py:203 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:204 msgid "As there are reserved stock, you cannot disable {0}." msgstr "" @@ -5164,8 +5170,8 @@ msgstr "" msgid "As there are sufficient raw materials, Material Request is not required for Warehouse {0}." msgstr "" -#: erpnext/stock/doctype/stock_settings/stock_settings.py:177 -#: erpnext/stock/doctype/stock_settings/stock_settings.py:189 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:178 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:190 msgid "As {0} is enabled, you can not enable {1}." msgstr "" @@ -5567,7 +5573,7 @@ msgstr "" msgid "Asset deleted" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:168 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:181 msgid "Asset issued to Employee {0}" msgstr "" @@ -5575,7 +5581,7 @@ msgstr "" msgid "Asset out of order due to Asset Repair {0}" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:155 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:168 msgid "Asset received at Location {0} and issued to Employee {1}" msgstr "" @@ -5608,7 +5614,7 @@ msgstr "" msgid "Asset submitted" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:163 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:176 msgid "Asset transferred to Location {0}" msgstr "" @@ -5628,15 +5634,15 @@ msgstr "" msgid "Asset {0} does not belong to Item {1}" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:44 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:45 msgid "Asset {0} does not belong to company {1}" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:92 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:105 msgid "Asset {0} does not belong to the custodian {1}" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:64 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:77 msgid "Asset {0} does not belong to the location {1}" msgstr "" @@ -6345,7 +6351,7 @@ msgstr "" msgid "Avg. Selling Price List Rate" msgstr "" -#: erpnext/accounts/report/gross_profit/gross_profit.py:336 +#: erpnext/accounts/report/gross_profit/gross_profit.py:347 msgid "Avg. Selling Rate" msgstr "" @@ -7224,10 +7230,6 @@ msgstr "" msgid "Base Taxable Amount" msgstr "" -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:163 -msgid "Base Total" -msgstr "" - #. Label of the base_total_billable_amount (Currency) field in DocType #. 'Timesheet' #: erpnext/projects/doctype/timesheet/timesheet.json @@ -7419,7 +7421,7 @@ msgstr "" msgid "Batch No is mandatory" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3256 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3262 msgid "Batch No {0} does not exists" msgstr "" @@ -7442,7 +7444,7 @@ msgstr "" msgid "Batch Nos" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1850 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1853 msgid "Batch Nos are created successfully" msgstr "" @@ -8356,7 +8358,7 @@ msgstr "" msgid "Buying & Selling Settings" msgstr "" -#: erpnext/accounts/report/gross_profit/gross_profit.py:357 +#: erpnext/accounts/report/gross_profit/gross_profit.py:368 msgid "Buying Amount" msgstr "" @@ -8679,6 +8681,10 @@ msgstr "" msgid "Campaign Schedules" msgstr "" +#: erpnext/crm/doctype/email_campaign/email_campaign.py:113 +msgid "Campaign {0} not found" +msgstr "" + #: erpnext/setup/doctype/authorization_control/authorization_control.py:60 msgid "Can be approved by {0}" msgstr "" @@ -8723,7 +8729,7 @@ msgid "Can refer row only if the charge type is 'On Previous Row Amount' or 'Pre msgstr "" #: erpnext/setup/doctype/company/company.py:207 -#: erpnext/stock/doctype/stock_settings/stock_settings.py:144 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:145 msgid "Can't change the valuation method, as there are transactions against some items which do not have its own valuation method" msgstr "" @@ -8933,7 +8939,7 @@ msgid "Cannot delete an item which has been ordered" msgstr "" #: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:195 -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:778 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:780 msgid "Cannot delete protected core DocType: {0}" msgstr "" @@ -10045,7 +10051,7 @@ msgstr "" #: erpnext/selling/report/sales_partner_commission_summary/sales_partner_commission_summary.py:67 #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.py:78 -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:82 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:83 msgid "Commission Rate %" msgstr "" @@ -10617,7 +10623,7 @@ msgstr "" msgid "Company Address Name" msgstr "" -#: erpnext/controllers/accounts_controller.py:4318 +#: erpnext/controllers/accounts_controller.py:4324 msgid "Company Address is missing. You don't have permission to update it. Please contact your System Manager." msgstr "" @@ -11410,7 +11416,7 @@ msgstr "" msgid "Contract Terms and Conditions" msgstr "" -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:76 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:77 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:122 msgid "Contribution %" msgstr "" @@ -11420,7 +11426,7 @@ msgstr "" msgid "Contribution (%)" msgstr "" -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:88 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:89 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:130 msgid "Contribution Amount" msgstr "" @@ -11486,7 +11492,7 @@ msgstr "" #: erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json #: erpnext/manufacturing/doctype/bom_item/bom_item.json #: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json -#: erpnext/public/js/utils.js:807 +#: erpnext/public/js/utils.js:811 #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json #: erpnext/stock/doctype/packed_item/packed_item.json #: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json @@ -11748,7 +11754,7 @@ msgstr "" #: erpnext/accounts/report/general_ledger/general_ledger.js:153 #: erpnext/accounts/report/general_ledger/general_ledger.py:778 #: erpnext/accounts/report/gross_profit/gross_profit.js:68 -#: erpnext/accounts/report/gross_profit/gross_profit.py:384 +#: erpnext/accounts/report/gross_profit/gross_profit.py:395 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:297 #: erpnext/accounts/report/purchase_register/purchase_register.js:46 #: erpnext/accounts/report/sales_payment_summary/sales_payment_summary.py:29 @@ -13071,7 +13077,7 @@ msgstr "" #: erpnext/accounts/doctype/tax_rule/tax_rule.json #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:38 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:29 -#: erpnext/accounts/report/gross_profit/gross_profit.py:405 +#: erpnext/accounts/report/gross_profit/gross_profit.py:416 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:37 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js:22 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:213 @@ -13125,7 +13131,7 @@ msgstr "" #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.js:53 #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.py:32 #: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.js:40 -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:53 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:54 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js:53 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:65 #: erpnext/selling/workspace/selling/selling.json @@ -13339,7 +13345,7 @@ msgstr "" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:185 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:56 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:165 -#: erpnext/accounts/report/gross_profit/gross_profit.py:412 +#: erpnext/accounts/report/gross_profit/gross_profit.py:423 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:200 #: erpnext/accounts/report/sales_register/sales_register.js:27 #: erpnext/accounts/report/sales_register/sales_register.py:202 @@ -13449,7 +13455,7 @@ msgstr "" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:156 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:92 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:35 -#: erpnext/accounts/report/gross_profit/gross_profit.py:419 +#: erpnext/accounts/report/gross_profit/gross_profit.py:430 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:220 #: erpnext/accounts/report/sales_register/sales_register.py:193 #: erpnext/buying/doctype/purchase_order/purchase_order.json @@ -13515,10 +13521,6 @@ msgstr "" msgid "Customer PO Details" msgstr "" -#: erpnext/public/js/utils/contact_address_quick_entry.js:114 -msgid "Customer POS Id" -msgstr "" - #. Label of the customer_pos_id (Data) field in DocType 'Customer' #: erpnext/selling/doctype/customer/customer.json msgid "Customer POS id" @@ -13728,7 +13730,7 @@ msgstr "" msgid "Daily Project Summary for {0}" msgstr "" -#: erpnext/setup/doctype/email_digest/email_digest.py:181 +#: erpnext/setup/doctype/email_digest/email_digest.py:179 msgid "Daily Reminders" msgstr "" @@ -14805,8 +14807,8 @@ msgstr "" msgid "Deleting {0} and all associated Common Code documents..." msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1095 -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1114 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1097 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1116 msgid "Deletion in Progress!" msgstr "" @@ -14939,7 +14941,7 @@ msgstr "" #: erpnext/manufacturing/doctype/master_production_schedule_item/master_production_schedule_item.json #: erpnext/manufacturing/doctype/sales_forecast_item/sales_forecast_item.json #: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:1067 -#: erpnext/public/js/utils.js:800 +#: erpnext/public/js/utils.js:804 #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:624 #: erpnext/selling/doctype/sales_order/sales_order.js:1486 @@ -16259,7 +16261,7 @@ msgid "Do you want to submit the stock entry?" msgstr "" #: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:180 -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:441 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:443 msgid "DocType {0} does not exist" msgstr "" @@ -16866,11 +16868,21 @@ msgstr "" msgid "Email Campaign" msgstr "" +#: erpnext/crm/doctype/email_campaign/email_campaign.py:112 +#: erpnext/crm/doctype/email_campaign/email_campaign.py:149 +#: erpnext/crm/doctype/email_campaign/email_campaign.py:157 +msgid "Email Campaign Error" +msgstr "" + #. Label of the email_campaign_for (Select) field in DocType 'Email Campaign' #: erpnext/crm/doctype/email_campaign/email_campaign.json msgid "Email Campaign For " msgstr "" +#: erpnext/crm/doctype/email_campaign/email_campaign.py:125 +msgid "Email Campaign Send Error" +msgstr "" + #. Label of the supplier_response_section (Section Break) field in DocType #. 'Request for Quotation' #: erpnext/buying/doctype/request_for_quotation/request_for_quotation.json @@ -17097,12 +17109,12 @@ msgstr "" msgid "Employee cannot report to himself." msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:96 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:109 msgid "Employee is required while issuing Asset {0}" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:79 -#: erpnext/assets/doctype/asset_movement/asset_movement.py:100 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:92 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:113 msgid "Employee {0} does not belong to the company {1}" msgstr "" @@ -17118,7 +17130,7 @@ msgstr "" msgid "Empty" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:750 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:752 msgid "Empty To Delete List" msgstr "" @@ -18004,7 +18016,7 @@ msgstr "" #: erpnext/accounts/report/account_balance/account_balance.js:28 #: erpnext/accounts/report/deferred_revenue_and_expense/deferred_revenue_and_expense.js:89 #: erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py:182 -#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:190 +#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:199 msgid "Expense" msgstr "" @@ -18273,6 +18285,10 @@ msgstr "" msgid "Failed to post depreciation entries" msgstr "" +#: erpnext/crm/doctype/email_campaign/email_campaign.py:126 +msgid "Failed to send email for campaign {0} to {1}" +msgstr "" + #: erpnext/setup/setup_wizard/setup_wizard.py:30 #: erpnext/setup/setup_wizard/setup_wizard.py:31 msgid "Failed to setup company" @@ -18434,15 +18450,15 @@ msgstr "" msgid "Fields will be copied over only at time of creation." msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1062 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1064 msgid "File does not belong to this Transaction Deletion Record" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1056 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1058 msgid "File not found" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1070 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1072 msgid "File not found on server" msgstr "" @@ -18666,7 +18682,7 @@ msgstr "" #. Service Item' #. Label of the fg_item (Link) field in DocType 'Subcontracting Order Service #. Item' -#: erpnext/public/js/utils.js:826 +#: erpnext/public/js/utils.js:830 #: erpnext/subcontracting/doctype/subcontracting_inward_order_service_item/subcontracting_inward_order_service_item.json #: erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.json msgid "Finished Good Item" @@ -18679,7 +18695,7 @@ msgstr "" msgid "Finished Good Item Code" msgstr "" -#: erpnext/public/js/utils.js:844 +#: erpnext/public/js/utils.js:848 msgid "Finished Good Item Qty" msgstr "" @@ -19506,7 +19522,7 @@ msgstr "" msgid "From Employee" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:85 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:98 msgid "From Employee is required while issuing Asset {0}" msgstr "" @@ -20044,7 +20060,7 @@ msgstr "" msgid "Generate To Delete List" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:468 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:470 msgid "Generate To Delete list first" msgstr "" @@ -20499,7 +20515,6 @@ msgstr "" #: erpnext/accounts/report/pos_register/pos_register.py:202 #: erpnext/accounts/report/purchase_register/purchase_register.py:275 #: erpnext/accounts/report/sales_register/sales_register.py:305 -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:175 #: erpnext/buying/doctype/purchase_order/purchase_order.json #: erpnext/buying/doctype/supplier_quotation/supplier_quotation.json #: erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json @@ -20533,6 +20548,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice/pos_invoice.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:169 #: erpnext/buying/doctype/purchase_order/purchase_order.json #: erpnext/buying/doctype/supplier_quotation/supplier_quotation.json #: erpnext/selling/doctype/quotation/quotation.json @@ -20542,6 +20558,10 @@ msgstr "" msgid "Grand Total (Company Currency)" msgstr "" +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:175 +msgid "Grand Total (Transaction Currency)" +msgstr "" + #. Label of the grant_commission (Check) field in DocType 'POS Invoice Item' #. Label of the grant_commission (Check) field in DocType 'Sales Invoice Item' #. Label of the grant_commission (Check) field in DocType 'Sales Order Item' @@ -20602,18 +20622,18 @@ msgstr "" #. Label of the gross_profit (Currency) field in DocType 'Quotation Item' #. Label of the gross_profit (Currency) field in DocType 'Sales Order Item' #: erpnext/accounts/report/gross_profit/gross_profit.json -#: erpnext/accounts/report/gross_profit/gross_profit.py:364 +#: erpnext/accounts/report/gross_profit/gross_profit.py:375 #: erpnext/accounts/workspace/financial_reports/financial_reports.json #: erpnext/selling/doctype/quotation_item/quotation_item.json #: erpnext/selling/doctype/sales_order_item/sales_order_item.json msgid "Gross Profit" msgstr "" -#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:197 +#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:206 msgid "Gross Profit / Loss" msgstr "" -#: erpnext/accounts/report/gross_profit/gross_profit.py:371 +#: erpnext/accounts/report/gross_profit/gross_profit.py:382 msgid "Gross Profit Percent" msgstr "" @@ -20664,7 +20684,7 @@ msgstr "" msgid "Group Same Items" msgstr "" -#: erpnext/stock/doctype/stock_settings/stock_settings.py:119 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:120 msgid "Group Warehouses cannot be used in transactions. Please change the value of {0}" msgstr "" @@ -21468,6 +21488,12 @@ msgstr "" msgid "If enabled, the source and target warehouse in the Material Transfer Stock Entry must be different else an error will be thrown. If inventory dimensions are present, same source and target warehouse can be allowed but atleast any one of the inventory dimension fields must be different." msgstr "" +#. Description of the 'Allow Negative Stock for Batch' (Check) field in DocType +#. 'Stock Settings' +#: erpnext/stock/doctype/stock_settings/stock_settings.json +msgid "If enabled, the system will allow negative stock entries for the batch, but this could calculate the valuation rate incorrectly, so avoid using this option." +msgstr "" + #. Description of the 'Allow UOM with Conversion Rate Defined in Item' (Check) #. field in DocType 'Stock Settings' #: erpnext/stock/doctype/stock_settings/stock_settings.json @@ -21889,7 +21915,7 @@ msgstr "" msgid "Import Successful" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:560 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:562 msgid "Import Summary" msgstr "" @@ -22130,7 +22156,7 @@ msgstr "" #. Label of the incentives (Currency) field in DocType 'Sales Team' #: erpnext/selling/doctype/sales_team/sales_team.json -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:93 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:94 msgid "Incentives" msgstr "" @@ -22344,7 +22370,7 @@ msgstr "" #: erpnext/accounts/report/account_balance/account_balance.js:27 #: erpnext/accounts/report/financial_statements.py:776 #: erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py:180 -#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:183 +#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:192 msgid "Income" msgstr "" @@ -22473,7 +22499,7 @@ msgid "Incorrect Type of Transaction" msgstr "" #: erpnext/stock/doctype/pick_list/pick_list.py:175 -#: erpnext/stock/doctype/stock_settings/stock_settings.py:122 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:123 msgid "Incorrect Warehouse" msgstr "" @@ -23009,7 +23035,7 @@ msgstr "" msgid "Invalid Blanket Order for the selected Customer and Item" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:494 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:496 msgid "Invalid CSV format. Expected column: doctype_name" msgstr "" @@ -23176,7 +23202,7 @@ msgstr "" msgid "Invalid condition expression" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1051 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1053 msgid "Invalid file URL" msgstr "" @@ -24412,7 +24438,7 @@ msgstr "" #: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1078 #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:68 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:37 -#: erpnext/accounts/report/gross_profit/gross_profit.py:301 +#: erpnext/accounts/report/gross_profit/gross_profit.py:312 #: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:142 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:159 #: erpnext/accounts/report/received_items_to_be_billed/received_items_to_be_billed.py:37 @@ -24663,7 +24689,7 @@ msgstr "" #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json #: erpnext/accounts/doctype/tax_rule/tax_rule.json #: erpnext/accounts/report/gross_profit/gross_profit.js:44 -#: erpnext/accounts/report/gross_profit/gross_profit.py:314 +#: erpnext/accounts/report/gross_profit/gross_profit.py:325 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js:21 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:28 #: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js:28 @@ -24890,7 +24916,7 @@ msgstr "" #: erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:74 #: erpnext/accounts/report/delivered_items_to_be_billed/delivered_items_to_be_billed.py:71 -#: erpnext/accounts/report/gross_profit/gross_profit.py:308 +#: erpnext/accounts/report/gross_profit/gross_profit.py:319 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:33 #: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:148 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:165 @@ -24941,7 +24967,7 @@ msgstr "" #: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py:92 #: erpnext/manufacturing/report/work_order_consumed_materials/work_order_consumed_materials.py:138 #: erpnext/public/js/controllers/transaction.js:2801 -#: erpnext/public/js/utils.js:736 +#: erpnext/public/js/utils.js:740 #: erpnext/selling/doctype/quotation_item/quotation_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:1252 #: erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -25559,11 +25585,11 @@ msgstr "" msgid "Items and Pricing" msgstr "" -#: erpnext/controllers/accounts_controller.py:4176 +#: erpnext/controllers/accounts_controller.py:4182 msgid "Items cannot be updated as Subcontracting Inward Order(s) exist against this Subcontracted Sales Order." msgstr "" -#: erpnext/controllers/accounts_controller.py:4169 +#: erpnext/controllers/accounts_controller.py:4175 msgid "Items cannot be updated as Subcontracting Order is created against the Purchase Order {0}." msgstr "" @@ -27615,7 +27641,7 @@ msgstr "" msgid "Mapping Subcontracting Order ..." msgstr "" -#: erpnext/public/js/utils.js:971 +#: erpnext/public/js/utils.js:975 msgid "Mapping {0} ..." msgstr "" @@ -28265,7 +28291,7 @@ msgstr "" msgid "Merge Similar Account Heads" msgstr "" -#: erpnext/public/js/utils.js:1003 +#: erpnext/public/js/utils.js:1007 msgid "Merge taxes from multiple documents" msgstr "" @@ -29012,7 +29038,7 @@ msgstr "" msgid "Naming Series is mandatory" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:932 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:934 msgid "Naming series '{0}' for DocType '{1}' does not contain standard '.' or '{{' separator. Using fallback extraction." msgstr "" @@ -29055,7 +29081,7 @@ msgstr "" msgid "Negative Quantity is not allowed" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1475 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1478 #: erpnext/stock/serial_batch_bundle.py:1520 msgid "Negative Stock Error" msgstr "" @@ -29619,7 +29645,7 @@ msgstr "" msgid "No Delivery Note selected for Customer {}" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:749 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:751 msgid "No DocTypes in To Delete list. Please generate or import the list before submitting." msgstr "" @@ -29712,7 +29738,7 @@ msgstr "" msgid "No Tax withholding account set for Company {0} in Tax Withholding Category {1}." msgstr "" -#: erpnext/accounts/report/gross_profit/gross_profit.py:893 +#: erpnext/accounts/report/gross_profit/gross_profit.py:965 msgid "No Terms" msgstr "" @@ -29770,6 +29796,10 @@ msgstr "" msgid "No difference found for stock account {0}" msgstr "" +#: erpnext/crm/doctype/email_campaign/email_campaign.py:150 +msgid "No email found for {0} {1}" +msgstr "" + #: erpnext/telephony/doctype/call_log/call_log.py:117 msgid "No employee was scheduled for call popup" msgstr "" @@ -29795,10 +29825,6 @@ msgstr "" msgid "No items in cart" msgstr "" -#: erpnext/setup/doctype/email_digest/email_digest.py:166 -msgid "No items to be received are overdue" -msgstr "" - #: erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py:456 msgid "No matches occurred via auto reconciliation" msgstr "" @@ -29925,6 +29951,10 @@ msgstr "" msgid "No recent transactions found" msgstr "" +#: erpnext/crm/doctype/email_campaign/email_campaign.py:158 +msgid "No recipients found for campaign {0}" +msgstr "" + #: erpnext/accounts/report/purchase_register/purchase_register.py:45 #: erpnext/accounts/report/sales_register/sales_register.py:46 #: erpnext/crm/report/lead_conversion_time/lead_conversion_time.py:18 @@ -30551,7 +30581,7 @@ msgstr "" msgid "Only CSV and Excel files can be used to for importing data. Please check the file format you are trying to upload" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1065 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1067 msgid "Only CSV files are allowed" msgstr "" @@ -33412,7 +33442,7 @@ msgstr "" #: erpnext/accounts/doctype/payment_term/payment_term.json #: erpnext/accounts/doctype/payment_terms_template_detail/payment_terms_template_detail.json #: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1214 -#: erpnext/accounts/report/gross_profit/gross_profit.py:438 +#: erpnext/accounts/report/gross_profit/gross_profit.py:449 #: erpnext/accounts/workspace/invoicing/invoicing.json #: erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py:30 msgid "Payment Term" @@ -33678,7 +33708,7 @@ msgstr "" msgid "Pending Work Order" msgstr "" -#: erpnext/setup/doctype/email_digest/email_digest.py:182 +#: erpnext/setup/doctype/email_digest/email_digest.py:180 msgid "Pending activities for today" msgstr "" @@ -35121,7 +35151,7 @@ msgstr "" #: erpnext/selling/report/sales_partner_commission_summary/sales_partner_commission_summary.py:21 #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.py:21 -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:42 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:43 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:54 msgid "Please select the document type first" msgstr "" @@ -35375,7 +35405,7 @@ msgstr "" msgid "Please set the cost center field in {0} or setup a default Cost Center for the Company." msgstr "" -#: erpnext/crm/doctype/email_campaign/email_campaign.py:50 +#: erpnext/crm/doctype/email_campaign/email_campaign.py:48 msgid "Please set up the Campaign Schedule in the Campaign {0}" msgstr "" @@ -35622,7 +35652,7 @@ msgstr "" #: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:66 #: erpnext/accounts/report/cheques_and_deposits_incorrectly_cleared/cheques_and_deposits_incorrectly_cleared.py:151 #: erpnext/accounts/report/general_ledger/general_ledger.py:681 -#: erpnext/accounts/report/gross_profit/gross_profit.py:289 +#: erpnext/accounts/report/gross_profit/gross_profit.py:300 #: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:175 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:192 #: erpnext/accounts/report/payment_ledger/payment_ledger.py:143 @@ -35640,7 +35670,7 @@ msgstr "" #: erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py:25 #: erpnext/selling/report/sales_partner_commission_summary/sales_partner_commission_summary.py:51 #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.py:45 -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:66 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:67 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:85 #: erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json #: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json @@ -35715,7 +35745,7 @@ msgstr "" #: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json #: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json #: erpnext/accounts/doctype/sales_invoice/sales_invoice.json -#: erpnext/accounts/report/gross_profit/gross_profit.py:295 +#: erpnext/accounts/report/gross_profit/gross_profit.py:306 #: erpnext/assets/doctype/asset_capitalization/asset_capitalization.json #: erpnext/stock/doctype/delivery_note/delivery_note.json #: erpnext/stock/doctype/purchase_receipt/purchase_receipt.json @@ -37248,7 +37278,7 @@ msgid "Prospects Engaged But Not Converted" msgstr "" #: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:196 -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:779 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:781 msgid "Protected DocType" msgstr "" @@ -37950,7 +37980,7 @@ msgstr "" #: erpnext/accounts/doctype/pricing_rule/pricing_rule.json #: erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json #: erpnext/accounts/print_format/sales_invoice_print/sales_invoice_print.html:91 -#: erpnext/accounts/report/gross_profit/gross_profit.py:334 +#: erpnext/accounts/report/gross_profit/gross_profit.py:345 #: erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.json #: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:240 #: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:224 @@ -37973,7 +38003,7 @@ msgstr "" #: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:398 #: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:499 #: erpnext/public/js/stock_reservation.js:134 -#: erpnext/public/js/stock_reservation.js:336 erpnext/public/js/utils.js:774 +#: erpnext/public/js/stock_reservation.js:336 erpnext/public/js/utils.js:778 #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json #: erpnext/selling/doctype/product_bundle_item/product_bundle_item.json #: erpnext/selling/doctype/sales_order/sales_order.js:390 @@ -38982,7 +39012,7 @@ msgstr "" #: erpnext/manufacturing/doctype/bom_item/bom_item.json #: erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.json #: erpnext/manufacturing/doctype/work_order_item/work_order_item.json -#: erpnext/public/js/utils.js:784 +#: erpnext/public/js/utils.js:788 #: erpnext/selling/doctype/product_bundle_item/product_bundle_item.json #: erpnext/selling/doctype/quotation_item/quotation_item.json #: erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -40660,7 +40690,7 @@ msgstr "" msgid "Reqd Qty (BOM)" msgstr "" -#: erpnext/public/js/utils.js:800 +#: erpnext/public/js/utils.js:804 msgid "Reqd by date" msgstr "" @@ -42737,7 +42767,7 @@ msgstr "" msgid "Row {0}: As {1} is enabled, raw materials cannot be added to {2} entry. Use {3} entry to consume raw materials." msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:882 +#: erpnext/stock/doctype/material_request/material_request.py:885 msgid "Row {0}: Bill of Materials not found for the Item {1}" msgstr "" @@ -43139,7 +43169,7 @@ msgstr "" msgid "SLA Paused On" msgstr "" -#: erpnext/public/js/utils.js:1160 +#: erpnext/public/js/utils.js:1164 msgid "SLA is on hold since {0}" msgstr "" @@ -43330,8 +43360,8 @@ msgstr "" #: erpnext/accounts/doctype/sales_invoice_reference/sales_invoice_reference.json #: erpnext/accounts/print_format/sales_auditing_voucher/sales_auditing_voucher.html:5 #: erpnext/accounts/report/gross_profit/gross_profit.js:30 -#: erpnext/accounts/report/gross_profit/gross_profit.py:276 -#: erpnext/accounts/report/gross_profit/gross_profit.py:283 +#: erpnext/accounts/report/gross_profit/gross_profit.py:287 +#: erpnext/accounts/report/gross_profit/gross_profit.py:294 #: erpnext/crm/doctype/contract/contract.json #: erpnext/projects/doctype/timesheet/timesheet.json #: erpnext/projects/doctype/timesheet_detail/timesheet_detail.json @@ -43783,14 +43813,14 @@ msgstr "" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:191 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:80 #: erpnext/accounts/report/gross_profit/gross_profit.js:50 -#: erpnext/accounts/report/gross_profit/gross_profit.py:391 +#: erpnext/accounts/report/gross_profit/gross_profit.py:402 #: erpnext/crm/workspace/crm/crm.json #: erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json #: erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json #: erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json #: erpnext/selling/doctype/sales_team/sales_team.json #: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.js:8 -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:69 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:70 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js:8 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:116 #: erpnext/selling/workspace/selling/selling.json @@ -43860,7 +43890,7 @@ msgstr "" msgid "Sales Representative" msgstr "" -#: erpnext/accounts/report/gross_profit/gross_profit.py:893 +#: erpnext/accounts/report/gross_profit/gross_profit.py:964 #: erpnext/stock/doctype/delivery_note/delivery_note.js:270 msgid "Sales Return" msgstr "" @@ -44384,7 +44414,7 @@ msgstr "" msgid "Segregate Serial / Batch Bundle" msgstr "" -#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:22 +#: erpnext/accounts/report/profitability_analysis/profitability_analysis.py:23 msgid "Select Accounting Dimension." msgstr "" @@ -44793,7 +44823,7 @@ msgstr "" msgid "Selling" msgstr "" -#: erpnext/accounts/report/gross_profit/gross_profit.py:350 +#: erpnext/accounts/report/gross_profit/gross_profit.py:361 msgid "Selling Amount" msgstr "" @@ -44812,7 +44842,7 @@ msgstr "" #: erpnext/selling/doctype/selling_settings/selling_settings.json #: erpnext/selling/workspace/selling/selling.json #: erpnext/setup/workspace/erpnext_settings/erpnext_settings.json -#: erpnext/stock/doctype/stock_settings/stock_settings.py:221 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:222 msgid "Selling Settings" msgstr "" @@ -45052,7 +45082,7 @@ msgstr "" msgid "Serial No Range" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2513 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2516 msgid "Serial No Reserved" msgstr "" @@ -45132,7 +45162,7 @@ msgstr "" msgid "Serial No {0} does not exist" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3250 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3256 msgid "Serial No {0} does not exists" msgstr "" @@ -45186,7 +45216,7 @@ msgstr "" msgid "Serial Nos and Batches" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1799 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1802 msgid "Serial Nos are created successfully" msgstr "" @@ -45268,11 +45298,11 @@ msgstr "" msgid "Serial and Batch Bundle" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2021 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2024 msgid "Serial and Batch Bundle created" msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2093 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2096 msgid "Serial and Batch Bundle updated" msgstr "" @@ -46686,7 +46716,7 @@ msgstr "" msgid "Skip Material Transfer to WIP Warehouse" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:559 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:561 msgid "Skipped {0} DocType(s):
{1}" msgstr "" @@ -46737,7 +46767,7 @@ msgstr "" msgid "Solvency Ratios" msgstr "" -#: erpnext/controllers/accounts_controller.py:4310 +#: erpnext/controllers/accounts_controller.py:4316 msgid "Some required Company details are missing. You don't have permission to update them. Please contact your System Manager." msgstr "" @@ -46857,7 +46887,7 @@ msgstr "" msgid "Source Warehouse {0} must be same as Customer Warehouse {1} in the Subcontracting Inward Order." msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:72 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:85 msgid "Source and Target Location cannot be same" msgstr "" @@ -47628,9 +47658,9 @@ msgstr "" #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1699 #: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1716 #: erpnext/stock/doctype/stock_settings/stock_settings.json -#: erpnext/stock/doctype/stock_settings/stock_settings.py:178 -#: erpnext/stock/doctype/stock_settings/stock_settings.py:190 -#: erpnext/stock/doctype/stock_settings/stock_settings.py:204 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:179 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:191 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:205 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:182 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:195 #: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:207 @@ -48640,11 +48670,11 @@ msgstr "" msgid "Suggestions" msgstr "" -#: erpnext/setup/doctype/email_digest/email_digest.py:188 +#: erpnext/setup/doctype/email_digest/email_digest.py:186 msgid "Summary for this month and pending activities" msgstr "" -#: erpnext/setup/doctype/email_digest/email_digest.py:185 +#: erpnext/setup/doctype/email_digest/email_digest.py:183 msgid "Summary for this week and pending activities" msgstr "" @@ -49445,11 +49475,11 @@ msgstr "" msgid "Target Location" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:70 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:83 msgid "Target Location is required for transferring Asset {0}" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:76 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:89 msgid "Target Location is required while receiving Asset {0}" msgstr "" @@ -49623,7 +49653,7 @@ msgstr "" #. Label of the amount (Currency) field in DocType 'Item Wise Tax Detail' #: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:169 +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:163 #: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:115 msgid "Tax Amount" msgstr "" @@ -49983,6 +50013,7 @@ msgstr "" #. Label of the taxable_amount (Currency) field in DocType 'Item Wise Tax #. Detail' #: erpnext/accounts/doctype/item_wise_tax_detail/item_wise_tax_detail.json +#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:157 #: erpnext/controllers/taxes_and_totals.py:1207 msgid "Taxable Amount" msgstr "" @@ -50413,7 +50444,7 @@ msgstr "" #: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py:182 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.js:68 #: erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py:171 -#: erpnext/accounts/report/gross_profit/gross_profit.py:425 +#: erpnext/accounts/report/gross_profit/gross_profit.py:436 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js:8 #: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:21 #: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:251 @@ -50442,7 +50473,7 @@ msgstr "" #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.js:59 #: erpnext/selling/report/sales_partner_transaction_summary/sales_partner_transaction_summary.py:39 #: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.js:46 -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:60 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:61 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js:59 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:72 #: erpnext/selling/report/territory_wise_sales/territory_wise_sales.py:22 @@ -50569,7 +50600,7 @@ msgstr "" msgid "The Serial No at Row #{0}: {1} is not available in warehouse {2}." msgstr "" -#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2510 +#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2513 msgid "The Serial No {0} is reserved against the {1} {2} and cannot be used for any other transaction." msgstr "" @@ -50684,7 +50715,7 @@ msgstr "" msgid "The following rows are duplicates:" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:892 +#: erpnext/stock/doctype/material_request/material_request.py:895 msgid "The following {0} were created: {1}" msgstr "" @@ -50787,7 +50818,7 @@ msgstr "" msgid "The percentage you are allowed to transfer more against the quantity ordered. For example, if you have ordered 100 units, and your Allowance is 10%, then you are allowed transfer 110 units." msgstr "" -#: erpnext/public/js/utils.js:872 +#: erpnext/public/js/utils.js:876 msgid "The reserved stock will be released when you update items. Are you certain you wish to proceed?" msgstr "" @@ -50926,7 +50957,7 @@ msgstr "" msgid "The {0} prefix '{1}' already exists. Please change the Serial No Series, otherwise you will get a Duplicate Entry error." msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:898 +#: erpnext/stock/doctype/material_request/material_request.py:901 msgid "The {0} {1} created successfully" msgstr "" @@ -51037,7 +51068,7 @@ msgstr "" msgid "This Item is a Variant of {0} (Template)." msgstr "" -#: erpnext/setup/doctype/email_digest/email_digest.py:187 +#: erpnext/setup/doctype/email_digest/email_digest.py:185 msgid "This Month's Summary" msgstr "" @@ -51049,7 +51080,7 @@ msgstr "" msgid "This Sales Order has been fully subcontracted." msgstr "" -#: erpnext/setup/doctype/email_digest/email_digest.py:184 +#: erpnext/setup/doctype/email_digest/email_digest.py:182 msgid "This Week's Summary" msgstr "" @@ -51786,7 +51817,7 @@ msgstr "" msgid "To use a different finance book, please uncheck 'Include Default FB Assets'" msgstr "" -#: erpnext/accounts/doctype/financial_report_template/financial_report_engine.py:709 +#: erpnext/accounts/doctype/financial_report_template/financial_report_engine.py:705 #: erpnext/accounts/report/financial_statements.py:624 #: erpnext/accounts/report/general_ledger/general_ledger.py:310 #: erpnext/accounts/report/trial_balance/trial_balance.py:310 @@ -51948,8 +51979,6 @@ msgstr "" #. Label of the total_amount (Currency) field in DocType 'Stock Entry' #: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.json #: erpnext/accounts/doctype/journal_entry/journal_entry.json -#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py:157 -#: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:109 #: erpnext/selling/page/sales_funnel/sales_funnel.py:167 #: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json #: erpnext/stock/doctype/stock_entry/stock_entry.json @@ -52471,6 +52500,10 @@ msgstr "" msgid "Total Tax" msgstr "" +#: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.py:109 +msgid "Total Taxable Amount" +msgstr "" + #. Label of the total_taxes_and_charges (Currency) field in DocType 'Payment #. Entry' #. Label of the total_taxes_and_charges (Currency) field in DocType 'POS @@ -52784,11 +52817,11 @@ msgstr "" msgid "Transaction Deletion Record To Delete" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1096 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1098 msgid "Transaction Deletion Record {0} is already running. {1}" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1115 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:1117 msgid "Transaction Deletion Record {0} is currently deleting {1}. Cannot save documents until deletion completes." msgstr "" @@ -52854,6 +52887,10 @@ msgstr "" msgid "Transaction currency: {0} cannot be different from Bank Account({1}) currency: {2}" msgstr "" +#: erpnext/assets/doctype/asset_movement/asset_movement.py:65 +msgid "Transaction date can't be earlier than previous movement date" +msgstr "" + #. Description of the 'Applicable For' (Section Break) field in DocType 'Tax #. Withholding Entry' #: erpnext/accounts/doctype/tax_withholding_entry/tax_withholding_entry.json @@ -53271,7 +53308,7 @@ msgstr "" #: erpnext/manufacturing/doctype/workstation/workstation.js:480 #: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:70 #: erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py:110 -#: erpnext/public/js/stock_analytics.js:94 erpnext/public/js/utils.js:745 +#: erpnext/public/js/stock_analytics.js:94 erpnext/public/js/utils.js:749 #: erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.json #: erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json #: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json @@ -53407,7 +53444,7 @@ msgstr "" msgid "UnReconcile Allocations" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:462 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:464 msgid "Unable to fetch DocType details. Please contact system administrator." msgstr "" @@ -53496,7 +53533,7 @@ msgstr "" msgid "Under Working Hours table, you can add start and end times for a Workstation. For example, a Workstation may be active from 9 am to 1 pm, then 2 pm to 5 pm. You can also specify the working hours based on shifts. While scheduling a Work Order, the system will check for the availability of the Workstation based on the working hours specified." msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:931 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:933 msgid "Unexpected Naming Series Pattern" msgstr "" @@ -53863,7 +53900,7 @@ msgstr "" #: erpnext/buying/doctype/purchase_order/purchase_order.js:324 #: erpnext/buying/doctype/supplier_quotation/supplier_quotation.js:43 -#: erpnext/public/js/utils.js:851 +#: erpnext/public/js/utils.js:855 #: erpnext/selling/doctype/quotation/quotation.js:135 #: erpnext/selling/doctype/sales_order/sales_order.js:75 #: erpnext/selling/doctype/sales_order/sales_order.js:940 @@ -54490,7 +54527,7 @@ msgstr "" #. Label of the valuation_rate (Currency) field in DocType 'Stock #. Reconciliation Item' #: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json -#: erpnext/accounts/report/gross_profit/gross_profit.py:343 +#: erpnext/accounts/report/gross_profit/gross_profit.py:354 #: erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json #: erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json #: erpnext/manufacturing/doctype/bom/bom.json @@ -55860,7 +55897,7 @@ msgstr "" #: erpnext/selling/doctype/sales_order/sales_order.js:1050 #: erpnext/stock/doctype/material_request/material_request.js:216 #: erpnext/stock/doctype/material_request/material_request.json -#: erpnext/stock/doctype/material_request/material_request.py:899 +#: erpnext/stock/doctype/material_request/material_request.py:902 #: erpnext/stock/doctype/pick_list/pick_list.json #: erpnext/stock/doctype/serial_no/serial_no.json #: erpnext/stock/doctype/stock_entry/stock_entry.json @@ -55920,7 +55957,7 @@ msgstr "" msgid "Work Order Summary" msgstr "" -#: erpnext/stock/doctype/material_request/material_request.py:905 +#: erpnext/stock/doctype/material_request/material_request.py:908 msgid "Work Order cannot be created for following reason:
{0}" msgstr "" @@ -55946,7 +55983,7 @@ msgid "Work Order {0}: Job Card not found for the operation {1}" msgstr "" #: erpnext/manufacturing/report/job_card_summary/job_card_summary.js:56 -#: erpnext/stock/doctype/material_request/material_request.py:893 +#: erpnext/stock/doctype/material_request/material_request.py:896 msgid "Work Orders" msgstr "" @@ -56413,7 +56450,7 @@ msgstr "" msgid "You had {} errors while creating opening invoices. Check {} for more details" msgstr "" -#: erpnext/public/js/utils.js:951 +#: erpnext/public/js/utils.js:955 msgid "You have already selected items from {0} {1}" msgstr "" @@ -56421,7 +56458,7 @@ msgstr "" msgid "You have been invited to collaborate on the project {0}." msgstr "" -#: erpnext/stock/doctype/stock_settings/stock_settings.py:216 +#: erpnext/stock/doctype/stock_settings/stock_settings.py:217 msgid "You have enabled {0} and {1} in {2}. This can lead to prices from the default price list being inserted in the transaction price list." msgstr "" @@ -56575,7 +56612,7 @@ msgstr "" msgid "discount applied" msgstr "" -#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:46 +#: erpnext/selling/report/sales_person_commission_summary/sales_person_commission_summary.py:47 #: erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py:58 msgid "doc_type" msgstr "" @@ -56922,7 +56959,7 @@ msgstr "" msgid "{0} and {1} are mandatory" msgstr "" -#: erpnext/assets/doctype/asset_movement/asset_movement.py:41 +#: erpnext/assets/doctype/asset_movement/asset_movement.py:42 msgid "{0} asset cannot be transferred" msgstr "" @@ -57007,7 +57044,7 @@ msgstr "" msgid "{0} in row {1}" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:448 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:450 msgid "{0} is a child table and will be deleted automatically with its parent" msgstr "" @@ -57021,7 +57058,7 @@ msgstr "" msgid "{0} is added multiple times on rows: {1}" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:624 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:626 msgid "{0} is already running for {1}" msgstr "" @@ -57074,7 +57111,7 @@ msgstr "" msgid "{0} is not enabled in {1}" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:632 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:634 msgid "{0} is not running. Cannot trigger events for this Document" msgstr "" @@ -57382,19 +57419,19 @@ msgstr "" msgid "{0}, complete the operation {1} before the operation {2}." msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:519 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:521 msgid "{0}: Child table (auto-deleted with parent)" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:514 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:516 msgid "{0}: Not found" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:510 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:512 msgid "{0}: Protected DocType" msgstr "" -#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:524 +#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:526 msgid "{0}: Virtual DocType (no database table)" msgstr "" From e46e8741b44c6ade4d2ae0f116657486cb05c324 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 16 Feb 2026 10:38:15 +0530 Subject: [PATCH 11/31] fix: better validation for negative batch (cherry picked from commit a8636e4f59d60759e3e988c4f2817c206663886e) --- .../serial_and_batch_bundle.py | 36 +++++++++++++------ .../stock_settings/stock_settings.json | 4 +-- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 6376f6b9f4e..2229e934491 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -17,6 +17,7 @@ from frappe.utils import ( cint, cstr, flt, + format_datetime, get_datetime, get_link_to_form, getdate, @@ -1459,22 +1460,33 @@ class SerialandBatchBundle(Document): if flt(available_qty, precision) < 0: self.throw_negative_batch(d.batch_no, available_qty, precision) - def throw_negative_batch(self, batch_no, available_qty, precision): + def throw_negative_batch(self, batch_no, available_qty, precision, posting_datetime=None): from erpnext.stock.stock_ledger import NegativeStockError if frappe.db.get_single_value("Stock Settings", "allow_negative_stock_for_batch"): return + date_msg = "" + if posting_datetime: + date_msg = " " + _("as of {0}").format(format_datetime(posting_datetime)) + + msg = _( + """ + The Batch {0} of an item {1} has negative stock in the warehouse {2}{3}. + Please add a stock quantity of {4} to proceed with this entry. + If it is not possible to make an adjustment entry, please enable 'Allow Negative Stock for Batch' in Stock Settings to proceed. + However, enabling this setting may lead to negative stock in the system. + So please ensure the stock levels are adjusted as soon as possible to maintain the correct valuation rate.""" + ).format( + bold(batch_no), + bold(self.item_code), + bold(self.warehouse), + date_msg, + bold(abs(flt(available_qty, precision))), + ) + frappe.throw( - _( - """ - The Batch {0} of an item {1} has negative stock in the warehouse {2}. Please add a stock quantity of {3} to proceed with this entry.""" - ).format( - bold(batch_no), - bold(self.item_code), - bold(self.warehouse), - bold(abs(flt(available_qty, precision))), - ), + msg, title=_("Negative Stock Error"), exc=NegativeStockError, ) @@ -1497,7 +1509,9 @@ class SerialandBatchBundle(Document): available_qty[row.batch_no] = flt(row.qty) if flt(available_qty[row.batch_no], precision) < 0: - self.throw_negative_batch(row.batch_no, available_qty[row.batch_no], precision) + self.throw_negative_batch( + row.batch_no, available_qty[row.batch_no], precision, row.posting_datetime + ) return available_qty diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json index e3851b5b41f..a9f6d1904a3 100644 --- a/erpnext/stock/doctype/stock_settings/stock_settings.json +++ b/erpnext/stock/doctype/stock_settings/stock_settings.json @@ -550,7 +550,7 @@ }, { "default": "0", - "description": "If enabled, the system will allow negative stock entries for the batch, but this could calculate the valuation rate incorrectly, so avoid using this option.", + "description": "If enabled, the system will allow negative stock entries for the batch. But, this may lead to incorrect valuation rates, so it is recommended to avoid using this option. The system will permit negative stock only when it is caused by backdated entries and will validate and block negative stock in all other cases.", "fieldname": "allow_negative_stock_for_batch", "fieldtype": "Check", "label": "Allow Negative Stock for Batch" @@ -562,7 +562,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2026-02-09 15:01:12.466175", + "modified": "2026-02-16 10:36:59.921491", "modified_by": "Administrator", "module": "Stock", "name": "Stock Settings", From 28592d01802266b6a61eaf7df93a6ed39dd6d13b Mon Sep 17 00:00:00 2001 From: Soham Kulkarni <77533095+sokumon@users.noreply.github.com> Date: Mon, 16 Feb 2026 21:06:30 +0530 Subject: [PATCH 12/31] fix(pos_invoice): add correct depends on condition (#52689) * fix(pos_invoice): add correct depends on condition * fix: show field in sales order * refactor: eval condition (cherry picked from commit 219cf6bc5728cda02f333ad8076530ae7b29fed2) --- .../sales_invoice_payment/sales_invoice_payment.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json index 1389e0992d3..dc50e65d258 100644 --- a/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json +++ b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json @@ -26,7 +26,7 @@ }, { "default": "0", - "depends_on": "eval:parent.doctype == 'Sales Invoice'", + "depends_on": "eval: [\"POS Invoice\", \"Sales Invoice\"].includes(parent.doctype)", "fieldname": "amount", "fieldtype": "Currency", "in_list_view": 1, @@ -85,14 +85,15 @@ ], "istable": 1, "links": [], - "modified": "2024-03-27 13:10:36.427565", + "modified": "2026-02-16 20:46:34.592604", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Payment", "owner": "Administrator", "permissions": [], "quick_entry": 1, + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} From ac90975f4306d191059f4caa898fedeb9b49b043 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 16 Feb 2026 19:19:30 +0530 Subject: [PATCH 13/31] fix: cancel SABB if SLE cancelled from LCV (cherry picked from commit f23a49a25ee0f7f7a479c2bb6ced9fc197e3fa44) --- erpnext/controllers/buying_controller.py | 21 +++- .../purchase_receipt/test_purchase_receipt.py | 96 +++++++++++++++++++ .../serial_and_batch_bundle.py | 3 + 3 files changed, 118 insertions(+), 2 deletions(-) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 837bbbc793c..86cfbc01172 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -783,7 +783,9 @@ class BuyingController(SubcontractingController): or self.is_return or (self.is_internal_transfer() and self.docstatus == 2) else self.get_package_for_target_warehouse( - d, type_of_transaction=type_of_transaction + d, + type_of_transaction=type_of_transaction, + via_landed_cost_voucher=via_landed_cost_voucher, ) ), }, @@ -871,7 +873,22 @@ class BuyingController(SubcontractingController): via_landed_cost_voucher=via_landed_cost_voucher, ) - def get_package_for_target_warehouse(self, item, warehouse=None, type_of_transaction=None) -> str: + def get_package_for_target_warehouse( + self, item, warehouse=None, type_of_transaction=None, via_landed_cost_voucher=None + ) -> str: + if via_landed_cost_voucher and item.get("warehouse"): + if sabb := frappe.db.get_value( + "Serial and Batch Bundle", + { + "voucher_detail_no": item.name, + "warehouse": item.get("warehouse"), + "docstatus": 1, + "is_cancelled": 0, + }, + "name", + ): + return sabb + if not item.serial_and_batch_bundle: return "" diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index df0b28f696e..7fb31928ac5 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -1017,6 +1017,102 @@ class TestPurchaseReceipt(IntegrationTestCase): pr.cancel() + def test_lcv_for_internal_transfer(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 + from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import ( + make_landed_cost_voucher, + ) + + prepare_data_for_internal_transfer() + + customer = "_Test Internal Customer 2" + company = "_Test Company with perpetual inventory" + + item_code = make_item( + "Test Item For LCV in Internal Transfer", + {"has_batch_no": 1, "create_new_batch": 1, "batch_naming_series": "TEST-SBATCH.###"}, + ).name + + pr1 = make_purchase_receipt( + item_code=item_code, + qty=10, + rate=100, + warehouse="Stores - TCP1", + company="_Test Company with perpetual inventory", + ) + + dn1 = create_delivery_note( + item_code=pr1.items[0].item_code, + company=company, + customer=customer, + cost_center="Main - TCP1", + expense_account="Cost of Goods Sold - TCP1", + qty=10, + rate=500, + warehouse="Stores - TCP1", + target_warehouse="Work In Progress - TCP1", + ) + + pr = make_inter_company_purchase_receipt(dn1.name) + pr.items[0].from_warehouse = "Work In Progress - TCP1" + pr.items[0].warehouse = "Stores - TCP1" + pr.submit() + + sle_entries = frappe.get_all( + "Stock Ledger Entry", + filters={"voucher_type": "Purchase Receipt", "voucher_no": pr.name}, + fields=["serial_and_batch_bundle", "actual_qty"], + ) + self.assertEqual(len(sle_entries), 2) + + inward_sabb = frappe.get_all( + "Serial and Batch Bundle", + filters={ + "voucher_type": "Purchase Receipt", + "voucher_no": pr.name, + "total_qty": (">", 0), + "docstatus": 1, + }, + pluck="name", + ) + self.assertEqual(len(inward_sabb), 1) + + original_cost = frappe.db.get_value("Serial and Batch Bundle", inward_sabb[0], "total_amount") + + make_landed_cost_voucher( + company=pr.company, + receipt_document_type="Purchase Receipt", + receipt_document=pr.name, + charges=100, + distribute_charges_based_on="Qty", + expense_account="Expenses Included In Valuation - TCP1", + ) + + sle_entries = frappe.get_all( + "Stock Ledger Entry", + filters={"voucher_type": "Purchase Receipt", "voucher_no": pr.name, "is_cancelled": 0}, + fields=["serial_and_batch_bundle", "actual_qty"], + ) + self.assertEqual(len(sle_entries), 2) + + new_inward_sabb = frappe.get_all( + "Serial and Batch Bundle", + filters={ + "voucher_type": "Purchase Receipt", + "voucher_no": pr.name, + "total_qty": (">", 0), + "docstatus": 1, + }, + pluck="name", + ) + self.assertEqual(len(new_inward_sabb), 1) + + new_cost = frappe.db.get_value("Serial and Batch Bundle", new_inward_sabb[0], "total_amount") + self.assertEqual(new_cost, original_cost + 100) + + self.assertTrue(new_inward_sabb[0] == inward_sabb[0]) + def test_stock_transfer_from_purchase_receipt_with_valuation(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/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 2229e934491..2d6c44defa7 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -1570,6 +1570,9 @@ class SerialandBatchBundle(Document): return query.run(as_dict=True) def validate_voucher_no_docstatus(self): + if self.is_cancelled: + return + if self.voucher_type == "POS Invoice": return From f08964683a2b60b9ccb7c02fc30ea3b5937a0c84 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 15 Feb 2026 20:54:44 +0530 Subject: [PATCH 14/31] chore: do not show stock details if update stock is disabled (cherry picked from commit 4499e974a0edeef91ff7fa3527dbea7376a6f762) # Conflicts: # erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json --- .../purchase_invoice_item.json | 13 +++++++------ .../sales_invoice_item/sales_invoice_item.json | 12 ++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index d007f4bf8cd..42fea055aeb 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -52,6 +52,7 @@ "stock_uom_rate", "is_free_item", "apply_tds", + "allow_zero_valuation_rate", "section_break_22", "net_rate", "net_amount", @@ -97,7 +98,6 @@ "service_start_date", "service_end_date", "reference", - "allow_zero_valuation_rate", "item_tax_rate", "bom", "include_exploded_items", @@ -420,6 +420,7 @@ "options": "UOM" }, { + "depends_on": "eval:parent.update_stock", "fieldname": "warehouse_section", "fieldtype": "Section Break", "label": "Warehouse" @@ -800,7 +801,7 @@ "read_only": 1 }, { - "depends_on": "eval:parent.is_internal_supplier && parent.update_stock", + "depends_on": "eval:parent.is_internal_supplier", "fieldname": "from_warehouse", "fieldtype": "Link", "ignore_user_permissions": 1, @@ -896,7 +897,7 @@ "label": "Consider for Tax Withholding" }, { - "depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)", + "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1", "fieldname": "serial_and_batch_bundle", "fieldtype": "Link", "label": "Serial and Batch Bundle", @@ -906,7 +907,7 @@ "search_index": 1 }, { - "depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)", + "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1", "fieldname": "rejected_serial_and_batch_bundle", "fieldtype": "Link", "label": "Rejected Serial and Batch Bundle", @@ -922,7 +923,7 @@ "options": "Asset" }, { - "depends_on": "eval:parent.update_stock === 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)", + "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1", "fieldname": "add_serial_batch_bundle", "fieldtype": "Button", "label": "Add Serial / Batch No" @@ -992,7 +993,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2025-12-13 14:10:02.379392", + "modified": "2026-02-15 20:52:20.097603", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 7608ea87de8..cab85d7e5f7 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -52,6 +52,7 @@ "is_free_item", "apply_tds", "grant_commission", + "allow_zero_valuation_rate", "section_break_21", "net_rate", "net_amount", @@ -88,7 +89,6 @@ "serial_and_batch_bundle", "use_serial_batch_fields", "col_break5", - "allow_zero_valuation_rate", "incoming_rate", "item_tax_rate", "actual_batch_qty", @@ -580,6 +580,7 @@ { "collapsible": 1, "collapsible_depends_on": "eval:doc.serial_no || doc.batch_no", + "depends_on": "eval:parent.update_stock", "fieldname": "warehouse_and_reference", "fieldtype": "Section Break", "label": "Stock Details" @@ -595,7 +596,7 @@ "print_hide": 1 }, { - "depends_on": "eval: parent.is_internal_customer && parent.update_stock", + "depends_on": "eval: parent.is_internal_customer", "fieldname": "target_warehouse", "fieldtype": "Link", "hidden": 1, @@ -906,7 +907,7 @@ "read_only": 1 }, { - "depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)", + "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1", "fieldname": "serial_and_batch_bundle", "fieldtype": "Link", "label": "Serial and Batch Bundle", @@ -916,7 +917,6 @@ "search_index": 1 }, { - "depends_on": "eval:parent.update_stock === 1", "fieldname": "pick_serial_and_batch", "fieldtype": "Button", "label": "Pick Serial / Batch No" @@ -1009,7 +1009,11 @@ "idx": 1, "istable": 1, "links": [], +<<<<<<< HEAD "modified": "2025-09-04 11:08:25.583561", +======= + "modified": "2026-02-15 20:50:18.580088", +>>>>>>> 4499e974a0 (chore: do not show stock details if update stock is disabled) "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", From 7677b2f5737b378543e2b7deb5831ebf4bcc5323 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 15 Feb 2026 21:06:26 +0530 Subject: [PATCH 15/31] chore: do not show serial batch selector if not needed (cherry picked from commit cdc62e7327735ebfb1dcc26634bd2c46878fb349) # Conflicts: # erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json --- .../purchase_invoice_item/purchase_invoice_item.json | 8 +++----- .../doctype/sales_invoice_item/sales_invoice_item.json | 8 ++++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 42fea055aeb..00951fdd4cc 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -448,7 +448,6 @@ "print_hide": 1 }, { - "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1", "fieldname": "batch_no", "fieldtype": "Link", "label": "Batch No", @@ -460,14 +459,12 @@ "fieldtype": "Column Break" }, { - "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1", "fieldname": "serial_no", "fieldtype": "Text", "label": "Serial No", "no_copy": 1 }, { - "depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1", "fieldname": "rejected_serial_no", "fieldtype": "Text", "label": "Rejected Serial No", @@ -578,6 +575,7 @@ }, { "default": "0", + "depends_on": "eval:parent.update_stock", "fieldname": "allow_zero_valuation_rate", "fieldtype": "Check", "label": "Allow Zero Valuation Rate", @@ -923,7 +921,7 @@ "options": "Asset" }, { - "depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1", + "depends_on": "eval:doc.use_serial_batch_fields === 0 && doc.docstatus === 0", "fieldname": "add_serial_batch_bundle", "fieldtype": "Button", "label": "Add Serial / Batch No" @@ -993,7 +991,7 @@ "idx": 1, "istable": 1, "links": [], - "modified": "2026-02-15 20:52:20.097603", + "modified": "2026-02-15 21:07:49.455930", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index cab85d7e5f7..7c7109b30dc 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -614,7 +614,6 @@ "options": "Quality Inspection" }, { - "depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1", "fieldname": "batch_no", "fieldtype": "Link", "label": "Batch No", @@ -627,6 +626,7 @@ }, { "default": "0", + "depends_on": "eval:parent.update_stock", "fieldname": "allow_zero_valuation_rate", "fieldtype": "Check", "label": "Allow Zero Valuation Rate", @@ -634,7 +634,6 @@ "print_hide": 1 }, { - "depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1", "fieldname": "serial_no", "fieldtype": "Text", "label": "Serial No", @@ -917,6 +916,7 @@ "search_index": 1 }, { + "depends_on": "eval:doc.use_serial_batch_fields === 0 && doc.docstatus === 0", "fieldname": "pick_serial_and_batch", "fieldtype": "Button", "label": "Pick Serial / Batch No" @@ -1009,11 +1009,15 @@ "idx": 1, "istable": 1, "links": [], +<<<<<<< HEAD <<<<<<< HEAD "modified": "2025-09-04 11:08:25.583561", ======= "modified": "2026-02-15 20:50:18.580088", >>>>>>> 4499e974a0 (chore: do not show stock details if update stock is disabled) +======= + "modified": "2026-02-15 21:08:57.341638", +>>>>>>> cdc62e7327 (chore: do not show serial batch selector if not needed) "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", From ca8f324b51ca0580742d7b7d38b46b2890b2f63a Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 16 Feb 2026 23:02:15 +0530 Subject: [PATCH 16/31] fix: consider sle for negative stock validation (cherry picked from commit 38f35acffe74dbf82e01a52f20663efdd9d49b9e) --- .../serial_and_batch_bundle/serial_and_batch_bundle.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index 2d6c44defa7..f1b16da4b3e 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -1545,10 +1545,13 @@ class SerialandBatchBundle(Document): def get_available_qty_from_sabb(self): batches = [d.batch_no for d in self.entries if d.batch_no] + sle = frappe.qb.DocType("Stock Ledger Entry") child = frappe.qb.DocType("Serial and Batch Entry") query = ( frappe.qb.from_(child) + .inner_join(sle) + .on(child.parent == sle.serial_and_batch_bundle) .select( child.batch_no, child.qty, @@ -1557,6 +1560,7 @@ class SerialandBatchBundle(Document): ) .where( (child.item_code == self.item_code) + & (sle.is_cancelled == 0) & (child.warehouse == self.warehouse) & (child.is_cancelled == 0) & (child.batch_no.isin(batches)) From 605c0db976b3be2b97b42a6c22837dfece3062a9 Mon Sep 17 00:00:00 2001 From: Sudharsanan11 Date: Wed, 11 Feb 2026 23:45:38 +0530 Subject: [PATCH 17/31] fix(manufacturing): add sales order fields in subassembly child table (cherry picked from commit c2282eaf083b8fa7802bdeaffc1889b761101d8e) --- .../production_plan_sub_assembly_item.json | 24 ++++++++++++++++++- .../production_plan_sub_assembly_item.py | 2 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json index 5fbb83ae579..26d65116396 100644 --- a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json +++ b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json @@ -21,6 +21,9 @@ "subcontracting_section", "supplier", "purchase_order", + "column_break_oqry", + "sales_order", + "sales_order_item", "work_order_details_section", "production_plan_item", "wo_produced_qty", @@ -240,13 +243,32 @@ "label": "Ordered Qty", "no_copy": 1, "read_only": 1 + }, + { + "fieldname": "column_break_oqry", + "fieldtype": "Column Break" + }, + { + "fieldname": "sales_order", + "fieldtype": "Link", + "label": "Sales Order", + "options": "Sales Order", + "read_only": 1 + }, + { + "fieldname": "sales_order_item", + "fieldtype": "Data", + "hidden": 1, + "label": "Sales Order Item", + "no_copy": 1, + "print_hide": 1 } ], "grid_page_length": 50, "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2025-11-03 14:33:50.677717", + "modified": "2026-02-11 13:00:09.092676", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Plan Sub Assembly Item", diff --git a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py index 5cdcc6cf118..72ae9612176 100644 --- a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py +++ b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.py @@ -34,6 +34,8 @@ class ProductionPlanSubAssemblyItem(Document): qty: DF.Float received_qty: DF.Float required_qty: DF.Float + sales_order: DF.Link | None + sales_order_item: DF.Data | None schedule_date: DF.Datetime | None stock_reserved_qty: DF.Float stock_uom: DF.Link | None From f4b0e646b401c920a4925acb5d81ee596168b8a4 Mon Sep 17 00:00:00 2001 From: Sudharsanan11 Date: Wed, 11 Feb 2026 23:48:19 +0530 Subject: [PATCH 18/31] fix(manufacturing): set sales order references in subassembly child table (cherry picked from commit 0f2ed28ab74d743f18b755aa7a2e293e2abe7740) --- .../doctype/production_plan/production_plan.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index ab989185b73..9efb2063c91 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -844,6 +844,8 @@ class ProductionPlan(Document): "stock_uom", "bom_level", "schedule_date", + "sales_order", + "sales_order_item", ]: if row.get(field): wo_data[field] = row.get(field) @@ -898,6 +900,8 @@ class ProductionPlan(Document): "qty", "description", "production_plan_item", + "sales_order", + "sales_order_item", ]: po_data[field] = row.get(field) @@ -1122,6 +1126,10 @@ class ProductionPlan(Document): if not is_group_warehouse: data.fg_warehouse = self.sub_assembly_warehouse + if not self.combine_sub_items: + data.sales_order = row.sales_order + data.sales_order_item = row.sales_order_item + def set_default_supplier_for_subcontracting_order(self): items = [ d.production_item for d in self.sub_assembly_items if d.type_of_manufacturing == "Subcontract" From ecfd1930029fa70cde99a1fd059bb6219411744d Mon Sep 17 00:00:00 2001 From: Sudharsanan11 Date: Mon, 16 Feb 2026 23:20:32 +0530 Subject: [PATCH 19/31] test(manufacturing): add test to validate the sales order references for sub assembly items (cherry picked from commit 341dc4be7a67db5b8a6efa9cba958652ea1be4b1) --- .../production_plan/test_production_plan.py | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index e960e734bc1..b7787d6489b 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -626,6 +626,90 @@ class TestProductionPlan(IntegrationTestCase): frappe.db.count("Purchase Order Item", {"production_plan": plan.name, "docstatus": 1}), 2 ) # 2 since we have already created and submitted 2 POs + def test_sales_order_references_for_sub_assembly_items(self): + """ + Test that Sales Order and Sales Order Item references in Work Order and Purchase Order + are correctly propagated from the Production Plan. + """ + + from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom + + # Setup Test Items & BOM + fg_item = "Test FG Good Item" + sub_assembly_item1 = "Test Sub Assembly Item 1" + sub_assembly_item2 = "Test Sub Assembly Item 2" + + bom_tree = { + fg_item: { + sub_assembly_item1: {"Test Raw Material 1": {}}, + sub_assembly_item2: {"Test Raw Material 2": {}}, + } + } + + create_nested_bom(bom_tree, prefix="") + + # Create Sales Order + so = make_sales_order(item_code=fg_item, qty=10) + so_item_row = so.items[0].name + + # Create Production Plan from Sales Order + production_plan = frappe.new_doc("Production Plan") + production_plan.company = so.company + production_plan.get_items_from = "Sales Order" + production_plan.item_code = fg_item + + production_plan.get_open_sales_orders() + self.assertEqual(production_plan.sales_orders[0].sales_order, so.name) + + production_plan.get_so_items() + + production_plan.skip_available_sub_assembly_item = 0 + production_plan.get_sub_assembly_items() + + self.assertEqual(len(production_plan.sub_assembly_items), 2) + + # Validate Sales Order references in Sub Assembly Items + for row in production_plan.sub_assembly_items: + if row.production_item == sub_assembly_item1: + row.supplier = "_Test Supplier" + row.type_of_manufacturing = "Subcontract" + + self.assertEqual(row.sales_order, so.name) + self.assertEqual(row.sales_order_item, so_item_row) + + # Submit Production Plan + production_plan.save() + production_plan.submit() + production_plan.make_work_order() + + # Validate Purchase Order (Subcontracted Item) + po_items = frappe.get_all( + "Purchase Order Item", + { + "production_plan": production_plan.name, + "fg_item": sub_assembly_item1, + }, + ["sales_order", "sales_order_item"], + ) + + self.assertTrue(po_items) + self.assertEqual(po_items[0].sales_order, so.name) + self.assertEqual(po_items[0].sales_order_item, so_item_row) + + # Validate Work Order (In-house Item) + work_orders = frappe.get_all( + "Work Order", + { + "production_plan": production_plan.name, + "production_item": sub_assembly_item2, + }, + ["sales_order", "sales_order_item"], + ) + + self.assertTrue(work_orders) + self.assertEqual(work_orders[0].sales_order, so.name) + self.assertEqual(work_orders[0].sales_order_item, so_item_row) + def test_production_plan_for_mr_items(self): from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom From 80c98cdcf4838301ffa9a123472291a3529bdab2 Mon Sep 17 00:00:00 2001 From: Shllokkk Date: Wed, 11 Feb 2026 17:53:05 +0530 Subject: [PATCH 20/31] fix: prevent rows from being added to sub_assembly_items and mr_items (cherry picked from commit 25f979a825f7d6ab9c67ef713323f8cd6cfdcb8c) --- .../manufacturing/doctype/production_plan/production_plan.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js index 308eb32ca90..22c87fe5d6a 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js @@ -24,8 +24,8 @@ frappe.ui.form.on("Production Plan", { "Material Request": "Material Request", }; - frm.set_df_property("sub_assembly_items", "cannot_delete_rows", true); - frm.set_df_property("mr_items", "cannot_delete_rows", true); + frm.set_df_property("sub_assembly_items", "cannot_add_rows", true); + frm.set_df_property("mr_items", "cannot_add_rows", true); }, setup_queries(frm) { From 1820c35880e9ce5718493e5d8ab9dd94ada587ea Mon Sep 17 00:00:00 2001 From: diptanilsaha Date: Tue, 17 Feb 2026 00:23:01 +0530 Subject: [PATCH 21/31] fix(selling-workspace-sidebar): changed order of pos profile (cherry picked from commit 72f4fd08ee3ebda78b9905fcbe9c9c2a21d6ebde) --- erpnext/workspace_sidebar/selling.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/erpnext/workspace_sidebar/selling.json b/erpnext/workspace_sidebar/selling.json index 3ac2dc8665c..6b5b9707fe7 100644 --- a/erpnext/workspace_sidebar/selling.json +++ b/erpnext/workspace_sidebar/selling.json @@ -89,6 +89,17 @@ "show_arrow": 0, "type": "Link" }, + { + "child": 1, + "collapsible": 1, + "indent": 0, + "keep_closed": 0, + "label": "POS Profile", + "link_to": "POS Profile", + "link_type": "DocType", + "show_arrow": 0, + "type": "Link" + }, { "child": 1, "collapsible": 1, @@ -122,17 +133,6 @@ "show_arrow": 0, "type": "Link" }, - { - "child": 1, - "collapsible": 1, - "indent": 0, - "keep_closed": 0, - "label": "POS Profile", - "link_to": "POS Profile", - "link_type": "DocType", - "show_arrow": 0, - "type": "Link" - }, { "child": 1, "collapsible": 1, @@ -687,7 +687,7 @@ "type": "Link" } ], - "modified": "2026-01-10 00:06:13.103140", + "modified": "2026-02-16 23:48:24.611112", "modified_by": "Administrator", "module": "Selling", "name": "Selling", From 98ff54a87173686398dd51e8c99a436d3e7a349f Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 17 Feb 2026 10:40:34 +0530 Subject: [PATCH 22/31] chore: resolve conflicts --- .../doctype/sales_invoice_item/sales_invoice_item.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 7c7109b30dc..28a2256e2ec 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -1009,15 +1009,7 @@ "idx": 1, "istable": 1, "links": [], -<<<<<<< HEAD -<<<<<<< HEAD - "modified": "2025-09-04 11:08:25.583561", -======= - "modified": "2026-02-15 20:50:18.580088", ->>>>>>> 4499e974a0 (chore: do not show stock details if update stock is disabled) -======= "modified": "2026-02-15 21:08:57.341638", ->>>>>>> cdc62e7327 (chore: do not show serial batch selector if not needed) "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", From 62ea18f1cc620473b8bace56868bc982b1b7b275 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 17 Feb 2026 10:36:25 +0530 Subject: [PATCH 23/31] fix: production plan status (cherry picked from commit b3e6b304e46b20fc9112a18db1c6a183dcfb5ce1) --- .../production_plan/production_plan.py | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 9efb2063c91..947eb45787e 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -694,8 +694,8 @@ class ProductionPlan(Document): self.status = "Completed" if self.status != "Completed": - self.update_ordered_status() self.update_requested_status() + self.update_ordered_status() if close is not None: self.db_set("status", self.status) @@ -704,25 +704,17 @@ class ProductionPlan(Document): self.update_bin_qty() def update_ordered_status(self): - update_status = False - for d in self.po_items: - if d.planned_qty == d.ordered_qty: - update_status = True - - if update_status and self.status != "Completed": - self.status = "In Process" + for child_table in ["po_items", "sub_assembly_items"]: + for item in self.get(child_table): + if item.ordered_qty: + self.status = "In Process" + return def update_requested_status(self): - if not self.mr_items: - return - - update_status = True for d in self.mr_items: - if d.quantity != d.requested_qty: - update_status = False - - if update_status: - self.status = "Material Requested" + if d.requested_qty: + self.status = "Material Requested" + break def get_production_items(self): item_dict = {} From a039c176c8ae820791f14b1f3d811c052c12c6aa Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 17 Feb 2026 11:54:12 +0530 Subject: [PATCH 24/31] fix: do not allow plant floor company and warehouse to be updated (cherry picked from commit fd721327430210f0048f29909d1dd884e0c6a9e3) --- .../doctype/plant_floor/plant_floor.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/manufacturing/doctype/plant_floor/plant_floor.json b/erpnext/manufacturing/doctype/plant_floor/plant_floor.json index f595cfd5fc4..ceadefdf01b 100644 --- a/erpnext/manufacturing/doctype/plant_floor/plant_floor.json +++ b/erpnext/manufacturing/doctype/plant_floor/plant_floor.json @@ -49,7 +49,8 @@ "fieldname": "warehouse", "fieldtype": "Link", "label": "Warehouse", - "options": "Warehouse" + "options": "Warehouse", + "set_only_once": 1 }, { "depends_on": "eval:!doc.__islocal && doc.warehouse", @@ -66,13 +67,14 @@ "fieldname": "company", "fieldtype": "Link", "label": "Company", - "options": "Company" + "options": "Company", + "set_only_once": 1 } ], "hide_toolbar": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2024-09-25 10:27:41.139634", + "modified": "2026-02-17 11:53:17.940039", "modified_by": "Administrator", "module": "Manufacturing", "name": "Plant Floor", @@ -92,7 +94,8 @@ "write": 1 } ], + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} From 1dd471fb188d67e306cfdbf022d0548746399898 Mon Sep 17 00:00:00 2001 From: Vishnu Priya Baskaran <145791817+ervishnucs@users.noreply.github.com> Date: Tue, 17 Feb 2026 12:25:15 +0530 Subject: [PATCH 25/31] Merge pull request #52649 from aerele/fix-sales-funnel-layout fix: ensure layout has Bootstrap row and column (cherry picked from commit ae0be7f6ceef4fffa4235b8f2100f2f769594b46) --- erpnext/selling/page/sales_funnel/sales_funnel.css | 4 ++-- erpnext/selling/page/sales_funnel/sales_funnel.js | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/selling/page/sales_funnel/sales_funnel.css b/erpnext/selling/page/sales_funnel/sales_funnel.css index 60b2392ac43..e7301cb7086 100644 --- a/erpnext/selling/page/sales_funnel/sales_funnel.css +++ b/erpnext/selling/page/sales_funnel/sales_funnel.css @@ -1,4 +1,4 @@ .funnel-wrapper { - margin: 15px; - width: 100%; + width: calc(100% - 30px); + margin-left: 30px; } diff --git a/erpnext/selling/page/sales_funnel/sales_funnel.js b/erpnext/selling/page/sales_funnel/sales_funnel.js index 75bbdf862c0..a819c72dc80 100644 --- a/erpnext/selling/page/sales_funnel/sales_funnel.js +++ b/erpnext/selling/page/sales_funnel/sales_funnel.js @@ -8,6 +8,9 @@ frappe.pages["sales-funnel"].on_page_load = function (wrapper) { single_column: true, }); + $(wrapper).find(".layout-main").addClass("row"); + $(wrapper).find(".layout-main-section-wrapper").addClass("col-md-12"); + wrapper.sales_funnel = new erpnext.SalesFunnel(wrapper); frappe.breadcrumbs.add("Selling"); From 6ae1b18616357b511dd78f4e58f15625a664aed2 Mon Sep 17 00:00:00 2001 From: Shllokkk Date: Tue, 17 Feb 2026 12:28:15 +0530 Subject: [PATCH 26/31] fix: wrong display_depends_on condition for item group and brand child tables (cherry picked from commit de2843d9f1c3002af8ecd6e06e5c7da666127714) --- erpnext/accounts/doctype/pricing_rule/pricing_rule.json | 7 ++++--- erpnext/accounts/doctype/pricing_rule/pricing_rule.py | 2 +- .../doctype/pricing_rule_brand/pricing_rule_brand.json | 7 ++++--- .../pricing_rule_item_group/pricing_rule_item_group.json | 7 ++++--- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json index bc8c3280412..9a4eba07423 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json @@ -121,7 +121,7 @@ "in_list_view": 1, "in_standard_filter": 1, "label": "Apply On", - "options": "\nItem Code\nItem Group\nBrand\nTransaction", + "options": "Item Code\nItem Group\nBrand\nTransaction", "reqd": 1 }, { @@ -657,7 +657,7 @@ "icon": "fa fa-gift", "idx": 1, "links": [], - "modified": "2025-08-20 11:40:07.096854", + "modified": "2026-02-17 12:24:07.553505", "modified_by": "Administrator", "module": "Accounts", "name": "Pricing Rule", @@ -714,9 +714,10 @@ "write": 1 } ], + "row_format": "Dynamic", "show_name_in_global_search": 1, "sort_field": "creation", "sort_order": "DESC", "states": [], "title_field": "title" -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index 378d349e83d..5a4f3ca3249 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -45,7 +45,7 @@ class PricingRule(Document): apply_discount_on: DF.Literal["Grand Total", "Net Total"] apply_discount_on_rate: DF.Check apply_multiple_pricing_rules: DF.Check - apply_on: DF.Literal["", "Item Code", "Item Group", "Brand", "Transaction"] + apply_on: DF.Literal["Item Code", "Item Group", "Brand", "Transaction"] apply_recursion_over: DF.Float apply_rule_on_other: DF.Literal["", "Item Code", "Item Group", "Brand"] brands: DF.Table[PricingRuleBrand] diff --git a/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.json b/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.json index 67c0525539c..73413a88cf4 100644 --- a/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.json +++ b/erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.json @@ -10,7 +10,7 @@ ], "fields": [ { - "depends_on": "eval:parent.apply_on == 'Item Code'", + "depends_on": "eval:parent.apply_on == 'Brand'", "fieldname": "brand", "fieldtype": "Link", "in_list_view": 1, @@ -28,14 +28,15 @@ ], "istable": 1, "links": [], - "modified": "2024-03-27 13:10:17.857046", + "modified": "2026-02-17 12:17:13.073587", "modified_by": "Administrator", "module": "Accounts", "name": "Pricing Rule Brand", "owner": "Administrator", "permissions": [], + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.json b/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.json index a3ac16226e0..d1b5443dc0a 100644 --- a/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.json +++ b/erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.json @@ -10,7 +10,7 @@ ], "fields": [ { - "depends_on": "eval:parent.apply_on == 'Item Code'", + "depends_on": "eval:parent.apply_on == 'Item Group'", "fieldname": "item_group", "fieldtype": "Link", "in_list_view": 1, @@ -28,14 +28,15 @@ ], "istable": 1, "links": [], - "modified": "2024-03-27 13:10:18.221095", + "modified": "2026-02-17 12:16:57.778471", "modified_by": "Administrator", "module": "Accounts", "name": "Pricing Rule Item Group", "owner": "Administrator", "permissions": [], + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} From 531bdbc7276a52c72378602d460d862eaf5d318d Mon Sep 17 00:00:00 2001 From: Abdeali Chharchhoda Date: Thu, 12 Feb 2026 15:41:14 +0530 Subject: [PATCH 27/31] fix: correct typos in marketing campaign custom fields function (cherry picked from commit 6b7fed7f5929535f24cb79e0dbcf5daecb14f874) --- erpnext/patches/v15_0/migrate_to_utm_analytics.py | 4 ++-- erpnext/setup/install.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/patches/v15_0/migrate_to_utm_analytics.py b/erpnext/patches/v15_0/migrate_to_utm_analytics.py index 4385e1ab453..cd4762cc6e7 100644 --- a/erpnext/patches/v15_0/migrate_to_utm_analytics.py +++ b/erpnext/patches/v15_0/migrate_to_utm_analytics.py @@ -2,7 +2,7 @@ import click import frappe from frappe.query_builder.functions import Coalesce -from erpnext.setup.install import create_marketgin_campagin_custom_fields +from erpnext.setup.install import create_marketing_campaign_custom_fields def execute(): @@ -31,7 +31,7 @@ def execute(): frappe.delete_doc("DocType", "Lead Source", ignore_missing=True) campaign = frappe.qb.DocType("Campaign") - create_marketgin_campagin_custom_fields() + create_marketing_campaign_custom_fields() marketing_campaign = frappe.qb.DocType("UTM Campaign") # Fetch all Campaigns diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index 5738182529b..94706443d6b 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -23,7 +23,7 @@ def after_install(): set_single_defaults() create_print_setting_custom_fields() - create_marketgin_campagin_custom_fields() + create_marketing_campaign_custom_fields() create_custom_company_links() add_all_roles_to("Administrator") create_default_success_action() @@ -119,16 +119,16 @@ def create_print_setting_custom_fields(): ) -def create_marketgin_campagin_custom_fields(): +def create_marketing_campaign_custom_fields(): create_custom_fields( { "UTM Campaign": [ { - "label": _("Messaging CRM Campagin"), + "label": _("Messaging CRM Campaign"), "fieldname": "crm_campaign", "fieldtype": "Link", "options": "Campaign", - "insert_after": "campaign_decription", + "insert_after": "campaign_description", }, ] } From 2200b9aa678f799f43539411165950d44951e7d2 Mon Sep 17 00:00:00 2001 From: AarDG10 Date: Sun, 15 Feb 2026 23:18:49 +0530 Subject: [PATCH 28/31] fix: log changes made to accounts settings (cherry picked from commit 45febbabd743d65e58d3f73e024c4da28851b4ef) --- .../accounts/doctype/accounts_settings/accounts_settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index c77750cf9f0..0c7d78b4cfc 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -640,7 +640,7 @@ } ], "grid_page_length": 50, - "hide_toolbar": 1, + "hide_toolbar": 0, "icon": "icon-cog", "idx": 1, "index_web_pages_for_search": 1, From 6f812ccaf5eb55fa9253f7d90093711db24aeeaa Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 17 Feb 2026 15:39:52 +0530 Subject: [PATCH 29/31] fix: allow sequence id edit in BOM if routing is not set (cherry picked from commit 08529964b4407faee3ab3f6d6890fccc17ab038d) --- .../manufacturing/doctype/bom_operation/bom_operation.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json index 27025c12fdb..ad33af6dfff 100644 --- a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json +++ b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json @@ -146,7 +146,7 @@ "label": "Batch Size" }, { - "depends_on": "eval:doc.parenttype == \"Routing\"", + "depends_on": "eval:doc.parenttype == \"Routing\" || !parent.routing", "description": "If you want to run operations in parallel, keep the same sequence ID for them.", "fieldname": "sequence_id", "fieldtype": "Int", @@ -297,7 +297,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2026-01-01 17:15:59.806874", + "modified": "2026-02-17 15:33:28.495850", "modified_by": "Administrator", "module": "Manufacturing", "name": "BOM Operation", From dd4e1867f5f7fe3cbeca06d867b0afe124a0ad01 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 15 Feb 2026 20:29:57 +0530 Subject: [PATCH 30/31] fix: standalone credit/debit notes should not fetch any serial or batch by default (cherry picked from commit 2017edca88639515c0d8dc4735145837d1869542) --- erpnext/public/js/utils/serial_no_batch_selector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index 5cc7238d6dd..6610078b9b4 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -708,7 +708,7 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate { } render_data() { - if (this.bundle || this.frm.doc.is_return) { + if (this.bundle || (this.frm.doc.is_return && this.frm.doc.return_against)) { frappe .call({ method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_serial_batch_ledgers", From 8649543ae062addaafb99ab837f64df44f5faed2 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 17 Feb 2026 15:07:37 +0530 Subject: [PATCH 31/31] feat: Negative Batch report (cherry picked from commit 34edbed00bb4dad11deec87d7da613c1ab77dfdc) --- .../report/negative_batch_report/__init__.py | 0 .../negative_batch_report.js | 41 +++++ .../negative_batch_report.json | 53 +++++++ .../negative_batch_report.py | 145 ++++++++++++++++++ 4 files changed, 239 insertions(+) create mode 100644 erpnext/stock/report/negative_batch_report/__init__.py create mode 100644 erpnext/stock/report/negative_batch_report/negative_batch_report.js create mode 100644 erpnext/stock/report/negative_batch_report/negative_batch_report.json create mode 100644 erpnext/stock/report/negative_batch_report/negative_batch_report.py diff --git a/erpnext/stock/report/negative_batch_report/__init__.py b/erpnext/stock/report/negative_batch_report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/stock/report/negative_batch_report/negative_batch_report.js b/erpnext/stock/report/negative_batch_report/negative_batch_report.js new file mode 100644 index 00000000000..3bfe8fe9c85 --- /dev/null +++ b/erpnext/stock/report/negative_batch_report/negative_batch_report.js @@ -0,0 +1,41 @@ +// Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.query_reports["Negative Batch Report"] = { + filters: [ + { + fieldname: "company", + label: __("Company"), + fieldtype: "Link", + options: "Company", + default: frappe.defaults.get_default("company"), + }, + { + fieldname: "item_code", + label: __("Item Code"), + fieldtype: "Link", + options: "Item", + get_query: function () { + return { + filters: { + has_batch_no: 1, + }, + }; + }, + }, + { + fieldname: "warehouse", + label: __("Warehouse"), + fieldtype: "Link", + options: "Warehouse", + get_query: function () { + return { + filters: { + is_group: 0, + company: frappe.query_report.get_filter_value("company"), + }, + }; + }, + }, + ], +}; diff --git a/erpnext/stock/report/negative_batch_report/negative_batch_report.json b/erpnext/stock/report/negative_batch_report/negative_batch_report.json new file mode 100644 index 00000000000..cecc5716055 --- /dev/null +++ b/erpnext/stock/report/negative_batch_report/negative_batch_report.json @@ -0,0 +1,53 @@ +{ + "add_total_row": 0, + "add_translate_data": 0, + "columns": [], + "creation": "2026-02-17 11:34:21.549485", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "json": "", + "letter_head": null, + "modified": "2026-02-17 11:34:59.106045", + "modified_by": "Administrator", + "module": "Stock", + "name": "Negative Batch Report", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Serial and Batch Bundle", + "report_name": "Negative Batch Report", + "report_type": "Script Report", + "roles": [ + { + "role": "System Manager" + }, + { + "role": "Purchase User" + }, + { + "role": "Purchase Manager" + }, + { + "role": "Stock User" + }, + { + "role": "Stock Manager" + }, + { + "role": "Delivery User" + }, + { + "role": "Delivery Manager" + }, + { + "role": "Manufacturing User" + }, + { + "role": "Manufacturing Manager" + } + ], + "timeout": 0 +} diff --git a/erpnext/stock/report/negative_batch_report/negative_batch_report.py b/erpnext/stock/report/negative_batch_report/negative_batch_report.py new file mode 100644 index 00000000000..b12bd87d538 --- /dev/null +++ b/erpnext/stock/report/negative_batch_report/negative_batch_report.py @@ -0,0 +1,145 @@ +# Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ +from frappe.utils import add_to_date, flt, today + +from erpnext.stock.report.stock_ledger.stock_ledger import execute as stock_ledger_execute + + +def execute(filters: dict | None = None): + """Return columns and data for the report. + + This is the main entry point for the report. It accepts the filters as a + dictionary and should return columns and data. It is called by the framework + every time the report is refreshed or a filter is updated. + """ + columns = get_columns() + data = get_data(filters) + + return columns, data + + +def get_columns() -> list[dict]: + return [ + { + "label": _("Posting Datetime"), + "fieldname": "posting_date", + "fieldtype": "Datetime", + "width": 160, + }, + { + "label": _("Batch No"), + "fieldname": "batch_no", + "fieldtype": "Link", + "options": "Batch", + "width": 120, + }, + { + "label": _("Item Code"), + "fieldname": "item_code", + "fieldtype": "Link", + "options": "Item", + "width": 150, + }, + { + "label": _("Warehouse"), + "fieldname": "warehouse", + "fieldtype": "Link", + "options": "Warehouse", + "width": 160, + }, + { + "label": _("Previous Qty"), + "fieldname": "previous_qty", + "fieldtype": "Float", + "width": 130, + }, + { + "label": _("Transaction Qty"), + "fieldname": "actual_qty", + "fieldtype": "Float", + "width": 130, + }, + { + "label": _("Qty After Transaction"), + "fieldname": "qty_after_transaction", + "fieldtype": "Float", + "width": 180, + }, + { + "label": _("Document Type"), + "fieldname": "voucher_type", + "fieldtype": "Data", + "width": 130, + }, + { + "label": _("Document No"), + "fieldname": "voucher_no", + "fieldtype": "Dynamic Link", + "options": "voucher_type", + "width": 130, + }, + ] + + +def get_data(filters) -> list[dict]: + batches = get_batches(filters) + companies = get_companies(filters) + batch_negative_data = [] + + flt_precision = frappe.db.get_default("float_precision") or 2 + for company in companies: + for batch in batches: + _c, data = stock_ledger_execute( + frappe._dict( + { + "company": company, + "batch_no": batch, + "from_date": add_to_date(today(), years=-12), + "to_date": today(), + "segregate_serial_batch_bundle": 1, + "warehouse": filters.get("warehouse"), + "valuation_field_type": "Currency", + } + ) + ) + + previous_qty = 0 + for row in data: + if flt(row.get("qty_after_transaction"), flt_precision) < 0: + batch_negative_data.append( + { + "posting_date": row.get("date"), + "batch_no": row.get("batch_no"), + "item_code": row.get("item_code"), + "item_name": row.get("item_name"), + "warehouse": row.get("warehouse"), + "actual_qty": row.get("actual_qty"), + "qty_after_transaction": row.get("qty_after_transaction"), + "previous_qty": previous_qty, + "voucher_type": row.get("voucher_type"), + "voucher_no": row.get("voucher_no"), + } + ) + + previous_qty = row.get("qty_after_transaction") + + return batch_negative_data + + +def get_batches(filters): + batch_filters = {} + if filters.get("item_code"): + batch_filters["item"] = filters["item_code"] + + return frappe.get_all("Batch", pluck="name", filters=batch_filters) + + +def get_companies(filters): + company_filters = {} + if filters.get("company"): + company_filters["name"] = filters["company"] + + return frappe.get_all("Company", pluck="name", filters=company_filters)