diff --git a/erpnext/accounts/custom/address.py b/erpnext/accounts/custom/address.py
index 9e43514f94a..1c657b9a7a3 100644
--- a/erpnext/accounts/custom/address.py
+++ b/erpnext/accounts/custom/address.py
@@ -71,4 +71,6 @@ def get_shipping_address(company: str, address: str | None = None):
if address:
address_as_dict = address[0]
name, address_template = get_address_templates(address_as_dict)
- return address_as_dict.get("name"), frappe.render_template(address_template, address_as_dict)
+ return address_as_dict.get("name"), frappe.render_template(
+ address_template, address_as_dict, restrict_globals=True
+ )
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 6ed89c22f24..e0d8f15a664 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -730,6 +730,8 @@ def get_company_default_account_fields():
"default_discount_account": "Default Payment Discount Account",
"unrealized_profit_loss_account": "Unrealized Profit / Loss Account",
"exchange_gain_loss_account": "Exchange Gain / Loss Account",
+ "exchange_gain_account": "Exchange Gain Account",
+ "exchange_loss_account": "Exchange Loss Account",
"unrealized_exchange_gain_loss_account": "Unrealized Exchange Gain / Loss Account",
"round_off_account": "Round Off Account",
"default_deferred_revenue_account": "Default Deferred Revenue Account",
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/in_standard_chart_of_accounts.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/in_standard_chart_of_accounts.json
index af0aca38c93..dde312ed04b 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/in_standard_chart_of_accounts.json
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/in_standard_chart_of_accounts.json
@@ -179,6 +179,9 @@
},
"Impairment": {
"account_category": "Operating Expenses"
+ },
+ "Exchange Loss": {
+ "account_category": "Operating Expenses"
}
},
"root_type": "Expense"
@@ -196,6 +199,10 @@
"account_type": "Income Account"
},
"Indirect Income": {
+ "Exchange Gain": {
+ "account_type": "Income Account",
+ "account_category": "Other Operating Income"
+ },
"account_type": "Income Account",
"is_group": 1
},
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py
index 7901cc90230..cb9be411b2a 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py
@@ -138,6 +138,7 @@ def get():
_("Gain/Loss on Asset Disposal"): {"account_category": "Other Operating Income"},
_("Impairment"): {"account_category": "Operating Expenses"},
_("Tax Expense"): {"account_category": "Tax Expense"},
+ _("Exchange Loss"): {"account_category": "Operating Expenses"},
},
"root_type": "Expense",
},
@@ -149,6 +150,7 @@ def get():
_("Indirect Income"): {
_("Interest Income"): {"account_category": "Investment Income"},
_("Interest on Fixed Deposits"): {"account_category": "Investment Income"},
+ _("Exchange Gain"): {"account_category": "Other Operating Income"},
"is_group": 1,
},
"root_type": "Income",
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py b/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py
index e38369ceb1d..f2fe198bc65 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py
@@ -233,6 +233,7 @@ def get():
},
_("Impairment"): {"account_number": "5224", "account_category": "Operating Expenses"},
_("Tax Expense"): {"account_number": "5225", "account_category": "Tax Expense"},
+ _("Exchange Loss"): {"account_number": "5226", "account_category": "Operating Expenses"},
"account_number": "5200",
},
"root_type": "Expense",
@@ -250,6 +251,10 @@ def get():
"account_number": "4220",
"account_category": "Investment Income",
},
+ _("Exchange Gain"): {
+ "account_number": "4230",
+ "account_category": "Other Operating Income",
+ },
"is_group": 1,
"account_number": "4200",
},
diff --git a/erpnext/accounts/doctype/journal_entry/services/reference_validator.py b/erpnext/accounts/doctype/journal_entry/services/reference_validator.py
index 1d75b171d08..802ce4d8b2f 100644
--- a/erpnext/accounts/doctype/journal_entry/services/reference_validator.py
+++ b/erpnext/accounts/doctype/journal_entry/services/reference_validator.py
@@ -184,6 +184,7 @@ class JournalEntryReferenceValidator:
continue
invoice = frappe.get_doc(reference_type, reference_name)
self._validate_invoice_outstanding(invoice, total, reference_type, reference_name)
+ self._validate_block_invoice(invoice)
def _validate_invoice_outstanding(self, invoice, total, reference_type, reference_name) -> None:
"""Payment booked against an invoice cannot exceed its outstanding amount."""
@@ -197,3 +198,15 @@ class JournalEntryReferenceValidator:
reference_type, reference_name, invoice.outstanding_amount
)
)
+
+ def _validate_block_invoice(self, invoice):
+ """Payment cannnot be booked against blocked Purchase Invoices"""
+ if invoice.doctype != "Purchase Invoice":
+ return
+
+ if invoice.invoice_is_blocked():
+ frappe.throw(
+ _("{0} {1} is blocked and on hold until {2}.").format(
+ invoice.doctype, invoice.name, invoice.release_date
+ )
+ )
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index 17d86dbf06b..de773579dce 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt
import frappe
-from frappe.utils import flt, nowdate
+from frappe.utils import add_days, flt, nowdate
from erpnext.accounts.doctype.account.test_account import get_inventory_account
from erpnext.accounts.doctype.journal_entry.journal_entry import StockAccountInvalidTransaction
@@ -748,6 +748,69 @@ class TestJournalEntry(ERPNextTestSuite):
self.assertEqual(jv.reference_types[invoice.name], "Sales Invoice")
self.assertEqual(jv.reference_accounts[invoice.name], "Debtors - _TC")
+ def make_jv_against_purchase_invoice(self, invoice, amount=100):
+ jv = make_journal_entry("Creditors - _TC", "_Test Cash - _TC", amount, save=False)
+ jv.accounts[0].party_type = "Supplier"
+ jv.accounts[0].party = invoice.supplier
+ jv.accounts[0].reference_type = "Purchase Invoice"
+ jv.accounts[0].reference_name = invoice.name
+ return jv
+
+ def test_jv_against_purchase_invoice_respects_hold_state(self):
+ """Payment can be booked against a Purchase Invoice only while it is not on hold."""
+ from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
+
+ release_date = add_days(nowdate(), 10)
+
+ def never_held():
+ return make_purchase_invoice()
+
+ def held_until_a_future_date():
+ invoice = make_purchase_invoice()
+ invoice.block_invoice(hold_comment="Waiting for the goods", release_date=release_date)
+ return invoice
+
+ def held_without_a_release_date():
+ invoice = make_purchase_invoice()
+ invoice.block_invoice(hold_comment="Under dispute")
+ return invoice
+
+ def held_until_a_date_that_has_passed():
+ invoice = held_until_a_future_date()
+ frappe.db.set_value("Purchase Invoice", invoice.name, "release_date", add_days(nowdate(), -1))
+ return invoice
+
+ def unblocked_again():
+ invoice = held_until_a_future_date()
+ invoice.unblock_invoice()
+ return invoice
+
+ for build_invoice in (held_until_a_future_date, held_without_a_release_date):
+ with self.subTest(build_invoice.__name__):
+ jv = self.make_jv_against_purchase_invoice(build_invoice())
+ self.assertRaisesRegex(frappe.ValidationError, "is blocked and on hold until", jv.insert)
+
+ for build_invoice in (never_held, held_until_a_date_that_has_passed, unblocked_again):
+ with self.subTest(build_invoice.__name__):
+ invoice = build_invoice()
+ jv = self.make_jv_against_purchase_invoice(invoice)
+ jv.insert()
+ self.assertEqual(jv.reference_types[invoice.name], "Purchase Invoice")
+
+ def test_jv_against_blocked_sales_invoice_reference_is_not_checked(self):
+ """A Sales Invoice has no hold state, so the check must skip it rather than fail."""
+ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
+
+ invoice = create_sales_invoice(rate=500)
+ jv = make_journal_entry("_Test Cash - _TC", "Debtors - _TC", 100, save=False)
+ jv.accounts[1].party_type = "Customer"
+ jv.accounts[1].party = "_Test Customer"
+ jv.accounts[1].reference_type = "Sales Invoice"
+ jv.accounts[1].reference_name = invoice.name
+ jv.insert()
+
+ self.assertEqual(jv.reference_types[invoice.name], "Sales Invoice")
+
def test_get_balance_places_difference_on_blank_row(self):
"""Characterize: get_balance puts the unbalanced difference on an amountless row."""
jv = frappe.new_doc("Journal Entry")
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index d39adeaaf5e..879b03e342d 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -950,6 +950,61 @@ class TestPaymentEntry(ERPNextTestSuite):
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0)
+ def test_exchange_gain_loss_split_accounts(self):
+ gain_account = create_account(
+ account_name="_Test Exchange Gain",
+ parent_account="Indirect Expenses - _TC",
+ company="_Test Company",
+ )
+ loss_account = create_account(
+ account_name="_Test Exchange Loss",
+ parent_account="Indirect Expenses - _TC",
+ company="_Test Company",
+ )
+ frappe.db.set_value("Company", "_Test Company", "exchange_gain_account", gain_account)
+ frappe.db.set_value("Company", "_Test Company", "exchange_loss_account", loss_account)
+ self.addCleanup(frappe.db.set_value, "Company", "_Test Company", "exchange_gain_account", "")
+ self.addCleanup(frappe.db.set_value, "Company", "_Test Company", "exchange_loss_account", "")
+
+ si_gain = create_sales_invoice(
+ customer="_Test Customer USD",
+ debit_to="_Test Receivable USD - _TC",
+ currency="USD",
+ conversion_rate=50,
+ )
+ pe_gain = get_payment_entry("Sales Invoice", si_gain.name, bank_account="_Test Bank USD - _TC")
+ pe_gain.reference_no = "1"
+ pe_gain.reference_date = "2016-01-01"
+ pe_gain.source_exchange_rate = 55
+ pe_gain.save()
+ self.assertEqual(pe_gain.references[0].exchange_gain_loss, 500)
+ pe_gain.submit()
+
+ self.assertEqual(self.get_gain_loss_journal_account(pe_gain.name), gain_account)
+
+ si_loss = create_sales_invoice(
+ customer="_Test Customer USD",
+ debit_to="_Test Receivable USD - _TC",
+ currency="USD",
+ conversion_rate=55,
+ )
+ pe_loss = get_payment_entry("Sales Invoice", si_loss.name, bank_account="_Test Bank USD - _TC")
+ pe_loss.reference_no = "2"
+ pe_loss.reference_date = "2016-01-01"
+ pe_loss.source_exchange_rate = 50
+ pe_loss.save()
+ self.assertEqual(pe_loss.references[0].exchange_gain_loss, -500)
+ pe_loss.submit()
+
+ self.assertEqual(self.get_gain_loss_journal_account(pe_loss.name), loss_account)
+
+ def get_gain_loss_journal_account(self, payment_entry_name: str) -> str | None:
+ return frappe.db.get_value(
+ "Journal Entry Account",
+ {"reference_type": "Payment Entry", "reference_name": payment_entry_name, "docstatus": 1},
+ "account",
+ )
+
def test_payment_entry_against_sales_invoice_with_cost_centre(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index d3ce2a0a2f7..2554d4d653f 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -18,6 +18,7 @@ from erpnext.accounts.doctype.process_payment_reconciliation.process_payment_rec
is_any_doc_running,
)
from erpnext.accounts.services.advances import get_advance_payment_entries_for_regional
+from erpnext.accounts.services.exchange_gain_loss import get_exchange_gain_loss_account
from erpnext.accounts.utils import (
QueryPaymentLedger,
create_gain_loss_journal,
@@ -485,9 +486,6 @@ class PaymentReconciliation(Document):
"Accounts Settings", "exchange_gain_loss_posting_date", cache=True
)
invoice_exchange_map = self.get_invoice_exchange_map(args.get("invoices"), args.get("payments"))
- default_exchange_gain_loss_account = frappe.get_cached_value(
- "Company", self.company, "exchange_gain_loss_account"
- )
entries = []
for pay in args.get("payments"):
@@ -507,7 +505,10 @@ class PaymentReconciliation(Document):
pay["exchange_rate"] = invoice_exchange_map.get(pay.get("reference_name"))
res.difference_amount = self.get_difference_amount(pay, inv, res["allocated_amount"])
- res.difference_account = default_exchange_gain_loss_account
+ is_gain = (
+ res.difference_amount > 0 if self.party_type == "Customer" else res.difference_amount < 0
+ )
+ res.difference_account = get_exchange_gain_loss_account(self.company, is_gain)
res.exchange_rate = inv.get("exchange_rate")
res.update({"gain_loss_posting_date": pay.get("posting_date")})
if not pay.get("is_advance"):
diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
index 03d5c9cc791..bec6ab1e236 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
@@ -6,6 +6,7 @@ import frappe
from frappe.utils import add_days, add_years, cint, flt, getdate, nowdate, today
from frappe.utils.data import getdate as convert_to_date
+from erpnext.accounts.doctype.account.test_account import create_account
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
@@ -187,6 +188,53 @@ class TestPaymentReconciliation(ERPNextTestSuite):
)
return je
+ def setup_split_exchange_accounts(self):
+ gain_account = create_account(
+ account_name="_Test PR Split Exchange Gain",
+ parent_account="Indirect Expenses - _TC",
+ company=self.company,
+ )
+ loss_account = create_account(
+ account_name="_Test PR Split Exchange Loss",
+ parent_account="Indirect Expenses - _TC",
+ company=self.company,
+ )
+ frappe.db.set_value("Company", self.company, "exchange_gain_account", gain_account)
+ frappe.db.set_value("Company", self.company, "exchange_loss_account", loss_account)
+ self.addCleanup(frappe.db.set_value, "Company", self.company, "exchange_gain_account", "")
+ self.addCleanup(frappe.db.set_value, "Company", self.company, "exchange_loss_account", "")
+ return gain_account, loss_account
+
+ def create_foreign_currency_sales_invoice(self, conversion_rate):
+ si = self.create_sales_invoice(
+ qty=1, rate=100, posting_date=nowdate(), do_not_save=True, do_not_submit=True
+ )
+ si.customer = self.customer_usd
+ si.currency = "USD"
+ si.conversion_rate = conversion_rate
+ si.debit_to = self.debtors_usd
+ si.save().submit()
+ return si
+
+ def create_foreign_currency_journal_payment(self, debtors_account, exchange_rate):
+ je = self.create_journal_entry(self.bank, debtors_account, 100, nowdate())
+ je.multi_currency = 1
+ je.accounts[0].exchange_rate = 1
+ je.accounts[0].credit_in_account_currency = 0
+ je.accounts[0].credit = 0
+ je.accounts[0].debit_in_account_currency = 100 * exchange_rate
+ je.accounts[0].debit = 100 * exchange_rate
+ je.accounts[1].party_type = "Customer"
+ je.accounts[1].party = self.customer_usd
+ je.accounts[1].exchange_rate = exchange_rate
+ je.accounts[1].credit_in_account_currency = 100
+ je.accounts[1].credit = 100 * exchange_rate
+ je.accounts[1].debit_in_account_currency = 0
+ je.accounts[1].debit = 0
+ je.save()
+ je.submit()
+ return je
+
def test_voucher_outstanding_metadata_comes_from_one_ledger_entry(self):
"""cost_center and remarks must describe the same Payment Ledger Entry.
@@ -956,6 +1004,85 @@ class TestPaymentReconciliation(ERPNextTestSuite):
frappe.db.get_value("Journal Entry", jea_parent.parent, "voucher_type"), "Exchange Gain Or Loss"
)
+ def test_exchange_gain_loss_split_default_account(self):
+ gain_account, loss_account = self.setup_split_exchange_accounts()
+
+ self.create_foreign_currency_sales_invoice(conversion_rate=80)
+ self.create_foreign_currency_journal_payment(self.debtors_usd, exchange_rate=85)
+
+ pr = self.create_payment_reconciliation()
+ pr.party = self.customer_usd
+ pr.receivable_payable_account = self.debtors_usd
+ pr.get_unreconciled_entries()
+
+ invoices = [x.as_dict() for x in pr.invoices]
+ payments = [x.as_dict() for x in pr.payments]
+ pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+
+ self.assertEqual(pr.allocation[0].difference_amount, 500)
+ self.assertEqual(pr.allocation[0].difference_account, gain_account)
+ pr.reconcile()
+
+ self.create_foreign_currency_sales_invoice(conversion_rate=85)
+ self.create_foreign_currency_journal_payment(self.debtors_usd, exchange_rate=80)
+
+ pr = self.create_payment_reconciliation()
+ pr.party = self.customer_usd
+ pr.receivable_payable_account = self.debtors_usd
+ pr.get_unreconciled_entries()
+
+ invoices = [x.as_dict() for x in pr.invoices]
+ payments = [x.as_dict() for x in pr.payments]
+ pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+
+ self.assertEqual(pr.allocation[0].difference_amount, -500)
+ self.assertEqual(pr.allocation[0].difference_account, loss_account)
+
+ def test_payment_reconciliation_difference_account_override(self):
+ _, loss_account = self.setup_split_exchange_accounts()
+ override_account = create_account(
+ account_name="_Test PR Override Exchange Account",
+ parent_account="Indirect Expenses - _TC",
+ company=self.company,
+ )
+
+ si = self.create_foreign_currency_sales_invoice(conversion_rate=85)
+ self.create_foreign_currency_journal_payment(self.debtors_usd, exchange_rate=80)
+
+ pr = self.create_payment_reconciliation()
+ pr.party = self.customer_usd
+ pr.receivable_payable_account = self.debtors_usd
+ pr.get_unreconciled_entries()
+
+ invoices = [x.as_dict() for x in pr.invoices]
+ payments = [x.as_dict() for x in pr.payments]
+ pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
+
+ # Default, computed from the split company fields, is pre-filled onto the row...
+ self.assertEqual(pr.allocation[0].difference_amount, -500)
+ self.assertEqual(pr.allocation[0].difference_account, loss_account)
+
+ # ...but the user can override it in the "Select Difference Account" dialog before reconciling,
+ # and that explicit choice must be what actually gets booked, not the computed default.
+ pr.allocation[0].difference_account = override_account
+ pr.reconcile()
+
+ jea_parent = frappe.db.get_all(
+ "Journal Entry Account",
+ filters={"account": self.debtors_usd, "docstatus": 1, "reference_name": si.name, "credit": 500},
+ fields=["parent"],
+ )[0]
+ self.assertEqual(
+ frappe.db.get_value("Journal Entry", jea_parent.parent, "voucher_type"), "Exchange Gain Or Loss"
+ )
+
+ gain_loss_line_account = frappe.db.get_value(
+ "Journal Entry Account",
+ {"parent": jea_parent.parent, "account": ["!=", self.debtors_usd]},
+ "account",
+ )
+ self.assertEqual(gain_loss_line_account, override_account)
+
def test_difference_amount_via_negative_debit_or_credit_journal_entry(self):
# Make Sale Invoice
si = self.create_sales_invoice(
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index df23560526d..e415be096c9 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -640,7 +640,7 @@ class PaymentRequest(Document):
}
if self.message:
- return frappe.render_template(self.message, context)
+ return frappe.render_template(self.message, context, restrict_globals=True)
def set_failed(self):
pass
diff --git a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
index 0169b282b9b..ca73391bfb4 100644
--- a/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
+++ b/erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
@@ -259,6 +259,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"reqd": 1
},
@@ -888,7 +889,7 @@
],
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice Item",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 9fd911a2762..9986dc89053 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -240,10 +240,8 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
unblock_invoice() {
const me = this;
- frappe.call({
- method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.unblock_invoice",
- args: { name: me.frm.doc.name },
- callback: (r) => me.frm.reload_doc(),
+ me.frm.call("unblock_invoice", null, () => {
+ me.frm.reload_doc();
});
}
@@ -294,15 +292,16 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
this.dialog.set_primary_action(__("Save"), function () {
const dialog_data = me.dialog.get_values();
- frappe.call({
- method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.block_invoice",
- args: {
- name: me.frm.doc.name,
+ me.frm.call(
+ "block_invoice",
+ {
hold_comment: dialog_data.hold_comment,
release_date: dialog_data.release_date,
},
- callback: (r) => me.frm.reload_doc(),
- });
+ () => {
+ me.frm.reload_doc();
+ }
+ );
me.dialog.hide();
});
@@ -341,10 +340,9 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
}
set_release_date(data) {
- return frappe.call({
- method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.change_release_date",
- args: data,
- callback: (r) => this.frm.reload_doc(),
+ const me = this;
+ return me.frm.call("change_release_date", { release_date: data.release_date }, () => {
+ me.frm.reload_doc();
});
}
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index f4766ef7413..2d1a4bc596b 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -360,6 +360,7 @@
{
"collapsible": 1,
"collapsible_depends_on": "eval:doc.on_hold",
+ "depends_on": "eval:doc.on_hold",
"fieldname": "sb_14",
"fieldtype": "Section Break",
"label": "Hold Invoice"
@@ -1694,7 +1695,7 @@
"idx": 204,
"is_submittable": 1,
"links": [],
- "modified": "2026-07-12 23:54:21.263951",
+ "modified": "2026-08-05 15:40:16.519774",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index fb4836026d6..62df2632262 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -5,7 +5,7 @@
import frappe
from frappe import _, throw
from frappe.model.document import Document
-from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
+from frappe.utils import DateTimeLikeObject, cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
import erpnext
from erpnext.accounts.deferred_revenue import validate_service_stop_date
@@ -306,6 +306,9 @@ class PurchaseInvoice(BuyingController):
PurchaseTaxWithholding(self).on_validate()
self.set_percentage_received()
+ if self.on_hold:
+ self.validate_invoice_hold()
+
def set_percentage_received(self):
total_billed_qty = 0.0
total_received_qty = 0.0
@@ -317,6 +320,13 @@ class PurchaseInvoice(BuyingController):
if total_billed_qty and total_received_qty:
self.per_received = total_received_qty / total_billed_qty * 100
+ def validate_invoice_hold(self):
+ if self.is_return:
+ frappe.throw(_("Return Purchase Invoice cannot be held."))
+
+ if self.docstatus < 1:
+ frappe.throw(_("Purchase Invoice can be held after submitting."))
+
def validate_release_date(self):
if self.release_date and getdate(nowdate()) >= getdate(self.release_date):
frappe.throw(_("Release date must be in the future"))
@@ -820,14 +830,38 @@ class PurchaseInvoice(BuyingController):
def on_recurring(self, reference_doc, auto_repeat_doc):
self.due_date = None
- def block_invoice(self, hold_comment=None, release_date=None):
- self.db_set("on_hold", 1)
- self.db_set("hold_comment", cstr(hold_comment))
+ @frappe.whitelist(methods=["POST"])
+ def block_invoice(self, hold_comment: str | None = None, release_date: DateTimeLikeObject | None = None):
+ self.check_permission("write")
+ self.on_hold = 1
+ self.release_date = release_date
+ self.validate_block_invoice()
+
+ self.db_set({"on_hold": 1, "hold_comment": cstr(hold_comment), "release_date": release_date})
+
+ @frappe.whitelist(methods=["POST"])
+ def unblock_invoice(self):
+ self.check_permission("write")
+ self.db_set({"on_hold": 0, "release_date": None})
+
+ @frappe.whitelist(methods=["POST"])
+ def change_release_date(self, release_date: DateTimeLikeObject | None = None):
+ self.check_permission("write")
+
+ if not self.on_hold:
+ frappe.throw(_("Invoice is not blocked. Block the invoice to change the release date."))
+
+ self.release_date = release_date
+ self.validate_block_invoice()
+
self.db_set("release_date", release_date)
- def unblock_invoice(self):
- self.db_set("on_hold", 0)
- self.db_set("release_date", None)
+ def validate_block_invoice(self):
+ self.validate_invoice_hold()
+ if self.outstanding_amount <= 0:
+ frappe.throw(_("Purchase Invoice without any outstanding amount cannot be held."))
+
+ self.validate_release_date()
def set_status(self, update=False, status=None, update_modified=True):
if self.is_new():
@@ -925,24 +959,3 @@ def get_list_context(context=None):
@erpnext.allow_regional
def make_regional_gl_entries(gl_entries, doc):
return gl_entries
-
-
-@frappe.whitelist()
-def change_release_date(name: str, release_date: str | None = None):
- pi = frappe.get_lazy_doc("Purchase Invoice", name)
- pi.check_permission()
- pi.db_set("release_date", release_date)
-
-
-@frappe.whitelist()
-def unblock_invoice(name: str):
- if frappe.db.exists("Purchase Invoice", name):
- pi = frappe.get_lazy_doc("Purchase Invoice", name)
- pi.unblock_invoice()
-
-
-@frappe.whitelist()
-def block_invoice(name: str, release_date: str, hold_comment: str | None = None):
- if frappe.db.exists("Purchase Invoice", name):
- pi = frappe.get_lazy_doc("Purchase Invoice", name)
- pi.block_invoice(hold_comment, release_date)
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index e60d3f4614c..dc80f2d5ef8 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -278,14 +278,166 @@ class TestPurchaseInvoice(ERPNextTestSuite, StockTestMixin):
def test_purchase_invoice_explicit_block(self):
pi = make_purchase_invoice()
- pi.block_invoice()
+ release_date = add_days(nowdate(), 10)
+
+ pi.block_invoice(hold_comment="Waiting for the goods", release_date=release_date)
self.assertEqual(pi.on_hold, 1)
+ on_hold, hold_comment, saved_release_date = frappe.db.get_value(
+ "Purchase Invoice", pi.name, ["on_hold", "hold_comment", "release_date"]
+ )
+ self.assertEqual(on_hold, 1)
+ self.assertEqual(hold_comment, "Waiting for the goods")
+ self.assertEqual(getdate(saved_release_date), getdate(release_date))
+
pi.unblock_invoice()
self.assertEqual(pi.on_hold, 0)
+ on_hold, saved_release_date = frappe.db.get_value(
+ "Purchase Invoice", pi.name, ["on_hold", "release_date"]
+ )
+ self.assertEqual(on_hold, 0)
+ self.assertIsNone(saved_release_date)
+
+ def test_purchase_invoice_cannot_be_held_before_submission(self):
+ pi = make_purchase_invoice(do_not_save=True)
+ pi.on_hold = 1
+
+ self.assertRaises(frappe.ValidationError, pi.save)
+
+ pi.on_hold = 0
+ pi.save()
+ pi.submit()
+
+ pi.block_invoice()
+ self.assertEqual(frappe.db.get_value("Purchase Invoice", pi.name, "on_hold"), 1)
+
+ def test_return_purchase_invoice_cannot_be_held(self):
+ from erpnext.controllers.sales_and_purchase_return import make_return_doc
+
+ pi = make_purchase_invoice()
+
+ return_pi = make_return_doc(pi.doctype, pi.name)
+ return_pi.on_hold = 1
+ self.assertRaisesRegex(frappe.ValidationError, "cannot be held", return_pi.save)
+
+ return_pi.on_hold = 0
+ return_pi.save()
+ return_pi.submit()
+
+ self.assertRaisesRegex(frappe.ValidationError, "cannot be held", return_pi.block_invoice)
+
+ def test_return_purchase_invoice_is_not_affected_by_hold_validations(self):
+ from erpnext.controllers.sales_and_purchase_return import make_return_doc
+
+ pi = make_purchase_invoice()
+
+ # a return has a negative outstanding amount, which must not be mistaken
+ # for an invalid hold on a document that was never held
+ return_pi = make_return_doc(pi.doctype, pi.name)
+ return_pi.save()
+ return_pi.submit()
+
+ self.assertEqual(return_pi.docstatus, 1)
+ self.assertEqual(return_pi.on_hold, 0)
+ self.assertLess(return_pi.outstanding_amount, 0)
+
+ def test_settled_purchase_invoice_cannot_be_held(self):
+ pi = make_purchase_invoice()
+
+ pe = get_payment_entry("Purchase Invoice", dn=pi.name, bank_account="_Test Bank - _TC")
+ pe.reference_no = "1"
+ pe.reference_date = nowdate()
+ pe.save()
+ pe.submit()
+
+ pi.reload()
+ self.assertEqual(pi.outstanding_amount, 0)
+
+ self.assertRaises(frappe.ValidationError, pi.block_invoice)
+ self.assertEqual(frappe.db.get_value("Purchase Invoice", pi.name, "on_hold"), 0)
+
+ def test_release_date_of_held_invoice_must_be_in_future(self):
+ pi = make_purchase_invoice()
+
+ self.assertRaises(frappe.ValidationError, pi.block_invoice, "Hold", add_days(nowdate(), -1))
+ self.assertRaises(frappe.ValidationError, pi.block_invoice, "Hold", nowdate())
+
+ def test_rejected_hold_does_not_partially_update_invoice(self):
+ pi = make_purchase_invoice()
+
+ self.assertRaises(frappe.ValidationError, pi.block_invoice, "Hold", add_days(nowdate(), -1))
+
+ pi.reload()
+ self.assertEqual(pi.on_hold, 0)
+ self.assertIsNone(pi.release_date)
+
+ def test_change_release_date_of_held_invoice(self):
+ pi = make_purchase_invoice()
+ pi.block_invoice(hold_comment="Hold", release_date=add_days(nowdate(), 10))
+
+ new_release_date = add_days(nowdate(), 20)
+ pi.change_release_date(new_release_date)
+
+ self.assertEqual(
+ getdate(frappe.db.get_value("Purchase Invoice", pi.name, "release_date")),
+ getdate(new_release_date),
+ )
+
+ self.assertRaises(frappe.ValidationError, pi.change_release_date, add_days(nowdate(), -1))
+
+ def test_release_date_cannot_be_changed_on_an_invoice_that_is_not_held(self):
+ pi = make_purchase_invoice()
+
+ self.assertRaisesRegex(
+ frappe.ValidationError,
+ "Invoice is not blocked",
+ pi.change_release_date,
+ add_days(nowdate(), 10),
+ )
+
+ self.assertIsNone(frappe.db.get_value("Purchase Invoice", pi.name, "release_date"))
+
+ def test_hold_methods_are_whitelisted_document_methods(self):
+ import erpnext.accounts.doctype.purchase_invoice.purchase_invoice as purchase_invoice_module
+
+ pi = frappe.new_doc("Purchase Invoice")
+
+ for method in ("block_invoice", "unblock_invoice", "change_release_date"):
+ # raises if the method is not whitelisted for client side calls
+ pi.is_whitelisted(method)
+
+ self.assertFalse(
+ hasattr(purchase_invoice_module, method),
+ f"{method} should only be exposed as a document method",
+ )
+
+ def test_hold_methods_require_write_permission(self):
+ pi = make_purchase_invoice()
+ user = "test_pi_hold_permission@example.com"
+
+ if not frappe.db.exists("User", user):
+ frappe.get_doc(
+ {
+ "doctype": "User",
+ "email": user,
+ "first_name": "Test PI Hold",
+ "roles": [{"role": "Employee"}],
+ }
+ ).insert(ignore_permissions=True)
+
+ frappe.set_user(user)
+ try:
+ self.assertRaises(frappe.PermissionError, pi.block_invoice)
+ self.assertRaises(frappe.PermissionError, pi.unblock_invoice)
+ self.assertRaises(frappe.PermissionError, pi.change_release_date, add_days(nowdate(), 10))
+ finally:
+ frappe.set_user("Administrator")
+
+ self.assertEqual(frappe.db.get_value("Purchase Invoice", pi.name, "on_hold"), 0)
+
def test_gl_entries_with_perpetual_inventory_against_pr(self):
pr = make_purchase_receipt(
company="_Test Company with perpetual inventory",
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 c5de538b897..9153209ff56 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -241,6 +241,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"read_only": 1,
"reqd": 1
@@ -1032,7 +1033,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 555c41a5058..ef70269196f 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -114,6 +114,14 @@ class TestSalesInvoice(ERPNextTestSuite):
si.save()
self.assertEqual(si.items[0].qty, 1)
+ @ERPNextTestSuite.change_settings("Selling Settings", {"allow_negative_rates_for_items": 1})
+ def test_sales_invoice_negative_grand_total_still_blocked_with_setting(self):
+ """allow_negative_rates_for_items must not bypass the >=0 guard for a non-return
+ invoice, since invoices post to the GL (unlike Sales Order)."""
+ si = create_sales_invoice(qty=1, rate=100, do_not_save=True)
+ si.append("items", {"item_code": "_Test Item 2", "qty": 1, "rate": -150})
+ self.assertRaises(frappe.ValidationError, si.save)
+
def test_timestamp_change(self):
w = frappe.copy_doc(self.globalTestRecords["Sales Invoice"][0])
w.docstatus = 0
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 7fd1ecc1400..a046b6c4e80 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
@@ -249,6 +249,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"reqd": 1
},
@@ -1066,7 +1067,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",
diff --git a/erpnext/accounts/doctype_settings_map/party_account_(standard)/party_account_(standard).json b/erpnext/accounts/doctype_settings_map/party_account.json
similarity index 93%
rename from erpnext/accounts/doctype_settings_map/party_account_(standard)/party_account_(standard).json
rename to erpnext/accounts/doctype_settings_map/party_account.json
index 625d61d03d3..ca9d355a1b5 100644
--- a/erpnext/accounts/doctype_settings_map/party_account_(standard)/party_account_(standard).json
+++ b/erpnext/accounts/doctype_settings_map/party_account.json
@@ -19,6 +19,6 @@
"modified": "2026-07-09 16:13:49.623613",
"modified_by": "Administrator",
"module": "Accounts",
- "name": "Party Account (Standard)",
+ "name": "Party Account - Accounts",
"owner": "Administrator"
}
diff --git a/erpnext/accounts/doctype_settings_map/payment_entry_(standard)/payment_entry_(standard).json b/erpnext/accounts/doctype_settings_map/payment_entry.json
similarity index 95%
rename from erpnext/accounts/doctype_settings_map/payment_entry_(standard)/payment_entry_(standard).json
rename to erpnext/accounts/doctype_settings_map/payment_entry.json
index 5cd47822a3d..93d417da191 100644
--- a/erpnext/accounts/doctype_settings_map/payment_entry_(standard)/payment_entry_(standard).json
+++ b/erpnext/accounts/doctype_settings_map/payment_entry.json
@@ -27,6 +27,6 @@
"modified": "2026-07-10 11:26:57.841200",
"modified_by": "Administrator",
"module": "Accounts",
- "name": "Payment Entry (Standard)",
+ "name": "Payment Entry - Accounts",
"owner": "Administrator"
}
diff --git a/erpnext/accounts/doctype_settings_map/purchase_invoice_(standard)/purchase_invoice_(standard).json b/erpnext/accounts/doctype_settings_map/purchase_invoice.json
similarity index 97%
rename from erpnext/accounts/doctype_settings_map/purchase_invoice_(standard)/purchase_invoice_(standard).json
rename to erpnext/accounts/doctype_settings_map/purchase_invoice.json
index e21c7876f73..14f280d0b9b 100644
--- a/erpnext/accounts/doctype_settings_map/purchase_invoice_(standard)/purchase_invoice_(standard).json
+++ b/erpnext/accounts/doctype_settings_map/purchase_invoice.json
@@ -71,6 +71,6 @@
"modified": "2026-07-20 15:56:46.025286",
"modified_by": "Administrator",
"module": "Accounts",
- "name": "Purchase Invoice (Standard)",
+ "name": "Purchase Invoice - Accounts",
"owner": "Administrator"
}
diff --git a/erpnext/accounts/doctype_settings_map/sales_invoice_(standard)/sales_invoice_(standard).json b/erpnext/accounts/doctype_settings_map/sales_invoice.json
similarity index 97%
rename from erpnext/accounts/doctype_settings_map/sales_invoice_(standard)/sales_invoice_(standard).json
rename to erpnext/accounts/doctype_settings_map/sales_invoice.json
index 800d9869411..3822459f776 100644
--- a/erpnext/accounts/doctype_settings_map/sales_invoice_(standard)/sales_invoice_(standard).json
+++ b/erpnext/accounts/doctype_settings_map/sales_invoice.json
@@ -63,6 +63,6 @@
"modified": "2026-07-20 15:32:43.080034",
"modified_by": "Administrator",
"module": "Accounts",
- "name": "Sales Invoice (Standard)",
+ "name": "Sales Invoice - Accounts",
"owner": "Administrator"
}
diff --git a/erpnext/accounts/doctype_settings_map/subscription_(standard)/subscription_(standard).json b/erpnext/accounts/doctype_settings_map/subscription.json
similarity index 93%
rename from erpnext/accounts/doctype_settings_map/subscription_(standard)/subscription_(standard).json
rename to erpnext/accounts/doctype_settings_map/subscription.json
index 0e141f25080..378c00823f0 100644
--- a/erpnext/accounts/doctype_settings_map/subscription_(standard)/subscription_(standard).json
+++ b/erpnext/accounts/doctype_settings_map/subscription.json
@@ -19,6 +19,6 @@
"modified": "2026-07-09 15:08:57.487184",
"modified_by": "Administrator",
"module": "Accounts",
- "name": "Subscription (Standard)",
+ "name": "Subscription - Accounts",
"owner": "Administrator"
}
diff --git a/erpnext/accounts/report/account_balance/test_account_balance.py b/erpnext/accounts/report/account_balance/test_account_balance.py
index d83a26abea6..78f88b5d6c4 100644
--- a/erpnext/accounts/report/account_balance/test_account_balance.py
+++ b/erpnext/accounts/report/account_balance/test_account_balance.py
@@ -24,6 +24,11 @@ class TestAccountBalance(ERPNextTestSuite):
"currency": "EUR",
"balance": -100.0,
},
+ {
+ "account": "Exchange Gain - _TC2",
+ "currency": "EUR",
+ "balance": 0.0,
+ },
{
"account": "Income - _TC2",
"currency": "EUR",
diff --git a/erpnext/accounts/services/child_item_update.py b/erpnext/accounts/services/child_item_update.py
index ae7f8109f74..d66c5621f7a 100644
--- a/erpnext/accounts/services/child_item_update.py
+++ b/erpnext/accounts/services/child_item_update.py
@@ -16,6 +16,11 @@ from erpnext.stock.get_item_details import (
get_conversion_factor,
get_item_warehouse_,
)
+from erpnext.stock.utils import (
+ is_group_warehouse,
+ validate_disabled_warehouse,
+ validate_warehouse_company,
+)
class ChildItemUpdater:
@@ -340,7 +345,7 @@ def set_order_defaults(
child_item.update({date_fieldname: trans_item.get(date_fieldname) or p_doc.get(date_fieldname)})
child_item.stock_uom = item.stock_uom
child_item.uom = trans_item.get("uom") or item.stock_uom
- child_item.warehouse = get_item_warehouse_(p_doc, item, overwrite_warehouse=True)
+ child_item.warehouse = get_new_child_item_warehouse(p_doc, item, trans_item, child_doctype)
conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
child_item.conversion_factor = flt(trans_item.get("conversion_factor")) or conversion_factor
child_item.update(get_bin_details(child_item.item_code, child_item.warehouse, p_doc.get("company")))
@@ -349,20 +354,44 @@ def set_order_defaults(
child_item.base_rate = 1
child_item.base_amount = 1
- if child_doctype == "Sales Order Item":
- child_item.warehouse = get_item_warehouse_(p_doc, item, overwrite_warehouse=True)
- if not child_item.warehouse:
- frappe.throw(
- _(
- "Cannot find a default warehouse for item {0}. Please set one in the Item Master or in Stock Settings."
- ).format(frappe.bold(item.item_code))
- )
-
set_child_tax_template_and_map(item, child_item, p_doc)
add_taxes_from_tax_template(child_item, p_doc)
return child_item
+def get_new_child_item_warehouse(p_doc, item, trans_item: dict, child_doctype: str) -> str | None:
+ """Return the warehouse picked in the Update Items dialog, else the configured default.
+
+ Validates whichever warehouse was resolved, since a submitted parent skips validate().
+ """
+ warehouse = trans_item.get("warehouse") or get_item_warehouse_(p_doc, item, overwrite_warehouse=True)
+
+ if not warehouse:
+ if is_warehouse_required_for_new_child_item(child_doctype, item, trans_item):
+ frappe.throw(
+ _(
+ "Cannot find a default warehouse for item {0}. Please select one in the Update Items dialog, or set a default in the Item Master or in the Company."
+ ).format(frappe.bold(item.item_code))
+ )
+ return None
+
+ validate_warehouse_company(warehouse, p_doc.company)
+ validate_disabled_warehouse(warehouse)
+ is_group_warehouse(warehouse)
+ return warehouse
+
+
+def is_warehouse_required_for_new_child_item(child_doctype: str, item, trans_item: dict) -> bool:
+ """Sales Order always needs one; buying documents only for stock rows, as in validate_stock_item_warehouse."""
+ if child_doctype == "Sales Order Item":
+ return True
+
+ if child_doctype in ("Purchase Order Item", "Supplier Quotation Item"):
+ return bool(item.is_stock_item and flt(trans_item.get("qty")) and not item.delivered_by_supplier)
+
+ return False
+
+
def validate_child_on_delete(row, parent, ordered_item=None) -> None:
"""Raise if a partially transacted child item is being deleted."""
if parent.doctype == "Sales Order":
diff --git a/erpnext/accounts/services/exchange_gain_loss.py b/erpnext/accounts/services/exchange_gain_loss.py
index a58a11105a1..df61e3e882a 100644
--- a/erpnext/accounts/services/exchange_gain_loss.py
+++ b/erpnext/accounts/services/exchange_gain_loss.py
@@ -11,6 +11,13 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import g
from erpnext.accounts.utils import create_gain_loss_journal, get_currency_precision
+def get_exchange_gain_loss_account(company: str, is_gain: bool) -> str | None:
+ fieldname = "exchange_gain_account" if is_gain else "exchange_loss_account"
+ return frappe.get_cached_value("Company", company, fieldname) or frappe.get_cached_value(
+ "Company", company, "exchange_gain_loss_account"
+ )
+
+
def gain_loss_journal_already_booked(
gain_loss_account: str,
exc_gain_loss: float,
@@ -163,9 +170,7 @@ def make_exchange_gain_loss_journal(
reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
- gain_loss_account = frappe.get_cached_value(
- "Company", doc.company, "exchange_gain_loss_account"
- )
+ gain_loss_account = get_exchange_gain_loss_account(doc.company, reverse_dr_or_cr == "credit")
je = create_gain_loss_journal(
doc.company,
args.get("difference_posting_date") if args else doc.posting_date,
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 0a28177ba74..a27689d6052 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -310,12 +310,45 @@ class PurchaseOrder(BuyingController):
itemwise_qty.setdefault(d.item_code, 0)
itemwise_qty[d.item_code] += flt(d.stock_qty)
+ precision = self.items[0].precision("stock_qty")
for item_code, qty in itemwise_qty.items():
- if flt(qty) < flt(itemwise_min_order_qty.get(item_code)):
+ if flt(qty, precision) < flt(itemwise_min_order_qty.get(item_code), precision):
frappe.throw(
_(
"Item {0}: Ordered qty {1} cannot be less than minimum order qty {2} (defined in Item)."
- ).format(item_code, qty, itemwise_min_order_qty.get(item_code))
+ ).format(item_code, flt(qty, precision), itemwise_min_order_qty.get(item_code))
+ )
+
+ self.warn_marginal_min_order_qty(itemwise_qty, itemwise_min_order_qty)
+
+ def warn_marginal_min_order_qty(self, itemwise_qty, itemwise_min_order_qty):
+ """Toast when an item's ordered qty exceeds its minimum only by purchase UOM rounding."""
+ if not self.is_new():
+ return
+
+ precision = self.items[0].precision("stock_qty")
+ itemwise_step = frappe._dict()
+ itemwise_stock_uom = frappe._dict()
+ for d in self.get("items"):
+ step = 10 ** -d.precision("qty") * flt(d.conversion_factor)
+ itemwise_step[d.item_code] = max(itemwise_step.get(d.item_code, 0), step)
+ itemwise_stock_uom[d.item_code] = d.stock_uom
+
+ for item_code, qty in itemwise_qty.items():
+ min_order_qty = flt(itemwise_min_order_qty.get(item_code))
+ overage = flt(qty) - min_order_qty
+ if min_order_qty and flt(overage, precision) > 0 and overage < itemwise_step[item_code]:
+ frappe.toast(
+ _(
+ "Item {0}: Ordered qty {1} {2} exceeds the minimum order qty {3} {2} by {4} {2} due to purchase UOM rounding."
+ ).format(
+ item_code,
+ flt(qty, precision),
+ itemwise_stock_uom[item_code],
+ min_order_qty,
+ flt(overage, precision),
+ ),
+ indicator="orange",
)
def get_schedule_dates(self):
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index d36dedb200a..86681eed676 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -54,6 +54,28 @@ class TestPurchaseOrder(ERPNextTestSuite):
po.save()
self.assertEqual(po.items[1].qty, 1)
+ @ERPNextTestSuite.change_settings("Buying Settings", {"allow_negative_rates_for_items": 0})
+ def test_purchase_order_negative_grand_total_blocked_without_setting(self):
+ po = create_purchase_order(qty=1, rate=100, do_not_save=True)
+ po.append("items", {"item_code": "_Test Item 2", "qty": 1, "rate": -150, "schedule_date": nowdate()})
+ self.assertRaises(frappe.ValidationError, po.save)
+
+ @ERPNextTestSuite.change_settings("Buying Settings", {"allow_negative_rates_for_items": 1})
+ def test_purchase_order_negative_grand_total_allowed_with_setting(self):
+ """Use a negative rate to represent a credit while order quantities remain positive."""
+ po = create_purchase_order(qty=1, rate=100, do_not_save=True)
+ po.append("items", {"item_code": "_Test Item 2", "qty": 1, "rate": -150, "schedule_date": nowdate()})
+ po.save()
+ po.submit()
+ self.assertEqual(po.docstatus, 1)
+ self.assertTrue(po.base_grand_total < 0)
+
+ @ERPNextTestSuite.change_settings("Buying Settings", {"allow_negative_rates_for_items": 1})
+ def test_purchase_order_negative_rate_setting_does_not_allow_negative_quantity(self):
+ po = create_purchase_order(qty=1, rate=100, do_not_save=True)
+ po.append("items", {"item_code": "_Test Item 2", "qty": -1, "rate": 100})
+ self.assertRaises(frappe.ValidationError, po.save)
+
def test_purchase_order_zero_qty(self):
po = create_purchase_order(qty=0, do_not_save=True)
@@ -320,6 +342,7 @@ class TestPurchaseOrder(ERPNextTestSuite):
po.load_from_db()
existing_ordered_qty = get_ordered_qty()
+ existing_ordered_qty_in_new_warehouse = get_ordered_qty(warehouse="_Test Warehouse 2 - _TC")
first_item_of_po = po.get("items")[0]
trans_item = json.dumps(
@@ -330,16 +353,62 @@ class TestPurchaseOrder(ERPNextTestSuite):
"qty": first_item_of_po.qty,
"docname": first_item_of_po.name,
},
- {"item_code": "_Test Item", "rate": 200, "qty": 7},
+ {"item_code": "_Test Item", "rate": 200, "qty": 7, "warehouse": "_Test Warehouse 2 - _TC"},
]
)
update_child_qty_rate("Purchase Order", trans_item, po.name)
po.reload()
self.assertEqual(len(po.get("items")), 2)
+ self.assertEqual(po.get("items")[-1].warehouse, "_Test Warehouse 2 - _TC")
self.assertEqual(po.status, "To Receive and Bill")
- # ordered qty should increase on row addition
- self.assertEqual(get_ordered_qty(), existing_ordered_qty + 7)
+ # ordered qty should increase on row addition, in the warehouse passed for the new row
+ self.assertEqual(get_ordered_qty(), existing_ordered_qty)
+ self.assertEqual(
+ get_ordered_qty(warehouse="_Test Warehouse 2 - _TC"),
+ existing_ordered_qty_in_new_warehouse + 7,
+ )
+
+ def test_update_child_adding_new_item_without_any_default_warehouse(self):
+ stock_item = make_item("_Test PO Item Without Default Warehouse", {"is_stock_item": 1}).name
+ service_item = make_item("_Test PO Item Non Stock", {"is_stock_item": 0}).name
+
+ po = create_purchase_order(do_not_save=1)
+ po.save()
+ po.submit()
+ first_item_of_po = po.get("items")[0]
+
+ company_default = frappe.db.get_value("Company", po.company, "default_warehouse")
+ frappe.db.set_value("Company", po.company, "default_warehouse", None)
+ self.addCleanup(frappe.db.set_value, "Company", po.company, "default_warehouse", company_default)
+
+ def get_trans_items(item_code):
+ return json.dumps(
+ [
+ {
+ "item_code": first_item_of_po.item_code,
+ "rate": first_item_of_po.rate,
+ "qty": first_item_of_po.qty,
+ "docname": first_item_of_po.name,
+ },
+ {"item_code": item_code, "rate": 200, "qty": 7},
+ ]
+ )
+
+ self.assertRaisesRegex(
+ frappe.ValidationError,
+ "Cannot find a default warehouse",
+ update_child_qty_rate,
+ "Purchase Order",
+ get_trans_items(stock_item),
+ po.name,
+ )
+
+ update_child_qty_rate("Purchase Order", get_trans_items(service_item), po.name)
+
+ po.reload()
+ self.assertEqual(po.get("items")[-1].item_code, service_item)
+ self.assertFalse(po.get("items")[-1].warehouse)
def test_update_child_removing_item(self):
po = create_purchase_order(do_not_save=1)
@@ -707,6 +776,66 @@ class TestPurchaseOrder(ERPNextTestSuite):
po = create_purchase_order(qty=3.4, do_not_save=True)
self.assertRaises(UOMMustBeIntegerError, po.insert)
+ def test_min_order_qty_with_uom_conversion_dust(self):
+ item_doc = make_item(properties={"min_order_qty": 2000, "stock_uom": "Kg"})
+ item_doc.append("uoms", {"uom": "Litre", "conversion_factor": 0.6})
+ item_doc.save()
+ item = item_doc.name
+
+ precision = frappe.get_precision("Purchase Order Item", "stock_qty")
+ po = create_purchase_order(item_code=item, qty=flt(2000 / 0.6, precision), do_not_save=1)
+ po.items[0].uom = "Litre"
+ po.items[0].conversion_factor = 0.6
+ po.insert()
+
+ below_minimum = create_purchase_order(item_code=item, qty=3000, do_not_save=1)
+ below_minimum.items[0].uom = "Litre"
+ below_minimum.items[0].conversion_factor = 0.6
+ self.assertRaises(frappe.ValidationError, below_minimum.insert)
+
+ def test_marginal_min_order_qty_overage_toast(self):
+ original_precision = frappe.db.get_default("float_precision")
+ frappe.db.set_default("float_precision", "3")
+ self.addCleanup(frappe.db.set_default, "float_precision", original_precision)
+
+ if not frappe.db.exists("UOM", "Gram"):
+ frappe.get_doc({"doctype": "UOM", "uom_name": "Gram"}).insert()
+
+ item_doc = make_item(properties={"min_order_qty": 50000, "stock_uom": "Gram"})
+ item_doc.append("uoms", {"uom": "Pound", "conversion_factor": 453.592292197})
+ item_doc.save()
+ item = item_doc.name
+
+ def insert_po(qty):
+ po = create_purchase_order(item_code=item, qty=qty, do_not_save=1)
+ po.items[0].uom = "Pound"
+ po.items[0].conversion_factor = 453.592292197
+ frappe.clear_messages()
+ po.insert()
+ return any("minimum order qty" in d.get("message", "") for d in frappe.get_message_log())
+
+ self.assertTrue(insert_po(110.232))
+ self.assertFalse(insert_po(150))
+
+ def test_uom_integer_check_tolerates_conversion_dust(self):
+ from erpnext.utilities.transaction_base import UOMMustBeIntegerError
+
+ item_doc = make_item(properties={"stock_uom": "Nos"})
+ item_doc.append("uoms", {"uom": "Kg", "conversion_factor": 0.6})
+ item_doc.save()
+ item = item_doc.name
+
+ precision = frappe.get_precision("Purchase Order Item", "stock_qty")
+ po = create_purchase_order(item_code=item, qty=flt(2000 / 0.6, precision), do_not_save=1)
+ po.items[0].uom = "Kg"
+ po.items[0].conversion_factor = 0.6
+ po.insert()
+
+ fractional = create_purchase_order(item_code=item, qty=3333.9, do_not_save=1)
+ fractional.items[0].uom = "Kg"
+ fractional.items[0].conversion_factor = 0.6
+ self.assertRaises(UOMMustBeIntegerError, fractional.insert)
+
def test_ordered_qty_for_closing_po(self):
bin = frappe.get_all(
"Bin",
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index b405c0b0be5..c65c9f992a0 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -260,6 +260,7 @@
"label": "UOM Conversion Factor",
"oldfieldname": "conversion_factor",
"oldfieldtype": "Currency",
+ "precision": "9",
"print_hide": 1,
"print_width": "100px",
"reqd": 1,
@@ -943,7 +944,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-15 10:30:04.600510",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
diff --git a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
index 48680aceeff..6ace8bddf39 100644
--- a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
+++ b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
@@ -132,6 +132,7 @@
"label": "Conversion Factor",
"oldfieldname": "conversion_factor",
"oldfieldtype": "Currency",
+ "precision": "9",
"read_only": 1
},
{
@@ -207,7 +208,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2024-03-27 13:10:26.235916",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Receipt Item Supplied",
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index 82a5b0c6103..3fe5fd03f7e 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -324,14 +324,14 @@ class RequestforQuotation(BuyingController):
message_template = self.mfs_html if self.use_html else self.message_for_supplier
# nosemgrep: frappe-semgrep-rules.rules.security.frappe-ssti
- rendered_message = frappe.render_template(message_template, doc_args)
+ rendered_message = frappe.render_template(message_template, doc_args, restrict_globals=True)
subject_source = (
self.subject
or frappe.get_value("Email Template", self.email_template, "subject")
or _("Request for Quotation")
)
- rendered_subject = frappe.render_template(subject_source, doc_args)
+ rendered_subject = frappe.render_template(subject_source, doc_args, restrict_globals=True)
if preview:
return {
"message": rendered_message,
diff --git a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
index 159965925c4..c540e0e5787 100644
--- a/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
+++ b/erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
@@ -241,6 +241,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"read_only": 1,
"reqd": 1
@@ -274,7 +275,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-06-15 00:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Buying",
"name": "Request for Quotation Item",
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
index 31efaa6690b..b11da04f94c 100644
--- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
@@ -217,6 +217,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"read_only": 1,
"reqd": 1
@@ -614,7 +615,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-15 10:33:24.855979",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation Item",
diff --git a/erpnext/buying/doctype_settings_map/purchase_order_(standard)/purchase_order_(standard).json b/erpnext/buying/doctype_settings_map/purchase_order.json
similarity index 97%
rename from erpnext/buying/doctype_settings_map/purchase_order_(standard)/purchase_order_(standard).json
rename to erpnext/buying/doctype_settings_map/purchase_order.json
index 8f8318021c0..104b197618d 100644
--- a/erpnext/buying/doctype_settings_map/purchase_order_(standard)/purchase_order_(standard).json
+++ b/erpnext/buying/doctype_settings_map/purchase_order.json
@@ -47,6 +47,6 @@
"modified": "2026-07-20 15:54:26.047600",
"modified_by": "Administrator",
"module": "Buying",
- "name": "Purchase Order (Standard)",
+ "name": "Purchase Order - Buying",
"owner": "Administrator"
}
diff --git a/erpnext/buying/doctype_settings_map/request_for_quotation_(standard)/request_for_quotation_(standard).json b/erpnext/buying/doctype_settings_map/request_for_quotation.json
similarity index 92%
rename from erpnext/buying/doctype_settings_map/request_for_quotation_(standard)/request_for_quotation_(standard).json
rename to erpnext/buying/doctype_settings_map/request_for_quotation.json
index fe64ff981df..c40af443a40 100644
--- a/erpnext/buying/doctype_settings_map/request_for_quotation_(standard)/request_for_quotation_(standard).json
+++ b/erpnext/buying/doctype_settings_map/request_for_quotation.json
@@ -19,6 +19,6 @@
"modified": "2026-07-03 17:18:03.006829",
"modified_by": "Administrator",
"module": "Buying",
- "name": "Request for Quotation (Standard)",
+ "name": "Request for Quotation - Buying",
"owner": "Administrator"
}
diff --git a/erpnext/buying/doctype_settings_map/supplier_quotation_(standard)/supplier_quotation_(standard).json b/erpnext/buying/doctype_settings_map/supplier_quotation.json
similarity index 91%
rename from erpnext/buying/doctype_settings_map/supplier_quotation_(standard)/supplier_quotation_(standard).json
rename to erpnext/buying/doctype_settings_map/supplier_quotation.json
index 950a8e96c10..1b3a70c57e9 100644
--- a/erpnext/buying/doctype_settings_map/supplier_quotation_(standard)/supplier_quotation_(standard).json
+++ b/erpnext/buying/doctype_settings_map/supplier_quotation.json
@@ -15,6 +15,6 @@
"modified": "2026-07-03 17:14:32.891939",
"modified_by": "Administrator",
"module": "Buying",
- "name": "Supplier Quotation (Standard)",
+ "name": "Supplier Quotation - Buying",
"owner": "Administrator"
}
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 70c5f3e77fe..4646055c49f 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -210,6 +210,23 @@ class AccountsController(TransactionBase):
)
frappe.msgprint(msg)
+ def is_negative_grand_total_allowed(self) -> bool:
+ """Return True if this document may save with a negative grand total.
+
+ Sales Order and Purchase Order never post to the GL, so a negative
+ total is safe there whenever the user has explicitly opted into
+ negative rates via Selling/Buying Settings. Every other
+ AccountsController doctype (invoices, delivery notes, receipts,
+ quotations, ...) keeps relying on the `is_return` escape hatch only.
+ """
+ if self.doctype == "Sales Order":
+ return bool(frappe.get_single_value("Selling Settings", "allow_negative_rates_for_items"))
+
+ if self.doctype == "Purchase Order":
+ return bool(frappe.get_single_value("Buying Settings", "allow_negative_rates_for_items"))
+
+ return False
+
def validate(self):
if not self.get("is_return") and not self.get("is_debit_note"):
self.validate_qty_is_not_zero()
@@ -262,7 +279,8 @@ class AccountsController(TransactionBase):
self.calculate_taxes_and_totals()
if not self.meta.get_field("is_return") or not self.is_return:
- self.validate_value("base_grand_total", ">=", 0)
+ if not self.is_negative_grand_total_allowed():
+ self.validate_value("base_grand_total", ">=", 0)
validate_return(self)
@@ -1039,9 +1057,16 @@ class AccountsController(TransactionBase):
party_account = self.credit_to
dr_or_cr = "debit_in_account_currency"
+ from erpnext.accounts.services.exchange_gain_loss import get_exchange_gain_loss_account
+
lst = []
for d in self.get("advances"):
if flt(d.allocated_amount) > 0:
+ is_gain = (
+ flt(d.get("exchange_gain_loss")) > 0
+ if party_type == "Customer"
+ else flt(d.get("exchange_gain_loss")) < 0
+ )
args = frappe._dict(
{
"voucher_type": d.reference_type,
@@ -1068,9 +1093,7 @@ class AccountsController(TransactionBase):
else self.grand_total
),
"outstanding_amount": self.outstanding_amount,
- "difference_account": frappe.get_cached_value(
- "Company", self.company, "exchange_gain_loss_account"
- ),
+ "difference_account": get_exchange_gain_loss_account(self.company, is_gain),
"exchange_gain_loss": flt(d.get("exchange_gain_loss")),
"difference_posting_date": d.get("difference_posting_date"),
}
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 9c6dc4d9ce5..970dd8e4b48 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -254,7 +254,7 @@ class SellingController(StockController):
total += sales_person.allocated_percentage
- if sales_team and total != 100.0:
+ if sales_team and flt(total, self.precision("allocated_percentage", "sales_team")) != 100.0:
throw(_("Total allocated percentage for sales team should be 100"))
def validate_sales_team(self, sales_team):
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 41614f93327..53a1de82d8b 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -265,6 +265,9 @@ class StatusUpdater(Document):
def validate_qty(self):
"""Validates qty at row level"""
+ selling_doctypes = ("Sales Order", "Sales Invoice", "Delivery Note")
+ buying_doctypes = ("Purchase Order", "Purchase Invoice", "Purchase Receipt")
+
for args in self.status_updater:
if "target_ref_field" not in args or args.get("validate_qty") is False:
# if target_ref_field is not specified or validate_qty is explicitly set to False, skip validation
@@ -292,11 +295,8 @@ class StatusUpdater(Document):
if hasattr(d, "qty") and flt(d.qty) > 0 and self.get("is_return"):
frappe.throw(_("For an item {0}, quantity must be a negative number").format(d.item_code))
- if (
- not selling_negative_rate_allowed and self.doctype in ["Sales Invoice", "Delivery Note"]
- ) or (
- not buying_negative_rate_allowed
- and self.doctype in ["Purchase Invoice", "Purchase Receipt"]
+ if (not selling_negative_rate_allowed and self.doctype in selling_doctypes) or (
+ not buying_negative_rate_allowed and self.doctype in buying_doctypes
):
if hasattr(d, "item_code") and hasattr(d, "rate") and flt(d.rate) < 0:
frappe.throw(
@@ -307,7 +307,7 @@ class StatusUpdater(Document):
frappe.bold(_("`Allow Negative rates for Items`")),
get_link_to_form(
"Selling Settings"
- if self.doctype in ["Sales Invoice", "Delivery Note"]
+ if self.doctype in selling_doctypes
else "Buying Settings"
),
),
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 64d2a0bd62a..c01b328c68e 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -888,7 +888,7 @@ def make_bundle_for_material_transfer(**kwargs):
row.stock_value_difference = abs(row.stock_value_difference)
if kwargs.type_of_transaction == "Outward":
row.qty *= -1
- row.stock_value_difference *= row.stock_value_difference
+ row.stock_value_difference *= -1
row.is_outward = 1
row.warehouse = kwargs.warehouse
diff --git a/erpnext/crm/doctype/contract_template/contract_template.py b/erpnext/crm/doctype/contract_template/contract_template.py
index b9dc9c8b7f3..f16987f3222 100644
--- a/erpnext/crm/doctype/contract_template/contract_template.py
+++ b/erpnext/crm/doctype/contract_template/contract_template.py
@@ -30,7 +30,7 @@ class ContractTemplate(Document):
def validate(self):
if self.contract_terms:
- validate_template(self.contract_terms)
+ validate_template(self.contract_terms, restrict_globals=True)
@frappe.whitelist()
@@ -41,6 +41,6 @@ def get_contract_template(template_name: str, doc: str | dict | Document):
contract_terms = None
if contract_template.contract_terms:
- contract_terms = frappe.render_template(contract_template.contract_terms, doc)
+ contract_terms = frappe.render_template(contract_template.contract_terms, doc, restrict_globals=True)
return {"contract_template": contract_template, "contract_terms": contract_terms}
diff --git a/erpnext/crm/doctype/email_campaign/email_campaign.py b/erpnext/crm/doctype/email_campaign/email_campaign.py
index bf0379b8e32..72ebdaa6090 100644
--- a/erpnext/crm/doctype/email_campaign/email_campaign.py
+++ b/erpnext/crm/doctype/email_campaign/email_campaign.py
@@ -171,8 +171,8 @@ def send_mail(entry, email_campaign):
context = {"doc": frappe.get_doc("Email Group", recipient)}
# Render template
- subject = frappe.render_template(email_template.get("subject"), context)
- content = frappe.render_template(email_template.response_, context)
+ subject = frappe.render_template(email_template.get("subject"), context, restrict_globals=True)
+ content = frappe.render_template(email_template.response_, context, restrict_globals=True)
frappe.db.savepoint("email_campaign_send")
try:
diff --git a/erpnext/locale/bs.po b/erpnext/locale/bs.po
index b784f2bcda0..969a75147d1 100644
--- a/erpnext/locale/bs.po
+++ b/erpnext/locale/bs.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: hello@frappe.io\n"
"POT-Creation-Date: 2026-08-02 10:09+0000\n"
-"PO-Revision-Date: 2026-08-05 10:02\n"
+"PO-Revision-Date: 2026-08-06 10:02\n"
"Last-Translator: hello@frappe.io\n"
"Language-Team: Bosnian\n"
"MIME-Version: 1.0\n"
@@ -789,9 +789,9 @@ msgstr "
Primjer Predloška Ugovora
\n\n"
"-Važi do: {{ end_date }}\n"
"\n\n"
"Kako dobiti imena polja
\n\n"
-"Nazivi polja koje možete koristiti u svom predlošku ugovora su polja u ugovoru za koje izradi predložak. Možete saznati polja bilo kojeg dokumenta putem Podešavanja > Prilagodi prikaz obrasca i odabir vrste dokumenta (npr. Ugovor)
\n\n"
+"Nazivi polja koje možete koristiti u svom predlošku ugovora su polja u ugovoru za koje izradi predložak. Možete saznati polja bilo kojeg dokumenta putem Podešavanja > Prilagodi prikaz obrasca i odabir tipa dokumenta (npr. Ugovor)
\n\n"
"Predložak
\n\n"
-"Predložci se kompajliraju koristeći Jinja Templating Language. Da saznate više o Jinji, pročitajte ovu dokumentaciju.
"
+"Predložci se kompajliraju koristeći Jinja Templating Language. Da saznate više o Jinji, pročitaj ovu dokumentaciju.
"
#. Content of the 'Terms and Conditions Help' (HTML) field in DocType 'Terms
#. and Conditions'
@@ -2926,11 +2926,11 @@ msgstr "Dodaj Bilješku"
#: banking/src/components/features/BankReconciliation/RecordPaymentModalContent.tsx:879
msgid "Add a charge to the payment entry with the difference amount"
-msgstr "Dodajte naplatu u unos plaćanja s iznosom razlike"
+msgstr "Dodaj naplatu u unos plaćanja s iznosom razlike"
#: banking/src/components/features/BankReconciliation/RecordPaymentModalContent.tsx:863
msgid "Add a charge to the payment entry with the unallocated amount"
-msgstr "Dodajte naplatu u unos plaćanja s nedodjeljnim iznosom"
+msgstr "Dodaj naplatu u unos plaćanja s nedodjeljnim iznosom"
#: banking/src/components/features/BankReconciliation/BankEntryModalContent.tsx:776
msgid "Add a row with the difference amount"
@@ -2942,7 +2942,7 @@ msgstr "Dodaj sve račune na koje želite podijeliti transakciju."
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:92
msgid "Add atleast one voucher to repost."
-msgstr "Dodajte barem jedan verifikat za ponovno knjiženje."
+msgstr "Dodaj barem jedan verifikat za ponovno knjiženje."
#: erpnext/www/book_appointment/index.html:42
msgid "Add details"
@@ -3405,7 +3405,7 @@ msgstr "Adresa & Kontakt"
#: erpnext/accounts/custom/address.py:35
msgid "Address needs to be linked to a Company. Please add a row for Company in the Links table."
-msgstr "Adresa mora biti povezana s firmom. Dodajte red za firmu u tabeli Veze."
+msgstr "Adresa mora biti povezana s firmom. Dodaj red za firmu u tabeli Veze."
#. Description of the 'Determine Address Tax Category from' (Select) field in
#. DocType 'Accounts Settings'
@@ -3966,7 +3966,7 @@ msgstr "Sve Prodajno Osoblje"
#. Description of a DocType
#: erpnext/setup/doctype/sales_person/sales_person.json
msgid "All Sales Transactions can be tagged against multiple Sales Persons so that you can set and monitor targets."
-msgstr "Sve prodajne transakcije mogu se označiti naspram više prodajnih osoba kako biste mogli postaviti i nadzirati ciljeve."
+msgstr "Sve prodajne transakcije mogu se odabrati naspram više prodajnih osoba kako biste mogli postaviti i nadzirati ciljeve."
#. Option for the 'Send To' (Select) field in DocType 'SMS Center'
#: erpnext/selling/doctype/sms_center/sms_center.json
@@ -4055,7 +4055,7 @@ msgstr "Sve odabrani artikli su već preneseni na ovu listu odabira"
#. in DocType 'CRM Settings'
#: erpnext/crm/doctype/crm_settings/crm_settings.json
msgid "All the Comments and Emails will be copied from one document to another newly created document(Lead -> Opportunity -> Quotation) throughout the CRM documents."
-msgstr "Svi komentari i e-pošta kopirat će se iz jednog dokumenta u drugi novostvoreni dokument (Potencijalni Klijent -> Prilika-> Ponuda) kroz dokumente Prodajne Podrške."
+msgstr "Svi komentari i e-pošta kopirat će se iz jednog dokumenta u drugi novoizrađeni dokument (Potencijalni Klijent -> Prilika-> Ponuda) kroz dokumente Prodajne Podrške."
#: erpnext/selling/page/point_of_sale/pos_past_order_summary.js:204
msgid "All the items have already been returned."
@@ -5598,7 +5598,7 @@ msgstr "Termin se može zakazati samo do {0} dana unaprijed."
#: erpnext/crm/doctype/appointment/appointment.py:79
msgid "Appointment cannot be scheduled for a past time."
-msgstr "Termin se ne može zakazati za prošlu vrijeme."
+msgstr "Termin se ne može zakazati za prošlo vrijeme."
#: erpnext/crm/doctype/appointment/appointment.py:98
msgid "Appointment cannot be scheduled on a holiday."
@@ -5664,11 +5664,11 @@ msgstr "Jeste li sigurni da želite izbrisati sve demo podatke?"
#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.js:51
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.js:100
msgid "Are you sure you want to create Reposting Entries?"
-msgstr "Jeste li sigurni da želite stvoriti ponovno knjiženje unosa?"
+msgstr "Jeste li sigurni da želite izraditi ponovno knjiženje unosa?"
#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.js:66
msgid "Are you sure you want to create a Reposting Entry?"
-msgstr "Jeste li sigurni da želite stvoriti ponovno knjiženje unosa?"
+msgstr "Jeste li sigurni da želite izraditi ponovno knjiženje unosa?"
#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:499
msgid "Are you sure you want to delete this Item?"
@@ -6455,7 +6455,7 @@ msgstr "Red {0}: Serijski Broj je obavezan za Artikal {1}"
#: erpnext/stock/services/serial_batch_bundle_service.py:504
msgid "At row {0}: Serial and Batch Bundle {1} has already been created. Please remove the values from the serial no or batch no fields."
-msgstr "U Redu {0}: Serijski i Šaržni Paket {1} je već stvoren. Uklonite vrijednosti iz polja za serijski ili šaržni broj."
+msgstr "U Redu {0}: Serijski i Šaržni Paket {1} je već izrađen. Uklonite vrijednosti iz polja za serijski ili šaržni broj."
#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:123
msgid "At row {0}: set Parent Row No for item {1}"
@@ -6729,7 +6729,7 @@ msgstr "Automatska izrada Podizvođačkom Naloga"
#. Label of the auto_create_assets (Check) field in DocType 'Item'
#: erpnext/stock/doctype/item/item.json
msgid "Auto create assets on purchase"
-msgstr "Automatski stvori sredstava pri nabavi"
+msgstr "Automatski izradi sredstava pri nabavi"
#. Label of the auto_insert_price_list_rate_if_missing (Check) field in DocType
#. 'Stock Settings'
@@ -6796,7 +6796,7 @@ msgstr "Automatski Izradi Novi Šaržu"
#. 'Accounts Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
msgid "Automatically add Taxes and Charges from Item Tax Template"
-msgstr "Automatski dodajte PDV i Naknade iz Predloška za PDV na Artikal"
+msgstr "Automatski dodaj PDV i Naknade iz Predloška za PDV na Artikal"
#. Label of the add_taxes_from_taxes_and_charges_template (Check) field in
#. DocType 'Accounts Settings'
@@ -7013,7 +7013,7 @@ msgstr "Prosječna Cjena"
#. Label of the avg_response_time (Duration) field in DocType 'Issue'
#: erpnext/support/doctype/issue/issue.json
msgid "Average Response Time"
-msgstr "Prosječno Vreme Odziva"
+msgstr "Prosječno Vreme Odgovora"
#. Description of the 'Lead Time in days' (Int) field in DocType 'Item'
#: erpnext/stock/doctype/item/item.json
@@ -7770,7 +7770,7 @@ msgstr "Bankovni Nacrt"
#: banking/src/components/features/BankReconciliation/BankEntryModalContent.tsx:98
msgid "Bank Entries Created"
-msgstr "Bankovni Unosi Stvoreni"
+msgstr "Bankovni Unosi Izrađeni"
#. Option for the 'Classify As' (Select) field in DocType 'Bank Transaction
#. Rule'
@@ -7792,7 +7792,7 @@ msgstr "Bankovni Unos"
#: banking/src/components/features/BankReconciliation/BankEntryModalContent.tsx:295
msgid "Bank Entry Created"
-msgstr "Bankovni Unos Stvoren"
+msgstr "Bankovni Unos Izrađen"
#. Label of the bank_entry_type (Select) field in DocType 'Bank Transaction
#. Rule'
@@ -8362,12 +8362,12 @@ msgstr "Šarža nije izrađena za artikal {0} jer nema Broj Šarže."
#. 'Item'
#: erpnext/stock/doctype/item/item.json
msgid "Batch number will be auto-created in format AAAA.00001 if not specified in transactions. Leave blank to always enter batch numbers manually."
-msgstr "Broj šarže bit će automatski stvoren u formatu AAAA.00001 ako nije naveden u transakcijama. Ostavite prazno da biste uvijek ručno unosili brojeve šarže."
+msgstr "Broj šarže bit će automatski izrađen u formatu AAAA.00001 ako nije naveden u transakcijama. Ostavite prazno da biste uvijek ručno unosili brojeve šarže."
#. Description of the 'Has Expiry Date' (Check) field in DocType 'Item'
#: erpnext/stock/doctype/item/item.json
msgid "Batch number will be created based on expiry date. Expiry dates can be set in the Batch master."
-msgstr "Broj šarže bit će stvoren na temelju datuma isteka. Datumi isteka mogu se postaviti u Postavkama Šarže."
+msgstr "Broj šarže bit će izrađen na temelju datuma isteka. Datumi isteka mogu se postaviti u Postavkama Šarže."
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:384
msgid "Batch {0} and Warehouse"
@@ -9949,7 +9949,7 @@ msgstr "Nije moguće izraditi knjigovodstvene unose naspram onemogućenih račun
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py:146
msgid "Cannot create more Subcontracting Orders against the Purchase Order {0}."
-msgstr "Ne može se stvoriti više Podugovornih Naloga na osnovu Naloga Nabave {0}."
+msgstr "Ne može se izraditi više Podugovornih Naloga na osnovu Naloga Nabave {0}."
#: erpnext/controllers/sales_and_purchase_return.py:444
msgid "Cannot create return for consolidated invoice {0}."
@@ -10998,7 +10998,7 @@ msgstr "Zatvorite Predmet nakon (dana)"
#: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js:69
msgid "Close Loan"
-msgstr "Zatvori Zajam"
+msgstr "Zatvori Kredit"
#. Label of the close_opportunity_after_days (Int) field in DocType 'CRM
#. Settings'
@@ -12182,7 +12182,7 @@ msgstr "Proizvedena Količina"
#: erpnext/manufacturing/doctype/job_card/job_card.py:1737
msgid "Completed Quantity ({0}), Pending Quantity ({1}) and Process Loss Quantity ({2}) must add up to the Qty to Manufacture ({3})."
-msgstr "Izvršena Količina ({0}), Količina na Čekanju ({1}) i Količina Gubitka u Procesu ({2}) moraju se zbrajati do Količine za Proizvodnju ({3})."
+msgstr "Završena Količina ({0}), Količina na Čekanju ({1}) i Količina Gubitka u Procesu ({2}) moraju se zbrajati do Količine za Proizvodnju ({3})."
#: erpnext/manufacturing/doctype/job_card/job_card.js:280
#: erpnext/public/js/shop_floor/shop_floor.js:825
@@ -14068,7 +14068,7 @@ msgstr "Stvarajednu grupisanu imovinu umjesto pojedinačnih kada se nabavlja na
#. 'Item'
#: erpnext/stock/doctype/item/item.json
msgid "Creates an Item Price automatically when the item is saved"
-msgstr "Automatski stvori cjenu artikla kada se artikal spremi"
+msgstr "Automatski izradi cjenu artikla kada se artikal spremi"
#: erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.js:140
msgid "Creating Accounts..."
@@ -17662,7 +17662,7 @@ msgstr "Rastavljena Količina"
#: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js:64
msgid "Disburse Loan"
-msgstr "Isplati Zajam"
+msgstr "Isplati Kredit"
#. Option for the 'Status' (Select) field in DocType 'Invoice Discounting'
#: erpnext/accounts/doctype/invoice_discounting/invoice_discounting.json
@@ -21632,7 +21632,7 @@ msgstr "Za individualnog Dobavljača"
#: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py:379
msgid "For item {0}, only {1} assets have been created or linked to {2}. Please create or link {3} more assets with the respective document."
-msgstr "Za artikal {0}, samo {1} imovina je stvorena ili povezana s {2}. Stvori ili poveži još {3} imovine s odgovarajućim dokumentom."
+msgstr "Za artikal {0}, samo {1} imovina je izrađena ili povezana s {2}. Izradi ili poveži još {3} imovine s odgovarajućim dokumentom."
#: erpnext/controllers/status_updater.py:303
msgid "For item {0}, rate must be a positive number. To allow negative rates, enable {1} in {2}"
@@ -21646,7 +21646,7 @@ msgstr "Za stare serijske brojeve, nemojte preuzimati nabvnu cjenu iz serijskog
#: erpnext/manufacturing/doctype/bom/bom.py:400
msgid "For operation {0} at row {1}, please add raw materials or set a BOM against it."
-msgstr "Za radnju {0} u redu {1}, molimo dodajte sirovine ili postavi Sastavnicu naspram nje."
+msgstr "Za radnju {0} u redu {1}, molimo dodaj sirovine ili postavi Sastavnicu naspram nje."
#: erpnext/manufacturing/doctype/work_order/mapper.py:383
msgid "For operation {0}: Quantity ({1}) can not be greater than pending quantity ({2})"
@@ -23856,7 +23856,7 @@ msgstr "Ako je Omogućeno - Usaglašavanje se dešava na Datum Knjiže
#: erpnext/accounts/doctype/loyalty_program/loyalty_program.js:34
msgid "If Auto Opt In is checked, then the customers will be automatically linked with the concerned Loyalty Program (on save)"
-msgstr "Ako je automatska registracija označena, tada će klijenti biti automatski povezani sa dotičnim Programom Lojalnosti (prilikom spremanja)"
+msgstr "Ako je automatska registracija odabrana, tada će klijenti biti automatski povezani sa dotičnim Programom Lojalnosti (prilikom spremanja)"
#. Description of the 'Cost Center' (Link) field in DocType 'Journal Entry
#. Account'
@@ -24118,7 +24118,7 @@ msgstr "Ako je omogućeno, sistem će dozvoliti korisnicima da uređuju sirovine
#. in DocType 'Buying Settings'
#: erpnext/buying/doctype/buying_settings/buying_settings.json
msgid "If enabled, the system will generate an accounting entry for materials rejected in the Purchase Receipt."
-msgstr "Ako je omogućeno, sistem će stvoriti knjigovodstveni unos za odbijene materijale u Nabavnom Računu."
+msgstr "Ako je omogućeno, sistem će izraditi knjigovodstveni unos za odbijene materijale u Nabavnom Računu."
#. Description of the 'Enable Item-wise Inventory Account' (Check) field in
#. DocType 'Company'
@@ -28000,7 +28000,7 @@ msgstr "Cjena Artikla se pojavljuje više puta na osnovu Cjenovnika, Dobavljača
#: erpnext/stock/doctype/item/item.py:186
msgid "Item Price created at rate {0}"
-msgstr "Cjena Artikla stvorena po stopi {0}"
+msgstr "Cjena Artikla izrađena po stopi {0}"
#: erpnext/stock/get_item_details.py:1160
msgid "Item Price updated for {0} in Price List {1}"
@@ -28341,7 +28341,7 @@ msgstr "Artikal Radnji"
#: erpnext/stock/doctype/stock_entry/stock_entry.py:676
msgid "Item rate has been updated to zero as Allow Zero Valuation Rate is checked for item {0}"
-msgstr "Cjena Artikla je ažurirana na nulu jer je Dozvoli Nultu Stopu Vrednovanja označena za artikal {0}"
+msgstr "Cjena Artikla je ažurirana na nulu jer je Dozvoli Nultu Stopu Vrednovanja odabrana za artikal {0}"
#: erpnext/stock/doctype/material_request/material_request.py:231
msgid "Item rates have been updated based on the selected Buying Price List {0}"
@@ -30955,7 +30955,7 @@ msgstr "Uporedi i Uskladi"
#: banking/src/components/features/BankReconciliation/MatchAndReconcile.tsx:62
msgid "Match or Create"
-msgstr "Uskladi ili Stvori"
+msgstr "Uskladi ili Izradi"
#. Label of the transfer_match_days (Int) field in DocType 'Accounts Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -32253,7 +32253,7 @@ msgstr "Za datum {0} postoji više fiskalnih godina. Postavi poduzeće u Fiskaln
#: erpnext/stock/doctype/stock_entry/stock_entry.py:957
msgid "Multiple items cannot be marked as finished item"
-msgstr "Više artikala se ne mogu označiti kao gotov proizvod"
+msgstr "Više artikala se ne mogu odabrati kao gotov proizvod"
#: erpnext/setup/setup_wizard/data/industry_type.txt:33
msgid "Music"
@@ -32900,7 +32900,7 @@ msgstr "Nove fakture će se izraditi prema rasporedu čak i ako su trenutne fakt
#: erpnext/support/doctype/issue/issue.js:126
msgid "New issue created: {0}"
-msgstr "Novi zahtjev stvoren: {0}"
+msgstr "Novi zahtjev izrađen: {0}"
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:261
msgid "New release date should be in the future"
@@ -35664,7 +35664,7 @@ msgstr "Kasa Faktura nije podnešena"
#: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:130
msgid "POS Invoice isn't created by user {0}"
-msgstr "Korisnik {0} nije stvorio Kasa Fakturu"
+msgstr "Korisnik {0} nije izradio Kasa Fakturu"
#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:208
msgid "POS Invoice should have the field {0} checked."
@@ -37339,7 +37339,7 @@ msgstr "Platni Zahtjevi ne mogu se izraditi naspram: {0}"
#. in DocType 'Accounts Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
msgid "Payment Requests made from Sales / Purchase Invoice will be put in Draft explicitly"
-msgstr "Zahtjevi Plaćanja stvoren iz Prodajne / Nabavne Fakture bit će eksplicitno stavljeni u Nacrt"
+msgstr "Zahtjevi Plaćanja izrađen iz Prodajne / Nabavne Fakture bit će eksplicitno stavljeni u Nacrt"
#. Label of the payment_schedule (Data) field in DocType 'Overdue Payment'
#. Label of the payment_schedule (Link) field in DocType 'Payment Reference'
@@ -47634,7 +47634,7 @@ msgstr "Red #{0}: Šarža {1} je već istekla."
#: erpnext/stock/doctype/stock_entry/stock_entry.py:417
msgid "Row #{0}: The job card item reference is missing. Kindly create the stock entry from the job card. If you have added the row manually then you won't be able to add job card item reference."
-msgstr "Red #{0}: Nedostaje referenca artikla na radnoj kartici. Stvori unos zaliha iz radne kartice. Ako ste red dodali ručno, nećete moći dodati referencu artikla na radnu karticu."
+msgstr "Red #{0}: Nedostaje referenca artikla na radnoj kartici. Izradi unos zaliha iz radne kartice. Ako ste red dodali ručno, nećete moći dodati referencu artikla na radnu karticu."
#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:103
msgid "Row #{0}: The original Invoice {1} of return invoice {2} is not consolidated."
@@ -50129,7 +50129,7 @@ msgstr "Odabrani Početni Unos Kase bi trebao biti otvoren."
#: erpnext/accounts/doctype/sales_invoice/mapper.py:158
msgid "Selected Price List should have buying and selling fields checked."
-msgstr "Odabrani Cjenovnik treba da ima označena polja za Nabavu i Prodaju."
+msgstr "Odabrani Cjenovnik treba da ima odabrana polja za Nabavu i Prodaju."
#: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py:123
msgid "Selected Print Format does not exist."
@@ -53118,7 +53118,7 @@ msgstr "Unos Zaliha {0} je izrađen"
#: erpnext/manufacturing/doctype/job_card/job_card.py:1785
msgid "Stock Entry {0} has been created"
-msgstr "Unos Zaliha {0} je stvoren"
+msgstr "Unos Zaliha {0} je izrađen"
#: erpnext/accounts/doctype/journal_entry/journal_entry.py:997
msgid "Stock Entry {0} is not submitted"
@@ -56619,7 +56619,7 @@ msgstr "Faktura nije u potpunosti dodijeljena jer postoji razlika od {0}."
#: erpnext/controllers/buying_controller.py:1263
msgid "The item {item} is not marked as {type_of} item. You can enable it as {type_of} item from its Item master."
-msgstr "Artikal {item} nije označen kao {type_of} artikal. Možete ga omogućiti kao {type_of} Artikal u Postavkama Artikla."
+msgstr "Artikal {item} nije odabran kao {type_of} artikal. Možete ga omogućiti kao {type_of} Artikal u Postavkama Artikla."
#: erpnext/stock/doctype/item/item.py:682
msgid "The items {0} and {1} are present in the following {2} :"
@@ -56627,7 +56627,7 @@ msgstr "Artikli {0} i {1} se nalaze u sljedećem {2} :"
#: erpnext/controllers/buying_controller.py:1256
msgid "The items {items} are not marked as {type_of} item. You can enable them as {type_of} item from their Item masters."
-msgstr "Artikli {items} nisu označeni kao {type_of} artikli. Možete ih omogućiti kao {type_of} artikle u Postavkama Artikala."
+msgstr "Artikli {items} nisu odabrani kao {type_of} artikli. Možete ih omogućiti kao {type_of} artikle u Postavkama Artikala."
#: erpnext/manufacturing/doctype/workstation/workstation.py:527
msgid "The job card {0} is in {1} state and you cannot complete it."
@@ -57098,7 +57098,7 @@ msgstr "Ovo omogućava izradu prodajnih naloga iz ponuda kojima je istekao rok v
#: erpnext/assets/doctype/asset/asset.py:438
msgid "This asset category is marked as non-depreciable. Please disable depreciation calculation or choose a different category."
-msgstr "Ova kategorija imovine je označena kao neamortizujuća. Onemogući obračun amortizacije ili odaberi drugu kategoriju."
+msgstr "Ova kategorija imovine je odabrana kao neamortizujuća. Onemogući obračun amortizacije ili odaberi drugu kategoriju."
#. Description of the 'Allow negative stock' (Check) field in DocType 'Stock
#. Settings'
@@ -57288,7 +57288,7 @@ msgstr "Ova radnja zahtijeva Kontrolu Kvalitete, ali nije konfiguriran predloža
#: erpnext/stock/doctype/delivery_note/delivery_note.js:509
msgid "This option can be checked to edit the 'Posting Date' and 'Posting Time' fields."
-msgstr "Ova opcija se može označiti za uređivanje polja 'Datum Knjiženja' i 'Vrijeme Knjiženja'."
+msgstr "Ova opcija se može odabrati za uređivanje polja 'Datum Knjiženja' i 'Vrijeme Knjiženja'."
#. Description of the 'Raise Material Request when stock reaches re-order
#. level' (Check) field in DocType 'Stock Settings'
@@ -59238,7 +59238,7 @@ msgstr "Transakcije naspram Poduzeća već postoje! Kontni Plan se može uvesti
#. 'Customer'
#: erpnext/selling/doctype/customer/customer.json
msgid "Transactions are blocked when the outstanding balance exceeds the credit limit. When Restrict Customer Over Billing is enabled, new invoices are also blocked when the customer's overdue amount exceeds the Overdue Limit."
-msgstr "Transakcije se blokiraju kada preostali dug premaši kreditni limit. Kada je omogućena opcija Ograniči Prekomjerno Fakturisanja Klijenta, nove fakture se također blokiraju kada iznos dospjelih obaveza klijenta premaši granicu za dospjele obaveze."
+msgstr "Transakcije se blokiraju kada preostali dug premaši kreditnu granicu. Kada je omogućena opcija Ograniči Prekomjerno Fakturisanja Klijenta, nove fakture se također blokiraju kada iznos dospjelih obaveza klijenta premaši granicu za dospjele obaveze."
#: banking/src/components/features/BankStatementImporter/CSV/StatementDetails.tsx:239
msgid "Transactions to be imported into the system"
@@ -61129,11 +61129,11 @@ msgstr "Stopa Vrednovanja artikla prema Prodajnoj Fakturi (samo za interne trans
#: erpnext/accounts/doctype/payment_entry/payment_entry.py:2010
#: erpnext/accounts/services/taxes.py:322
msgid "Valuation type charges can not be marked as Inclusive"
-msgstr "Naknade za tip vrijednovanja ne mogu biti označene kao Inkluzivne"
+msgstr "Naknade za tip vrijednovanja ne mogu biti odabrane kao Inkluzivne"
#: erpnext/public/js/controllers/accounts.js:228
msgid "Valuation type charges cannot be marked as Inclusive"
-msgstr "Naknade tipa procjene vrijednosti ne mogu biti označene kao uključene."
+msgstr "Naknade tipa procjene vrijednosti ne mogu biti odabrane kao uključene."
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.js:58
msgid "Value (G - D)"
@@ -62118,13 +62118,13 @@ msgstr "Upozori pri novim Zahtjevima za Ponudu"
#. in DocType 'Selling Settings'
#: erpnext/selling/doctype/selling_settings/selling_settings.json
msgid "Warn or stop if Item rate is changed in Delivery Notes and Sales Invoices generated from a Sales Order."
-msgstr "Upozori ili zaustavi ako se cjena artikla promijeni u Otpremnicama i Prodajnim Fakturama stvorenih iz Prodajnog Naloga."
+msgstr "Upozori ili zaustavi ako se cjena artikla promijeni u Otpremnicama i Prodajnim Fakturama izrađenih iz Prodajnog Naloga."
#. Description of the 'Maintain same rate throughout the purchase cycle'
#. (Check) field in DocType 'Buying Settings'
#: erpnext/buying/doctype/buying_settings/buying_settings.json
msgid "Warn or stop if Item rate is changed in Purchase Invoice or Purchase Receipt generated from a Purchase Order."
-msgstr "Upozori ili zaustavi ako se cjena artikla promijeni u fakturi ili potvrdi o nabavi stvorenoj iz naloga nabave."
+msgstr "Upozori ili zaustavi ako se cjena artikla promijeni u fakturi ili potvrdi o nabavi izrađenoj iz naloga nabave."
#: erpnext/projects/doctype/timesheet_detail/timesheet_detail.py:134
msgid "Warning - Row {0}: Billing Hours are more than Actual Hours"
@@ -64185,7 +64185,7 @@ msgstr "{0} mora biti negativan u povratnom dokumentu"
#: erpnext/accounts/doctype/sales_invoice/services/inter_company.py:60
msgid "{0} not allowed to transact with {1}. Please change the Company or add the Company in the 'Allowed To Transact With'-Section in the Customer record."
-msgstr "{0} nije dozvoljeno obavljati transakcije sa {1}. Promijeni poduzeće ili dodaj poduzeće u sekciju 'Dozvoljena Transakcija s' u zapisu klijenata."
+msgstr "{0} nije dozvoljeno obavljati transakcije sa {1}. Promijeni poduzeće ili dodaj poduzeće u odjeljak 'Dozvoljena Transakcija s' u zapisu klijenata."
#: erpnext/manufacturing/doctype/bom/services/costing.py:63
msgid "{0} not found for item {1}"
diff --git a/erpnext/locale/fa.po b/erpnext/locale/fa.po
index 5e12843a768..8bcb288523c 100644
--- a/erpnext/locale/fa.po
+++ b/erpnext/locale/fa.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: hello@frappe.io\n"
"POT-Creation-Date: 2026-08-02 10:09+0000\n"
-"PO-Revision-Date: 2026-08-05 10:02\n"
+"PO-Revision-Date: 2026-08-06 10:02\n"
"Last-Translator: hello@frappe.io\n"
"Language-Team: Persian\n"
"MIME-Version: 1.0\n"
@@ -39010,7 +39010,7 @@ msgstr "لطفاً یک یادداشت تحویل را انتخاب کنید"
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:81
msgid "Please select a Holiday List to enable Appointment Scheduling."
-msgstr ""
+msgstr "لطفا برای فعال کردن زمانبندی قرار ملاقات، یک لیست تعطیلات انتخاب کنید."
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py:152
msgid "Please select a Subcontracting Purchase Order."
@@ -39096,7 +39096,7 @@ msgstr ""
#: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1356
msgid "Please select a valid {0}"
-msgstr ""
+msgstr "لطفا یک {0} معتبر انتخاب کنید"
#: erpnext/selling/doctype/quotation/quotation.js:245
msgid "Please select a value for {0} quotation_to {1}"
@@ -44133,7 +44133,7 @@ msgstr ""
#: erpnext/stock/doctype/bin/bin.js:10
msgid "Recalculate Values"
-msgstr ""
+msgstr "محاسبه مجدد مقادیر"
#. Option for the 'Status' (Select) field in DocType 'Asset'
#. Option for the 'Purpose' (Select) field in DocType 'Asset Movement'
@@ -49365,7 +49365,7 @@ msgstr "زمانبند غیرفعال است. نمیتوان حسابها
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:232
msgid "Scheduler is inactive. Reposting will only run once background jobs are processed."
-msgstr ""
+msgstr "زمانبند غیرفعال است. ارسال مجدد فقط زمانی اجرا میشود که کارهای پسزمینه پردازش شوند."
#. Label of the schedules (Table) field in DocType 'Maintenance Schedule'
#: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json
@@ -49811,7 +49811,7 @@ msgstr "انتخاب آدرس تامین کننده"
#: erpnext/stock/doctype/material_request/material_request.js:449
msgid "Select Supplier for Items"
-msgstr ""
+msgstr "انتخاب تامین کننده برای آیتمها"
#: erpnext/stock/doctype/batch/batch.js:150
msgid "Select Target Warehouse"
@@ -49865,7 +49865,7 @@ msgstr "یک تامین کننده انتخاب کنید"
#: erpnext/stock/doctype/material_request/mapper.py:230
#: erpnext/stock/doctype/material_request/material_request.js:553
msgid "Select a Supplier for Item {0}"
-msgstr ""
+msgstr "انتخاب یک تأمینکننده برای آیتم {0}"
#: banking/src/components/features/BankReconciliation/MatchAndReconcile.tsx:49
msgid "Select a bank account to reconcile"
@@ -49910,7 +49910,7 @@ msgstr "از هر مجموعه یک آیتم را برای استفاده در
#: erpnext/stock/doctype/material_request/mapper.py:211
#: erpnext/stock/doctype/material_request/material_request.js:540
msgid "Select at least one Item"
-msgstr ""
+msgstr "حداقل یک آیتم را انتخاب کنید"
#: erpnext/stock/doctype/item/item.js:1256
msgid "Select at least one attribute value."
@@ -50249,7 +50249,7 @@ msgstr "ارسال با پیوست"
#: erpnext/accounts/doctype/payment_request/payment_request.js:51
#: erpnext/accounts/doctype/payment_request/payment_request.js:55
msgid "Sending Email"
-msgstr ""
+msgstr "ارسال ایمیل"
#. Option for the 'Detected Amount Format' (Select) field in DocType 'Bank
#. Statement Import Log'
@@ -51134,7 +51134,7 @@ msgstr "تنظیم تامین کننده"
#: erpnext/stock/doctype/material_request/material_request.js:456
msgid "Set Supplier for All Items"
-msgstr ""
+msgstr "تنظیم تأمینکننده برای همه آیتمها"
#. Label of the set_target_warehouse (Link) field in DocType 'Sales Invoice'
#. Label of the set_warehouse (Link) field in DocType 'Purchase Order'
@@ -61276,7 +61276,7 @@ msgstr ""
#. Label of the verification_token (Data) field in DocType 'Appointment'
#: erpnext/crm/doctype/appointment/appointment.json
msgid "Verification Token"
-msgstr ""
+msgstr "توکن تأیید"
#: erpnext/www/book_appointment/verify/index.html:15
msgid "Verification failed please check the link"
@@ -62147,7 +62147,7 @@ msgstr ""
#: erpnext/templates/emails/appointment_confirmed.html:3
msgid "We look forward to meeting you"
-msgstr ""
+msgstr "مشتاق دیدار شما هستیم"
#: banking/src/pages/BankStatementImporter.tsx:169
msgid "We support uploading CSV, XLSX, XLS and PDF files. Please make sure the file contains the correct columns."
diff --git a/erpnext/locale/hr.po b/erpnext/locale/hr.po
index 3b4f0d3c4ff..4c8050477f5 100644
--- a/erpnext/locale/hr.po
+++ b/erpnext/locale/hr.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: hello@frappe.io\n"
"POT-Creation-Date: 2026-08-02 10:09+0000\n"
-"PO-Revision-Date: 2026-08-03 09:29\n"
+"PO-Revision-Date: 2026-08-06 10:02\n"
"Last-Translator: hello@frappe.io\n"
"Language-Team: Croatian\n"
"MIME-Version: 1.0\n"
@@ -104,7 +104,7 @@ msgstr "\"SB-01::10\" za \"SB-01\" do \"SB-10\""
#: erpnext/public/js/utils/serial_batch_inline_editor.js:764
msgid "\"SN-01::10\" for \"SN-01\" to \"SN-10\". Missing Serial Nos will be created on Save"
-msgstr ""
+msgstr "\"SN-01::10\" za \"SN-01\" do \"SN-10\". Nedostajuće serijske brojeve bit će izrađeni pri Spremanju."
#: erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py:157
msgid "# In Stock"
@@ -142,7 +142,7 @@ msgstr "% Završeno Metoda"
#: erpnext/projects/doctype/project/project.py:282
msgid "% Complete must be between 0 and 100"
-msgstr ""
+msgstr "% dovršenosti mora biti između 0 i 100"
#. Label of the percent_complete (Percent) field in DocType 'Project'
#: erpnext/projects/doctype/project/project.json
@@ -339,7 +339,7 @@ msgstr "'Ažuriraj Zalihe' ne može se provjeriti za prodaju osnovne Imovine"
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:112
msgid "'Verification Link Expiry Duration' must be between 15 to 60 minutes."
-msgstr ""
+msgstr "'Trajanje Važenja Verifikacijske Poveznice' mora biti između 15 i 60 minuta."
#: erpnext/accounts/doctype/bank_account/bank_account.py:79
msgid "'{0}' account is already used by {1}. Use another account."
@@ -1108,7 +1108,7 @@ msgstr "Proizvod ili Usluga koja se kupuje, nabavlja ili drži na zalihama."
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:156
msgid "A Proforma Invoice can only be created against a submitted Sales Order."
-msgstr ""
+msgstr "Proforma Faktura se može izraditi samo na osnovu podnešenog Prodajnog Naloga."
#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:603
msgid "A Reconciliation Job {0} is running for the same filters. Cannot reconcile now"
@@ -1120,7 +1120,7 @@ msgstr "Obrnuti naloga knjiženja {0} već postoji za ovaj nalog knjiženja."
#: erpnext/public/js/sales_order_proforma.js:306
msgid "A cancelled Proforma Invoice cannot be emailed."
-msgstr ""
+msgstr "Otkazana Proforma Faktura ne može se poslati e-poštom."
#. Description of a DocType
#: erpnext/accounts/doctype/shipping_rule_condition/shipping_rule_condition.json
@@ -1140,11 +1140,11 @@ msgstr "Onemogućeni Paket Artikal ne može se odabrati u transakcijama."
#: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py:643
msgid "A draft reverse journal for {0} has been created: {1}"
-msgstr ""
+msgstr "Nacrt obrnutog naloga knjiženja za {0} je izrađen: {1}"
#: erpnext/public/js/utils/draft_link_guard.js:49
msgid "A draft {0} already exists for this {1}: {2}. Do you still want to create a new one?"
-msgstr ""
+msgstr "Nacrt {0} već postoji za {1}: {2}. Želite li i dalje izraditi novi?"
#: erpnext/stock/doctype/delivery_trip/delivery_trip.py:59
msgid "A driver must be set to submit."
@@ -1189,7 +1189,7 @@ msgstr "Kontrola Kvaliteta mora biti izvršena prije izdavanja Nabavnog Računa
#: erpnext/stock/doctype/material_request/material_request.js:477
msgid "A separate Purchase Order is created for each Supplier."
-msgstr ""
+msgstr "Za svakog Dobavljača izrađuje se zasebni Nalog Nabave."
#: erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py:99
msgid "A template with tax category {0} already exists. Only one template is allowed with each tax category"
@@ -1202,7 +1202,7 @@ msgstr "Distributer / trgovac / komisionar / podružnica / preprodavač treće s
#: erpnext/crm/doctype/appointment/appointment.py:70
msgid "A verified appointment cannot be moved back to 'Unverified' status."
-msgstr ""
+msgstr "Potvrđeni termin se ne može vratiti u status 'Neverificirano'."
#. Option for the 'Blood Group' (Select) field in DocType 'Employee'
#: erpnext/setup/doctype/employee/employee.json
@@ -2397,7 +2397,7 @@ msgstr "Radnja je Pokrenuta"
#. DocType 'Appointment Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "Action for Expired Unverified Appointments"
-msgstr ""
+msgstr "Radnja za Istekle Nepotvrđene Termine"
#. Label of the action_if_accumulated_monthly_budget_exceeded (Select) field in
#. DocType 'Budget'
@@ -2942,7 +2942,7 @@ msgstr "Dodaj sve račune na koje želite podijeliti transakciju."
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:92
msgid "Add atleast one voucher to repost."
-msgstr ""
+msgstr "Dodaj barem jedan verifikat za ponovno knjiženje."
#: erpnext/www/book_appointment/index.html:42
msgid "Add details"
@@ -3452,7 +3452,7 @@ msgstr "Iznos Predujma"
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:93
msgid "Advance Booking Days is mandatory for Appointment Scheduling."
-msgstr ""
+msgstr "Prethodna Rezervacija Dana je obavezna za Zakazivanje Termina."
#. Label of the advance_paid (Currency) field in DocType 'Sales Order'
#: erpnext/selling/doctype/sales_order/sales_order.json
@@ -3775,7 +3775,7 @@ msgstr "Dob ({0})"
#: erpnext/accounts/report/accounts_receivable/accounts_receivable.js:102
#: erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.js:28
msgid "Age as on"
-msgstr ""
+msgstr "Dob na"
#. Label of the ageing_based_on (Select) field in DocType 'Process Statement Of
#. Accounts'
@@ -4455,7 +4455,7 @@ msgstr "Dopusti interne prenose po korisnički definiranoj cijeni"
#. 'Selling Settings'
#: erpnext/selling/doctype/selling_settings/selling_settings.json
msgid "Allow issuing Proforma Invoices against a Sales Order."
-msgstr ""
+msgstr "Omogućite izdavanje Proforma Faktura na osnovu Prodajnog Naloga."
#. Description of the 'Allow Continuous Material Consumption' (Check) field in
#. DocType 'Manufacturing Settings'
@@ -5136,7 +5136,7 @@ msgstr "Grupa Artikla je način za klasifikaciju Artikala na temelju tipa."
#: erpnext/crm/doctype/appointment/appointment.py:74
msgid "An appointment booked through the portal can only be opened via email verification."
-msgstr ""
+msgstr "Termin rezerviran putem portala može se otvoriti samo putem potvrde e-poštom."
#. Description of the 'Notify by email on creation of automatic Material
#. Request' (Check) field in DocType 'Stock Settings'
@@ -5535,7 +5535,7 @@ msgstr "Imenovanje"
#. Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "Appointment Booking Portal Settings"
-msgstr ""
+msgstr "Postavke Portala za Zakazivanje Termina"
#. Name of a DocType
#. Label of a Workspace Sidebar Item
@@ -5555,7 +5555,7 @@ msgstr "Potvrda Termina"
#: erpnext/crm/doctype/appointment/appointment.py:189
msgid "Appointment Confirmed"
-msgstr ""
+msgstr "Termin Potvrđen"
#. Label of the appointment_details_section (Section Break) field in DocType
#. 'Appointment Booking Settings'
@@ -5573,7 +5573,7 @@ msgstr "Trajanje Termina (u minutama)"
#. 'Appointment Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "Appointment Scheduling"
-msgstr ""
+msgstr "Zakazivanje Termina"
#: erpnext/www/book_appointment/index.py:24
msgid "Appointment Scheduling Disabled"
@@ -5585,7 +5585,7 @@ msgstr "Zakazivanje termina je onemogućeno za ovu stranicu"
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:101
msgid "Appointment Scheduling needs to be enabled for Appointment Booking through portal."
-msgstr ""
+msgstr "Zakazivanje Termina mora biti omogućeno za Rezervaciju Termina putem portala."
#. Label of the appointment_with (Link) field in DocType 'Appointment'
#: erpnext/crm/doctype/appointment/appointment.json
@@ -5594,15 +5594,15 @@ msgstr "Termin s"
#: erpnext/crm/doctype/appointment/appointment.py:86
msgid "Appointment can only be scheduled up to {0} day(s) in advance."
-msgstr ""
+msgstr "Termin se može zakazati samo do {0} dana unaprijed."
#: erpnext/crm/doctype/appointment/appointment.py:79
msgid "Appointment cannot be scheduled for a past time."
-msgstr ""
+msgstr "Termin se ne može zakazati za prošlo vrijeme."
#: erpnext/crm/doctype/appointment/appointment.py:98
msgid "Appointment cannot be scheduled on a holiday."
-msgstr ""
+msgstr "Termin se ne može zakazati na praznik."
#: erpnext/www/book_appointment/index.js:237
msgid "Appointment created successfully"
@@ -5610,19 +5610,19 @@ msgstr "Termin je uspješno zakazan"
#: erpnext/www/book_appointment/verify/index.py:28
msgid "Appointment has been closed. Please book the appointment again."
-msgstr ""
+msgstr "Termin je zatvoren. Ponovo zakažete novi termin."
#: erpnext/www/book_appointment/verify/index.py:33
msgid "Appointment is already verified."
-msgstr ""
+msgstr "Termin je već potvrđen."
#: erpnext/crm/doctype/appointment/appointment.py:116
msgid "Appointment must be scheduled within the available slot timings."
-msgstr ""
+msgstr "Termin se mora zakazati unutar raspoloživih vremenskih utora."
#: erpnext/crm/doctype/appointment/appointment.py:66
msgid "Appointments created manually cannot have 'Unverified' status."
-msgstr ""
+msgstr "Ručno rezervirani termini ne mogu imati status 'Nepotvrđeno'."
#. Label of the approving_role (Link) field in DocType 'Authorization Rule'
#: erpnext/setup/doctype/authorization_rule/authorization_rule.json
@@ -6627,12 +6627,12 @@ msgstr "Automatski Preuzmi"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:225
#: erpnext/public/js/utils/serial_batch_inline_editor.js:573
msgid "Auto Fetch Batch Nos"
-msgstr ""
+msgstr "Automatski Preuzmi Šaržne Brojeve"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:224
#: erpnext/public/js/utils/serial_batch_inline_editor.js:573
msgid "Auto Fetch Serial Nos"
-msgstr ""
+msgstr "Automatski Preuzmi Serijske Brojeve"
#: erpnext/selling/page/point_of_sale/pos_item_details.js:228
msgid "Auto Fetch Serial Numbers"
@@ -8705,7 +8705,7 @@ msgstr "Spremnik"
#: erpnext/stock/doctype/bin/bin.js:16
msgid "Bin Values Recalculated"
-msgstr ""
+msgstr "Vrijednosti Spremnika Ponovo Izračunate"
#. Label of the bio (Text Editor) field in DocType 'Employee'
#: erpnext/setup/doctype/employee/employee.json
@@ -8844,7 +8844,7 @@ msgstr "Blokiraj Dostavljača"
#. 'Accounts Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
msgid "Block a new Sales Invoice when the customer's overdue amount exceeds the Overdue Limit set on the customer."
-msgstr ""
+msgstr "Blokiraj novu Prodajnu Fakturu kada iznos dospjelog plaćanja klijenta premaši ograničenje dospjelog plaćanja postavljeno za klijenta."
#. Description of the 'Is Frozen' (Check) field in DocType 'Customer'
#: erpnext/selling/doctype/customer/customer.json
@@ -9961,7 +9961,7 @@ msgstr "Sastavnica se nemože deaktivirati ili otkazati jer je povezana sa drugi
#: erpnext/crm/doctype/opportunity/opportunity.py:283
msgid "Cannot declare as Lost because an active Quotation exists."
-msgstr ""
+msgstr "Ne može se proglasiti izgubljeno jer postoji aktivna Ponuda."
#: erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js:16
#: erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js:26
@@ -10078,7 +10078,7 @@ msgstr "Ne može se upućivati na broj reda veći ili jednak trenutnom broju red
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:96
msgid "Cannot repost more than {0} vouchers at once. Split them into multiple documents."
-msgstr ""
+msgstr "Nije moguće ponovo knjižiti više od {0} verifikata odjednom. Podijeli ih u više dokumenata."
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:626
msgid "Cannot reserve more than Allowed Qty {0} {1} for Item {2} against {3} {4}.
The Allowed Qty is calculated as follows:
- Actual Qty [Available Qty at Warehouse] = {5}
- Reserved Stock [Ignore current SRE] = {6}
- Available Qty To Reserve [Actual Qty - Reserved Stock] = {7}
- Voucher Qty [Voucher Item Qty] = {8}
- Delivered Qty [Qty delivered against the Voucher Item] = {9}
- Total Reserved Qty [Qty reserved against the Voucher Item] = {10}
- Allowed Qty [Minimum of (Available Qty To Reserve, (Voucher Qty - Delivered Qty - Total Reserved Qty))] = {11}
"
@@ -10944,7 +10944,7 @@ msgstr "Brisanje Demo Podataka..."
#: erpnext/public/js/utils/serial_batch_inline_editor.js:991
msgid "Click on 'Add row' to add Serial / Batch entries"
-msgstr ""
+msgstr "Klikni na 'Dodaj red' da biste dodali Serijske / Šaržne unose"
#: erpnext/manufacturing/doctype/production_plan/production_plan.js:747
msgid "Click on 'Get Finished Goods for Manufacture' to fetch the items from the above Sales Orders. Items only for which a BOM is present will be fetched."
@@ -11234,7 +11234,7 @@ msgstr "Kombinovani dio Fakture mora biti 100%"
#: erpnext/public/js/sales_order_proforma.js:340
msgid "Comma separated email addresses"
-msgstr ""
+msgstr "Adrese e-pošte odvojene zarezima"
#: erpnext/setup/setup_wizard/operations/install_fixtures.py:181
msgid "Commercial"
@@ -12182,12 +12182,12 @@ msgstr "Proizvedena Količina"
#: erpnext/manufacturing/doctype/job_card/job_card.py:1737
msgid "Completed Quantity ({0}), Pending Quantity ({1}) and Process Loss Quantity ({2}) must add up to the Qty to Manufacture ({3})."
-msgstr ""
+msgstr "Završena Količina ({0}), Količina na Čekanju ({1}) i Količina Gubitka u Procesu ({2}) moraju se zbrajati do Količine za Proizvodnju ({3})."
#: erpnext/manufacturing/doctype/job_card/job_card.js:280
#: erpnext/public/js/shop_floor/shop_floor.js:825
msgid "Completed Quantity cannot be greater than {0}"
-msgstr ""
+msgstr "Završena količina ne može biti veća od {0}"
#: erpnext/public/js/shop_floor/shop_floor.js:906
msgid "Completed Quantity should be greater than 0"
@@ -12212,7 +12212,7 @@ msgstr "Obrađeni Radni Nalozi"
#: erpnext/manufacturing/doctype/job_card/job_card.js:253
#: erpnext/public/js/shop_floor/shop_floor.js:798
msgid "Completed, Pending and Process Loss quantities must add up to this."
-msgstr ""
+msgstr "Količine Završenih, Na Čekanju i Gubitaka u Procesu moraju se zbrajati do ovog iznosa."
#: erpnext/projects/report/project_summary/project_summary.py:73
msgid "Completion"
@@ -13779,7 +13779,7 @@ msgstr "Izradi Format Ispisivanja"
#: erpnext/public/js/sales_order_proforma.js:61
msgid "Create Proforma Invoice"
-msgstr ""
+msgstr "Izradi Proforma Fakturu"
#. Title of an Onboarding Step
#. Label of an action in the Onboarding Step 'Create Project'
@@ -13869,7 +13869,7 @@ msgstr "Izradi Prodajne Naloge kako biste lakše planirali svoj posao i isporuč
#: erpnext/public/js/utils/serial_batch_inline_editor.js:234
#: erpnext/public/js/utils/serial_batch_inline_editor.js:757
msgid "Create Serial Nos from Range"
-msgstr ""
+msgstr "Izradi Serijske Brojeve iz Raspona"
#. Title of an Onboarding Step
#. Label of an action in the Onboarding Step 'Create Service Item'
@@ -14043,7 +14043,7 @@ msgstr "Izrađeno Migracijom"
#. Label of the created_through_portal (Check) field in DocType 'Appointment'
#: erpnext/crm/doctype/appointment/appointment.json
msgid "Created through Portal"
-msgstr ""
+msgstr "Izrađeno putem Portala"
#: erpnext/accounts/bulk_payment.py:77
msgid "Created {0} draft Grouped Payment Entries"
@@ -14100,7 +14100,7 @@ msgstr "Izrada Otpremnice u toku..."
#: erpnext/public/js/sales_order_proforma.js:231
msgid "Creating Proforma Invoice..."
-msgstr ""
+msgstr "Izrada Proforma Fakture..."
#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js:68
msgid "Creating Purchase Invoices ..."
@@ -16275,7 +16275,7 @@ msgstr "Standard Prioritet"
#. Settings'
#: erpnext/selling/doctype/selling_settings/selling_settings.json
msgid "Default Proforma Print Format"
-msgstr ""
+msgstr "Standard Format Ispisa Proforma Fakture"
#. Label of the default_provisional_account (Link) field in DocType 'Company'
#: erpnext/setup/doctype/company/company.json
@@ -16431,7 +16431,7 @@ msgstr "Zadani cjenik za nabavu ili prodaju ovog artikla"
#. 'Selling Settings'
#: erpnext/selling/doctype/selling_settings/selling_settings.json
msgid "Default print format used when generating a Proforma Invoice PDF."
-msgstr ""
+msgstr "Standard format ispisa koji se koristi pri izradi PDF datoteke Proforma Fakture."
#. Description of a DocType
#: erpnext/stock/doctype/stock_settings/stock_settings.json
@@ -16630,7 +16630,7 @@ msgstr "Obriši Potencijalne Klijente i Adrese"
#. in DocType 'Appointment Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "Delete Permanently"
-msgstr ""
+msgstr "Trajno Izbriši"
#. Label of the delete_transactions_status (Select) field in DocType
#. 'Transaction Deletion Record'
@@ -18621,7 +18621,7 @@ msgstr "Kopiraj red {0} sa istim {1}"
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:110
msgid "Duplicate vouchers found. Remove the duplicate vouchers to continue to repost."
-msgstr ""
+msgstr "Pronađeni su duplikati verifikata. Ukloni duplikate verifikata da biste nastavili s ponovnim knjiženjem."
#: erpnext/accounts/doctype/pricing_rule/pricing_rule.py:157
msgid "Duplicate {0} found in the table"
@@ -18961,11 +18961,11 @@ msgstr "E-pošta poslana Dobavljaču {0}"
#. Label of the email_verified (Check) field in DocType 'Appointment'
#: erpnext/crm/doctype/appointment/appointment.json
msgid "Email Verified"
-msgstr ""
+msgstr "E-pošta Potvrđena"
#: erpnext/accounts/doctype/payment_request/payment_request.js:57
msgid "Email couldn't be sent."
-msgstr ""
+msgstr "E-pošta nije mogla biti poslana."
#: erpnext/setup/doctype/employee/employee.py:443
msgid "Email is required to create a user"
@@ -18995,7 +18995,7 @@ msgstr "E-pošta poslana {0}"
#. Label of the emailed_to (Small Text) field in DocType 'Proforma Invoice'
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
msgid "Emailed To"
-msgstr ""
+msgstr "Poslano e-poštom"
#: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js:20
msgid "Emails queued"
@@ -19212,7 +19212,7 @@ msgstr "Omogući Dozvoli Djelomičnu Rezervaciju u Postavkama Zaliha da rezervi
#. Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "Enable Appointment Booking Through Portal"
-msgstr ""
+msgstr "Omogući Zakazivanje Termina Putem Portala"
#. Label of the enable_scheduling (Check) field in DocType 'Appointment Booking
#. Settings'
@@ -19336,7 +19336,7 @@ msgstr "Omogući Stalno Upravljanje Zalihama"
#. Settings'
#: erpnext/selling/doctype/selling_settings/selling_settings.json
msgid "Enable Proforma Invoice"
-msgstr ""
+msgstr "Omogući Proforma Fakturu"
#. Label of the enable_provisional_accounting_for_non_stock_items (Check) field
#. in DocType 'Company'
@@ -20165,7 +20165,7 @@ msgstr "Postojeći Klijent"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:581
msgid "Existing entries will be replaced with the fetched entries"
-msgstr ""
+msgstr "Postojeći unosi će biti zamijenjeni preuzetim unosima"
#: banking/src/components/features/BankStatementImporter/CSV/StatementDetails.tsx:307
msgid "Existing transactions in the system belonging to the same bank account and date range"
@@ -20713,7 +20713,7 @@ msgstr "Naknade"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:591
msgid "Fetch"
-msgstr ""
+msgstr "Preuzmi"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:586
#: erpnext/public/js/utils/serial_no_batch_selector.js:396
@@ -23567,7 +23567,7 @@ msgstr "Sakrij Slike"
#: erpnext/public/js/sales_order_proforma.js:99
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
msgid "Hide Item Quantity in Print"
-msgstr ""
+msgstr "Sakrij Količinu Artikal pri Ispisu"
#: erpnext/selling/page/point_of_sale/pos_controller.js:261
msgid "Hide Recent Orders"
@@ -23582,7 +23582,7 @@ msgstr "Sakrij Nedostupne Artikle"
#. 'Proforma Invoice'
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
msgid "Hide the item quantity and rate on the printed proforma."
-msgstr ""
+msgstr "Sakrij količinu artikla i cijenu na ispisanoj Proforma Fakturi."
#. Description of the 'Hide If Zero' (Check) field in DocType 'Financial Report
#. Row'
@@ -23650,7 +23650,7 @@ msgstr "Lista Praznika"
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:89
msgid "Holiday List - {0} is not valid for current date."
-msgstr ""
+msgstr "Popis Praznika - {0} nije valjan za trenutni datum."
#. Label of the holiday_list_name (Data) field in DocType 'Holiday List'
#: erpnext/setup/doctype/holiday_list/holiday_list.json
@@ -24655,7 +24655,7 @@ msgstr "U Minutama"
#. DocType 'Appointment Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "In Minutes (min: 15 mins, max: 60 mins)"
-msgstr ""
+msgstr "U minutama (min: 15 min, maks: 60 min)"
#: erpnext/accounts/report/accounts_payable/accounts_payable.js:149
#: erpnext/accounts/report/accounts_receivable/accounts_receivable.js:181
@@ -26034,7 +26034,7 @@ msgstr "Nevažeći parametar. 'dn' treba biti tipa str"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:773
msgid "Invalid range. Use the format {0}"
-msgstr ""
+msgstr "Nevažeći raspon. Koristi format {0}"
#: erpnext/utilities/transaction_base.py:126
msgid "Invalid reference {0} {1}"
@@ -28380,7 +28380,7 @@ msgstr "Artikal {0} nemože se dodati kao sam podsklop"
#: erpnext/stock/doctype/material_request/mapper.py:225
msgid "Item {0} cannot be ordered more than once"
-msgstr ""
+msgstr "Artikal {0} se ne može naručiti više od jednom"
#: erpnext/manufacturing/doctype/blanket_order/blanket_order.py:197
msgid "Item {0} cannot be ordered more than {1} against Blanket Order {2}."
@@ -28779,7 +28779,7 @@ msgstr "Radna Kartica {0}: Prema redoslijedu operacija u radnom nalogu {1}, dovr
#: erpnext/manufacturing/doctype/job_card/job_card.py:1529
msgid "Job Card {0}: As per the sequence of the operations in the work order {1}, submit the manufacturing entry for the operation {2} before the operation {3}."
-msgstr ""
+msgstr "Radna kartica {0}: Prema redoslijedu radnji u radnom nalogu {1}, podnesi unos proizvodnje za {2} prije {3}."
#: erpnext/accounts/doctype/process_period_closing_voucher/process_period_closing_voucher.js:17
msgid "Job Started"
@@ -30882,7 +30882,7 @@ msgstr "Označi kao Zatvoreno"
#. in DocType 'Appointment Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "Mark as Closed"
-msgstr ""
+msgstr "Odaberi kao Zatvoreno"
#. Description of the 'Is Internal Customer' (Check) field in DocType
#. 'Customer'
@@ -31947,7 +31947,7 @@ msgstr "Nedostaje Obavezni Filter"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:671
msgid "Missing Serial / Batch Nos will be created on Save"
-msgstr ""
+msgstr "Nedostajući Serijski / Šaržni brojevi bit će izrađeni prilikom Spremanja"
#: erpnext/assets/doctype/asset_repair/asset_repair.py:300
msgid "Missing Serial No Bundle"
@@ -32820,7 +32820,7 @@ msgstr "Nova Napomena"
#: erpnext/public/js/sales_order_proforma.js:320
msgid "New Proforma Invoice"
-msgstr ""
+msgstr "Nova Proforma Faktura"
#. Label of the purchase_invoice (Check) field in DocType 'Email Digest'
#: erpnext/setup/doctype/email_digest/email_digest.json
@@ -32854,7 +32854,7 @@ msgstr "Nova Prodajna Faktura"
#. Credit Limit'
#: erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.json
msgid "New Sales Invoices are blocked when the customer's overdue amount exceeds this. Requires 'Restrict Customer Over Billing' in Accounts Settings."
-msgstr ""
+msgstr "Nove prodajne fakture se blokiraju kada iznos dospjelog duga klijenta premaši ovaj iznos. Zahtijeva opciju 'Ograniči Prekomjerno Fakturisanje Klijenta' u Postavkama Knjiženja."
#. Label of the sales_order (Check) field in DocType 'Email Digest'
#: erpnext/setup/doctype/email_digest/email_digest.json
@@ -33146,7 +33146,7 @@ msgstr "Nema dostupnih dodatnih polja"
#: erpnext/crm/doctype/appointment/appointment.py:103
msgid "No availability of slots are found. Please add on Appointment Booking Settings."
-msgstr ""
+msgstr "Nije pronađeno nikakvo slobodno vrijeme termina. Dodaj ih u Postavkama Zakazivanja Termina."
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1396
msgid "No available quantity to reserve for item {0} in warehouse {1}"
@@ -33215,7 +33215,7 @@ msgstr "Nije pronađen nijedan unos"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:302
msgid "No entries found in the uploaded file"
-msgstr ""
+msgstr "Nisu pronađeni unosi u učitanoj datoteci."
#: banking/src/components/features/BankReconciliation/BankReconciliationStatement.tsx:214
msgid "No entries with a payment document in this list."
@@ -33388,7 +33388,7 @@ msgstr "Nema pronađenih proizvoda."
#: erpnext/public/js/sales_order_proforma.js:260
msgid "No proforma invoices yet."
-msgstr ""
+msgstr "Još nema proforma faktura."
#: erpnext/selling/page/point_of_sale/pos_item_cart.js:1029
msgid "No recent transactions found"
@@ -33448,7 +33448,7 @@ msgstr "Još nema postavljenih pravila"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:620
msgid "No stock available for Item {0} in Warehouse {1}"
-msgstr ""
+msgstr "Nema zaliha za Artikal {0} u Skladištu {1}"
#: erpnext/stock/doctype/batch/batch.js:77
msgid "No stock available for this batch."
@@ -33493,7 +33493,7 @@ msgstr "Nisu pronađeni vaučeri za ovu transakciju"
#: erpnext/stock/doctype/item/item.py:1782
msgid "No warehouse found for company {0}. Please set a Default Warehouse in Item Defaults or Company."
-msgstr ""
+msgstr "Nije pronađeno skladište za {0}. Postavi standard skladište u Postavkama Artikala ili Postavkama Tvrtke."
#: erpnext/public/js/shop_floor/shop_floor.js:329
msgid "No work orders here."
@@ -34182,7 +34182,7 @@ msgstr "Jedina Vrijednost dostupna za Unos Plaćanja"
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:216
msgid "Only an issued Proforma Invoice can be emailed."
-msgstr ""
+msgstr "Samo izdata Proforma Faktura može se poslati e-poštom."
#. Description of the 'Posting Date inheritance for exchange gain / loss'
#. (Select) field in DocType 'Accounts Settings'
@@ -34678,7 +34678,7 @@ msgstr "Operacija"
#: erpnext/manufacturing/doctype/job_card/job_card.js:532
msgid "Operation Row"
-msgstr ""
+msgstr "Red Radnje"
#. Label of the operation_row_id (Int) field in DocType 'Job Card'
#: erpnext/manufacturing/doctype/job_card/job_card.json
@@ -34720,11 +34720,11 @@ msgstr "Operacija {0} ne pripada radnom nalogu {1}"
#: erpnext/manufacturing/doctype/job_card/job_card.js:535
msgid "Operation {0} is added multiple times in the work order {1}"
-msgstr ""
+msgstr "Radnja {0} je dodana više puta u radni nalog {1}"
#: erpnext/manufacturing/doctype/job_card/job_card.py:1407
msgid "Operation {0} is added multiple times in the work order {1}. Please select the operation row."
-msgstr ""
+msgstr "Radnja {0} je dodana više puta u radni nalog {1}. Odaberi red radnje."
#: erpnext/manufacturing/doctype/workstation/workstation.py:385
msgid "Operation {0} is longer than any available working hours in workstation {1}, break down the operation into multiple operations"
@@ -35425,15 +35425,15 @@ msgstr "Dana Zakašnjenja"
#. Credit Limit'
#: erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.json
msgid "Overdue Limit"
-msgstr ""
+msgstr "Granica Dospijeća"
#: erpnext/selling/doctype/customer/customer.py:608
msgid "Overdue Limit Crossed"
-msgstr ""
+msgstr "Granica Dospijeća Prekoračena"
#: erpnext/selling/doctype/customer/customer.py:603
msgid "Overdue Limit crossed for customer {0}. Overdue amount {1} exceeds the allowed limit {2}."
-msgstr ""
+msgstr "Granica Dospijeća prekoračena je za {0}. Iznos dospijeća {1} prelazi dozvoljenu granicu {2}."
#. Name of a DocType
#: erpnext/accounts/doctype/overdue_payment/overdue_payment.json
@@ -36357,7 +36357,7 @@ msgstr "Djelimično Usaglašeno"
#. Option for the 'Status' (Select) field in DocType 'Repost Accounting Ledger'
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json
msgid "Partially Reposted"
-msgstr ""
+msgstr "Djelomično Ponovo Knjiženo"
#. Option for the 'Status' (Select) field in DocType 'Stock Reservation Entry'
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json
@@ -37138,7 +37138,7 @@ msgstr "Ograničenje Plaćanja"
#: erpnext/accounts/doctype/payment_request/payment_request.py:600
msgid "Payment Link couldn't be sent."
-msgstr ""
+msgstr "Poveznica za plaćanje nije mogla biti poslana."
#: erpnext/accounts/report/pos_register/pos_register.js:50
#: erpnext/accounts/report/pos_register/pos_register.py:135
@@ -38457,7 +38457,7 @@ msgstr "Dodaj Račun za Privremeno Otvaranje u Kontni Plan"
#: erpnext/crm/doctype/appointment/appointment.py:95
msgid "Please add a valid Holiday List on Appointment Booking Settings."
-msgstr ""
+msgstr "Dodaj valjani Popis Praznika u Postavke Zakazivanja Termina."
#: erpnext/accounts/doctype/bank_transaction_rule/bank_transaction_rule.py:119
msgid "Please add an account for the Bank Entry rule."
@@ -38469,7 +38469,7 @@ msgstr "Dodaj barem jedan Serijski Broj / Broj Šarže"
#: erpnext/stock/doctype/serial_and_batch_bundle/inline_editor.py:132
msgid "Please add at least one Serial No or Batch to save"
-msgstr ""
+msgstr "Dodaj barem jedan Serijski broj ili Šaržu za spremanje"
#: erpnext/stock/doctype/item/item.js:942
msgid "Please add at least one row in Item Defaults with a Company before setting opening stock."
@@ -38764,7 +38764,7 @@ msgstr "Unesi Otpisni Račun"
#: erpnext/public/js/sales_order_proforma.js:215
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:179
msgid "Please enter a quantity or amount for at least one item."
-msgstr ""
+msgstr "Unesi količinu ili iznos za barem jedan artikal."
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:511
msgid "Please enter a valid Write Off Account"
@@ -38856,11 +38856,11 @@ msgstr "Popuni Tabelu Prodajnih Naloga"
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:57
msgid "Please fill up the Availability of Slots table to enable Appointment Scheduling."
-msgstr ""
+msgstr "Popuni tablicu Dostupnosti Termina kako biste omogućili Zakazivanje Termina."
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:226
msgid "Please find attached the proforma invoice {0}."
-msgstr ""
+msgstr "U prilogu vam dostavljamo Proforma Fakturu {0}."
#: erpnext/stock/doctype/shipment/shipment.js:277
msgid "Please first set Full Name, Email and Phone for the user"
@@ -39051,7 +39051,7 @@ msgstr "Odaberi Količina naspram Artikla {0}"
#: erpnext/stock/doctype/item/item.py:393
msgid "Please select Sample Retention Warehouse in Company first"
-msgstr ""
+msgstr "Odaberi Skladište za Zadržavanje Uzoraka u Tvrtki"
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:451
msgid "Please select Serial/Batch Nos to reserve or change Reservation Based On to Qty."
@@ -39102,7 +39102,7 @@ msgstr "Odaberi Dostavnicu"
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.py:81
msgid "Please select a Holiday List to enable Appointment Scheduling."
-msgstr ""
+msgstr "Odaberi Popis Praznika kako biste omogućili Zakazivanje Termina."
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py:152
msgid "Please select a Subcontracting Purchase Order."
@@ -39188,7 +39188,7 @@ msgstr "Odaberi valjani tip dokumenta."
#: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1356
msgid "Please select a valid {0}"
-msgstr ""
+msgstr "Odaberi valjani {0}"
#: erpnext/selling/doctype/quotation/quotation.js:245
msgid "Please select a value for {0} quotation_to {1}"
@@ -39396,7 +39396,7 @@ msgstr "Postavi Broj Nadređenog reda za artikal {0}"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:656
#: erpnext/public/js/utils/serial_batch_inline_editor.js:752
msgid "Please set Rejected Warehouse first"
-msgstr ""
+msgstr "Postavi Odbijeno Skladište"
#: erpnext/accounts/doctype/ledger_merge/ledger_merge.js:24
#: erpnext/accounts/doctype/ledger_merge/ledger_merge.js:35
@@ -39421,7 +39421,7 @@ msgstr "Postavi PDV Račune za Tvrtku: \"{0}\" u postavkama PDV-a UAE"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:565
msgid "Please set Warehouse first"
-msgstr ""
+msgstr "Postavi Skladište"
#: erpnext/accounts/doctype/account/account_tree.js:19
msgid "Please set a Company"
@@ -39596,7 +39596,7 @@ msgstr "Postavi {0} u Tvrtku {1} kako biste knjižili rezultat tečaja"
#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1295
msgid "Please set {0} in Company {1} to retain samples."
-msgstr ""
+msgstr "Postavi {0} u {1} kako biste zadržali uzorke."
#: erpnext/controllers/accounts_controller.py:506
msgid "Please set {0} to {1}, the same account that was used in the original invoice {2}."
@@ -40865,7 +40865,7 @@ msgstr "Količinski Gubitak Procesa"
#: erpnext/manufacturing/doctype/job_card/job_card.js:339
#: erpnext/public/js/shop_floor/shop_floor.js:882
msgid "Process Loss Quantity cannot be greater than {0}"
-msgstr ""
+msgstr "Količina Gubitka Procesa ne može biti veća od {0}"
#. Name of a report
#: erpnext/manufacturing/report/process_loss_report/process_loss_report.json
@@ -41365,7 +41365,7 @@ msgstr "Analiza Profitabilnosti"
#: erpnext/selling/doctype/sales_order/sales_order.json
#: erpnext/selling/doctype/sales_order/sales_order_dashboard.py:27
msgid "Proforma"
-msgstr ""
+msgstr "Proforma"
#. Name of a DocType
#. Label of the proforma_invoice_section (Section Break) field in DocType
@@ -41375,42 +41375,42 @@ msgstr ""
#: erpnext/selling/doctype/selling_settings/selling_settings.js:53
#: erpnext/selling/doctype/selling_settings/selling_settings.json
msgid "Proforma Invoice"
-msgstr ""
+msgstr "Proforma Faktura"
#. Name of a DocType
#: erpnext/selling/doctype/proforma_invoice_item/proforma_invoice_item.json
msgid "Proforma Invoice Item"
-msgstr ""
+msgstr "Artikal Proforma Fakture"
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:235
msgid "Proforma Invoice is not enabled in Selling Settings."
-msgstr ""
+msgstr "Proforma Faktura nije omogućena u Postavkama Prodaje."
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:225
msgid "Proforma Invoice {0}"
-msgstr ""
+msgstr "Proforma Faktura {0}"
#: erpnext/public/js/sales_order_proforma.js:236
msgid "Proforma Invoice {0} created"
-msgstr ""
+msgstr "Proforma Faktura {0} izrađena"
#. Label of the proforma_html (HTML) field in DocType 'Sales Order'
#: erpnext/selling/doctype/sales_order/sales_order.json
msgid "Proforma Invoices"
-msgstr ""
+msgstr "Proforma Fakture"
#: erpnext/public/js/sales_order_proforma.js:272
msgid "Proforma No"
-msgstr ""
+msgstr "Broj Proforma Fakture"
#. Label of the proforma_pdf (Attach) field in DocType 'Proforma Invoice'
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
msgid "Proforma PDF"
-msgstr ""
+msgstr "Proforma Faktura PDF"
#: erpnext/public/js/sales_order_proforma.js:349
msgid "Proforma emailed"
-msgstr ""
+msgstr "Proforma Faktura poslana e-poštom"
#: erpnext/projects/doctype/task/task.py:156
#, python-format
@@ -42752,7 +42752,7 @@ msgstr "Količina u Jedinici Zaliha"
#: erpnext/manufacturing/doctype/job_card/job_card.js:295
#: erpnext/public/js/shop_floor/shop_floor.js:840
msgid "Qty left for a later cycle or for another job card."
-msgstr ""
+msgstr "Preostala količina za kasniji ciklus ili za drugu radnu karticu."
#. Label of the for_qty (Float) field in DocType 'Pick List'
#: erpnext/stock/doctype/pick_list/pick_list.js:206
@@ -42773,7 +42773,7 @@ msgstr "Količina sirovina će se odlučivati na osnovu količine gotovog proizv
#: erpnext/manufacturing/doctype/job_card/job_card.js:325
#: erpnext/public/js/shop_floor/shop_floor.js:869
msgid "Qty scrapped in this cycle, nobody will produce it."
-msgstr ""
+msgstr "Količina otpada u ovom ciklusu, niko je neće proizvoditi."
#. Label of the consumed_qty (Float) field in DocType 'Purchase Receipt Item
#. Supplied'
@@ -42806,7 +42806,7 @@ msgstr "Količina za Preuzeti"
#: erpnext/manufacturing/doctype/job_card/job_card.js:249
#: erpnext/public/js/shop_floor/shop_floor.js:794
msgid "Qty to Manufacture in this Cycle"
-msgstr ""
+msgstr "Količina za Proizvodnju u ovom ciklusu"
#. Label of the qty (Float) field in DocType 'Production Plan Sub Assembly
#. Item'
@@ -42830,7 +42830,7 @@ msgstr "Količina za Prijem"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:910
msgid "Qty updated to {0} to match the Serial and Batch Bundle. Please save the document."
-msgstr ""
+msgstr "Količina ažurirana na {0} kako bi odgovarala Serijskom i Šaržnom Paketu. Spremi dokument."
#. Label of the qualification_tab (Section Break) field in DocType 'Lead'
#. Label of the qualification (Data) field in DocType 'Employee Education'
@@ -43344,12 +43344,12 @@ msgstr "Količina ne može biti veća od {0} za artikal {1}"
#: erpnext/stock/doctype/material_request/mapper.py:235
msgid "Quantity for Item {0} must be greater than zero and cannot exceed {1}"
-msgstr ""
+msgstr "Količina za Artikal {0} mora biti veća od nule i ne može biti veća od {1}"
#: erpnext/stock/doctype/material_request/material_request.js:565
msgctxt "${pending_qty}"
msgid "Quantity for Item {0} must be greater than zero and cannot exceed {1}"
-msgstr ""
+msgstr "Količina za Artikal {0} mora biti veća od nule i ne može biti veća od {1}"
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:563
msgid "Quantity is mandatory for the selected items."
@@ -44225,7 +44225,7 @@ msgstr "Ponovo izračunaj Stopu Vrednovanja"
#: erpnext/stock/doctype/bin/bin.js:10
msgid "Recalculate Values"
-msgstr ""
+msgstr "Preračunaj Vrijednosti"
#. Option for the 'Status' (Select) field in DocType 'Asset'
#. Option for the 'Purpose' (Select) field in DocType 'Asset Movement'
@@ -44972,7 +44972,7 @@ msgstr "Odbijena Količina"
#: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
#: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
msgid "Rejected Serial / Batch Entries"
-msgstr ""
+msgstr "Odbijeni Serijski / Šaržni Unosi"
#. Label of the rejected_serial_no (Text) field in DocType 'Purchase Invoice
#. Item'
@@ -45441,7 +45441,7 @@ msgstr "Ponovno Knjiženje je započeto u pozadini"
#. Items'
#: erpnext/accounts/doctype/repost_accounting_ledger_items/repost_accounting_ledger_items.json
msgid "Reposted"
-msgstr ""
+msgstr "Ponovno Knjiženo"
#. Label of the reposting_data_file (Attach) field in DocType 'Repost Item
#. Valuation'
@@ -45478,7 +45478,7 @@ msgstr "Referansa Ponovnog knjiženja"
#. 'Repost Accounting Ledger Items'
#: erpnext/accounts/doctype/repost_accounting_ledger_items/repost_accounting_ledger_items.json
msgid "Reposting Status"
-msgstr ""
+msgstr "Status Ponovnog Knjiženja"
#. Label of the vouchers_based_on_item_and_warehouse_section (Section Break)
#. field in DocType 'Repost Item Valuation'
@@ -45492,11 +45492,11 @@ msgstr "Napred Ponovnog Knjiženja Kaučera"
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:216
msgid "Reposting can be started only for submitted document."
-msgstr ""
+msgstr "Ponovno Knjiženje se može pokrenuti samo za podnešeni dokument."
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:221
msgid "Reposting cannot be started when status is {0}."
-msgstr ""
+msgstr "Ponovno Knjiženje se ne može pokrenuti kada je status {0}."
#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:232
#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:340
@@ -45521,11 +45521,11 @@ msgstr "Ponovno Knjiženje u pozadini."
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:211
msgid "Reposting is still in progress in background."
-msgstr ""
+msgstr "Ponovno knjiženje je još uvijek u tijeku u pozadini."
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:315
msgid "Reposting {0} {1}"
-msgstr ""
+msgstr "Ponovno knjiženje {0} {1}"
#. Label of the represents_company (Link) field in DocType 'Purchase Invoice'
#. Label of the represents_company (Link) field in DocType 'Sales Invoice'
@@ -46190,7 +46190,7 @@ msgstr "Ograniči"
#. 'Accounts Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
msgid "Restrict Customer Over Billing"
-msgstr ""
+msgstr "Ograničiti Prekomjerno Fakturisanje Klijenta"
#. Label of the restrict_based_on (Select) field in DocType 'Party Specific
#. Item'
@@ -46215,7 +46215,7 @@ msgstr "Ograničeno na Zemlje"
#: erpnext/stock/doctype/company_restriction/company_restriction.py:151
msgid "Restricted to Other Companies"
-msgstr ""
+msgstr "Ograničeno na Druge Tvrtke"
#. Label of the result_key (Table) field in DocType 'Currency Exchange
#. Settings'
@@ -46537,7 +46537,7 @@ msgstr "Obrnuta Signatura"
#: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py:635
msgid "Reverse {0} already available in draft status: {1}"
-msgstr ""
+msgstr "Obrnuto {0} već je dostupno u statusu nacrta: {1}"
#: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js:118
msgid "Reversing Journals..."
@@ -46666,7 +46666,7 @@ msgstr "Štap"
#. 'Accounts Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
msgid "Role Allowed to Bypass Over Billing Restriction"
-msgstr ""
+msgstr "Uloga kojoj je dopušteno zaobilaženje Ograničenja Prekomjernog Fakturisanja"
#. Label of the role_allowed_to_over_deliver_receive (Link) field in DocType
#. 'Stock Settings'
@@ -49256,7 +49256,7 @@ msgstr "Skladište Zadržavanja Uzoraka"
#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1298
msgid "Sample Retention Warehouse Missing"
-msgstr ""
+msgstr "Nedostaje Skladište Zadržavanja Uzoraka"
#. Label of the sample_size (Float) field in DocType 'Quality Inspection'
#: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py:93
@@ -49305,7 +49305,7 @@ msgstr "Sazhen"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:368
msgid "Scan / select Serial No"
-msgstr ""
+msgstr "Skeniraj / odaberi Serijski Broj"
#. Label of the scan_barcode (Data) field in DocType 'POS Invoice'
#. Label of the scan_barcode (Data) field in DocType 'Purchase Invoice'
@@ -49343,7 +49343,7 @@ msgstr "Skeniraj Broj Šarže"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:230
#: erpnext/public/js/utils/serial_batch_inline_editor.js:664
msgid "Scan Batch Nos"
-msgstr ""
+msgstr "Skeneraj Brojeve Šarže"
#: erpnext/public/js/shop_floor/shop_floor.js:88
#: erpnext/public/js/shop_floor/shop_floor.js:1476
@@ -49365,7 +49365,7 @@ msgstr "Skeniraj Serijski Broj"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:230
#: erpnext/public/js/utils/serial_batch_inline_editor.js:664
msgid "Scan Serial Nos"
-msgstr ""
+msgstr "Skeniraj Serijske Brojeve"
#: erpnext/public/js/utils/barcode_scanner.js:205
msgid "Scan barcode for item {0}"
@@ -49395,7 +49395,7 @@ msgstr "Skenirana Količina"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:680
msgid "Scanned: {0}"
-msgstr ""
+msgstr "Skenirano: {0}"
#. Label of the schedule_date (Date) field in DocType 'Depreciation Schedule'
#. Label of the schedule_date (Datetime) field in DocType 'Production Plan Sub
@@ -49461,7 +49461,7 @@ msgstr "Raspoređivač je neaktivan. Nije moguće spojiti račune."
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:232
msgid "Scheduler is inactive. Reposting will only run once background jobs are processed."
-msgstr ""
+msgstr "Zakazivač je neaktivan. Ponovno Knjiženje će se pokrenuti tek nakon što se obrade pozadinski zadaci."
#. Label of the schedules (Table) field in DocType 'Maintenance Schedule'
#: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json
@@ -49866,7 +49866,7 @@ msgstr "Odaberi Program Lojaliteta"
#: erpnext/manufacturing/doctype/job_card/job_card.js:545
msgid "Select Operation Row"
-msgstr ""
+msgstr "Odaberi Red Radnje"
#: erpnext/public/js/controllers/transaction.js:542
msgid "Select Payment Schedule"
@@ -49909,7 +49909,7 @@ msgstr "Odaberi Adresu Dobavljača"
#: erpnext/stock/doctype/material_request/material_request.js:449
msgid "Select Supplier for Items"
-msgstr ""
+msgstr "Odaberi Dobavljača za Artikle"
#: erpnext/stock/doctype/batch/batch.js:150
msgid "Select Target Warehouse"
@@ -49963,7 +49963,7 @@ msgstr "Odaberi Dobavljača"
#: erpnext/stock/doctype/material_request/mapper.py:230
#: erpnext/stock/doctype/material_request/material_request.js:553
msgid "Select a Supplier for Item {0}"
-msgstr ""
+msgstr "Odaberi Dobavljača za Artikal {0}"
#: banking/src/components/features/BankReconciliation/MatchAndReconcile.tsx:49
msgid "Select a bank account to reconcile"
@@ -50008,7 +50008,7 @@ msgstr "Odaber artikal iz svakog skupa koja će se koristiti u Prodajnom Nalogu.
#: erpnext/stock/doctype/material_request/mapper.py:211
#: erpnext/stock/doctype/material_request/material_request.js:540
msgid "Select at least one Item"
-msgstr ""
+msgstr "Odaberi barem jedan Artikal"
#: erpnext/stock/doctype/item/item.js:1256
msgid "Select at least one attribute value."
@@ -50306,7 +50306,7 @@ msgstr "Pošalji e-poštu Dobavljačima"
#: erpnext/public/js/sales_order_proforma.js:354
msgid "Send Proforma Invoice"
-msgstr ""
+msgstr "Pošalji Proforma Fakturu"
#. Label of the send_sms (Button) field in DocType 'SMS Center'
#: erpnext/public/js/controllers/transaction.js:746
@@ -50347,7 +50347,7 @@ msgstr "Pošalji sa Prilogom"
#: erpnext/accounts/doctype/payment_request/payment_request.js:51
#: erpnext/accounts/doctype/payment_request/payment_request.js:55
msgid "Sending Email"
-msgstr ""
+msgstr "Slanje e-pošte u tijeku"
#. Option for the 'Detected Amount Format' (Select) field in DocType 'Bank
#. Statement Import Log'
@@ -50432,7 +50432,7 @@ msgstr "Serijski / Šaržni Paket"
#: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
#: erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
msgid "Serial / Batch Entries"
-msgstr ""
+msgstr "Serijski / Šaržni Unosi"
#. Label of the serial_no_and_batch_no_tab (Section Break) field in DocType
#. 'Serial and Batch Bundle'
@@ -50633,7 +50633,7 @@ msgstr "Serijski Broj je obavezan za artikal {0}"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:724
msgid "Serial No {0} already added"
-msgstr ""
+msgstr "Serijski Broj {0} je već dodan"
#: erpnext/public/js/utils/serial_no_batch_selector.js:604
msgid "Serial No {0} already exists"
@@ -51232,7 +51232,7 @@ msgstr "Postavi Dobavljača"
#: erpnext/stock/doctype/material_request/material_request.js:456
msgid "Set Supplier for All Items"
-msgstr ""
+msgstr "Postavi Dobavljača za Sve Artikle"
#. Label of the set_target_warehouse (Link) field in DocType 'Sales Invoice'
#. Label of the set_warehouse (Link) field in DocType 'Purchase Order'
@@ -52025,7 +52025,7 @@ msgstr "Prikaži Zalihe po Skladištu"
#. DocType 'Stock Settings'
#: erpnext/stock/doctype/stock_settings/stock_settings.json
msgid "Show an inline editable table for serial numbers / batches on the item row instead of the dialog"
-msgstr ""
+msgstr "Prikažite ugrađenu uređivu tabelu za serijske brojeve / šarže u redu artikla umjesto dijaloga"
#: erpnext/manufacturing/report/bom_stock_analysis/bom_stock_analysis.js:26
msgid "Show availability of exploded items"
@@ -53756,7 +53756,7 @@ msgstr "Zaliha nije dostupna za Artikal {0} u Skladištu {1}."
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1269
msgid "Stock not available to reserve for the Item {0} in Warehouse {1}."
-msgstr ""
+msgstr "Zaliha nije dostupna za rezervaciju za Artikal {0} u Skladištu {1}."
#: erpnext/selling/page/point_of_sale/pos_controller.js:826
msgid "Stock quantity is not enough for Item Code: {0} under warehouse {1}. Available quantity {2} {3}."
@@ -56422,7 +56422,7 @@ msgstr "Računa pod Obavezama ili Kapitalom, u kojoj će se knjižiti Rezultat"
#: erpnext/accounts/doctype/account/account.py:226
msgid "The account type of {0} cannot be changed from {1} because stock ledger entries exist against it."
-msgstr ""
+msgstr "Tip računa {0} ne može se promijeniti iz {1} jer postoje unosi u Registru Zaliha."
#: erpnext/accounts/doctype/payment_request/payment_request.py:1180
msgid "The allocated amount is greater than the outstanding amount of Payment Request {0}"
@@ -56438,7 +56438,7 @@ msgstr "Iznos {0} postavljen u ovom zahtjevu plaćanja razlikuje se od izračuna
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:222
msgid "The attached PDF file could not be found."
-msgstr ""
+msgstr "Priložena PDF datoteka nije pronađena."
#: erpnext/accounts/doctype/bank_statement_import_log/bank_statement_import_log.py:97
#: erpnext/accounts/doctype/bank_statement_import_log/bank_statement_import_log.py:505
@@ -56468,7 +56468,7 @@ msgstr "Završena količina {0} operacije {1} ne može biti veća od završene k
#: erpnext/manufacturing/doctype/job_card/job_card.py:1542
msgid "The completed quantity {0} of an operation {1} cannot be greater than the manufactured quantity {2} of a previous operation {3}. Submit the manufacturing entry for the operation {3} first."
-msgstr ""
+msgstr "Završena količina {0} radnje {1} ne može biti veća od proizvedene količine {2} prethodne radnje {3}. Prvo podnesi unos proizvodnje za radnju {3}."
#: erpnext/accounts/doctype/dunning/dunning.py:87
msgid "The currency of invoice {0} ({1}) is different from the currency of this dunning ({2})."
@@ -56592,7 +56592,7 @@ msgstr "Sljedeći redovi su duplikati:"
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:130
msgid "The following vouchers are not submitted: {0}"
-msgstr ""
+msgstr "Sljedeći verifikati nisu podnešeni: {0}"
#: erpnext/stock/doctype/material_request/material_request.py:605
msgid "The following {0} were created: {1}"
@@ -56760,7 +56760,7 @@ msgstr "Odabrani artikal ne može imati Šaržu"
#: erpnext/stock/doctype/serial_and_batch_bundle/inline_editor.py:151
msgid "The selected row does not belong to the {0}"
-msgstr ""
+msgstr "Odabrani red ne pripada {0}"
#: erpnext/assets/doctype/asset/asset.js:670
msgid "The sell quantity is less than the total asset quantity. The remaining quantity will be split into a new asset. This action cannot be undone.
Do you want to continue?"
@@ -57068,7 +57068,7 @@ msgstr "Ovaj Artikal Paket je povezan sa {0}. Morat ćete otkazati ove dokumente
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.py:218
msgid "This Proforma Invoice has no PDF to send."
-msgstr ""
+msgstr "Ova Proforma Faktura nema PDF za slanje."
#: erpnext/buying/doctype/purchase_order/mapper.py:253
msgid "This Purchase Order has been fully subcontracted."
@@ -57120,7 +57120,7 @@ msgstr "Ovaj dokument je preko ograničenja za {0} {1} za artikal {4}. Da li pra
#: erpnext/templates/emails/appointment_confirmed.html:6
msgid "This email was sent from {0}"
-msgstr ""
+msgstr "Ova e-pošta je poslana od {0}"
#: erpnext/stock/doctype/delivery_note/delivery_note.js:496
msgid "This field is used to set the 'Customer'."
@@ -57262,7 +57262,7 @@ msgstr "Ovaj filter artikala je već primijenjen za {0}"
#: erpnext/templates/emails/confirm_appointment.html:4
msgid "This link is valid for {0} minutes"
-msgstr ""
+msgstr "Ova poveznica vrijedi {0} minuta"
#: erpnext/public/js/shop_floor/shop_floor.js:699
msgid "This machine can run at most {0} job(s) in parallel. Pause or complete a running job before starting another."
@@ -57391,7 +57391,7 @@ msgstr "Ova vrijednost će se koristiti kada se ne pronađe odgovarajući Zajedn
#: erpnext/www/book_appointment/verify/index.py:18
msgid "This verification link is invalid. Please book the appointment again."
-msgstr ""
+msgstr "Ova poveznica za verifikaciju je nevažeća. Ponovo zakaži termin."
#: banking/src/components/features/Settings/Preferences.tsx:86
msgid "This will automatically run transaction matching rules on unreconciled transactions every hour."
@@ -57415,7 +57415,7 @@ msgstr "Ovo će se automatski popuniti ako nije postavljeno."
#: erpnext/public/js/utils/serial_batch_inline_editor.js:1120
msgid "This will delete all {0} entries. Continue?"
-msgstr ""
+msgstr "Ovim će se izbrisati svih {0} unosa. Želite li nastaviti?"
#: banking/src/components/features/BankReconciliation/Rules/RuleForm.tsx:265
msgid "This will just suggest creating a new entry, and will not automatically create it."
@@ -57423,7 +57423,7 @@ msgstr "Ovo će samo predložiti stvaranje novog unosa, a neće ga automatski st
#: erpnext/public/js/utils/serial_batch_inline_editor.js:307
msgid "This will replace the existing entries. Continue?"
-msgstr ""
+msgstr "Ovim će se zamijeniti postojeći unosi. Želite li nastaviti?"
#. Description of the 'Create User Permission' (Check) field in DocType
#. 'Employee'
@@ -58280,7 +58280,7 @@ msgstr "Ukupno Završeno Količinski"
#: erpnext/manufacturing/doctype/job_card/job_card.py:957
msgid "Total Completed Qty ({0}), Process Loss Qty ({1}) and Pending Qty ({2}) must add up to the Qty to Manufacture ({3})."
-msgstr ""
+msgstr "Ukupna Završena Količina ({0}), Količina Gubitaka u Procesu ({1}) i Količina na Čekanju ({2}) moraju se zbrojiti u Količinu za Proizvodnju ({3})."
#: erpnext/manufacturing/doctype/job_card/job_card.py:194
msgid "Total Completed Qty is required for Job Card {0}, please start and complete the job card before submission"
@@ -58635,7 +58635,7 @@ msgstr "Ukupna Količina"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:1066
msgid "Total Qty: {0}"
-msgstr ""
+msgstr "Ukupna Količina: {0}"
#. Label of the total_quantity (Float) field in DocType 'POS Closing Entry'
#. Label of the total_qty (Float) field in DocType 'POS Invoice'
@@ -58917,7 +58917,7 @@ msgstr "Ukupna postotna suma naspram Centara Troškova treba da bude 100"
#: erpnext/public/js/sales_order_proforma.js:199
msgid "Total proforma {0} (including past proformas) exceeds the ordered {0} for: {1}"
-msgstr ""
+msgstr "Ukupni iznos proforma fakture {0} (uključujući prethodne proforma fakture) premašuje naručeni iznos {0} za: {1}"
#: erpnext/selling/doctype/sales_order/sales_order.js:703
msgid "Total quantity in delivery schedule cannot be greater than the item quantity"
@@ -59238,7 +59238,7 @@ msgstr "Transakcije naspram Tvrtke već postoje! Kontni Plan se može uvesti sam
#. 'Customer'
#: erpnext/selling/doctype/customer/customer.json
msgid "Transactions are blocked when the outstanding balance exceeds the credit limit. When Restrict Customer Over Billing is enabled, new invoices are also blocked when the customer's overdue amount exceeds the Overdue Limit."
-msgstr ""
+msgstr "Transakcije se blokiraju kada preostali dug premaši kreditnu granicu. Kada je omogućena opcija Ograniči Prekomjerno Fakturisanja Klijenta, nove fakture se također blokiraju kada iznos dospjelih obaveza klijenta premaši granicu za dospjele obaveze."
#: banking/src/components/features/BankStatementImporter/CSV/StatementDetails.tsx:239
msgid "Transactions to be imported into the system"
@@ -59865,7 +59865,7 @@ msgstr "Poništi Dodjele"
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:375
msgid "Unable to Repost Accounting Ledger"
-msgstr ""
+msgstr "Nije moguće ponovo knjižiti Knjigovodstveni Registar"
#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:479
msgid "Unable to fetch DocType details. Please contact system administrator."
@@ -60568,7 +60568,7 @@ msgstr "Koristi HTTP Protokol"
#. Settings'
#: erpnext/stock/doctype/stock_settings/stock_settings.json
msgid "Use Inline Serial / Batch Editor"
-msgstr ""
+msgstr "Koristi ugradbeni Serijski / Šaržni Uređivač"
#. Label of the item_based_reposting (Check) field in DocType 'Stock Reposting
#. Settings'
@@ -60594,7 +60594,7 @@ msgstr "Koristi Višeslojnu Sastavnicu"
#. DocType 'Global Defaults'
#: erpnext/setup/doctype/global_defaults/global_defaults.json
msgid "Use Posting Date for Naming Documents"
-msgstr ""
+msgstr "Koristi Datum Knjiženja za Imenovanje Dokumenata"
#. Label of the use_serial_batch_fields (Check) field in DocType 'Stock
#. Settings'
@@ -60814,7 +60814,7 @@ msgstr "Korisnicima sa ovom ulogom je dozvoljena prekomjerna Dostava/Primanje na
#. field in DocType 'Accounts Settings'
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.json
msgid "Users with this role can still submit invoices for customers who have crossed their Overdue Limit."
-msgstr ""
+msgstr "Korisnici s ovom ulogom i dalje mogu podnositi fakture za klijente koji su prekoračili granicu dospjelosti."
#. Description of the 'Role to Notify on Depreciation Failure' (Link) field in
#. DocType 'Accounts Settings'
@@ -61374,12 +61374,12 @@ msgstr "Rizični Kapital"
#. 'Appointment Booking Settings'
#: erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
msgid "Verification Link Expiry Duration"
-msgstr ""
+msgstr "Trajanje Vađenaj Verifikacijske Poveznice"
#. Label of the verification_token (Data) field in DocType 'Appointment'
#: erpnext/crm/doctype/appointment/appointment.json
msgid "Verification Token"
-msgstr ""
+msgstr "Verifikacijski Kod"
#: erpnext/www/book_appointment/verify/index.html:15
msgid "Verification failed please check the link"
@@ -61387,7 +61387,7 @@ msgstr "Verifikacija nije uspjela, provjeri vezu"
#: erpnext/www/book_appointment/verify/index.py:38
msgid "Verification link has expired."
-msgstr ""
+msgstr "Veza za provjeru je istekla."
#. Label of the verified_by (Data) field in DocType 'Quality Inspection'
#: erpnext/stock/doctype/quality_inspection/quality_inspection.json
@@ -61491,7 +61491,7 @@ msgstr "Prikaži Sad"
#: erpnext/public/js/sales_order_proforma.js:298
msgid "View PDF"
-msgstr ""
+msgstr "Prikaži PDF"
#. Title of an Onboarding Step
#. Label of an action in the Onboarding Step 'View Project Summary'
@@ -62250,7 +62250,7 @@ msgstr "Vidimo da je {0} napravljen protiv {1}. Ako želite da se ažuriraju pre
#: erpnext/templates/emails/appointment_confirmed.html:3
msgid "We look forward to meeting you"
-msgstr ""
+msgstr "Radujemo se susretu s vama"
#: banking/src/pages/BankStatementImporter.tsx:169
msgid "We support uploading CSV, XLSX, XLS and PDF files. Please make sure the file contains the correct columns."
@@ -62444,7 +62444,7 @@ msgstr "Kada je odabrano, prag transakcije će se primjenjivati samo za pojedina
#. DocType 'Global Defaults'
#: erpnext/setup/doctype/global_defaults/global_defaults.json
msgid "When checked, the system will use the posting date of the document for naming instead of the creation date."
-msgstr ""
+msgstr "Kada je odabrano, sustav će za imenovanje koristiti datum knjiženja dokumenta umjesto datuma izrade."
#: erpnext/stock/doctype/item/item.js:1615
msgid "When creating an Item, entering a value for this field will automatically create an Item Price at the backend."
@@ -63362,7 +63362,7 @@ msgstr "Vaše Ime (obavezno)"
#: erpnext/templates/emails/appointment_confirmed.html:2
msgid "Your email has been verified and your appointment has been confirmed for {0}"
-msgstr ""
+msgstr "Vaša e-pošta je potvrđena i vaš termin je potvrđen za {0}"
#: erpnext/www/book_appointment/verify/index.html:11
msgid "Your email has been verified and your appointment has been scheduled"
@@ -63830,7 +63830,7 @@ msgstr "{0} Zadržani Uzorak se zasniva na Šarži, provjeri Ima Broj Šarže da
#: erpnext/public/js/utils/serial_batch_inline_editor.js:798
msgid "{0} Serial Nos added. They will be saved with the document."
-msgstr ""
+msgstr "{0} Serijskih brojeva dodano. Bit će spremljeni s dokumentom."
#: erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py:1048
msgid "{0} Transaction(s) Reconciled"
@@ -63964,7 +63964,7 @@ msgstr "{0} nacrta radnih kartica koje čekaju na podnošenje"
#: erpnext/public/js/utils/draft_link_guard.js:55
msgid "{0} draft {1} documents already exist for this {2}: {3}. Do you still want to create a new one?"
-msgstr ""
+msgstr "{0} nacrt {1} dokumenti već postoje za ovo {2}: {3}. Želite li i dalje izraditi novi?"
#: erpnext/accounts/doctype/item_tax_template/item_tax_template.py:74
msgid "{0} entered twice in Item Tax"
@@ -63977,7 +63977,7 @@ msgstr "{0} uneseno dvaput {1} u PDV Artikla"
#: erpnext/public/js/utils/serial_batch_inline_editor.js:648
msgid "{0} entries fetched"
-msgstr ""
+msgstr "{0} unosa preuzeto"
#: erpnext/accounts/utils.py:138
#: erpnext/projects/doctype/activity_cost/activity_cost.py:40
@@ -64125,7 +64125,7 @@ msgstr "{0} se ne izvršava. Ne može pokrenuti događaje za ovaj dokument"
#: erpnext/stock/doctype/serial_and_batch_bundle/inline_editor.py:147
msgid "{0} is not supported for the inline Serial / Batch editor"
-msgstr ""
+msgstr "{0} nije podržano za ugradbeni Uređivač Serijskih Brojeva / Šarži"
#: erpnext/stock/doctype/material_request/material_request.py:517
msgid "{0} is not the default supplier for any items."
@@ -64271,7 +64271,7 @@ msgstr "Prikaz {0} trenutno nije podržan u Prilagođenom Financijskom Izvješć
#: erpnext/stock/doctype/material_request/mapper.py:263
msgid "{0} was set to today for items whose requested date has passed"
-msgstr ""
+msgstr "{0} je postavljen na danas za artikle čiji je traženi datum prošao"
#: erpnext/accounts/doctype/payment_term/payment_term.js:19
msgid "{0} will be given as discount."
@@ -64299,7 +64299,7 @@ msgstr "{0} {1} se ne može ažurirati. Ako trebate napraviti promjene, preporu
#: erpnext/stock/doctype/company_restriction/company_restriction.py:145
msgid "{0} {1} cannot be used with Company {2} because of Company Restrictions"
-msgstr ""
+msgstr "{0} {1} ne može se koristiti s {2} zbog ograničenja"
#: erpnext/accounts/doctype/payment_order/payment_order.py:130
msgid "{0} {1} created"
@@ -64307,7 +64307,7 @@ msgstr "{0} {1} izrađen"
#: erpnext/setup/doctype/company/company.py:335
msgid "{0} {1} does not belong to company {2}"
-msgstr ""
+msgstr "{0} {1} ne pripada {2}"
#: erpnext/accounts/doctype/payment_entry/payment_entry.py:630
#: erpnext/accounts/doctype/payment_entry/payment_entry.py:683
diff --git a/erpnext/locale/main.pot b/erpnext/locale/main.pot
index 425b4a7e3cc..624a7d657be 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-08-02 10:09+0000\n"
-"PO-Revision-Date: 2026-08-02 10:09+0000\n"
+"POT-Creation-Date: 2026-08-09 09:47+0000\n"
+"PO-Revision-Date: 2026-08-09 09:47+0000\n"
"Last-Translator: hello@frappe.io\n"
"Language-Team: hello@frappe.io\n"
"MIME-Version: 1.0\n"
@@ -29,7 +29,7 @@ msgstr ""
msgid " Amount"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:133
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:122
msgid " BOM"
msgstr ""
@@ -48,7 +48,7 @@ msgstr ""
msgid " Is Subcontracted"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:215
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:204
msgid " Item"
msgstr ""
@@ -57,8 +57,8 @@ msgstr ""
msgid " Name"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:163
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:204
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:152
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:193
msgid " Phantom Item"
msgstr ""
@@ -66,7 +66,7 @@ msgstr ""
msgid " Rate"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:141
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:130
msgid " Raw Material"
msgstr ""
@@ -75,8 +75,8 @@ msgstr ""
msgid " Skip Material Transfer"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:152
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:193
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:141
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:182
msgid " Sub Assembly"
msgstr ""
@@ -265,7 +265,7 @@ msgstr ""
msgid "% of materials delivered against this Sales Order"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1227
+#: erpnext/controllers/accounts_controller.py:1232
msgid "'Account' in the Accounting section of Customer {0}"
msgstr ""
@@ -281,7 +281,7 @@ msgstr ""
msgid "'Days Since Last Order' must be greater than or equal to zero"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1232
+#: erpnext/controllers/accounts_controller.py:1237
msgid "'Default {0} Account' in Company {1}"
msgstr ""
@@ -303,17 +303,17 @@ msgstr ""
msgid "'Has Serial No' cannot be 'Yes' for non-stock item"
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:149
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:152
msgid "'Inspection Required before Delivery' is disabled for the item {0}, no need to create the QI"
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:140
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:143
msgid "'Inspection Required before Purchase' is disabled for the item {0}, no need to create the QI"
msgstr ""
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:684
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:725
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:832
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:687
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:780
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:914
msgid "'Opening'"
msgstr ""
@@ -347,23 +347,23 @@ msgstr ""
msgid "'{0}' has been already added."
msgstr ""
-#: erpnext/setup/doctype/company/company.py:417
-#: erpnext/setup/doctype/company/company.py:428
+#: erpnext/setup/doctype/company/company.py:421
+#: erpnext/setup/doctype/company/company.py:432
msgid "'{0}' should be in company currency {1}."
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:174
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:214
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:223
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:106
msgid "(A) Qty After Transaction"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:219
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:228
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:111
msgid "(B) Expected Qty After Transaction"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:234
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:243
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:126
msgid "(C) Total Qty in Queue"
msgstr ""
@@ -373,7 +373,7 @@ msgid "(C) Total qty in queue"
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:194
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:244
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:253
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:136
msgid "(D) Balance Stock Value"
msgstr ""
@@ -384,12 +384,12 @@ msgid "(Daily Yield * No of Units Produced) / 100"
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:199
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:249
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:258
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:141
msgid "(E) Balance Stock Value in Queue"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:259
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:268
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:151
msgid "(F) Change in Stock Value"
msgstr ""
@@ -398,7 +398,7 @@ msgstr ""
msgid "(Forecast)"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:264
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:273
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:156
msgid "(G) Sum of Change in Stock Value"
msgstr ""
@@ -409,7 +409,7 @@ msgstr ""
msgid "(Good Units Produced / Total Units Produced) × 100"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:274
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:283
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:166
msgid "(H) Change in Stock Value (FIFO Queue)"
msgstr ""
@@ -424,17 +424,17 @@ msgstr ""
msgid "(Hour Rate / 60) * Actual Operation Time"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:284
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:293
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:176
msgid "(I) Valuation Rate"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:289
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:298
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:181
msgid "(J) Valuation Rate as per FIFO"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:299
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:308
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:191
msgid "(K) Valuation = Value (D) ÷ Qty (A)"
msgstr ""
@@ -1013,18 +1013,18 @@ msgid ""
"\n"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:224
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:233
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:116
msgid "A - B"
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:189
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:239
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:248
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:131
msgid "A - C"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:370
+#: erpnext/selling/doctype/customer/customer.py:371
msgid "A Customer Group exists with the same name. Please change the Customer name or rename the Customer Group"
msgstr ""
@@ -1058,7 +1058,7 @@ msgstr ""
msgid "A Proforma Invoice can only be created against a submitted Sales Order."
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:603
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:604
msgid "A Reconciliation Job {0} is running for the same filters. Cannot reconcile now"
msgstr ""
@@ -1111,7 +1111,7 @@ msgstr ""
msgid "A logical Warehouse against which stock entries are made."
msgstr ""
-#: erpnext/stock/serial_batch_bundle.py:1525
+#: erpnext/stock/serial_batch_bundle.py:1612
msgid "A naming series conflict occurred while creating serial numbers. Please change the naming series for the item {0}."
msgstr ""
@@ -1229,11 +1229,11 @@ msgstr ""
msgid "Abbreviation"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:351
+#: erpnext/setup/doctype/company/company.py:353
msgid "Abbreviation already used for another company"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:348
+#: erpnext/setup/doctype/company/company.py:350
msgid "Abbreviation is mandatory"
msgstr ""
@@ -1263,7 +1263,7 @@ msgstr ""
msgid "Accept the rule for the selected transaction"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1015
+#: erpnext/public/js/shop_floor/shop_floor.js:1021
msgid "Acceptable range: {0} to {1}"
msgstr ""
@@ -1299,7 +1299,7 @@ msgid "Accepted Qty in Stock UOM"
msgstr ""
#. Label of the qty (Float) field in DocType 'Purchase Receipt Item'
-#: erpnext/public/js/controllers/transaction.js:2955
+#: erpnext/public/js/controllers/transaction.js:2963
#: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
msgid "Accepted Quantity"
msgstr ""
@@ -1461,7 +1461,7 @@ msgid "Account Manager"
msgstr ""
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:760
-#: erpnext/controllers/accounts_controller.py:1236
+#: erpnext/controllers/accounts_controller.py:1241
msgid "Account Missing"
msgstr ""
@@ -1658,7 +1658,7 @@ msgstr ""
msgid "Account {0} does not belong to company {1}"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:399
+#: erpnext/setup/doctype/company/company.py:403
msgid "Account {0} does not belong to company: {1}"
msgstr ""
@@ -1686,7 +1686,7 @@ msgstr ""
msgid "Account {0} is added in the child company {1}"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:388
+#: erpnext/setup/doctype/company/company.py:392
msgid "Account {0} is disabled."
msgstr ""
@@ -2118,7 +2118,7 @@ msgstr ""
#: erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.json
#: erpnext/assets/doctype/asset_category/asset_category.json
#: erpnext/setup/doctype/company/company.json
-#: erpnext/setup/doctype/company/company.py:560
+#: erpnext/setup/doctype/company/company.py:564
#: erpnext/setup/doctype/customer_group/customer_group.json
#: erpnext/setup/doctype/email_digest/email_digest.json
#: erpnext/setup/doctype/incoterm/incoterm.json
@@ -2153,8 +2153,8 @@ msgstr ""
#. Entry'
#. Name of a report
#. Label of a Workspace Sidebar Item
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:158
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:261
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:160
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:266
#: erpnext/accounts/doctype/journal_entry/journal_entry.json
#: erpnext/accounts/report/accounts_payable/accounts_payable.json
#: erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.js:129
@@ -2261,8 +2261,8 @@ msgstr ""
msgid "Accounts to Merge"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:162
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:270
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:164
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:275
msgid "Accrued Expenses"
msgstr ""
@@ -2714,7 +2714,7 @@ msgstr ""
msgid "Add Employees"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:275
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:264
#: erpnext/selling/doctype/sales_order/sales_order.js:278
#: erpnext/stock/dashboard/item_dashboard.js:216
msgid "Add Item"
@@ -2770,8 +2770,8 @@ msgstr ""
msgid "Add Order Discount"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:300
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:435
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:289
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:424
msgid "Add Phantom Item"
msgstr ""
@@ -2848,8 +2848,8 @@ msgstr ""
msgid "Add Stock"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:300
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:435
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:289
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:424
msgid "Add Sub Assembly"
msgstr ""
@@ -3189,7 +3189,7 @@ msgstr ""
msgid "Additional Information updated successfully."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:843
+#: erpnext/manufacturing/doctype/work_order/work_order.js:851
msgid "Additional Material Transfer"
msgstr ""
@@ -3361,7 +3361,7 @@ msgstr ""
msgid "Address used to determine Tax Category in transactions"
msgstr ""
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1189
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1194
msgid "Adjustment Against"
msgstr ""
@@ -3665,7 +3665,7 @@ msgstr ""
msgid "Against Stock Entry"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:336
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:346
msgid "Against Supplier Invoice {0}"
msgstr ""
@@ -3844,7 +3844,7 @@ msgstr ""
msgid "All Activities HTML"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:423
+#: erpnext/manufacturing/doctype/bom/bom.py:424
msgid "All BOMs"
msgstr ""
@@ -3944,7 +3944,7 @@ msgstr ""
msgid "All Territories"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:492
+#: erpnext/setup/doctype/company/company.py:496
msgid "All Warehouses"
msgstr ""
@@ -3967,7 +3967,7 @@ msgstr ""
msgid "All invoices and orders for this customer will be created in this currency."
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:60
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:61
msgid "All items are already requested"
msgstr ""
@@ -3983,7 +3983,7 @@ msgstr ""
msgid "All items have already been transferred for this Work Order."
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:3078
+#: erpnext/public/js/controllers/transaction.js:3086
msgid "All items in this document already have a linked Quality Inspection."
msgstr ""
@@ -3999,6 +3999,12 @@ msgstr ""
msgid "All picked items have already been transferred against this Pick List"
msgstr ""
+#: erpnext/manufacturing/doctype/work_order/mapper.py:570
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1203
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1223
+msgid "All required items have already been transferred, requested or picked."
+msgstr ""
+
#. Description of the 'Carry Forward Communication and Comments' (Check) field
#. in DocType 'CRM Settings'
#: erpnext/crm/doctype/crm_settings/crm_settings.json
@@ -4009,7 +4015,7 @@ msgstr ""
msgid "All the items have already been returned."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1292
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1344
msgid "All the required items (raw materials) will be fetched from BOM and populated in this table. Here you can also change the Source Warehouse for any item. And during the production, you can track transferred raw materials from this table."
msgstr ""
@@ -4217,8 +4223,8 @@ msgstr ""
#. Valuation'
#: erpnext/stock/doctype/item/item.json
#: erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:211
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:223
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:216
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:228
msgid "Allow Negative Stock"
msgstr ""
@@ -4628,7 +4634,11 @@ msgstr ""
msgid "Already Imported"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:1132
+#: erpnext/accounts/bulk_payment.py:94
+msgid "Already Paid"
+msgstr ""
+
+#: erpnext/stock/doctype/pick_list/pick_list.py:1191
msgid "Already Picked"
msgstr ""
@@ -4859,7 +4869,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/bom_item/bom_item.json
#: erpnext/manufacturing/doctype/work_order_additional_item/work_order_additional_item.json
#: erpnext/manufacturing/doctype/work_order_item/work_order_item.json
-#: erpnext/public/js/controllers/transaction.js:584
+#: erpnext/public/js/controllers/transaction.js:589
#: erpnext/public/js/sales_order_proforma.js:142
#: erpnext/selling/doctype/proforma_invoice/proforma_invoice.json
#: erpnext/selling/doctype/proforma_invoice_item/proforma_invoice_item.json
@@ -5618,7 +5628,7 @@ msgstr ""
msgid "Are you sure you want to create a Reposting Entry?"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:499
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:488
msgid "Are you sure you want to delete this Item?"
msgstr ""
@@ -5696,7 +5706,7 @@ msgstr ""
msgid "As the field {0} is enabled, the value of the field {1} should be more than 1."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1125
+#: erpnext/stock/doctype/item/item.py:1135
msgid "As there are existing submitted transactions against item {0}, you can not change the value of {1}."
msgstr ""
@@ -5704,16 +5714,16 @@ msgstr ""
msgid "As there are sufficient Sub Assembly Items, Work Order is not required for Warehouse {0}."
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:470
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:471
msgid "As there are sufficient raw materials, Material Request is not required for Warehouse {0}."
msgstr ""
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:236
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:241
msgid "As there is reserved stock, you cannot disable {0}."
msgstr ""
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:210
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:222
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:215
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:227
msgid "As {0} is enabled, you can not enable {1}."
msgstr ""
@@ -6023,8 +6033,8 @@ msgstr ""
#. Option for the 'Account Type' (Select) field in DocType 'Account'
#. Label of the asset_received_but_not_billed (Link) field in DocType 'Company'
#: erpnext/accounts/doctype/account/account.json
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:169
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:284
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:171
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:289
#: erpnext/accounts/report/account_balance/account_balance.js:38
#: erpnext/setup/doctype/company/company.json
msgid "Asset Received But Not Billed"
@@ -6324,7 +6334,7 @@ msgstr ""
msgid "At Row #{0}: The picked quantity {1} for the item {2} is greater than available stock {3} in the warehouse {4}."
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1501
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1551
msgid "At Row {0}: In Serial and Batch Bundle {1} must have docstatus as 1 and not 0"
msgstr ""
@@ -6344,7 +6354,7 @@ msgstr ""
msgid "At least one invoice has to be selected."
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:169
+#: erpnext/controllers/sales_and_purchase_return.py:187
msgid "At least one item should be entered with negative quantity in return document"
msgstr ""
@@ -6385,7 +6395,7 @@ msgstr ""
msgid "At row #{0}: you have selected the Difference Account {1}..."
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1249
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1299
msgid "At row {0}: Batch No is mandatory for Item {1}"
msgstr ""
@@ -6393,11 +6403,11 @@ msgstr ""
msgid "At row {0}: Parent Row No cannot be set for item {1}"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1234
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1284
msgid "At row {0}: Qty is mandatory for the batch {1}"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1241
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1291
msgid "At row {0}: Serial No is mandatory for Item {1}"
msgstr ""
@@ -6461,11 +6471,11 @@ msgstr ""
msgid "Attribute Value"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:891
+#: erpnext/stock/doctype/item/item.py:901
msgid "Attribute Value {0} is not valid for the selected attribute {1}."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1037
+#: erpnext/stock/doctype/item/item.py:1047
msgid "Attribute table is mandatory"
msgstr ""
@@ -6473,19 +6483,19 @@ msgstr ""
msgid "Attribute value: {0} must appear only once"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:880
+#: erpnext/stock/doctype/item/item.py:890
msgid "Attribute {0} is disabled."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:868
+#: erpnext/stock/doctype/item/item.py:878
msgid "Attribute {0} is not valid for the selected template."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1041
+#: erpnext/stock/doctype/item/item.py:1051
msgid "Attribute {0} selected multiple times in Attributes Table"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:969
+#: erpnext/stock/doctype/item/item.py:979
msgid "Attributes"
msgstr ""
@@ -6978,7 +6988,7 @@ msgid "Avg Rate"
msgstr ""
#: erpnext/stock/report/available_serial_no/available_serial_no.py:154
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:368
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:371
msgid "Avg Rate (Balance Stock)"
msgstr ""
@@ -7317,7 +7327,7 @@ msgstr ""
msgid "BOM recursion: {0} cannot be an ancestor of itself"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:766
+#: erpnext/manufacturing/doctype/bom/bom.py:767
msgid "BOM recursion: {1} cannot be parent or child of {0}"
msgstr ""
@@ -7325,19 +7335,19 @@ msgstr ""
msgid "BOM update is queued and may take a few minutes. Check {0} for progress."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:1434
+#: erpnext/manufacturing/doctype/bom/bom.py:1495
msgid "BOM {0} does not belong to Item {1}"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:1429
+#: erpnext/manufacturing/doctype/bom/bom.py:1490
msgid "BOM {0} must be active"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:1432
+#: erpnext/manufacturing/doctype/bom/bom.py:1493
msgid "BOM {0} must be submitted"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:839
+#: erpnext/manufacturing/doctype/bom/bom.py:840
msgid "BOM {0} not found for the item {1}"
msgstr ""
@@ -7362,7 +7372,7 @@ msgstr ""
msgid "Backdated Entries Will Be Blocked"
msgstr ""
-#: erpnext/stock/stock_ledger.py:100
+#: erpnext/stock/stock_ledger.py:99
msgid "Backdated Entry Not Allowed"
msgstr ""
@@ -7442,7 +7452,7 @@ msgstr ""
#: erpnext/stock/report/available_serial_no/available_serial_no.py:126
#: erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py:84
#: erpnext/stock/report/stock_balance/stock_balance.py:517
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:331
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:334
msgid "Balance Qty"
msgstr ""
@@ -7515,7 +7525,7 @@ msgstr ""
#: erpnext/stock/report/available_serial_no/available_serial_no.py:174
#: erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py:86
#: erpnext/stock/report/stock_balance/stock_balance.py:525
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:388
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:391
msgid "Balance Value"
msgstr ""
@@ -7776,8 +7786,8 @@ msgstr ""
msgid "Bank Name"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:183
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:314
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:185
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:319
msgid "Bank Overdraft Account"
msgstr ""
@@ -8104,8 +8114,8 @@ msgstr ""
#: erpnext/stock/report/batch_item_expiry_status/batch_item_expiry_status.py:34
#: erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py:80
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:158
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:418
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:182
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:421
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:191
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:80
#: erpnext/stock/report/stock_qty_vs_batch_qty/stock_qty_vs_batch_qty.js:19
#: erpnext/stock/report/stock_qty_vs_batch_qty/stock_qty_vs_batch_qty.py:32
@@ -8185,7 +8195,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.json
#: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js:89
#: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py:115
-#: erpnext/public/js/controllers/transaction.js:2981
+#: erpnext/public/js/controllers/transaction.js:2989
#: erpnext/public/js/utils/barcode_scanner.js:286
#: erpnext/public/js/utils/serial_batch_inline_editor.js:929
#: erpnext/public/js/utils/serial_no_batch_selector.js:450
@@ -8217,11 +8227,11 @@ msgstr ""
msgid "Batch No"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1252
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1302
msgid "Batch No is mandatory"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3655
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3705
msgid "Batch No {0} does not exist"
msgstr ""
@@ -8229,11 +8239,11 @@ msgstr ""
msgid "Batch No {0} is linked with Item {1} which has serial no. Please scan serial no instead."
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:491
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:541
msgid "Batch No {0} is not present in the original {1} {2}, hence you can't return it against the {1} {2}"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:724
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:774
msgid "Batch No {0} of Item {1} has negative stock of quantity {2} in the warehouse {3}"
msgstr ""
@@ -8248,11 +8258,11 @@ msgstr ""
msgid "Batch Nos"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2096
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2146
msgid "Batch Nos are created successfully"
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:1203
+#: erpnext/controllers/sales_and_purchase_return.py:1221
msgid "Batch Not Available for Return"
msgstr ""
@@ -8321,7 +8331,7 @@ msgstr ""
msgid "Batch {0} and Warehouse"
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:1202
+#: erpnext/controllers/sales_and_purchase_return.py:1220
msgid "Batch {0} is not available in warehouse {1}"
msgstr ""
@@ -8344,7 +8354,7 @@ msgid "Batch-Wise Balance History"
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:164
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:194
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:203
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:86
msgid "Batchwise Valuation"
msgstr ""
@@ -8360,7 +8370,7 @@ msgstr ""
msgid "Begin On (Days)"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:397
+#: erpnext/accounts/doctype/subscription/subscription.py:400
msgid "Below Subscription Plans are of different currency to the party default billing currency/Company currency: {0}"
msgstr ""
@@ -8415,7 +8425,7 @@ msgstr ""
#. Label of a Card Break in the Manufacturing Workspace
#. Label of a Link in the Manufacturing Workspace
#. Label of the bom_info_section (Section Break) field in DocType 'Stock Entry'
-#: erpnext/manufacturing/doctype/bom/bom.py:1168
+#: erpnext/manufacturing/doctype/bom/bom.py:1169
#: erpnext/manufacturing/workspace/manufacturing/manufacturing.json
#: erpnext/stock/doctype/material_request/material_request.js:143
#: erpnext/stock/doctype/stock_entry/stock_entry.js:766
@@ -8607,7 +8617,7 @@ msgstr ""
msgid "Billing Interval Count cannot be less than 1"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:446
+#: erpnext/accounts/doctype/subscription/subscription.py:449
msgid "Billing Interval in Subscription Plan must be Month to follow calendar months"
msgstr ""
@@ -8777,7 +8787,7 @@ msgid "Blanket Orders"
msgstr ""
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:109
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:271
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:269
msgid "Block Invoice"
msgstr ""
@@ -8928,7 +8938,7 @@ msgstr ""
msgid "Both Receivable Account: {0} and Advance Account: {1} must be of same currency for company: {2}"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:416
+#: erpnext/accounts/doctype/subscription/subscription.py:419
msgid "Both Trial Period Start Date and Trial Period End Date must be set"
msgstr ""
@@ -9178,15 +9188,15 @@ msgstr ""
msgid "Bulk Payment"
msgstr ""
-#: erpnext/accounts/bulk_payment.py:84
+#: erpnext/accounts/bulk_payment.py:44
msgid "Bulk Payment Entries"
msgstr ""
-#: erpnext/accounts/bulk_payment.py:75
+#: erpnext/accounts/bulk_payment.py:137
msgid "Bulk Payment Entry creation failed for {0}"
msgstr ""
-#: erpnext/accounts/bulk_payment.py:61
+#: erpnext/accounts/bulk_payment.py:126
msgid "Bulk Payment Entry skipped for {0}"
msgstr ""
@@ -9703,11 +9713,11 @@ msgstr ""
msgid "Can refer row only if the charge type is 'On Previous Row Amount' or 'Previous Row Total'"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:283
+#: erpnext/setup/doctype/company/company.py:285
msgid "Can't change the valuation method, as there are transactions against some items which do not have its own valuation method"
msgstr ""
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:177
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:182
msgid "Can't change the valuation method, as there are transactions against some items which do not have their own valuation method"
msgstr ""
@@ -9747,11 +9757,11 @@ msgstr ""
msgid "Cannot Assign Cashier"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:302
+#: erpnext/setup/doctype/company/company.py:304
msgid "Cannot Change Inventory Account Setting"
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:445
+#: erpnext/controllers/sales_and_purchase_return.py:463
msgid "Cannot Create Return"
msgstr ""
@@ -9810,7 +9820,7 @@ msgstr ""
msgid "Cannot cancel because submitted Stock Entry {0} exists"
msgstr ""
-#: erpnext/stock/stock_ledger.py:230
+#: erpnext/stock/stock_ledger.py:257
msgid "Cannot cancel the transaction. Reposting of item valuation on submission is not completed yet."
msgstr ""
@@ -9826,15 +9836,15 @@ msgstr ""
msgid "Cannot cancel this document as it is linked with the submitted asset {asset_link}. Please cancel the asset to continue."
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:425
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:434
msgid "Cannot cancel transaction for Completed Work Order."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:989
+#: erpnext/stock/doctype/item/item.py:999
msgid "Cannot change Attributes after stock transaction. Make a new Item and transfer stock to the new Item"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1150
+#: erpnext/stock/doctype/item/item.py:1160
msgid "Cannot change Item {0} from serialized to non-serialized because a Serial and Batch Bundle exists for it. Please delete or cancel the Serial and Batch Bundle first."
msgstr ""
@@ -9846,15 +9856,15 @@ msgstr ""
msgid "Cannot change Service Stop Date for item in row {0}"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:980
+#: erpnext/stock/doctype/item/item.py:990
msgid "Cannot change Variant properties after stock transaction. You will have to make a new Item to do this."
msgstr ""
-#: erpnext/setup/doctype/company/company.py:444
+#: erpnext/setup/doctype/company/company.py:448
msgid "Cannot change company's default currency, because there are existing transactions. Transactions must be cancelled to change the default currency."
msgstr ""
-#: erpnext/projects/doctype/task/task.py:147
+#: erpnext/projects/doctype/task/task.py:148
msgid "Cannot complete task {0} as its dependent task {1} is not completed / cancelled."
msgstr ""
@@ -9878,7 +9888,7 @@ msgstr ""
msgid "Cannot create Intercompany {0}. All items in the source {1} have already been fully invoiced. Please check the existing linked {2}s."
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:103
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:104
msgid "Cannot create Material Request for item {0} in group warehouse {1}."
msgstr ""
@@ -9887,7 +9897,7 @@ msgid "Cannot create Stock Reservation Entries for future dated Purchase Receipt
msgstr ""
#: erpnext/selling/doctype/sales_order/mapper.py:983
-#: erpnext/stock/doctype/pick_list/pick_list.py:258
+#: erpnext/stock/doctype/pick_list/pick_list.py:297
msgid "Cannot create a pick list for Sales Order {0} because it has reserved stock. Please unreserve the stock in order to create a pick list."
msgstr ""
@@ -9899,15 +9909,15 @@ msgstr ""
msgid "Cannot create more Subcontracting Orders against the Purchase Order {0}."
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:444
+#: erpnext/controllers/sales_and_purchase_return.py:462
msgid "Cannot create return for consolidated invoice {0}."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:912
+#: erpnext/manufacturing/doctype/bom/bom.py:913
msgid "Cannot deactivate or cancel BOM as it is linked with other BOMs"
msgstr ""
-#: erpnext/crm/doctype/opportunity/opportunity.py:283
+#: erpnext/crm/doctype/opportunity/opportunity.py:293
msgid "Cannot declare as Lost because an active Quotation exists."
msgstr ""
@@ -9924,7 +9934,7 @@ msgstr ""
msgid "Cannot delete Serial No {0}, as it is used in stock transactions"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:403
+#: erpnext/accounts/services/child_item_update.py:432
msgid "Cannot delete an item which has been ordered"
msgstr ""
@@ -9937,15 +9947,15 @@ msgstr ""
msgid "Cannot delete virtual DocType: {0}. Virtual DocTypes do not have database tables."
msgstr ""
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:144
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:149
msgid "Cannot disable Serial and Batch No for Item, as there are existing records for serial / batch."
msgstr ""
-#: erpnext/setup/doctype/company/company.py:676
+#: erpnext/setup/doctype/company/company.py:680
msgid "Cannot disable perpetual inventory, as there are existing Stock Ledger Entries for the company {0}. Please cancel the stock transactions first and try again."
msgstr ""
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:125
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:130
msgid "Cannot disable {0} as it may lead to incorrect stock valuation."
msgstr ""
@@ -9957,7 +9967,7 @@ msgstr ""
msgid "Cannot disassemble {0} qty against Stock Entry {1}. Only {2} qty available to disassemble."
msgstr ""
-#: erpnext/setup/doctype/company/company.py:299
+#: erpnext/setup/doctype/company/company.py:301
msgid "Cannot enable Item-wise Inventory Account, as there are existing Stock Ledger Entries for the company {0} with Warehouse-wise Inventory Account. Please cancel the stock transactions first and try again."
msgstr ""
@@ -9982,11 +9992,11 @@ msgstr ""
msgid "Cannot find Item with this Barcode"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:356
-msgid "Cannot find a default warehouse for item {0}. Please set one in the Item Master or in Stock Settings."
+#: erpnext/accounts/services/child_item_update.py:372
+msgid "Cannot find a default warehouse for item {0}. Please select one in the Update Items dialog, or set a default in the Item Master or in the Company."
msgstr ""
-#: erpnext/accounts/party.py:1116
+#: erpnext/accounts/party.py:1118
msgid "Cannot merge {0} '{1}' into '{2}' as both have existing accounting entries in different currencies for company '{3}'."
msgstr ""
@@ -9994,7 +10004,7 @@ msgstr ""
msgid "Cannot optimize route as the driver address is missing."
msgstr ""
-#: erpnext/stock/stock_ledger.py:90
+#: erpnext/stock/stock_ledger.py:89
msgid "Cannot post Standard Cost item {0} on {1}: it is before {2}, the effective date of its latest Standard Valuation Rate {3}."
msgstr ""
@@ -10014,7 +10024,7 @@ msgstr ""
msgid "Cannot receive from customer against negative outstanding"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:289
+#: erpnext/accounts/services/child_item_update.py:294
msgid "Cannot reduce quantity than ordered or purchased quantity"
msgstr ""
@@ -10040,7 +10050,7 @@ msgstr ""
msgid "Cannot retrieve link token. Check Error Log for more information"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:383
+#: erpnext/selling/doctype/customer/customer.py:384
msgid "Cannot select a Group type Customer Group. Please select a non-group Customer Group."
msgstr ""
@@ -10073,11 +10083,11 @@ msgstr ""
msgid "Cannot set multiple account rows for the same company"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:258
+#: erpnext/accounts/services/child_item_update.py:263
msgid "Cannot set quantity less than delivered quantity."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:259
+#: erpnext/accounts/services/child_item_update.py:264
msgid "Cannot set quantity less than received quantity."
msgstr ""
@@ -10093,7 +10103,7 @@ msgstr ""
msgid "Cannot submit Job Card {0} while it is On Hold. Please resume and complete the job before submission."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:283
+#: erpnext/accounts/services/child_item_update.py:288
msgid "Cannot update rate as item {0} is already ordered or purchased against this quotation"
msgstr ""
@@ -10136,7 +10146,7 @@ msgstr ""
msgid "Capacity Planning For (Days)"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:698
+#: erpnext/public/js/shop_floor/shop_floor.js:704
msgid "Capacity Reached"
msgstr ""
@@ -10154,8 +10164,8 @@ msgstr ""
msgid "Capital Equipment"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:194
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:338
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:196
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:343
msgid "Capital Stock"
msgstr ""
@@ -10278,7 +10288,7 @@ msgstr ""
msgid "Cash In Hand"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:326
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:336
msgid "Cash or Bank Account is mandatory for making payment entry"
msgstr ""
@@ -10703,7 +10713,7 @@ msgstr ""
#. Label of the reference_date (Date) field in DocType 'Payment Entry'
#: erpnext/accounts/doctype/payment_entry/payment_entry.json
-#: erpnext/public/js/controllers/transaction.js:2892
+#: erpnext/public/js/controllers/transaction.js:2900
msgid "Cheque/Reference Date"
msgstr ""
@@ -10761,7 +10771,7 @@ msgstr ""
#. Label of the child_row_reference (Data) field in DocType 'Quality
#. Inspection'
-#: erpnext/public/js/controllers/transaction.js:2987
+#: erpnext/public/js/controllers/transaction.js:2995
#: erpnext/stock/doctype/quality_inspection/quality_inspection.json
msgid "Child Row Reference"
msgstr ""
@@ -10770,7 +10780,7 @@ msgstr ""
msgid "Child Table Not Allowed"
msgstr ""
-#: erpnext/projects/doctype/task/task.py:327
+#: erpnext/projects/doctype/task/task.py:345
msgid "Child Task exists for this Task. You cannot delete this Task."
msgstr ""
@@ -10788,7 +10798,7 @@ msgstr ""
msgid "Child warehouse exists for this warehouse. You can not delete this warehouse."
msgstr ""
-#: erpnext/projects/doctype/task/task.py:257
+#: erpnext/projects/doctype/task/task.py:258
msgid "Circular Reference Error"
msgstr ""
@@ -10954,7 +10964,7 @@ msgstr ""
msgid "Close Replied Opportunity After Days"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1455
+#: erpnext/public/js/shop_floor/shop_floor.js:1461
msgid "Close detail / blur search"
msgstr ""
@@ -10972,6 +10982,10 @@ msgstr ""
msgid "Closed Documents"
msgstr ""
+#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:145
+msgid "Closed Period"
+msgstr ""
+
#: erpnext/manufacturing/doctype/work_order/work_order.py:1132
msgid "Closed Work Order can not be stopped or Re-opened"
msgstr ""
@@ -11007,7 +11021,7 @@ msgstr ""
msgid "Closing Account Head"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:135
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:139
msgid "Closing Account {0} must be of type Liability / Equity"
msgstr ""
@@ -11590,7 +11604,7 @@ msgstr ""
#: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js:8
#: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:316
#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.js:8
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:268
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:291
#: erpnext/buying/report/subcontract_order_summary/subcontract_order_summary.js:7
#: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js:8
#: erpnext/crm/doctype/lead/lead.json
@@ -11736,10 +11750,10 @@ msgstr ""
#: erpnext/stock/report/stock_balance/stock_balance.js:8
#: erpnext/stock/report/stock_balance/stock_balance.py:580
#: erpnext/stock/report/stock_ledger/stock_ledger.js:8
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:441
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:444
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.js:18
#: erpnext/stock/report/stock_projected_qty/stock_projected_qty.js:8
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js:8
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js:32
#: erpnext/stock/report/total_stock_summary/total_stock_summary.js:17
#: erpnext/stock/report/total_stock_summary/total_stock_summary.py:29
#: erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.js:8
@@ -11819,11 +11833,11 @@ msgstr ""
msgid "Company Address Name"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1633
+#: erpnext/controllers/accounts_controller.py:1638
msgid "Company Address is missing. You don't have permission to create an Address. Please contact your System Manager."
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1621
+#: erpnext/controllers/accounts_controller.py:1626
msgid "Company Address is missing. You don't have permission to update it. Please contact your System Manager."
msgstr ""
@@ -11968,7 +11982,7 @@ msgstr ""
msgid "Company is mandatory for company account"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:482
+#: erpnext/accounts/doctype/subscription/subscription.py:485
msgid "Company is mandatory for generating an invoice. Please set a default company in Global Defaults."
msgstr ""
@@ -12091,7 +12105,7 @@ msgstr ""
msgid "Completed On"
msgstr ""
-#: erpnext/projects/doctype/task/task.py:187
+#: erpnext/projects/doctype/task/task.py:188
msgid "Completed On cannot be greater than Today"
msgstr ""
@@ -12124,7 +12138,7 @@ msgid "Completed Qty cannot be greater than 'Qty to Manufacture'"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:263
-#: erpnext/public/js/shop_floor/shop_floor.js:808
+#: erpnext/public/js/shop_floor/shop_floor.js:814
msgid "Completed Quantity"
msgstr ""
@@ -12133,11 +12147,11 @@ msgid "Completed Quantity ({0}), Pending Quantity ({1}) and Process Loss Quantit
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:280
-#: erpnext/public/js/shop_floor/shop_floor.js:825
+#: erpnext/public/js/shop_floor/shop_floor.js:831
msgid "Completed Quantity cannot be greater than {0}"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:906
+#: erpnext/public/js/shop_floor/shop_floor.js:912
msgid "Completed Quantity should be greater than 0"
msgstr ""
@@ -12158,7 +12172,7 @@ msgid "Completed Work Orders"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:253
-#: erpnext/public/js/shop_floor/shop_floor.js:798
+#: erpnext/public/js/shop_floor/shop_floor.js:804
msgid "Completed, Pending and Process Loss quantities must add up to this."
msgstr ""
@@ -12266,7 +12280,7 @@ msgstr ""
msgid "Configure Chart of Accounts"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:56
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:45
msgid "Configure Product Assembly"
msgstr ""
@@ -12334,7 +12348,7 @@ msgstr ""
msgid "Consider Minimum Order Qty"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1103
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1134
msgid "Consider Process Loss"
msgstr ""
@@ -12565,7 +12579,7 @@ msgstr ""
msgid "Consumer Products"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:209
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:218
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:101
msgid "Consumption Rate"
msgstr ""
@@ -12846,7 +12860,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/bom_item/bom_item.json
#: erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json
#: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
-#: erpnext/public/js/utils.js:927
+#: erpnext/public/js/utils.js:930
#: 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
@@ -12880,15 +12894,15 @@ msgstr ""
msgid "Conversion factor for item {0} has been reset to 1.0 as the uom {1} is same as stock uom {2}."
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1314
+#: erpnext/controllers/accounts_controller.py:1319
msgid "Conversion rate cannot be 0"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1321
+#: erpnext/controllers/accounts_controller.py:1326
msgid "Conversion rate is 1.00, but document currency is different from company currency"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1317
+#: erpnext/controllers/accounts_controller.py:1322
msgid "Conversion rate must be 1.00 if document currency is same as company currency"
msgstr ""
@@ -13288,7 +13302,7 @@ msgstr ""
msgid "Cost Per Unit"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:474
+#: erpnext/manufacturing/doctype/bom/bom.py:475
msgid "Cost allocation between finished goods and secondary items should equal 100%"
msgstr ""
@@ -13698,7 +13712,7 @@ msgid "Create POS Opening Entry"
msgstr ""
#: erpnext/accounts/report/accounts_payable/accounts_payable.js:196
-#: erpnext/accounts/report/accounts_payable/accounts_payable.js:288
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:331
msgid "Create Payment Entries"
msgstr ""
@@ -13713,14 +13727,10 @@ msgstr ""
msgid "Create Payment Entry for Consolidated POS Invoices."
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:592
+#: erpnext/public/js/controllers/transaction.js:597
msgid "Create Payment Request"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:821
-msgid "Create Pick List"
-msgstr ""
-
#: erpnext/accounts/doctype/cheque_print_template/cheque_print_template.js:11
msgid "Create Print Format"
msgstr ""
@@ -13933,10 +13943,14 @@ msgstr ""
msgid "Create Workstation"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1123
+#: erpnext/public/js/shop_floor/shop_floor.js:1129
msgid "Create a Manufacture stock entry for the finished goods?"
msgstr ""
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:231
+msgid "Create a Stock Closing Entry for the entire company with To Date as {0} before submitting the Period Closing Voucher."
+msgstr ""
+
#: banking/src/components/features/BankReconciliation/MatchAndReconcile.tsx:683
msgid "Create a journal entry for expenses, income or split transactions"
msgstr ""
@@ -13954,7 +13968,7 @@ msgstr ""
msgid "Create a variant with the template image."
msgstr ""
-#: erpnext/stock/stock_ledger.py:2220
+#: erpnext/stock/stock_ledger.py:2263
msgid "Create an incoming stock transaction for the Item."
msgstr ""
@@ -13993,8 +14007,8 @@ msgstr ""
msgid "Created through Portal"
msgstr ""
-#: erpnext/accounts/bulk_payment.py:77
-msgid "Created {0} draft Grouped Payment Entries"
+#: erpnext/accounts/bulk_payment.py:39
+msgid "Created {0} draft Payment Entries"
msgstr ""
#: erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py:232
@@ -14058,7 +14072,7 @@ msgstr ""
msgid "Creating Purchase Order ..."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:725
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:723
#: erpnext/buying/doctype/purchase_order/purchase_order.js:471
#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:74
msgid "Creating Purchase Receipt ..."
@@ -14101,7 +14115,7 @@ msgid "Creating {} out of {} {}"
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:141
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:165
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:174
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:46
msgid "Creation"
msgstr ""
@@ -14239,7 +14253,7 @@ msgstr ""
msgid "Credit Limit"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:557
+#: erpnext/selling/doctype/customer/customer.py:558
msgid "Credit Limit Crossed"
msgstr ""
@@ -14307,9 +14321,9 @@ msgstr ""
#. Label of the credit_to (Link) field in DocType 'Purchase Invoice'
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:380
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:388
-#: erpnext/controllers/accounts_controller.py:1216
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:390
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:398
+#: erpnext/controllers/accounts_controller.py:1221
msgid "Credit To"
msgstr ""
@@ -14318,20 +14332,20 @@ msgstr ""
msgid "Credit in Company Currency"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:523
-#: erpnext/selling/doctype/customer/customer.py:579
+#: erpnext/selling/doctype/customer/customer.py:524
+#: erpnext/selling/doctype/customer/customer.py:580
msgid "Credit limit has been crossed for customer {0} ({1}/{2})"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:410
+#: erpnext/selling/doctype/customer/customer.py:411
msgid "Credit limit is already defined for the Company {0}"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:578
+#: erpnext/selling/doctype/customer/customer.py:579
msgid "Credit limit reached for customer {0}"
msgstr ""
-#: erpnext/accounts/utils.py:2850
+#: erpnext/accounts/utils.py:2875
msgid "Credit limit warning — submission may be blocked: {0}"
msgstr ""
@@ -14339,8 +14353,8 @@ msgstr ""
msgid "Creditor Turnover Ratio"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:159
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:262
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:161
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:267
msgid "Creditors"
msgstr ""
@@ -14517,15 +14531,15 @@ msgstr ""
#: erpnext/accounts/doctype/payment_entry/services/gl_composer.py:215
#: erpnext/accounts/doctype/payment_entry/services/gl_composer.py:284
-#: erpnext/accounts/utils.py:2569
+#: erpnext/accounts/utils.py:2594
msgid "Currency for {0} must be {1}"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:142
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:146
msgid "Currency of the Closing Account must be {0}"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:680
+#: erpnext/manufacturing/doctype/bom/bom.py:681
msgid "Currency of the price list {0} must be {1} or {2}"
msgstr ""
@@ -14600,8 +14614,8 @@ msgstr ""
msgid "Current Level"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:157
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:260
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:159
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:265
msgid "Current Liabilities"
msgstr ""
@@ -14818,7 +14832,7 @@ msgstr ""
#: erpnext/assets/doctype/asset/asset.json
#: erpnext/buying/doctype/purchase_order/purchase_order.json
#: erpnext/buying/doctype/supplier/supplier.js:234
-#: erpnext/controllers/trends.py:434 erpnext/crm/doctype/contract/contract.json
+#: erpnext/controllers/trends.py:479 erpnext/crm/doctype/contract/contract.json
#: erpnext/crm/doctype/lead/lead.js:32
#: erpnext/crm/doctype/opportunity/opportunity.js:99
#: erpnext/crm/doctype/prospect/prospect.js:8
@@ -14962,8 +14976,8 @@ msgstr ""
msgid "Customer Addresses And Contacts"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:163
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:274
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:165
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:279
msgid "Customer Advances"
msgstr ""
@@ -15092,7 +15106,7 @@ msgstr ""
#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:208
#: erpnext/accounts/report/sales_register/sales_register.js:27
#: erpnext/accounts/report/sales_register/sales_register.py:216
-#: erpnext/controllers/trends.py:465
+#: erpnext/controllers/trends.py:516
#: erpnext/crm/doctype/opportunity/opportunity.json
#: erpnext/crm/doctype/prospect/prospect.json
#: erpnext/crm/workspace/crm/crm.json
@@ -15206,7 +15220,7 @@ msgstr ""
#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:228
#: erpnext/accounts/report/sales_register/sales_register.py:207
#: erpnext/buying/doctype/purchase_order/purchase_order.json
-#: erpnext/controllers/trends.py:441
+#: erpnext/controllers/trends.py:486
#: erpnext/crm/doctype/opportunity/opportunity.json
#: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json
#: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json
@@ -15306,7 +15320,7 @@ msgstr ""
msgid "Customer Provided Item Cost"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:602
+#: erpnext/setup/doctype/company/company.py:606
msgid "Customer Service"
msgstr ""
@@ -15466,7 +15480,7 @@ msgid "Cycle/Second"
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:204
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:254
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:263
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:146
msgid "D - E"
msgstr ""
@@ -15781,6 +15795,7 @@ msgstr ""
#. Option for the 'Journal Entry Type' (Select) field in DocType 'Journal Entry
#. Template'
#. Label of a Workspace Sidebar Item
+#: erpnext/accounts/bulk_payment.py:90
#: erpnext/accounts/doctype/journal_entry/journal_entry.json
#: erpnext/accounts/doctype/journal_entry_template/journal_entry_template.json
#: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html:178
@@ -15813,7 +15828,7 @@ msgstr ""
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.json
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:764
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:775
-#: erpnext/controllers/accounts_controller.py:1216
+#: erpnext/controllers/accounts_controller.py:1221
msgid "Debit To"
msgstr ""
@@ -15966,14 +15981,14 @@ msgstr ""
#. Label of the default_advance_paid_account (Link) field in DocType 'Company'
#: erpnext/setup/doctype/company/company.json
-#: erpnext/setup/doctype/company/company.py:429
+#: erpnext/setup/doctype/company/company.py:433
msgid "Default Advance Paid Account"
msgstr ""
#. Label of the default_advance_received_account (Link) field in DocType
#. 'Company'
#: erpnext/setup/doctype/company/company.json
-#: erpnext/setup/doctype/company/company.py:418
+#: erpnext/setup/doctype/company/company.py:422
msgid "Default Advance Received Account"
msgstr ""
@@ -15992,15 +16007,15 @@ msgstr ""
msgid "Default BOM ({0}) must be active for this item or its template"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/mapper.py:88
+#: erpnext/manufacturing/doctype/work_order/mapper.py:89
msgid "Default BOM for {0} not found"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:309
+#: erpnext/accounts/services/child_item_update.py:314
msgid "Default BOM not found for FG Item {0}"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/mapper.py:84
+#: erpnext/manufacturing/doctype/work_order/mapper.py:85
msgid "Default BOM not found for Item {0} and Project {1}"
msgstr ""
@@ -16322,15 +16337,15 @@ msgstr ""
msgid "Default Unit of Measure"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1431
+#: erpnext/stock/doctype/item/item.py:1441
msgid "Default Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. You need to either cancel the linked documents or create a new Item."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1411
+#: erpnext/stock/doctype/item/item.py:1421
msgid "Default Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. You will need to create a new Item to use a different Default UOM."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1015
+#: erpnext/stock/doctype/item/item.py:1025
msgid "Default Unit of Measure for Variant '{0}' must be same as in Template '{1}'"
msgstr ""
@@ -16744,7 +16759,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:1068
-#: erpnext/public/js/utils.js:920
+#: erpnext/public/js/utils.js:923
#: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json
#: erpnext/selling/doctype/sales_order/sales_order.js:662
#: erpnext/selling/doctype/sales_order/sales_order.js:1571
@@ -17000,7 +17015,7 @@ msgstr ""
msgid "Dependent Task"
msgstr ""
-#: erpnext/projects/doctype/task/task.py:180
+#: erpnext/projects/doctype/task/task.py:181
msgid "Dependent Task {0} is not a Template Task"
msgstr ""
@@ -17293,7 +17308,7 @@ msgstr ""
#: erpnext/public/js/bank_reconciliation_tool/number_card.js:30
#: erpnext/stock/report/incorrect_balance_qty_after_transaction/incorrect_balance_qty_after_transaction.py:130
#: erpnext/stock/report/stock_qty_vs_batch_qty/stock_qty_vs_batch_qty.py:35
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:35
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:41
msgid "Difference"
msgstr ""
@@ -17450,8 +17465,8 @@ msgstr ""
#. Option for the 'Account Type' (Select) field in DocType 'Account'
#: erpnext/accounts/doctype/account/account.json
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:145
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:242
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:146
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:243
msgid "Direct Income"
msgstr ""
@@ -17583,7 +17598,7 @@ msgstr ""
#. Option for the 'Purpose' (Select) field in DocType 'Stock Entry'
#. Option for the 'Purpose' (Select) field in DocType 'Stock Entry Type'
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1081
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1112
#: erpnext/stock/doctype/stock_entry/stock_entry.js:386
#: erpnext/stock/doctype/stock_entry/stock_entry.js:429
#: erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -17890,7 +17905,7 @@ msgstr ""
msgid "Dislikes"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:596
+#: erpnext/setup/doctype/company/company.py:600
msgid "Dispatch"
msgstr ""
@@ -18091,8 +18106,8 @@ msgstr ""
msgid "Distributor"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:195
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:343
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:197
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:348
msgid "Dividends Paid"
msgstr ""
@@ -18114,7 +18129,7 @@ msgstr ""
msgid "Do Not Explode"
msgstr ""
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:126
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:131
msgid "Do Not Use Batchwise Valuation"
msgstr ""
@@ -18531,11 +18546,11 @@ msgstr ""
msgid "Duplicate Sales Invoices found"
msgstr ""
-#: erpnext/stock/serial_batch_bundle.py:1528
+#: erpnext/stock/serial_batch_bundle.py:1615
msgid "Duplicate Serial Number Error"
msgstr ""
-#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:79
+#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:121
msgid "Duplicate Stock Closing Entry"
msgstr ""
@@ -18584,8 +18599,8 @@ msgstr ""
msgid "Duration in Days"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:174
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:291
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:176
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:296
#: erpnext/setup/setup_wizard/operations/taxes_setup.py:258
msgid "Duties and Taxes"
msgstr ""
@@ -18682,7 +18697,7 @@ msgstr ""
msgid "Earnest Money"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:544
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:533
msgid "Edit BOM"
msgstr ""
@@ -18787,8 +18802,8 @@ msgstr ""
msgid "Either 'Selling' or 'Buying' must be selected"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:309
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:460
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:298
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:449
msgid "Either Workstation or Workstation Type is mandatory"
msgstr ""
@@ -18999,7 +19014,7 @@ msgstr ""
#: erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py:24
#: erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.js:10
#: erpnext/projects/report/timesheet_billing_summary/timesheet_billing_summary.js:45
-#: erpnext/public/js/shop_floor/shop_floor.js:726
+#: erpnext/public/js/shop_floor/shop_floor.js:732
#: erpnext/quality_management/doctype/non_conformance/non_conformance.json
#: erpnext/setup/doctype/company/company.json
#: erpnext/setup/doctype/department/department.json
@@ -19033,8 +19048,8 @@ msgstr ""
msgid "Employee Advances"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:188
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:327
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:190
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:332
msgid "Employee Benefits Obligation"
msgstr ""
@@ -19125,7 +19140,7 @@ msgstr ""
msgid "Employee {0} not found"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:720
+#: erpnext/public/js/shop_floor/shop_floor.js:726
msgid "Employees"
msgstr ""
@@ -19142,7 +19157,7 @@ msgstr ""
msgid "Ems(Pica)"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:3050
+#: erpnext/public/js/controllers/transaction.js:3058
msgid "Enable {0} on the Item master to proceed with {1} inspection."
msgstr ""
@@ -19174,7 +19189,7 @@ msgstr ""
msgid "Enable Auto Email"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1219
+#: erpnext/stock/doctype/item/item.py:1229
msgid "Enable Auto Re-Order"
msgstr ""
@@ -19500,7 +19515,7 @@ msgstr ""
msgid "End Date cannot be before Start Date."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:961
+#: erpnext/public/js/shop_floor/shop_floor.js:967
#: erpnext/public/js/templates/shop_floor_template.html:786
msgid "End Session"
msgstr ""
@@ -19511,7 +19526,7 @@ msgstr ""
#. Label of the end_time (Datetime) field in DocType 'Call Log'
#: erpnext/manufacturing/doctype/job_card/job_card.js:381
#: erpnext/manufacturing/doctype/workstation_working_hour/workstation_working_hour.json
-#: erpnext/public/js/shop_floor/shop_floor.js:896
+#: erpnext/public/js/shop_floor/shop_floor.js:902
#: erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
#: erpnext/support/doctype/service_day/service_day.json
#: erpnext/telephony/doctype/call_log/call_log.json
@@ -19553,7 +19568,7 @@ msgstr ""
msgid "End of Life"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1458
+#: erpnext/public/js/shop_floor/shop_floor.js:1464
msgid "End session for active job"
msgstr ""
@@ -19692,7 +19707,7 @@ msgstr ""
msgid "Enter the quantity of the Item that will be manufactured from this Bill of Materials."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1254
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1306
msgid "Enter the quantity to manufacture. Raw material Items will be fetched only when this is set."
msgstr ""
@@ -19733,8 +19748,8 @@ msgstr ""
#. Option for the 'Root Type' (Select) field in DocType 'Account Category'
#. Option for the 'Root Type' (Select) field in DocType 'Ledger Merge'
#: erpnext/accounts/doctype/account/account.json
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:193
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:337
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:195
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:342
#: erpnext/accounts/doctype/account_category/account_category.json
#: erpnext/accounts/doctype/ledger_merge/ledger_merge.json
#: erpnext/accounts/report/account_balance/account_balance.js:29
@@ -19853,7 +19868,7 @@ msgstr ""
msgid "Example URL"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1131
+#: erpnext/stock/doctype/item/item.py:1141
msgid "Example of a linked document: {0}"
msgstr ""
@@ -19873,10 +19888,18 @@ msgstr ""
msgid "Example: If the transaction amount is 200, then this will be calculated as {} = {}"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2509
+#: erpnext/stock/stock_ledger.py:2552
msgid "Example: Serial No {0} reserved in {1}."
msgstr ""
+#: erpnext/manufacturing/doctype/work_order/services/required_items.py:230
+msgid "Exceeds Pending Qty"
+msgstr ""
+
+#: erpnext/stock/doctype/pick_list/pick_list.py:277
+msgid "Exceeds Requested Qty"
+msgstr ""
+
#. Label of the exception_budget_approver_role (Link) field in DocType
#. 'Company'
#: erpnext/setup/doctype/company/company.json
@@ -19904,6 +19927,12 @@ msgstr ""
msgid "Excessive machine set up time"
msgstr ""
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:153
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:254
+#: erpnext/setup/doctype/company/company.py:801
+msgid "Exchange Gain"
+msgstr ""
+
#. Label of the exchange_gain__loss_section (Section Break) field in DocType
#. 'Company'
#: erpnext/setup/doctype/company/company.json
@@ -19915,6 +19944,11 @@ msgstr ""
msgid "Exchange Gain / Loss Account"
msgstr ""
+#. Label of the exchange_gain_account (Link) field in DocType 'Company'
+#: erpnext/setup/doctype/company/company.json
+msgid "Exchange Gain Account"
+msgstr ""
+
#. Option for the 'Entry Type' (Select) field in DocType 'Journal Entry'
#: erpnext/accounts/doctype/journal_entry/journal_entry.json
msgid "Exchange Gain Or Loss"
@@ -19931,15 +19965,26 @@ msgstr ""
#: erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
#: erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
#: erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
-#: erpnext/setup/doctype/company/company.py:790
+#: erpnext/setup/doctype/company/company.py:794
msgid "Exchange Gain/Loss"
msgstr ""
-#: erpnext/accounts/services/exchange_gain_loss.py:113
-#: erpnext/accounts/services/exchange_gain_loss.py:190
+#: erpnext/accounts/services/exchange_gain_loss.py:120
+#: erpnext/accounts/services/exchange_gain_loss.py:195
msgid "Exchange Gain/Loss amount has been booked through {0}"
msgstr ""
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:141
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:236
+#: erpnext/setup/doctype/company/company.py:808
+msgid "Exchange Loss"
+msgstr ""
+
+#. Label of the exchange_loss_account (Link) field in DocType 'Company'
+#: erpnext/setup/doctype/company/company.json
+msgid "Exchange Loss Account"
+msgstr ""
+
#. Label of the exchange_rate (Float) field in DocType 'Advance Payment Ledger
#. Entry'
#. Label of the exchange_rate (Float) field in DocType 'Journal Entry Account'
@@ -20184,7 +20229,7 @@ msgstr ""
msgid "Expected End Date"
msgstr ""
-#: erpnext/projects/doctype/task/task.py:114
+#: erpnext/projects/doctype/task/task.py:115
msgid "Expected End Date should be less than or equal to parent task's Expected End Date {0}."
msgstr ""
@@ -20231,7 +20276,7 @@ msgstr ""
msgid "Expected Value After Useful Life"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1017
+#: erpnext/public/js/shop_floor/shop_floor.js:1023
msgid "Expected: {0}"
msgstr ""
@@ -20382,7 +20427,7 @@ msgstr ""
msgid "Expenses Included In Valuation"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:310
+#: erpnext/stock/doctype/pick_list/pick_list.py:350
#: erpnext/stock/doctype/stock_entry/stock_entry.js:512
msgid "Expired Batches"
msgstr ""
@@ -20515,7 +20560,7 @@ msgid "FIFO Stock Queue (qty, rate)"
msgstr ""
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:179
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:229
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:238
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:121
msgid "FIFO/LIFO Queue"
msgstr ""
@@ -20593,7 +20638,7 @@ msgstr ""
msgid "Failed to setup defaults"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:970
+#: erpnext/setup/doctype/company/company.py:988
msgid "Failed to setup defaults for country {0}. Please contact support."
msgstr ""
@@ -20738,7 +20783,7 @@ msgid "Fetching Sales Orders..."
msgstr ""
#: erpnext/accounts/doctype/dunning/dunning.js:135
-#: erpnext/public/js/controllers/transaction.js:1645
+#: erpnext/public/js/controllers/transaction.js:1650
msgid "Fetching exchange rates ..."
msgstr ""
@@ -20990,9 +21035,9 @@ msgstr ""
msgid "Financial reports will be generated using GL Entry doctypes (should be enabled if Period Closing Voucher is not posted for all years sequentially or missing) "
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:909
-#: erpnext/manufacturing/doctype/work_order/work_order.js:924
-#: erpnext/manufacturing/doctype/work_order/work_order.js:933
+#: erpnext/manufacturing/doctype/work_order/work_order.js:920
+#: erpnext/manufacturing/doctype/work_order/work_order.js:935
+#: erpnext/manufacturing/doctype/work_order/work_order.js:944
msgid "Finish"
msgstr ""
@@ -21023,7 +21068,7 @@ msgstr ""
#. Service Item'
#. Label of the fg_item (Link) field in DocType 'Subcontracting Order Service
#. Item'
-#: erpnext/public/js/utils.js:942
+#: erpnext/public/js/utils.js:968
#: 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"
@@ -21036,7 +21081,7 @@ msgstr ""
msgid "Finished Good Item Code"
msgstr ""
-#: erpnext/public/js/utils.js:960
+#: erpnext/public/js/utils.js:986
msgid "Finished Good Item Qty"
msgstr ""
@@ -21049,15 +21094,15 @@ msgstr ""
msgid "Finished Good Item Quantity"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:295
+#: erpnext/accounts/services/child_item_update.py:300
msgid "Finished Good Item is not specified for service item {0}"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:312
+#: erpnext/accounts/services/child_item_update.py:317
msgid "Finished Good Item {0} Qty can not be zero"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:306
+#: erpnext/accounts/services/child_item_update.py:311
msgid "Finished Good Item {0} must be a sub-contracted item"
msgstr ""
@@ -21103,7 +21148,7 @@ msgid "Finished Good {0} must be a sub-contracted item."
msgstr ""
#: erpnext/selling/doctype/sales_order/sales_order.js:1475
-#: erpnext/setup/doctype/company/company.py:495
+#: erpnext/setup/doctype/company/company.py:499
msgid "Finished Goods"
msgstr ""
@@ -21144,7 +21189,7 @@ msgstr ""
msgid "Finished Goods based Operating Cost"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:940
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:971
msgid "Finished Item {0} does not match with Work Order {1}"
msgstr ""
@@ -21314,7 +21359,7 @@ msgstr ""
msgid "Fixed Asset Turnover Ratio"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:737
+#: erpnext/manufacturing/doctype/bom/bom.py:738
msgid "Fixed Asset item {0} cannot be used in BOMs."
msgstr ""
@@ -21522,7 +21567,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
#: erpnext/manufacturing/doctype/production_plan/production_plan.js:497
#: erpnext/manufacturing/doctype/production_plan/production_plan.json
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:180
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:181
#: erpnext/selling/doctype/sales_order/sales_order.js:1488
#: erpnext/stock/doctype/material_request/material_request.js:363
#: erpnext/templates/form_grid/material_request_grid.html:36
@@ -21589,11 +21634,11 @@ msgstr ""
msgid "For legacy serial nos, do not fetch incoming rate from serial no and calculate it based on the inward transaction"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:400
+#: erpnext/manufacturing/doctype/bom/bom.py:401
msgid "For operation {0} at row {1}, please add raw materials or set a BOM against it."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/mapper.py:383
+#: erpnext/manufacturing/doctype/work_order/mapper.py:384
msgid "For operation {0}: Quantity ({1}) can not be greater than pending quantity ({2})"
msgstr ""
@@ -21620,7 +21665,7 @@ msgstr ""
msgid "For row {0} in {1}. To include {2} in Item rate, rows {3} must also be included"
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:270
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:271
msgid "For row {0}: Enter Planned Qty"
msgstr ""
@@ -21639,7 +21684,7 @@ msgstr ""
msgid "For the convenience of customers, these codes can be used in print formats like Invoices and Delivery Notes"
msgstr ""
-#: erpnext/stock/serial_batch_bundle.py:1240
+#: erpnext/stock/serial_batch_bundle.py:1327
msgid "For the item {0}, the Available qty {1} is less than the Required Qty {2} in the warehouse {3}. Please add sufficient qty in the warehouse."
msgstr ""
@@ -21647,7 +21692,7 @@ msgstr ""
msgid "For the item {0}, the consumed quantity should be {1} according to the BOM {2}."
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:1445
+#: erpnext/public/js/controllers/transaction.js:1450
msgctxt "Clear payment terms template and/or payment schedule when due date is changed"
msgid "For the new {0} to take effect, would you like to clear the current {1}?"
msgstr ""
@@ -21656,7 +21701,7 @@ msgstr ""
msgid "For the {0}, no stock is available for the return in the warehouse {1}."
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:1254
+#: erpnext/controllers/sales_and_purchase_return.py:1272
msgid "For the {0}, the quantity is required to make the return entry"
msgstr ""
@@ -22265,7 +22310,7 @@ msgstr ""
msgid "Future date is not allowed"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:269
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:278
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:161
msgid "G - D"
msgstr ""
@@ -22344,7 +22389,7 @@ msgstr ""
#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:138
#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:225
-#: erpnext/setup/doctype/company/company.py:798
+#: erpnext/setup/doctype/company/company.py:816
msgid "Gain/Loss on Asset Disposal"
msgstr ""
@@ -22801,7 +22846,7 @@ msgstr ""
msgid "Goods"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:496
+#: erpnext/setup/doctype/company/company.py:500
#: erpnext/stock/doctype/stock_entry/stock_entry_list.js:34
msgid "Goods In Transit"
msgstr ""
@@ -22810,7 +22855,7 @@ msgstr ""
msgid "Goods Transferred"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:1388
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1419
msgid "Goods are already received against the outward entry {0}"
msgstr ""
@@ -23107,7 +23152,7 @@ msgstr ""
msgid "Group Same Items"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:327
+#: erpnext/setup/doctype/company/company.py:329
msgid "Group Warehouses cannot be used in transactions. Please change the value of {0}"
msgstr ""
@@ -23176,7 +23221,7 @@ msgstr ""
msgid "Growth View"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:279
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:288
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:171
msgid "H - F"
msgstr ""
@@ -23445,7 +23490,7 @@ msgstr ""
msgid "Here are the error logs for the aforementioned failed depreciation entries: {0}"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2205
+#: erpnext/stock/stock_ledger.py:2248
msgid "Here are the options to proceed:"
msgstr ""
@@ -23692,7 +23737,7 @@ msgstr ""
msgid "Hrs"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:608
+#: erpnext/setup/doctype/company/company.py:612
msgid "Human Resources"
msgstr ""
@@ -23706,12 +23751,12 @@ msgstr ""
msgid "Hundredweight (US)"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:294
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:303
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:186
msgid "I - J"
msgstr ""
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:304
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:313
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:196
msgid "I - K"
msgstr ""
@@ -24145,7 +24190,7 @@ msgstr ""
msgid "If no taxes are set, and Taxes and Charges Template is selected, the system will automatically apply the taxes from the chosen template."
msgstr ""
-#: erpnext/stock/stock_ledger.py:2215
+#: erpnext/stock/stock_ledger.py:2258
msgid "If not, you can Cancel / Submit this entry"
msgstr ""
@@ -24182,7 +24227,7 @@ msgstr ""
msgid "If set, the system does not use the user's Email or the standard outgoing Email account for sending request for quotations."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1287
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1339
msgid "If the BOM results in Scrap material, the Scrap Warehouse needs to be selected."
msgstr ""
@@ -24191,7 +24236,7 @@ msgstr ""
msgid "If the account is frozen, entries are allowed to restricted users."
msgstr ""
-#: erpnext/stock/stock_ledger.py:2208
+#: erpnext/stock/stock_ledger.py:2251
msgid "If the item is transacting as a Zero Valuation Rate item in this entry, please enable 'Allow Zero Valuation Rate' in the {0} Item table."
msgstr ""
@@ -24201,7 +24246,7 @@ msgstr ""
msgid "If the reorder check is set at the Group warehouse level, the available quantity becomes the sum of the projected quantities of all its child warehouses."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1306
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1358
msgid "If the selected BOM has Operations mentioned in it, the system will fetch all Operations from BOM, these values can be changed."
msgstr ""
@@ -24292,7 +24337,7 @@ msgstr ""
msgid "If you still want to proceed, please disable {0} checkbox."
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:475
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:476
msgid "If you still want to proceed, please enable {0}."
msgstr ""
@@ -24632,7 +24677,7 @@ msgstr ""
#: erpnext/stock/report/available_serial_no/available_serial_no.py:112
#: erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py:82
#: erpnext/stock/report/stock_balance/stock_balance.py:547
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:317
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:320
msgid "In Qty"
msgstr ""
@@ -25000,8 +25045,8 @@ msgstr ""
#. Option for the 'Type' (Select) field in DocType 'Process Deferred
#. Accounting'
#: erpnext/accounts/doctype/account/account.json
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:144
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:241
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:145
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:242
#: erpnext/accounts/doctype/account_category/account_category.json
#: erpnext/accounts/doctype/ledger_merge/ledger_merge.json
#: erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.json
@@ -25083,8 +25128,8 @@ msgstr ""
#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
#: erpnext/stock/report/available_serial_no/available_serial_no.py:146
#: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:169
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:360
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:204
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:363
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:213
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:96
msgid "Incoming Rate"
msgstr ""
@@ -25167,12 +25212,12 @@ msgstr ""
msgid "Incorrect Stock Value Report"
msgstr ""
-#: erpnext/stock/serial_batch_bundle.py:173
+#: erpnext/stock/serial_batch_bundle.py:174
msgid "Incorrect Type of Transaction"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:330
-#: erpnext/setup/doctype/company/company.py:338
+#: erpnext/setup/doctype/company/company.py:332
+#: erpnext/setup/doctype/company/company.py:340
#: erpnext/stock/doctype/pick_list/pick_list.py:190
#: erpnext/stock/doctype/pick_list/pick_list.py:214
msgid "Incorrect Warehouse"
@@ -25269,8 +25314,8 @@ msgstr ""
#. Option for the 'Account Type' (Select) field in DocType 'Account'
#: erpnext/accounts/doctype/account/account.json
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:149
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:247
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:150
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:248
msgid "Indirect Income"
msgstr ""
@@ -25337,7 +25382,7 @@ msgstr ""
msgid "Initiated"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1045
+#: erpnext/public/js/shop_floor/shop_floor.js:1051
msgid "Inspect {0} for job card {1}"
msgstr ""
@@ -25349,15 +25394,15 @@ msgid "Inspected By"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.py:889
-#: erpnext/public/js/shop_floor/shop_floor.js:1083
-#: erpnext/stock/services/quality_inspection_service.py:147
+#: erpnext/public/js/shop_floor/shop_floor.js:1089
+#: erpnext/stock/services/quality_inspection_service.py:163
msgid "Inspection Rejected"
msgstr ""
#. Label of the inspection_required (Check) field in DocType 'Stock Entry'
#: erpnext/stock/doctype/stock_entry/stock_entry.json
-#: erpnext/stock/services/quality_inspection_service.py:117
-#: erpnext/stock/services/quality_inspection_service.py:119
+#: erpnext/stock/services/quality_inspection_service.py:133
+#: erpnext/stock/services/quality_inspection_service.py:135
msgid "Inspection Required"
msgstr ""
@@ -25374,7 +25419,7 @@ msgid "Inspection Required before Purchase"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.py:879
-#: erpnext/stock/services/quality_inspection_service.py:132
+#: erpnext/stock/services/quality_inspection_service.py:148
msgid "Inspection Submission"
msgstr ""
@@ -25443,24 +25488,24 @@ msgstr ""
msgid "Insufficient Capacity"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:213
-#: erpnext/accounts/services/child_item_update.py:235
-#: erpnext/controllers/accounts_controller.py:1663
-#: erpnext/controllers/accounts_controller.py:1669
-#: erpnext/controllers/accounts_controller.py:1691
+#: erpnext/accounts/services/child_item_update.py:218
+#: erpnext/accounts/services/child_item_update.py:240
+#: erpnext/controllers/accounts_controller.py:1668
+#: erpnext/controllers/accounts_controller.py:1674
+#: erpnext/controllers/accounts_controller.py:1696
msgid "Insufficient Permissions"
msgstr ""
#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:466
#: erpnext/stock/doctype/pick_list/pick_list.py:148
#: erpnext/stock/doctype/pick_list/pick_list.py:166
-#: erpnext/stock/doctype/pick_list/pick_list.py:1139
-#: erpnext/stock/serial_batch_bundle.py:1243 erpnext/stock/stock_ledger.py:1890
-#: erpnext/stock/stock_ledger.py:2397
+#: erpnext/stock/doctype/pick_list/pick_list.py:1198
+#: erpnext/stock/serial_batch_bundle.py:1330 erpnext/stock/stock_ledger.py:1933
+#: erpnext/stock/stock_ledger.py:2440
msgid "Insufficient Stock"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2412
+#: erpnext/stock/stock_ledger.py:2455
msgid "Insufficient Stock for Batch"
msgstr ""
@@ -25585,8 +25630,8 @@ msgstr ""
msgid "Interest Expense"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:150
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:248
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:151
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:249
msgid "Interest Income"
msgstr ""
@@ -25594,8 +25639,8 @@ msgstr ""
msgid "Interest and/or dunning fee"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:151
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:249
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:152
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:250
msgid "Interest on Fixed Deposits"
msgstr ""
@@ -25615,7 +25660,7 @@ msgstr ""
msgid "Internal Customer Accounting"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:269
+#: erpnext/selling/doctype/customer/customer.py:270
msgid "Internal Customer for company {0} already exists"
msgstr ""
@@ -25652,6 +25697,7 @@ msgstr ""
#. 'Sales Invoice Item'
#. Label of the internal_transfer_section (Section Break) field in DocType
#. 'Delivery Note Item'
+#: erpnext/accounts/bulk_payment.py:92
#: erpnext/accounts/doctype/payment_entry/payment_entry.json
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -25700,8 +25746,8 @@ msgstr ""
msgid "Interval should be between 1 to 59 MInutes"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:381
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:389
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:391
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:399
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:770
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:780
#: erpnext/accounts/services/taxes.py:271
@@ -25745,7 +25791,7 @@ msgstr ""
msgid "Invalid Barcode. There is no Item attached to this barcode."
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:3269
+#: erpnext/public/js/controllers/transaction.js:3277
msgid "Invalid Blanket Order for the selected Customer and Item"
msgstr ""
@@ -25775,7 +25821,7 @@ msgstr ""
msgid "Invalid Cost Center"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:384
+#: erpnext/selling/doctype/customer/customer.py:385
msgid "Invalid Customer Group"
msgstr ""
@@ -25816,8 +25862,8 @@ msgstr ""
msgid "Invalid File Type"
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:330
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:335
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:374
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:379
msgid "Invalid Formula"
msgstr ""
@@ -25826,11 +25872,11 @@ msgid "Invalid Group By"
msgstr ""
#: erpnext/accounts/doctype/pos_invoice/pos_invoice.py:503
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:52
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:53
msgid "Invalid Item"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1569
+#: erpnext/stock/doctype/item/item.py:1579
msgid "Invalid Item Defaults"
msgstr ""
@@ -25878,7 +25924,7 @@ msgstr ""
msgid "Invalid Priority"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:982
+#: erpnext/manufacturing/doctype/bom/bom.py:983
msgid "Invalid Process Loss Configuration"
msgstr ""
@@ -25886,8 +25932,8 @@ msgstr ""
msgid "Invalid Purchase Invoice"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:254
-#: erpnext/accounts/services/child_item_update.py:267
+#: erpnext/accounts/services/child_item_update.py:259
+#: erpnext/accounts/services/child_item_update.py:272
msgid "Invalid Qty"
msgstr ""
@@ -25899,6 +25945,10 @@ msgstr ""
msgid "Invalid Query"
msgstr ""
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:325
+msgid "Invalid Reading"
+msgstr ""
+
#: erpnext/selling/page/point_of_sale/pos_past_order_summary.js:202
msgid "Invalid Return"
msgstr ""
@@ -25916,7 +25966,7 @@ msgstr ""
msgid "Invalid Selling Price"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:1015
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1046
msgid "Invalid Serial and Batch Bundle"
msgstr ""
@@ -26001,7 +26051,7 @@ msgstr ""
msgid "Invalid status group: {0}"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:1743
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1774
msgid "Invalid subcontract order field: {0}"
msgstr ""
@@ -26244,6 +26294,10 @@ msgstr ""
msgid "Invoice can't be made for zero billing hour"
msgstr ""
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:852
+msgid "Invoice is not blocked. Block the invoice to change the release date."
+msgstr ""
+
#: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html:171
#: erpnext/accounts/report/accounts_payable/accounts_payable.html:139
#: erpnext/accounts/report/accounts_receivable/accounts_receivable.html:140
@@ -26268,8 +26322,8 @@ msgstr ""
#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json
#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
#: erpnext/accounts/doctype/pos_profile/pos_profile.json
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1204
-#: erpnext/accounts/report/accounts_payable/accounts_payable.js:273
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1205
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:289
#: erpnext/buying/doctype/supplier/supplier.json
#: erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py:64
msgid "Invoices"
@@ -27023,7 +27077,7 @@ msgstr ""
#: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:202
#: erpnext/buying/workspace/buying/buying.json
#: erpnext/controllers/taxes_and_totals.py:1290
-#: erpnext/controllers/trends.py:385
+#: erpnext/controllers/trends.py:420
#: erpnext/manufacturing/doctype/blanket_order/blanket_order.json
#: erpnext/manufacturing/doctype/bom/bom.js:1092
#: erpnext/manufacturing/doctype/plant_floor/plant_floor.js:109
@@ -27034,8 +27088,8 @@ msgstr ""
#: erpnext/manufacturing/report/process_loss_report/process_loss_report.js:15
#: erpnext/manufacturing/report/process_loss_report/process_loss_report.py:76
#: erpnext/manufacturing/workspace/manufacturing/manufacturing.json
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:253
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:404
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:242
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:393
#: erpnext/public/js/purchase_trends_filters.js:48
#: erpnext/public/js/purchase_trends_filters.js:63
#: erpnext/public/js/sales_order_proforma.js:116
@@ -27085,7 +27139,7 @@ msgstr ""
#: erpnext/stock/report/stock_analytics/stock_analytics.js:15
#: erpnext/stock/report/stock_analytics/stock_analytics.py:43
#: erpnext/stock/report/stock_balance/stock_balance.py:470
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:287
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:290
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.js:27
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:51
#: erpnext/stock/report/stock_projected_qty/stock_projected_qty.js:28
@@ -27299,7 +27353,7 @@ msgstr ""
#: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
#: erpnext/buying/report/item_wise_purchase_history/item_wise_purchase_history.py:26
#: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:231
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:200
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:223
#: erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/subcontracted_raw_materials_to_be_transferred.py:35
#: erpnext/crm/doctype/opportunity_item/opportunity_item.json
#: erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json
@@ -27334,10 +27388,10 @@ msgstr ""
#: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py:86
#: erpnext/manufacturing/report/work_order_stock_report/work_order_stock_report.py:128
#: erpnext/projects/doctype/timesheet/timesheet.js:216
-#: erpnext/public/js/controllers/transaction.js:2943
+#: erpnext/public/js/controllers/transaction.js:2951
#: erpnext/public/js/stock_reservation.js:112
#: erpnext/public/js/stock_reservation.js:318 erpnext/public/js/utils.js:608
-#: erpnext/public/js/utils.js:765
+#: erpnext/public/js/utils.js:766
#: erpnext/public/js/utils/serial_no_batch_selector.js:96
#: erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
#: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json
@@ -27401,7 +27455,7 @@ msgstr ""
#: erpnext/stock/report/stock_ageing/stock_ageing.py:177
#: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:105
#: erpnext/stock/report/stock_qty_vs_batch_qty/stock_qty_vs_batch_qty.py:25
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:26
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:32
#: erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json
#: erpnext/subcontracting/doctype/subcontracting_inward_order_received_item/subcontracting_inward_order_received_item.json
#: erpnext/subcontracting/doctype/subcontracting_inward_order_secondary_item/subcontracting_inward_order_secondary_item.json
@@ -27431,7 +27485,7 @@ msgstr ""
msgid "Item Code cannot be changed for Serial No."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:448
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:458
msgid "Item Code required at Row No {0}"
msgstr ""
@@ -27554,7 +27608,7 @@ msgstr ""
#: erpnext/buying/report/item_wise_purchase_history/item_wise_purchase_history.js:30
#: erpnext/buying/report/item_wise_purchase_history/item_wise_purchase_history.py:40
#: erpnext/buying/workspace/buying/buying.json
-#: erpnext/controllers/trends.py:398
+#: erpnext/controllers/trends.py:435
#: erpnext/crm/doctype/opportunity_item/opportunity_item.json
#: erpnext/manufacturing/doctype/bom_creator/bom_creator.json
#: erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
@@ -27604,7 +27658,7 @@ msgstr ""
#: erpnext/stock/report/stock_balance/stock_balance.js:32
#: erpnext/stock/report/stock_balance/stock_balance.py:479
#: erpnext/stock/report/stock_ledger/stock_ledger.js:71
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:345
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:348
#: erpnext/stock/report/stock_projected_qty/stock_projected_qty.js:39
#: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:115
#: erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.js:33
@@ -27793,8 +27847,8 @@ msgstr ""
#: erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
#: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
#: erpnext/buying/report/item_wise_purchase_history/item_wise_purchase_history.py:34
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:206
-#: erpnext/controllers/trends.py:386
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:229
+#: erpnext/controllers/trends.py:421
#: erpnext/crm/doctype/opportunity_item/opportunity_item.json
#: erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js:101
#: erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json
@@ -27827,8 +27881,8 @@ msgstr ""
#: erpnext/manufacturing/report/production_planning_report/production_planning_report.py:378
#: 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:2949
-#: erpnext/public/js/utils.js:856
+#: erpnext/public/js/controllers/transaction.js:2957
+#: erpnext/public/js/utils.js:859
#: erpnext/selling/doctype/proforma_invoice_item/proforma_invoice_item.json
#: erpnext/selling/doctype/quotation_item/quotation_item.json
#: erpnext/selling/doctype/sales_order/sales_order.js:1324
@@ -27872,10 +27926,10 @@ msgstr ""
#: erpnext/stock/report/stock_ageing/stock_ageing.py:184
#: erpnext/stock/report/stock_analytics/stock_analytics.py:45
#: erpnext/stock/report/stock_balance/stock_balance.py:477
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:293
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:296
#: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:112
#: erpnext/stock/report/stock_qty_vs_batch_qty/stock_qty_vs_batch_qty.py:31
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:32
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:38
#: erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py:98
#: erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json
#: erpnext/subcontracting/doctype/subcontracting_inward_order_service_item/subcontracting_inward_order_service_item.json
@@ -27934,8 +27988,8 @@ msgstr ""
msgid "Item Price Stock"
msgstr ""
-#: erpnext/stock/get_item_details.py:1177
-#: erpnext/stock/get_item_details.py:1201
+#: erpnext/stock/get_item_details.py:1257
+#: erpnext/stock/get_item_details.py:1281
msgid "Item Price added for {0} in Price List - {1}"
msgstr ""
@@ -27947,7 +28001,7 @@ msgstr ""
msgid "Item Price created at rate {0}"
msgstr ""
-#: erpnext/stock/get_item_details.py:1160
+#: erpnext/stock/get_item_details.py:1240
msgid "Item Price updated for {0} in Price List {1}"
msgstr ""
@@ -28258,11 +28312,11 @@ msgstr ""
msgid "Item for row {0} does not match Material Request"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:902
+#: erpnext/stock/doctype/item/item.py:912
msgid "Item has variants."
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:455
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:444
msgid "Item is mandatory in Raw Materials table."
msgstr ""
@@ -28284,7 +28338,7 @@ msgstr ""
msgid "Item operation"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:676
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:703
msgid "Item rate has been updated to zero as Allow Zero Valuation Rate is checked for item {0}"
msgstr ""
@@ -28307,7 +28361,7 @@ msgstr ""
msgid "Item valuation reposting in progress. Report might show incorrect item valuation."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1059
+#: erpnext/stock/doctype/item/item.py:1069
msgid "Item variant {0} exists with same attributes"
msgstr ""
@@ -28327,7 +28381,7 @@ msgstr ""
msgid "Item {0} cannot be ordered more than once"
msgstr ""
-#: erpnext/manufacturing/doctype/blanket_order/blanket_order.py:197
+#: erpnext/manufacturing/doctype/blanket_order/blanket_order.py:201
msgid "Item {0} cannot be ordered more than {1} against Blanket Order {2}."
msgstr ""
@@ -28337,10 +28391,11 @@ msgstr ""
#: erpnext/assets/doctype/asset/asset.py:347
#: erpnext/stock/doctype/item/item.py:698
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:102
msgid "Item {0} does not exist"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:665
+#: erpnext/manufacturing/doctype/bom/bom.py:666
msgid "Item {0} does not exist in the system or has expired"
msgstr ""
@@ -28353,7 +28408,7 @@ msgstr ""
msgid "Item {0} entered multiple times."
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:222
+#: erpnext/controllers/sales_and_purchase_return.py:240
msgid "Item {0} has already been returned"
msgstr ""
@@ -28369,15 +28424,15 @@ msgstr ""
msgid "Item {0} has no changes in delivered quantity. Please unselect the row if you do not wish to update its quantity."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1281
+#: erpnext/stock/doctype/item/item.py:1291
msgid "Item {0} has reached its end of life on {1}"
msgstr ""
-#: erpnext/stock/stock_ledger.py:168
+#: erpnext/stock/stock_ledger.py:195
msgid "Item {0} ignored since it is not a stock item"
msgstr ""
-#: erpnext/stock/get_item_details.py:357
+#: erpnext/stock/get_item_details.py:437
msgid "Item {0} is a template, please select one of its variants"
msgstr ""
@@ -28385,11 +28440,11 @@ msgstr ""
msgid "Item {0} is already reserved/delivered against Sales Order {1}."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1301
+#: erpnext/stock/doctype/item/item.py:1311
msgid "Item {0} is cancelled"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1285
+#: erpnext/stock/doctype/item/item.py:1295
msgid "Item {0} is disabled"
msgstr ""
@@ -28401,11 +28456,11 @@ msgstr ""
msgid "Item {0} is not a serialized Item"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1293
+#: erpnext/stock/doctype/item/item.py:1303
msgid "Item {0} is not a stock Item"
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:51
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:52
msgid "Item {0} is not a subcontracted item"
msgstr ""
@@ -28413,7 +28468,7 @@ msgstr ""
msgid "Item {0} is not a template item."
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:1311
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1342
msgid "Item {0} is not active or end of life has been reached"
msgstr ""
@@ -28421,7 +28476,7 @@ msgstr ""
msgid "Item {0} must be a Fixed Asset Item"
msgstr ""
-#: erpnext/stock/get_item_details.py:363
+#: erpnext/stock/get_item_details.py:443
msgid "Item {0} must be a Non-Stock Item"
msgstr ""
@@ -28437,10 +28492,14 @@ msgstr ""
msgid "Item {0} not found."
msgstr ""
-#: erpnext/buying/doctype/purchase_order/purchase_order.py:316
+#: erpnext/buying/doctype/purchase_order/purchase_order.py:317
msgid "Item {0}: Ordered qty {1} cannot be less than minimum order qty {2} (defined in Item)."
msgstr ""
+#: erpnext/buying/doctype/purchase_order/purchase_order.py:342
+msgid "Item {0}: Ordered qty {1} {2} exceeds the minimum order qty {3} {2} by {4} {2} due to purchase UOM rounding."
+msgstr ""
+
#: erpnext/manufacturing/doctype/production_plan/production_plan.js:600
msgid "Item {0}: {1} qty produced. "
msgstr ""
@@ -28487,15 +28546,15 @@ msgstr ""
msgid "Item-wise sales Register"
msgstr ""
-#: erpnext/stock/get_item_details.py:762
+#: erpnext/stock/get_item_details.py:842
msgid "Item/Item Code required to get Item Tax Template."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:484
+#: erpnext/manufacturing/doctype/bom/bom.py:485
msgid "Item: {0} does not exist in the system"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:979
+#: erpnext/manufacturing/doctype/bom/bom.py:980
msgid "Item: {0} with Stock UOM: {1} cannot have fractional process loss qty as UOM {2} is a whole number."
msgstr ""
@@ -28515,7 +28574,7 @@ msgstr ""
msgid "Items Filter"
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:218
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:219
#: erpnext/selling/doctype/sales_order/sales_order.js:1757
msgid "Items Required"
msgstr ""
@@ -28534,11 +28593,11 @@ msgstr ""
msgid "Items and Pricing"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:170
+#: erpnext/accounts/services/child_item_update.py:175
msgid "Items cannot be updated as Subcontracting Inward Order(s) exist against this Subcontracted Sales Order."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:162
+#: erpnext/accounts/services/child_item_update.py:167
msgid "Items cannot be updated as Subcontracting Order is created against the Purchase Order {0}."
msgstr ""
@@ -28550,7 +28609,7 @@ msgstr ""
msgid "Items not found."
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:672
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:699
msgid "Items rate has been updated to zero as Allow Zero Valuation Rate is checked for the following items: {0}"
msgstr ""
@@ -28560,7 +28619,7 @@ msgstr ""
msgid "Items to Be Repost"
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:217
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:218
msgid "Items to Manufacture are required to pull the Raw Materials associated with it."
msgstr ""
@@ -28673,7 +28732,7 @@ msgstr ""
msgid "Job Card Secondary Item"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1113
+#: erpnext/public/js/shop_floor/shop_floor.js:1119
msgid "Job Card Submitted"
msgstr ""
@@ -28701,12 +28760,12 @@ msgstr ""
msgid "Job Card {0} has been completed"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1515
+#: erpnext/public/js/shop_floor/shop_floor.js:1521
msgid "Job Card {0} is already running. Open its machine or work order to pause or complete it."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1510
-#: erpnext/public/js/shop_floor/shop_floor.js:1531
+#: erpnext/public/js/shop_floor/shop_floor.js:1516
+#: erpnext/public/js/shop_floor/shop_floor.js:1537
msgid "Job Card {0} is already submitted."
msgstr ""
@@ -28714,7 +28773,7 @@ msgstr ""
msgid "Job Card {0} not found"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1506
+#: erpnext/public/js/shop_floor/shop_floor.js:1512
msgid "Job Card {0} was not found."
msgstr ""
@@ -28788,11 +28847,11 @@ msgstr ""
msgid "Job Worker Warehouse"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/mapper.py:464
+#: erpnext/manufacturing/doctype/work_order/mapper.py:465
msgid "Job card {0} created"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1120
+#: erpnext/public/js/shop_floor/shop_floor.js:1126
msgid "Job card {0} has been submitted."
msgstr ""
@@ -28804,7 +28863,7 @@ msgstr ""
msgid "Job started"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1554
+#: erpnext/public/js/shop_floor/shop_floor.js:1560
msgid "Job {0} is running"
msgstr ""
@@ -29096,7 +29155,7 @@ msgstr ""
#. Name of a DocType
#. Label of a Link in the Stock Workspace
#. Label of a Workspace Sidebar Item
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:671
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:669
#: erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json
#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:88
#: erpnext/stock/workspace/stock/stock.json
@@ -29577,7 +29636,7 @@ msgstr ""
msgid "License Plate"
msgstr ""
-#: erpnext/controllers/status_updater.py:513
+#: erpnext/controllers/status_updater.py:514
msgid "Limit Crossed"
msgstr ""
@@ -29659,7 +29718,7 @@ msgstr ""
msgid "Linked Location"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1135
+#: erpnext/stock/doctype/item/item.py:1145
msgid "Linked with submitted documents"
msgstr ""
@@ -29705,7 +29764,7 @@ msgstr ""
msgid "Loading Invoices! Please Wait..."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:981
+#: erpnext/public/js/shop_floor/shop_floor.js:987
msgid "Loading quality checklist..."
msgstr ""
@@ -29734,8 +29793,8 @@ msgstr ""
msgid "Loan Start Date and Loan Period are mandatory to save the Invoice Discounting"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:180
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:305
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:182
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:310
msgid "Loans (Liabilities)"
msgstr ""
@@ -29780,8 +29839,8 @@ msgstr ""
msgid "Logo"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:187
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:323
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:189
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:328
msgid "Long-term Provisions"
msgstr ""
@@ -29948,7 +30007,7 @@ msgstr ""
#: erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json
#: erpnext/accounts/doctype/loyalty_program/loyalty_program.json
#: erpnext/accounts/doctype/pos_invoice/pos_invoice.json
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1234
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1239
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.json
#: erpnext/selling/doctype/customer/customer.json
#: erpnext/selling/page/point_of_sale/pos_item_cart.js:963
@@ -30035,10 +30094,10 @@ msgstr ""
msgid "Machine operator errors"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:836
-#: erpnext/setup/doctype/company/company.py:851
-#: erpnext/setup/doctype/company/company.py:852
-#: erpnext/setup/doctype/company/company.py:853
+#: erpnext/setup/doctype/company/company.py:854
+#: erpnext/setup/doctype/company/company.py:869
+#: erpnext/setup/doctype/company/company.py:870
+#: erpnext/setup/doctype/company/company.py:871
msgid "Main"
msgstr ""
@@ -30285,8 +30344,6 @@ msgstr ""
#. Label of the make (Data) field in DocType 'Vehicle'
#: erpnext/accounts/doctype/journal_entry/journal_entry.js:272
#: erpnext/manufacturing/doctype/job_card/job_card.js:488
-#: erpnext/manufacturing/doctype/work_order/work_order.js:864
-#: erpnext/manufacturing/doctype/work_order/work_order.js:898
#: erpnext/setup/doctype/vehicle/vehicle.json
msgid "Make"
msgstr ""
@@ -30306,7 +30363,7 @@ msgstr ""
msgid "Make Difference Entry"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1129
+#: erpnext/public/js/shop_floor/shop_floor.js:1135
msgid "Make Manufacture Entry"
msgstr ""
@@ -30389,7 +30446,7 @@ msgstr ""
msgid "Manage your orders"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:614
+#: erpnext/setup/doctype/company/company.py:618
msgid "Management"
msgstr ""
@@ -30425,11 +30482,11 @@ msgstr ""
msgid "Mandatory Missing"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:475
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:485
msgid "Mandatory Purchase Order"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:497
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:507
msgid "Mandatory Purchase Receipt"
msgstr ""
@@ -30504,8 +30561,8 @@ msgstr ""
#: erpnext/stock/doctype/material_request_item/material_request_item.json
#: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
#: erpnext/stock/doctype/stock_entry/stock_entry.json
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:774
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:791
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:803
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:820
#: erpnext/stock/doctype/stock_entry_type/stock_entry_type.json
#: erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
#: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
@@ -30738,7 +30795,7 @@ msgstr ""
msgid "Mapping Subcontracting Order ..."
msgstr ""
-#: erpnext/public/js/utils.js:1087
+#: erpnext/public/js/utils.js:1113
msgid "Mapping {0} ..."
msgstr ""
@@ -30850,7 +30907,7 @@ msgstr ""
msgid "Market Segment"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:566
+#: erpnext/setup/doctype/company/company.py:570
msgid "Marketing"
msgstr ""
@@ -30933,7 +30990,7 @@ msgstr ""
msgid "Material"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:889
+#: erpnext/manufacturing/doctype/work_order/work_order.js:900
msgid "Material Consumption"
msgstr ""
@@ -30941,7 +30998,7 @@ msgstr ""
#. Option for the 'Purpose' (Select) field in DocType 'Stock Entry Type'
#: erpnext/setup/setup_wizard/operations/install_fixtures.py:117
#: erpnext/stock/doctype/stock_entry/stock_entry.json
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:775
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:804
#: erpnext/stock/doctype/stock_entry_type/stock_entry_type.json
msgid "Material Consumption for Manufacture"
msgstr ""
@@ -31020,7 +31077,7 @@ msgstr ""
#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.js:56
#: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.js:33
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:186
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:209
#: erpnext/buying/workspace/buying/buying.json
#: erpnext/manufacturing/doctype/job_card/job_card.js:219
#: erpnext/manufacturing/doctype/production_plan/production_plan.js:185
@@ -31028,15 +31085,16 @@ msgstr ""
#: erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
#: erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
#: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
-#: erpnext/manufacturing/doctype/work_order/work_order.js:825
+#: erpnext/manufacturing/doctype/work_order/work_order.js:830
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1216
#: erpnext/manufacturing/doctype/work_order/work_order.json
#: erpnext/selling/doctype/sales_order/sales_order.js:1130
#: erpnext/selling/doctype/sales_order_item/sales_order_item.json
#: erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py:37
#: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
#: erpnext/stock/doctype/material_request/material_request.json
-#: erpnext/stock/doctype/material_request/material_request.py:476
-#: erpnext/stock/doctype/material_request/material_request.py:493
+#: erpnext/stock/doctype/material_request/material_request.py:506
+#: erpnext/stock/doctype/material_request/material_request.py:523
#: erpnext/stock/doctype/pick_list/pick_list.json
#: erpnext/stock/doctype/pick_list_item/pick_list_item.json
#: erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -31338,9 +31396,9 @@ msgstr ""
msgid "Max discount allowed for item: {0} is {1}%"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1065
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1072
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1095
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1096
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1103
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1126
#: erpnext/stock/doctype/pick_list/pick_list.js:208
#: erpnext/stock/doctype/stock_entry/stock_entry.js:398
msgid "Max: {0}"
@@ -31372,11 +31430,11 @@ msgstr ""
msgid "Maximum Producible Items"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1325
+#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1357
msgid "Maximum Samples - {0} can be retained for Batch {1} and Item {2}."
msgstr ""
-#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1314
+#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1346
msgid "Maximum Samples - {0} have already been retained for Batch {1} and Item {2} in Batch {3}."
msgstr ""
@@ -31412,7 +31470,7 @@ msgstr ""
msgid "Maximum sample quantity that can be retained"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1020
+#: erpnext/public/js/shop_floor/shop_floor.js:1026
msgid "Measured value"
msgstr ""
@@ -31441,7 +31499,7 @@ msgstr ""
msgid "Megawatt"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2221
+#: erpnext/stock/stock_ledger.py:2264
msgid "Mention Valuation Rate in the Item master."
msgstr ""
@@ -31476,7 +31534,7 @@ msgstr ""
msgid "Merge similar Account Heads"
msgstr ""
-#: erpnext/public/js/utils.js:1119
+#: erpnext/public/js/utils.js:1145
msgid "Merge taxes from multiple documents"
msgstr ""
@@ -31869,11 +31927,11 @@ msgstr ""
msgid "Missing Finance Book"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:950
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:981
msgid "Missing Finished Good"
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:315
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:359
msgid "Missing Formula"
msgstr ""
@@ -31917,7 +31975,7 @@ msgstr ""
msgid "Missing required filter: {0}"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:920
+#: erpnext/manufacturing/doctype/bom/bom.py:921
#: erpnext/manufacturing/doctype/work_order/work_order.py:936
msgid "Missing value"
msgstr ""
@@ -32118,7 +32176,7 @@ msgstr ""
msgid "Move Stock"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1453
+#: erpnext/public/js/shop_floor/shop_floor.js:1459
msgid "Move selection"
msgstr ""
@@ -32169,7 +32227,7 @@ msgstr ""
msgid "Multiple Accounts (Journal Template)"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:458
+#: erpnext/selling/doctype/customer/customer.py:459
msgid "Multiple Loyalty Programs found for Customer {0}. Please select manually."
msgstr ""
@@ -32199,7 +32257,7 @@ msgstr ""
msgid "Multiple fiscal years exist for the date {0}. Please set company in Fiscal Year"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:957
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:988
msgid "Multiple items cannot be marked as finished item"
msgstr ""
@@ -32211,7 +32269,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/work_order/work_order.py:883
#: erpnext/setup/doctype/uom/uom.json
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:267
-#: erpnext/utilities/transaction_base.py:627
+#: erpnext/utilities/transaction_base.py:629
msgid "Must be Whole Number"
msgstr ""
@@ -32350,8 +32408,8 @@ msgstr ""
msgid "Negative Stock"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1672
-#: erpnext/stock/serial_batch_bundle.py:1594
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1722
+#: erpnext/stock/serial_batch_bundle.py:1681
msgid "Negative Stock Error"
msgstr ""
@@ -32823,7 +32881,7 @@ msgid "New Task"
msgstr ""
#: erpnext/manufacturing/doctype/bom/bom.js:247
-#: erpnext/selling/doctype/product_bundle/product_bundle.js:17
+#: erpnext/selling/doctype/product_bundle/product_bundle.js:22
msgid "New Version"
msgstr ""
@@ -32836,7 +32894,7 @@ msgstr ""
msgid "New Workplace"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:423
+#: erpnext/selling/doctype/customer/customer.py:424
msgid "New credit limit is less than current outstanding amount for the customer. Credit limit has to be at least {0}"
msgstr ""
@@ -32850,7 +32908,7 @@ msgstr ""
msgid "New issue created: {0}"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:261
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:259
msgid "New release date should be in the future"
msgstr ""
@@ -32947,11 +33005,11 @@ msgstr ""
msgid "No Impact on Accounting Ledger"
msgstr ""
-#: erpnext/stock/get_item_details.py:338
+#: erpnext/stock/get_item_details.py:418
msgid "No Item with Barcode {0}"
msgstr ""
-#: erpnext/stock/get_item_details.py:342
+#: erpnext/stock/get_item_details.py:422
msgid "No Item with Serial No {0}"
msgstr ""
@@ -32987,14 +33045,18 @@ msgstr ""
msgid "No POS Profile found. Please create a New POS Profile first"
msgstr ""
+#: erpnext/manufacturing/doctype/work_order/mapper.py:571
+msgid "No Pending Materials"
+msgstr ""
+
#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1124
#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1200
#: erpnext/accounts/doctype/journal_entry/journal_entry.py:1221
-#: erpnext/stock/doctype/item/item.py:1528
+#: erpnext/stock/doctype/item/item.py:1538
msgid "No Permission"
msgstr ""
-#: erpnext/accounts/bulk_payment.py:24
+#: erpnext/accounts/bulk_payment.py:18
msgid "No Purchase Invoices selected"
msgstr ""
@@ -33010,11 +33072,11 @@ msgstr ""
msgid "No Selection"
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:982
+#: erpnext/controllers/sales_and_purchase_return.py:1000
msgid "No Serial / Batches are available for return"
msgstr ""
-#: erpnext/stock/stock_ledger.py:991
+#: erpnext/stock/stock_ledger.py:1018
msgid "No Standard Valuation Rate found for Item {0} in Company {1} as on {2}. Please create an Item Standard Cost record."
msgstr ""
@@ -33116,7 +33178,7 @@ msgstr ""
msgid "No billing email found for customer: {0}"
msgstr ""
-#: banking/src/components/features/BankReconciliation/CompanySelector.tsx:66
+#: banking/src/components/features/BankReconciliation/CompanySelector.tsx:79
msgid "No company found."
msgstr ""
@@ -33202,7 +33264,7 @@ msgstr ""
msgid "No matches occurred via auto reconciliation"
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:133
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:134
msgid "No material request created"
msgstr ""
@@ -33302,12 +33364,12 @@ msgstr ""
msgid "No open task"
msgstr ""
-#: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py:360
-msgid "No outstanding invoices found"
+#: erpnext/accounts/bulk_payment.py:127
+msgid "No outstanding amount for the selected invoice(s)."
msgstr ""
-#: erpnext/accounts/bulk_payment.py:62
-msgid "No outstanding invoices found for the selected vouchers in account {0}"
+#: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py:360
+msgid "No outstanding invoices found"
msgstr ""
#: erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py:358
@@ -33361,15 +33423,15 @@ msgstr ""
msgid "No records for these settings."
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:776
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:777
msgid "No records found in Allocation table"
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:653
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:654
msgid "No records found in the Invoices table"
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:656
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:657
msgid "No records found in the Payments table"
msgstr ""
@@ -33439,7 +33501,7 @@ msgstr ""
msgid "No vouchers found for this transaction"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1782
+#: erpnext/stock/doctype/item/item.py:1792
msgid "No warehouse found for company {0}. Please set a Default Warehouse in Item Defaults or Company."
msgstr ""
@@ -33488,8 +33550,8 @@ msgstr ""
msgid "Non stock items"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:186
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:322
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:188
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:327
msgid "Non-Current Liabilities"
msgstr ""
@@ -33506,6 +33568,11 @@ msgstr ""
msgid "None of the items have any change in quantity or value."
msgstr ""
+#: erpnext/accounts/bulk_payment.py:22
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:244
+msgid "None of the selected invoices are payable"
+msgstr ""
+
#. Label of the section_normal_balances (Tab Break) field in DocType 'Process
#. Period Closing Voucher'
#: erpnext/accounts/doctype/process_period_closing_voucher/process_period_closing_voucher.json
@@ -33615,6 +33682,10 @@ msgstr ""
msgid "Not authorized to edit frozen Account {0}"
msgstr ""
+#: erpnext/accounts/bulk_payment.py:109
+msgid "Not available"
+msgstr ""
+
#: erpnext/templates/form_grid/stock_entry_grid.html:26
msgid "Not in Stock"
msgstr ""
@@ -33631,6 +33702,10 @@ msgstr ""
msgid "Not permitted to read Job Card"
msgstr ""
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:94
+msgid "Not permitted to update Serial No"
+msgstr ""
+
#: erpnext/manufacturing/doctype/bom_update_log/bom_update_log_list.js:21
msgid "Note: Automatic log deletion only applies to logs of type Update Cost"
msgstr ""
@@ -33645,7 +33720,7 @@ msgstr ""
msgid "Note: Email will not be sent to disabled users"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:769
+#: erpnext/manufacturing/doctype/bom/bom.py:770
msgid "Note: If you want to use the finished good {0} as a raw material, then enable the 'Do Not Explode' checkbox in the Items table against the same raw material."
msgstr ""
@@ -34161,7 +34236,7 @@ msgstr ""
msgid "Only one of Deposit or Withdrawal should be non-zero when applying an Excluded Fee."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:362
+#: erpnext/manufacturing/doctype/bom/bom.py:363
msgid "Only one operation can have 'Is Final Finished Good' checked when 'Track Semi Finished Goods' is enabled."
msgstr ""
@@ -34170,7 +34245,7 @@ msgstr ""
msgid "Only one version of a Product Bundle can be active at a time for a given Parent Item. Activating a version deactivates the previously active one."
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:790
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:819
msgid "Only one {0} entry can be created against the Work Order {1}"
msgstr ""
@@ -34211,6 +34286,10 @@ msgstr ""
msgid "Only {0} are supported"
msgstr ""
+#: erpnext/manufacturing/doctype/work_order/services/required_items.py:227
+msgid "Only {0} {1} of {2} is pending in Work Order {3}."
+msgstr ""
+
#. Label of the open_activities_html (HTML) field in DocType 'Lead'
#. Label of the open_activities_html (HTML) field in DocType 'Opportunity'
#. Label of the open_activities_html (HTML) field in DocType 'Prospect'
@@ -34328,7 +34407,7 @@ msgstr ""
msgid "Open the settings dialog"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1454
+#: erpnext/public/js/shop_floor/shop_floor.js:1460
msgid "Open work order / run primary action"
msgstr ""
@@ -34400,8 +34479,8 @@ msgstr ""
msgid "Opening Balance Details"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:196
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:348
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:198
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:353
msgid "Opening Balance Equity"
msgstr ""
@@ -34488,20 +34567,20 @@ msgstr ""
#. Option for the 'Purpose' (Select) field in DocType 'Stock Reconciliation'
#: erpnext/stock/doctype/item/item.js:986 erpnext/stock/doctype/item/item.json
#: erpnext/stock/doctype/item/item.py:354
-#: erpnext/stock/doctype/item/item.py:1685
+#: erpnext/stock/doctype/item/item.py:1695
#: erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
msgid "Opening Stock"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1639
+#: erpnext/stock/doctype/item/item.py:1649
msgid "Opening Stock can only be set for stock items."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1646
+#: erpnext/stock/doctype/item/item.py:1656
msgid "Opening Stock cannot be created as stock transactions already exist for item {0}."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1642
+#: erpnext/stock/doctype/item/item.py:1652
msgid "Opening Stock for serialised or batch items must be set via the Stock Reconciliation form."
msgstr ""
@@ -34510,7 +34589,7 @@ msgid "Opening Stock reconciliation created with zero valuation rate: {0}"
msgstr ""
#: erpnext/stock/doctype/item/item.py:367
-#: erpnext/stock/doctype/item/item.py:1688
+#: erpnext/stock/doctype/item/item.py:1698
msgid "Opening Stock reconciliation created: {0}"
msgstr ""
@@ -34688,8 +34767,8 @@ msgstr ""
#: erpnext/manufacturing/doctype/bom/bom.json
#: erpnext/manufacturing/doctype/work_order/work_order.js:334
#: erpnext/manufacturing/doctype/work_order/work_order.json
-#: erpnext/public/js/shop_floor/shop_floor.js:387
-#: erpnext/setup/doctype/company/company.py:584
+#: erpnext/public/js/shop_floor/shop_floor.js:391
+#: erpnext/setup/doctype/company/company.py:588
#: erpnext/setup/doctype/email_digest/email_digest.json
#: erpnext/templates/generators/bom.html:61
msgid "Operations"
@@ -34701,7 +34780,7 @@ msgstr ""
msgid "Operations Routing"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:929
+#: erpnext/manufacturing/doctype/bom/bom.py:930
msgid "Operations cannot be left blank"
msgstr ""
@@ -34879,7 +34958,7 @@ msgstr ""
msgid "Optional group warehouse. Raw material availability is checked across its child warehouses; material is still received into For Warehouse."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1042
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1073
msgid "Optional. Select a specific manufacture entry to reverse."
msgstr ""
@@ -34999,8 +35078,8 @@ msgstr ""
#. Label of the ordered_qty (Float) field in DocType 'Sales Order Item'
#. Label of the ordered_qty (Float) field in DocType 'Bin'
#. Label of the ordered_qty (Float) field in DocType 'Packed Item'
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:171
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:240
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:194
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:263
#: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
#: erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
#: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
@@ -35140,7 +35219,7 @@ msgstr ""
#: erpnext/stock/report/available_serial_no/available_serial_no.py:119
#: erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py:83
#: erpnext/stock/report/stock_balance/stock_balance.py:555
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:324
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:327
msgid "Out Qty"
msgstr ""
@@ -35162,7 +35241,7 @@ msgstr ""
msgid "Out of Order"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:672
+#: erpnext/stock/doctype/pick_list/pick_list.py:722
msgid "Out of Stock"
msgstr ""
@@ -35201,7 +35280,7 @@ msgstr ""
#. Label of the outgoing_rate (Currency) field in DocType 'Stock Ledger Entry'
#: erpnext/stock/doctype/serial_and_batch_entry/serial_and_batch_entry.json
#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:378
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:381
msgid "Outgoing Rate"
msgstr ""
@@ -35317,7 +35396,7 @@ msgstr ""
msgid "Over Receipt"
msgstr ""
-#: erpnext/controllers/status_updater.py:518
+#: erpnext/controllers/status_updater.py:519
msgid "Over Receipt/Delivery of {0} {1} ignored for item {2} because you have {3} role."
msgstr ""
@@ -35338,7 +35417,7 @@ msgstr ""
msgid "Overbilling of {0} ignored because you have {1} role."
msgstr ""
-#: erpnext/controllers/status_updater.py:520
+#: erpnext/controllers/status_updater.py:521
msgid "Overbilling of {0} {1} ignored for item {2} because you have {3} role."
msgstr ""
@@ -35375,11 +35454,11 @@ msgstr ""
msgid "Overdue Limit"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:608
+#: erpnext/selling/doctype/customer/customer.py:609
msgid "Overdue Limit Crossed"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:603
+#: erpnext/selling/doctype/customer/customer.py:604
msgid "Overdue Limit crossed for customer {0}. Overdue amount {1} exceeds the allowed limit {2}."
msgstr ""
@@ -35991,7 +36070,7 @@ msgstr ""
msgid "Paid To Account Type"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:331
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:341
#: erpnext/accounts/doctype/sales_invoice/services/pos.py:205
msgid "Paid amount + Write Off Amount can not be greater than Grand Total"
msgstr ""
@@ -36086,7 +36165,7 @@ msgstr ""
msgid "Parent Company"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:719
+#: erpnext/setup/doctype/company/company.py:723
msgid "Parent Company must be a group company"
msgstr ""
@@ -36171,11 +36250,11 @@ msgstr ""
msgid "Parent Task"
msgstr ""
-#: erpnext/projects/doctype/task/task.py:170
+#: erpnext/projects/doctype/task/task.py:171
msgid "Parent Task {0} is not a Template Task"
msgstr ""
-#: erpnext/projects/doctype/task/task.py:193
+#: erpnext/projects/doctype/task/task.py:194
msgid "Parent Task {0} must be a Group Task"
msgstr ""
@@ -36452,7 +36531,7 @@ msgstr ""
#: erpnext/accounts/report/tax_withholding_details/tax_withholding_details.js:25
#: erpnext/accounts/report/tds_computation_summary/tds_computation_summary.js:26
#: erpnext/accounts/report/trial_balance_for_party/trial_balance_for_party.js:57
-#: erpnext/controllers/trends.py:413
+#: erpnext/controllers/trends.py:450
#: erpnext/crm/doctype/appointment/appointment.json
#: erpnext/crm/doctype/opportunity/opportunity.json
#: erpnext/crm/report/lost_opportunity/lost_opportunity.js:55
@@ -36573,7 +36652,7 @@ msgstr ""
#: erpnext/accounts/doctype/payment_request/payment_request.json
#: erpnext/accounts/report/general_ledger/general_ledger.js:111
#: erpnext/accounts/report/general_ledger/general_ledger.py:785
-#: erpnext/controllers/trends.py:419 erpnext/crm/doctype/contract/contract.json
+#: erpnext/controllers/trends.py:456 erpnext/crm/doctype/contract/contract.json
#: erpnext/selling/doctype/party_specific_item/party_specific_item.json
#: erpnext/selling/report/address_and_contacts/address_and_contacts.js:22
msgid "Party Name"
@@ -36768,12 +36847,12 @@ msgstr ""
#: erpnext/accounts/doctype/process_period_closing_voucher/process_period_closing_voucher.js:25
#: erpnext/manufacturing/doctype/job_card_operation/job_card_operation.json
#: erpnext/manufacturing/doctype/workstation/workstation_job_card.html:68
-#: erpnext/public/js/shop_floor/shop_floor.js:1572
+#: erpnext/public/js/shop_floor/shop_floor.js:1578
#: erpnext/public/js/templates/shop_floor_template.html:783
msgid "Pause"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1457
+#: erpnext/public/js/shop_floor/shop_floor.js:1463
msgid "Pause / Resume job"
msgstr ""
@@ -36828,7 +36907,7 @@ msgid "Payable"
msgstr ""
#: erpnext/accounts/report/accounts_payable/accounts_payable.js:50
-#: erpnext/accounts/report/accounts_payable/accounts_payable.js:265
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:281
#: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1165
#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:209
#: erpnext/accounts/report/purchase_register/purchase_register.py:212
@@ -36836,7 +36915,7 @@ msgstr ""
msgid "Payable Account"
msgstr ""
-#: erpnext/accounts/report/accounts_payable/accounts_payable.js:281
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:297
msgid "Payable Amount"
msgstr ""
@@ -36953,6 +37032,10 @@ msgstr ""
msgid "Payment Entries"
msgstr ""
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:367
+msgid "Payment Entries are created as drafts for your review"
+msgstr ""
+
#: erpnext/accounts/utils.py:1161
msgid "Payment Entries {0} are un-linked"
msgstr ""
@@ -37315,7 +37398,7 @@ msgstr ""
msgid "Payment Schedule based Payment Requests cannot be created because a Payment Entry already exists for this document."
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:547
+#: erpnext/public/js/controllers/transaction.js:552
msgid "Payment Schedules"
msgstr ""
@@ -37336,7 +37419,7 @@ msgstr ""
#: erpnext/accounts/report/accounts_receivable/accounts_receivable.py:1218
#: erpnext/accounts/report/gross_profit/gross_profit.py:451
#: erpnext/accounts/workspace/invoicing/invoicing.json
-#: erpnext/public/js/controllers/transaction.js:562
+#: erpnext/public/js/controllers/transaction.js:567
#: erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py:32
msgid "Payment Term"
msgstr ""
@@ -37447,7 +37530,7 @@ msgstr ""
msgid "Payment Unlink Error"
msgstr ""
-#: erpnext/accounts/doctype/journal_entry/services/reference_validator.py:196
+#: erpnext/accounts/doctype/journal_entry/services/reference_validator.py:197
msgid "Payment against {0} {1} cannot be greater than Outstanding Amount {2}"
msgstr ""
@@ -37540,8 +37623,8 @@ msgstr ""
msgid "Payroll Entry"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:160
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:267
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:162
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:272
msgid "Payroll Payable"
msgstr ""
@@ -37609,13 +37692,13 @@ msgstr ""
#: erpnext/buying/report/subcontracted_item_to_be_received/subcontracted_item_to_be_received.py:54
#: erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/subcontracted_raw_materials_to_be_transferred.py:44
#: erpnext/manufacturing/doctype/job_card/job_card.js:292
-#: erpnext/public/js/shop_floor/shop_floor.js:837
+#: erpnext/public/js/shop_floor/shop_floor.js:843
msgid "Pending Quantity"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:72
#: erpnext/manufacturing/doctype/job_card/job_card.js:309
-#: erpnext/public/js/shop_floor/shop_floor.js:853
+#: erpnext/public/js/shop_floor/shop_floor.js:859
msgid "Pending Quantity cannot be greater than {0}"
msgstr ""
@@ -37799,11 +37882,11 @@ msgstr ""
msgid "Period Closing Voucher"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:514
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:633
msgid "Period Closing Voucher {0} GL Entry Cancellation Failed"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:493
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:612
msgid "Period Closing Voucher {0} GL Entry Processing Failed"
msgstr ""
@@ -37823,7 +37906,7 @@ msgstr ""
msgid "Period End Date"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:77
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:81
msgid "Period End Date cannot be greater than Fiscal Year End Date"
msgstr ""
@@ -37865,11 +37948,11 @@ msgstr ""
msgid "Period Start Date"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:74
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:78
msgid "Period Start Date cannot be greater than Period End Date"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:71
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:75
msgid "Period Start Date must be {0}"
msgstr ""
@@ -37971,11 +38054,11 @@ msgid "Phantom BOM cannot be created for stock item {0}."
msgstr ""
#: erpnext/manufacturing/doctype/bom/bom_item_preview.html:16
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:340
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:329
msgid "Phantom Item"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:449
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:438
msgid "Phantom Item is mandatory"
msgstr ""
@@ -38015,6 +38098,8 @@ msgstr ""
#. Reservation Entry'
#. Label of a Link in the Stock Workspace
#. Label of a Workspace Sidebar Item
+#: erpnext/manufacturing/doctype/work_order/work_order.js:822
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1240
#: erpnext/selling/doctype/sales_order/sales_order.js:1066
#: erpnext/stock/doctype/delivery_note/delivery_note.js:199
#: erpnext/stock/doctype/material_request/material_request.js:160
@@ -38027,7 +38112,7 @@ msgstr ""
msgid "Pick List"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:270
+#: erpnext/stock/doctype/pick_list/pick_list.py:309
msgid "Pick List Incomplete"
msgstr ""
@@ -38073,8 +38158,10 @@ msgstr ""
msgid "Pick Serial / Batch No"
msgstr ""
+#. Label of the picked_qty (Float) field in DocType 'Work Order Item'
#. Label of the picked_qty (Float) field in DocType 'Material Request Item'
#. Label of the picked_qty (Float) field in DocType 'Packed Item'
+#: erpnext/manufacturing/doctype/work_order_item/work_order_item.json
#: erpnext/stock/doctype/material_request_item/material_request_item.json
#: erpnext/stock/doctype/packed_item/packed_item.json
msgid "Picked Qty"
@@ -38353,7 +38440,7 @@ msgstr ""
msgid "Plants and Machineries"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:669
+#: erpnext/stock/doctype/pick_list/pick_list.py:719
msgid "Please Restock Items and Update the Pick List to continue. To discontinue, cancel the Pick List."
msgstr ""
@@ -38448,7 +38535,7 @@ msgstr ""
msgid "Please attach CSV file"
msgstr ""
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1263
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1264
msgid "Please cancel and amend the Payment Entry"
msgstr ""
@@ -38510,7 +38597,7 @@ msgstr ""
msgid "Please click on 'Generate Schedule' to get schedule"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1068
+#: erpnext/public/js/shop_floor/shop_floor.js:1074
msgid "Please complete every check before submitting the inspection."
msgstr ""
@@ -38526,11 +38613,11 @@ msgstr ""
msgid "Please contact any of the following users for this transaction."
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:549
+#: erpnext/selling/doctype/customer/customer.py:550
msgid "Please contact any of the following users to extend the credit limits for {0}: {1}"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:542
+#: erpnext/selling/doctype/customer/customer.py:543
msgid "Please contact your administrator to extend the credit limits for {0}."
msgstr ""
@@ -38582,7 +38669,7 @@ msgstr ""
msgid "Please enable Applicable on Purchase Order and Applicable on Booking Actual Expenses"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:321
+#: erpnext/stock/doctype/pick_list/pick_list.py:361
msgid "Please enable Use Old Serial / Batch Fields to make_bundle"
msgstr ""
@@ -38598,11 +38685,11 @@ msgstr ""
msgid "Please enable {0} in {1} to allow same item in multiple rows"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:378
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:388
msgid "Please ensure that the {0} account is a Balance Sheet account. You can change the parent account to a Balance Sheet account or select a different account."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:386
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:396
msgid "Please ensure that the {0} account {1} is a Payable account. You can change the account type to Payable or select a different account."
msgstr ""
@@ -38652,7 +38739,7 @@ msgstr ""
msgid "Please enter Item Code to get Batch Number"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:3126
+#: erpnext/public/js/controllers/transaction.js:3134
msgid "Please enter Item Code to get batch no"
msgstr ""
@@ -38704,7 +38791,7 @@ msgstr ""
msgid "Please enter Warehouse and Date"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:501
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:511
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:964
msgid "Please enter Write Off Account"
msgstr ""
@@ -38714,11 +38801,11 @@ msgstr ""
msgid "Please enter a quantity or amount for at least one item."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:511
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:521
msgid "Please enter a valid Write Off Account"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:522
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:532
msgid "Please enter a valid Write Off Cost Center"
msgstr ""
@@ -38738,7 +38825,7 @@ msgstr ""
msgid "Please enter company name first"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1311
+#: erpnext/controllers/accounts_controller.py:1316
msgid "Please enter default currency in Company Master"
msgstr ""
@@ -38947,7 +39034,7 @@ msgstr ""
msgid "Please select Customer first"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:650
+#: erpnext/setup/doctype/company/company.py:654
msgid "Please select Existing Company for creating Chart of Accounts"
msgstr ""
@@ -38989,7 +39076,7 @@ msgstr ""
msgid "Please select Posting Date first"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:1082
+#: erpnext/manufacturing/doctype/bom/bom.py:1083
msgid "Please select Price List"
msgstr ""
@@ -39013,7 +39100,7 @@ msgstr ""
msgid "Please select Stock Asset Account"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:235
+#: erpnext/setup/doctype/company/company.py:237
msgid "Please select Stock Delivered But Not Billed Account"
msgstr ""
@@ -39027,15 +39114,15 @@ msgstr ""
#: erpnext/accounts/party.py:447
#: erpnext/selling/page/sales_funnel/sales_funnel.py:19
-#: erpnext/stock/doctype/pick_list/pick_list.py:1409
+#: erpnext/stock/doctype/pick_list/pick_list.py:1468
msgid "Please select a Company"
msgstr ""
#: erpnext/accounts/doctype/payment_entry/payment_entry.js:268
#: erpnext/manufacturing/doctype/bom/bom.js:734
-#: erpnext/manufacturing/doctype/bom/bom.py:302
+#: erpnext/manufacturing/doctype/bom/bom.py:303
#: erpnext/public/js/controllers/accounts.js:274
-#: erpnext/public/js/controllers/transaction.js:3425
+#: erpnext/public/js/controllers/transaction.js:3433
msgid "Please select a Company first."
msgstr ""
@@ -39142,6 +39229,10 @@ msgstr ""
msgid "Please select a value for {0} quotation_to {1}"
msgstr ""
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js:9
+msgid "Please select a warehouse first."
+msgstr ""
+
#: erpnext/assets/doctype/asset_repair/asset_repair.js:203
msgid "Please select an item code before setting the warehouse."
msgstr ""
@@ -39174,7 +39265,7 @@ msgstr ""
msgid "Please select at least one row with difference value"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:599
+#: erpnext/public/js/controllers/transaction.js:604
msgid "Please select at least one schedule."
msgstr ""
@@ -39258,11 +39349,11 @@ msgid "Please select weekly off day"
msgstr ""
#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1215
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:649
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:650
msgid "Please select {0} first"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:150
+#: erpnext/public/js/controllers/transaction.js:155
msgid "Please set 'Apply Additional Discount On'"
msgstr ""
@@ -39304,7 +39395,7 @@ msgstr ""
#: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js:58
#: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js:68
#: erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.js:78
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:905
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:910
msgid "Please set Company"
msgstr ""
@@ -39388,7 +39479,7 @@ msgid "Please set a Purchase Price Variance Account for Item {0} or a Default Pu
msgstr ""
#: erpnext/stock/doctype/item/item.py:342
-#: erpnext/stock/doctype/item/item.py:1672
+#: erpnext/stock/doctype/item/item.py:1682
msgid "Please set a Temporary Opening account for company {0} to create an Opening Stock reconciliation."
msgstr ""
@@ -39441,7 +39532,7 @@ msgstr ""
msgid "Please set default Cash or Bank account in Mode of Payments {0}"
msgstr ""
-#: erpnext/accounts/utils.py:2564
+#: erpnext/accounts/utils.py:2589
msgid "Please set default Exchange Gain/Loss Account in Company {0}"
msgstr ""
@@ -39470,7 +39561,7 @@ msgstr ""
msgid "Please set filter based on Item or Warehouse"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1224
+#: erpnext/controllers/accounts_controller.py:1229
msgid "Please set one of the following:"
msgstr ""
@@ -39478,7 +39569,7 @@ msgstr ""
msgid "Please set opening number of booked depreciations"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:2784
+#: erpnext/public/js/controllers/transaction.js:2792
msgid "Please set recurring after saving"
msgstr ""
@@ -39542,7 +39633,7 @@ msgstr ""
msgid "Please set {0} in Company {1} to account for Exchange Gain / Loss"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1295
+#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1327
msgid "Please set {0} in Company {1} to retain samples."
msgstr ""
@@ -39558,13 +39649,13 @@ msgstr ""
msgid "Please share this email with your support team so that they can find and fix the issue."
msgstr ""
-#: erpnext/stock/get_item_details.py:349
+#: erpnext/stock/get_item_details.py:429
msgid "Please specify Company"
msgstr ""
#: erpnext/accounts/doctype/pos_invoice/pos_invoice.js:120
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:430
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:638
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:428
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:643
msgid "Please specify Company to proceed"
msgstr ""
@@ -39589,7 +39680,7 @@ msgstr ""
msgid "Please specify from/to range"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:2640
+#: erpnext/public/js/controllers/transaction.js:2648
msgid "Please specify {0}. It is needed to fetch Item Details."
msgstr ""
@@ -39694,7 +39785,7 @@ msgstr ""
msgid "Post Title Key"
msgstr ""
-#: erpnext/stock/stock_ledger.py:99
+#: erpnext/stock/stock_ledger.py:98
msgid "Post this entry on or after {0}."
msgstr ""
@@ -39820,7 +39911,7 @@ msgstr ""
#: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:88
#: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:25
#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:159
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:155
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:164
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:36
#: erpnext/templates/form_grid/bank_reconciliation_grid.html:6
msgid "Posting Date"
@@ -39837,7 +39928,7 @@ msgstr ""
msgid "Posting Date inheritance for exchange gain / loss"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:1155
+#: erpnext/public/js/controllers/transaction.js:1160
msgid "Posting Date will change to today's date as Edit Posting Date and Time is unchecked. Are you sure want to proceed?"
msgstr ""
@@ -39894,7 +39985,7 @@ msgstr ""
#: erpnext/stock/report/serial_no_ledger/serial_no_ledger.js:63
#: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:26
#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:160
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:160
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:169
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:41
#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
msgid "Posting Time"
@@ -39979,15 +40070,15 @@ msgstr ""
msgid "Pre Sales"
msgstr ""
-#: erpnext/accounts/utils.py:2802
+#: erpnext/accounts/utils.py:2827
msgid "Pre-Submit Warning"
msgstr ""
-#: erpnext/accounts/utils.py:2851
+#: erpnext/accounts/utils.py:2876
msgid "Pre-Submit Warning: Credit Limit"
msgstr ""
-#: erpnext/accounts/utils.py:2863
+#: erpnext/accounts/utils.py:2888
msgid "Pre-Submit Warning: Packed Qty"
msgstr ""
@@ -40025,7 +40116,7 @@ msgstr ""
msgid "Prepaid Expenses"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1159
+#: erpnext/public/js/shop_floor/shop_floor.js:1165
msgid "Preparing stock entry..."
msgstr ""
@@ -40141,7 +40232,7 @@ msgstr ""
msgid "Previous Work Experience"
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:111
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:115
msgid "Previous Year is not closed, please close it first"
msgstr ""
@@ -40264,7 +40355,7 @@ msgstr ""
msgid "Price List Currency"
msgstr ""
-#: erpnext/stock/get_item_details.py:1379
+#: erpnext/stock/get_item_details.py:1459
msgid "Price List Currency not selected"
msgstr ""
@@ -40778,7 +40869,7 @@ msgstr ""
msgid "Process Loss %"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:976
+#: erpnext/manufacturing/doctype/bom/bom.py:977
msgid "Process Loss Percentage cannot be greater than 100"
msgstr ""
@@ -40806,12 +40897,12 @@ msgid "Process Loss Qty"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:323
-#: erpnext/public/js/shop_floor/shop_floor.js:866
+#: erpnext/public/js/shop_floor/shop_floor.js:872
msgid "Process Loss Quantity"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:339
-#: erpnext/public/js/shop_floor/shop_floor.js:882
+#: erpnext/public/js/shop_floor/shop_floor.js:888
msgid "Process Loss Quantity cannot be greater than {0}"
msgstr ""
@@ -41098,7 +41189,7 @@ msgstr ""
#. Label of a Card Break in the Manufacturing Workspace
#: erpnext/manufacturing/doctype/workstation/workstation.json
#: erpnext/manufacturing/workspace/manufacturing/manufacturing.json
-#: erpnext/setup/doctype/company/company.py:590
+#: erpnext/setup/doctype/company/company.py:594
msgid "Production"
msgstr ""
@@ -41360,7 +41451,7 @@ msgstr ""
msgid "Proforma emailed"
msgstr ""
-#: erpnext/projects/doctype/task/task.py:156
+#: erpnext/projects/doctype/task/task.py:157
#, python-format
msgid "Progress % for a task cannot be more than 100."
msgstr ""
@@ -41497,7 +41588,7 @@ msgstr ""
msgid "Project wise Stock Tracking "
msgstr ""
-#: erpnext/controllers/trends.py:561
+#: erpnext/controllers/trends.py:610
msgid "Project-wise data is not available for Quotation"
msgstr ""
@@ -41706,7 +41797,7 @@ msgstr ""
msgid "Providing"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:689
+#: erpnext/setup/doctype/company/company.py:693
msgid "Provisional Account"
msgstr ""
@@ -41786,7 +41877,7 @@ msgstr ""
#: erpnext/accounts/doctype/tax_rule/tax_rule.json
#: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
#: erpnext/projects/doctype/project/project_dashboard.py:16
-#: erpnext/setup/doctype/company/company.py:578 erpnext/setup/install.py:419
+#: erpnext/setup/doctype/company/company.py:582 erpnext/setup/install.py:419
#: erpnext/stock/doctype/item/item.json
#: erpnext/stock/doctype/item/item_list.js:30
#: erpnext/stock/doctype/item_lead_time/item_lead_time.json
@@ -41950,11 +42041,19 @@ msgstr ""
msgid "Purchase Invoice Trends"
msgstr ""
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:328
+msgid "Purchase Invoice can be held after submitting."
+msgstr ""
+
#: erpnext/assets/doctype/asset/asset.py:340
msgid "Purchase Invoice cannot be made against an existing asset {0}"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:918
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:862
+msgid "Purchase Invoice without any outstanding amount cannot be held."
+msgstr ""
+
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:952
msgid "Purchase Invoices"
msgstr ""
@@ -42075,11 +42174,11 @@ msgstr ""
msgid "Purchase Order Pricing Rule"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:471
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:481
msgid "Purchase Order Required"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:466
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:476
msgid "Purchase Order Required for item {0}"
msgstr ""
@@ -42105,11 +42204,11 @@ msgstr ""
msgid "Purchase Order {0} created"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:529
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:539
msgid "Purchase Order {0} is not submitted"
msgstr ""
-#: erpnext/buying/doctype/purchase_order/purchase_order.py:583
+#: erpnext/buying/doctype/purchase_order/purchase_order.py:616
msgid "Purchase Orders"
msgstr ""
@@ -42139,7 +42238,7 @@ msgstr ""
msgid "Purchase Orders to Receive"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1164
+#: erpnext/controllers/accounts_controller.py:1169
msgid "Purchase Orders {0} are unlinked"
msgstr ""
@@ -42174,8 +42273,8 @@ msgstr ""
#. Label of a Workspace Sidebar Item
#: erpnext/accounts/doctype/accounts_settings/accounts_settings.js:62
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:181
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:647
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:657
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:645
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:655
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js:49
#: erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
#: erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py:244
@@ -42235,11 +42334,11 @@ msgstr ""
msgid "Purchase Receipt No"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:493
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:503
msgid "Purchase Receipt Required"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:488
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:498
msgid "Purchase Receipt Required for item {0}"
msgstr ""
@@ -42267,7 +42366,7 @@ msgstr ""
msgid "Purchase Receipt {0} created."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:533
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:543
msgid "Purchase Receipt {0} is not submitted"
msgstr ""
@@ -42481,7 +42580,7 @@ msgstr ""
#: erpnext/accounts/report/gross_profit/gross_profit.py:347
#: erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.json
#: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:242
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:226
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:249
#: erpnext/controllers/trends.py:300 erpnext/controllers/trends.py:312
#: erpnext/controllers/trends.py:317
#: erpnext/crm/doctype/opportunity_item/opportunity_item.json
@@ -42497,13 +42596,13 @@ msgstr ""
#: erpnext/manufacturing/doctype/work_order_item/work_order_item.json
#: erpnext/manufacturing/doctype/workstation/workstation_job_card.html:28
#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:89
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:254
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:352
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:417
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:517
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:243
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:341
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:406
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:506
#: erpnext/public/js/sales_order_proforma.js:123
#: erpnext/public/js/stock_reservation.js:134
-#: erpnext/public/js/stock_reservation.js:336 erpnext/public/js/utils.js:894
+#: erpnext/public/js/stock_reservation.js:336 erpnext/public/js/utils.js:897
#: erpnext/public/js/utils/serial_batch_inline_editor.js:930
#: erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json
#: erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
@@ -42592,7 +42691,7 @@ msgstr ""
#: erpnext/stock/doctype/stock_closing_balance/stock_closing_balance.json
#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:169
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:199
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:208
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:91
msgid "Qty Change"
msgstr ""
@@ -42684,21 +42783,21 @@ msgstr ""
msgid "Qty for which recursion isn't applicable."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1070
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1093
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1101
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1124
msgid "Qty for {0}"
msgstr ""
#. Label of the stock_qty (Float) field in DocType 'Purchase Order Item'
#. Label of the stock_qty (Float) field in DocType 'Delivery Note Item'
#: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:233
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:256
#: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
msgid "Qty in Stock UOM"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:295
-#: erpnext/public/js/shop_floor/shop_floor.js:840
+#: erpnext/public/js/shop_floor/shop_floor.js:846
msgid "Qty left for a later cycle or for another job card."
msgstr ""
@@ -42708,7 +42807,7 @@ msgstr ""
msgid "Qty of Finished Goods Item"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:716
+#: erpnext/stock/doctype/pick_list/pick_list.py:766
msgid "Qty of Finished Goods Item should be greater than 0."
msgstr ""
@@ -42719,7 +42818,7 @@ msgid "Qty of raw materials will be decided based on the qty of the Finished Goo
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:325
-#: erpnext/public/js/shop_floor/shop_floor.js:869
+#: erpnext/public/js/shop_floor/shop_floor.js:875
msgid "Qty scrapped in this cycle, nobody will produce it."
msgstr ""
@@ -42752,14 +42851,14 @@ msgid "Qty to Fetch"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:249
-#: erpnext/public/js/shop_floor/shop_floor.js:794
+#: erpnext/public/js/shop_floor/shop_floor.js:800
msgid "Qty to Manufacture in this Cycle"
msgstr ""
#. Label of the qty (Float) field in DocType 'Production Plan Sub Assembly
#. Item'
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:170
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:261
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:193
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:284
#: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
msgid "Qty to Order"
msgstr ""
@@ -42770,8 +42869,8 @@ msgstr ""
msgid "Qty to Produce"
msgstr ""
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:173
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:254
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:196
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:277
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:541
msgid "Qty to Receive"
msgstr ""
@@ -42840,7 +42939,7 @@ msgstr ""
msgid "Quality Action Resolution"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1038
+#: erpnext/public/js/shop_floor/shop_floor.js:1044
msgid "Quality Check"
msgstr ""
@@ -42929,7 +43028,7 @@ msgstr ""
msgid "Quality Inspection Analysis"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:3049
+#: erpnext/public/js/controllers/transaction.js:3057
msgid "Quality Inspection Not Configured"
msgstr ""
@@ -42988,7 +43087,7 @@ msgstr ""
msgid "Quality Inspection Template"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:988
+#: erpnext/public/js/shop_floor/shop_floor.js:994
msgid "Quality Inspection Template Missing"
msgstr ""
@@ -43002,7 +43101,7 @@ msgstr ""
msgid "Quality Inspection is required for the item {0} before completing the job card {1}"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1085
+#: erpnext/public/js/shop_floor/shop_floor.js:1091
msgid "Quality Inspection {0} is Rejected. Resolve the issue or follow your rejection process before submitting the job card."
msgstr ""
@@ -43014,7 +43113,7 @@ msgstr ""
msgid "Quality Inspection {0} is rejected for the item: {1}"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:446
+#: erpnext/public/js/controllers/transaction.js:451
#: erpnext/stock/doctype/stock_entry/stock_entry.js:206
msgid "Quality Inspection(s)"
msgstr ""
@@ -43024,7 +43123,7 @@ msgstr ""
msgid "Quality Inspections"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:620
+#: erpnext/setup/doctype/company/company.py:624
msgid "Quality Management"
msgstr ""
@@ -43311,7 +43410,9 @@ msgstr ""
msgid "Quantity must be greater than zero"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1652
+#: erpnext/manufacturing/doctype/work_order/mapper.py:563
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1154
+#: erpnext/stock/doctype/item/item.py:1662
msgid "Quantity must be greater than zero."
msgstr ""
@@ -43319,16 +43420,16 @@ msgstr ""
msgid "Quantity must be less than or equal to {0}"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1123
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1159
#: erpnext/stock/doctype/pick_list/pick_list.js:214
msgid "Quantity must not be more than {0}"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:729
+#: erpnext/manufacturing/doctype/bom/bom.py:730
msgid "Quantity required for Item {0} in row {1}"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:673
+#: erpnext/manufacturing/doctype/bom/bom.py:674
#: erpnext/manufacturing/doctype/job_card/job_card.js:391
msgid "Quantity should be greater than 0"
msgstr ""
@@ -43337,7 +43438,7 @@ msgstr ""
msgid "Quantity to Manufacture"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/mapper.py:376
+#: erpnext/manufacturing/doctype/work_order/mapper.py:377
msgid "Quantity to Manufacture can not be zero for the operation {0}"
msgstr ""
@@ -43349,7 +43450,7 @@ msgstr ""
msgid "Quantity to Scan"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:972
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1003
msgid "Quantity {0} should not be greater than allowed quantity {1}"
msgstr ""
@@ -43619,7 +43720,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json
#: erpnext/manufacturing/doctype/work_order_additional_item/work_order_additional_item.json
#: erpnext/manufacturing/doctype/work_order_item/work_order_item.json
-#: erpnext/public/js/utils.js:904
+#: erpnext/public/js/utils.js:907
#: erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
#: erpnext/selling/doctype/proforma_invoice_item/proforma_invoice_item.json
#: erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -43803,7 +43904,7 @@ msgstr ""
msgid "Rate at which this tax is applied"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:516
+#: erpnext/accounts/services/child_item_update.py:545
msgid "Rate of '{0}' items cannot be changed"
msgstr ""
@@ -43902,7 +44003,7 @@ msgstr ""
#. 'Production Plan'
#: erpnext/manufacturing/doctype/production_plan/production_plan.json
#: erpnext/manufacturing/doctype/production_plan/production_plan.py:160
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:180
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:181
msgid "Raw Material Group Warehouse"
msgstr ""
@@ -43951,7 +44052,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/bom/bom.js:1085
#: erpnext/manufacturing/doctype/job_card/job_card.json
#: erpnext/manufacturing/doctype/production_plan/production_plan.json
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:398
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:387
msgid "Raw Materials"
msgstr ""
@@ -44007,7 +44108,7 @@ msgstr ""
msgid "Raw Materials Supplied Cost"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:721
+#: erpnext/manufacturing/doctype/bom/bom.py:722
msgid "Raw Materials cannot be blank."
msgstr ""
@@ -44128,7 +44229,7 @@ msgid "Real Estate"
msgstr ""
#. Label of the hold_comment (Small Text) field in DocType 'Purchase Invoice'
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:285
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:283
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
msgid "Reason For Putting On Hold"
msgstr ""
@@ -44319,8 +44420,8 @@ msgstr ""
#: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:77
#: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
#: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:249
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:172
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:247
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:195
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:270
#: erpnext/buying/report/subcontract_order_summary/subcontract_order_summary.py:135
#: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
#: erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -44578,7 +44679,7 @@ msgstr ""
msgid "Recording URL"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1076
+#: erpnext/public/js/shop_floor/shop_floor.js:1082
msgid "Recording inspection..."
msgstr ""
@@ -44690,7 +44791,7 @@ msgstr ""
msgid "Reference #{0} dated {1}"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:2905
+#: erpnext/public/js/controllers/transaction.js:2913
msgid "Reference Date for Early Payment Discount"
msgstr ""
@@ -44987,15 +45088,15 @@ msgstr ""
#. Label of the release_date (Date) field in DocType 'Purchase Invoice'
#. Label of the release_date (Date) field in DocType 'Supplier'
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:277
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:321
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:275
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:320
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#: erpnext/buying/doctype/supplier/supplier.json
#: erpnext/manufacturing/report/material_requirements_planning_report/material_requirements_planning_report.py:1078
msgid "Release Date"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:322
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:332
msgid "Release date must be in the future"
msgstr ""
@@ -45447,7 +45548,7 @@ msgid "Reposting cannot be started when status is {0}."
msgstr ""
#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:232
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:340
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:349
msgid "Reposting entries created: {0}"
msgstr ""
@@ -45512,7 +45613,7 @@ msgstr ""
msgid "Reqd Qty (BOM)"
msgstr ""
-#: erpnext/public/js/utils.js:920
+#: erpnext/public/js/utils.js:923
msgid "Reqd by date"
msgstr ""
@@ -45607,11 +45708,13 @@ msgstr ""
#. Label of the requested_qty (Float) field in DocType 'Job Card'
#. Label of the requested_qty (Float) field in DocType 'Material Request Plan
#. Item'
+#. Label of the requested_qty (Float) field in DocType 'Work Order Item'
#. Label of the requested_qty (Float) field in DocType 'Sales Order Item'
#. Label of the indented_qty (Float) field in DocType 'Bin'
#. Label of the requested_qty (Float) field in DocType 'Packed Item'
#: erpnext/manufacturing/doctype/job_card/job_card.json
#: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
+#: erpnext/manufacturing/doctype/work_order_item/work_order_item.json
#: erpnext/selling/doctype/sales_order_item/sales_order_item.json
#: erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py:45
#: erpnext/stock/doctype/bin/bin.json
@@ -45648,7 +45751,7 @@ msgstr ""
#: erpnext/buying/doctype/purchase_order/purchase_order.json
#: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
#: erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py:203
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:193
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:216
#: erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
#: erpnext/stock/doctype/material_request/material_request.json
#: erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -45734,7 +45837,7 @@ msgstr ""
msgid "Research"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:626
+#: erpnext/setup/doctype/company/company.py:630
msgid "Research & Development"
msgstr ""
@@ -45777,7 +45880,7 @@ msgstr ""
msgid "Reservation Based On"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:950
+#: erpnext/manufacturing/doctype/work_order/work_order.js:961
#: erpnext/selling/doctype/sales_order/sales_order.js:107
#: erpnext/stock/doctype/pick_list/pick_list.js:158
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:179
@@ -45899,14 +46002,14 @@ msgstr ""
msgid "Reserved Quantity for Production"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2515
+#: erpnext/stock/stock_ledger.py:2558
msgid "Reserved Serial No."
msgstr ""
#. Label of the reserved_stock (Float) field in DocType 'Bin'
#. Name of a report
#: erpnext/manufacturing/doctype/plant_floor/stock_summary_template.html:24
-#: erpnext/manufacturing/doctype/work_order/work_order.js:966
+#: erpnext/manufacturing/doctype/work_order/work_order.js:977
#: erpnext/public/js/stock_reservation.js:236
#: erpnext/selling/doctype/sales_order/sales_order.js:128
#: erpnext/selling/doctype/sales_order/sales_order.js:495
@@ -45917,13 +46020,13 @@ msgstr ""
#: erpnext/stock/report/reserved_stock/reserved_stock.json
#: erpnext/stock/report/stock_balance/stock_balance.py:573
#: erpnext/stock/report/stock_projected_qty/stock_projected_qty.py:207
-#: erpnext/stock/stock_ledger.py:2499
+#: erpnext/stock/stock_ledger.py:2542
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:204
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:332
msgid "Reserved Stock"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2544
+#: erpnext/stock/stock_ledger.py:2587
msgid "Reserved Stock for Batch"
msgstr ""
@@ -46222,8 +46325,8 @@ msgstr ""
msgid "Retain Sample"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:200
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:353
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:202
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:358
msgid "Retained Earnings"
msgstr ""
@@ -46313,6 +46416,10 @@ msgstr ""
msgid "Return Issued"
msgstr ""
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:325
+msgid "Return Purchase Invoice cannot be held."
+msgstr ""
+
#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.js:327
#: erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js:127
msgid "Return Qty"
@@ -46447,8 +46554,8 @@ msgstr ""
msgid "Revaluation Journals"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:201
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:358
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:203
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:363
msgid "Revaluation Surplus"
msgstr ""
@@ -46882,7 +46989,7 @@ msgstr ""
msgid "Routing Name"
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:226
+#: erpnext/controllers/sales_and_purchase_return.py:244
msgid "Row # {0}: Cannot return more than {1} for Item {2}"
msgstr ""
@@ -46920,11 +47027,11 @@ msgstr ""
msgid "Row #{0}: A reorder entry already exists for warehouse {1} with reorder type {2}."
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:334
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:378
msgid "Row #{0}: Acceptance Criteria Formula is incorrect."
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:314
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:358
msgid "Row #{0}: Acceptance Criteria Formula is required."
msgstr ""
@@ -46998,27 +47105,27 @@ msgstr ""
msgid "Row #{0}: Cannot create entry with different taxable AND withholding document links."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:397
+#: erpnext/accounts/services/child_item_update.py:426
msgid "Row #{0}: Cannot delete item {1} which has already been billed."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:371
+#: erpnext/accounts/services/child_item_update.py:400
msgid "Row #{0}: Cannot delete item {1} which has already been delivered"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:390
+#: erpnext/accounts/services/child_item_update.py:419
msgid "Row #{0}: Cannot delete item {1} which has already been received"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:377
+#: erpnext/accounts/services/child_item_update.py:406
msgid "Row #{0}: Cannot delete item {1} which has work order assigned to it."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:383
+#: erpnext/accounts/services/child_item_update.py:412
msgid "Row #{0}: Cannot delete item {1} which is already ordered against this Sales Order."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:526
+#: erpnext/accounts/services/child_item_update.py:555
msgid "Row #{0}: Cannot set Rate if the billed amount is greater than the amount for Item {1}."
msgstr ""
@@ -47157,7 +47264,7 @@ msgstr ""
msgid "Row #{0}: Finished Good Item is not specified for service item {1}"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:371
+#: erpnext/manufacturing/doctype/bom/bom.py:372
msgid "Row #{0}: Finished Good Item {1} cannot be added in the Secondary Items table."
msgstr ""
@@ -47166,7 +47273,7 @@ msgstr ""
msgid "Row #{0}: Finished Good Item {1} must be a sub-contracted item"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:403
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:412
msgid "Row #{0}: Finished Good must be {1}"
msgstr ""
@@ -47199,7 +47306,7 @@ msgstr ""
msgid "Row #{0}: From Time and To Time fields are required"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:689
+#: erpnext/stock/doctype/pick_list/pick_list.py:739
msgid "Row #{0}: Item Code is Mandatory"
msgstr ""
@@ -47357,7 +47464,7 @@ msgstr ""
msgid "Row #{0}: Please use a different Finance Book."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:378
+#: erpnext/manufacturing/doctype/bom/bom.py:379
#, python-format
msgid "Row #{0}: Process Loss Percentage should be less than 100% for {1} Item {2}"
msgstr ""
@@ -47379,15 +47486,15 @@ msgstr ""
msgid "Row #{0}: Qty should be less than or equal to Available Qty to Reserve (Actual Qty - Reserved Qty) {1} for Item {2} against Batch {3} in Warehouse {4}."
msgstr ""
-#: erpnext/stock/services/quality_inspection_service.py:113
+#: erpnext/stock/services/quality_inspection_service.py:129
msgid "Row #{0}: Quality Inspection is required for Item {1}"
msgstr ""
-#: erpnext/stock/services/quality_inspection_service.py:128
+#: erpnext/stock/services/quality_inspection_service.py:144
msgid "Row #{0}: Quality Inspection {1} is not submitted for the item: {2}"
msgstr ""
-#: erpnext/stock/services/quality_inspection_service.py:143
+#: erpnext/stock/services/quality_inspection_service.py:159
msgid "Row #{0}: Quality Inspection {1} was rejected for item {2}"
msgstr ""
@@ -47399,6 +47506,10 @@ msgstr ""
msgid "Row #{0}: Quantity for Item {1} cannot be zero."
msgstr ""
+#: erpnext/crm/doctype/opportunity/opportunity.py:151
+msgid "Row #{0}: Quantity must be greater than 0 for Item {1}"
+msgstr ""
+
#: erpnext/controllers/subcontracting_inward_controller.py:544
msgid "Row #{0}: Quantity of Item {1} cannot be more than {2} {3} against Subcontracting Inward Order {4}"
msgstr ""
@@ -47413,6 +47524,10 @@ msgstr ""
msgid "Row #{0}: Rate must be same as {1}: {2} ({3} / {4})"
msgstr ""
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:316
+msgid "Row #{0}: Reading {1} {2} is not a valid number in the {3} number format. Use {4} as the decimal separator."
+msgstr ""
+
#: erpnext/accounts/doctype/payment_entry/payment_entry.js:1247
msgid "Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry"
msgstr ""
@@ -47525,7 +47640,7 @@ msgstr ""
msgid "Row #{0}: Start Time must be before End Time"
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:215
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:218
msgid "Row #{0}: Status is mandatory"
msgstr ""
@@ -47578,7 +47693,7 @@ msgstr ""
msgid "Row #{0}: The batch {1} has already expired."
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:417
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:426
msgid "Row #{0}: The job card item reference is missing. Kindly create the stock entry from the job card. If you have added the row manually then you won't be able to add job card item reference."
msgstr ""
@@ -47634,6 +47749,10 @@ msgstr ""
msgid "Row #{0}: item {1} has been picked already."
msgstr ""
+#: erpnext/stock/doctype/pick_list/pick_list.py:274
+msgid "Row #{0}: picked qty {1} {2} exceeds the pending qty in Material Request {3}."
+msgstr ""
+
#: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:142
#: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:207
msgid "Row #{0}: {1}"
@@ -47647,7 +47766,7 @@ msgstr ""
msgid "Row #{0}: {1} can not be negative for item {2}"
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:327
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:371
msgid "Row #{0}: {1} is not a valid reading field. Please refer to the field description."
msgstr ""
@@ -47659,7 +47778,7 @@ msgstr ""
msgid "Row #{0}: {1} of {2} should be {3}. Please update the {1} or select a different account."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1560
+#: erpnext/stock/doctype/item/item.py:1570
msgid "Row #{0}: {1} {2} does not belong to Company {3}. Please select valid {4}."
msgstr ""
@@ -47667,7 +47786,7 @@ msgstr ""
msgid "Row #{0}: {1} {2} does not exist."
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:251
+#: erpnext/accounts/services/child_item_update.py:256
msgid "Row #{0}:Quantity for Item {1} cannot be zero."
msgstr ""
@@ -47711,7 +47830,7 @@ msgstr ""
msgid "Row #{}: Please assign task to a member."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:437
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:447
msgid "Row No {0}: Warehouse is required. Please set a Default Warehouse for Item {1} and Company {2}"
msgstr ""
@@ -47719,7 +47838,7 @@ msgstr ""
msgid "Row {0} : Operation is required against the raw material item {1}"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:267
+#: erpnext/stock/doctype/pick_list/pick_list.py:306
msgid "Row {0} picked quantity is less than the required quantity, additional {1} {2} required."
msgstr ""
@@ -47747,19 +47866,19 @@ msgstr ""
msgid "Row {0}: Advance against Supplier must be debit"
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:770
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:771
msgid "Row {0}: Allocated amount {1} must be less than or equal to invoice outstanding amount {2}"
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:762
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:763
msgid "Row {0}: Allocated amount {1} must be less than or equal to remaining payment amount {2}"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:769
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:798
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:595
+#: erpnext/stock/doctype/material_request/material_request.py:625
msgid "Row {0}: Bill of Materials not found for the Item {1}"
msgstr ""
@@ -47892,7 +48011,7 @@ msgstr ""
msgid "Row {0}: Item {1}'s quantity cannot be higher than the available quantity."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:949
+#: erpnext/manufacturing/doctype/bom/bom.py:950
msgid "Row {0}: Operation time should be greater than 0 for operation {1}"
msgstr ""
@@ -47973,7 +48092,7 @@ msgid "Row {0}: Qty must be greater than 0."
msgstr ""
#: erpnext/manufacturing/doctype/blanket_order/blanket_order.py:124
-msgid "Row {0}: Quantity cannot be negative."
+msgid "Row {0}: Quantity must be greater than zero."
msgstr ""
#: erpnext/accounts/doctype/sales_invoice/services/timesheet_billing.py:24
@@ -48036,7 +48155,7 @@ msgstr ""
msgid "Row {0}: Warehouse {1} is linked to company {2}. Please select a warehouse belonging to company {3}."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:943
+#: erpnext/manufacturing/doctype/bom/bom.py:944
#: erpnext/manufacturing/doctype/work_order/work_order.py:489
msgid "Row {0}: Workstation or Workstation Type is mandatory for an operation {1}"
msgstr ""
@@ -48073,7 +48192,7 @@ msgstr ""
msgid "Row {0}: {2} Item {1} does not exist in {2} {3}"
msgstr ""
-#: erpnext/utilities/transaction_base.py:622
+#: erpnext/utilities/transaction_base.py:624
msgid "Row {1}: Quantity ({0}) cannot be a fraction. To allow this, disable '{2}' in UOM {3}."
msgstr ""
@@ -48245,7 +48364,7 @@ msgstr ""
msgid "SLA Paused On"
msgstr ""
-#: erpnext/public/js/utils.js:1280
+#: erpnext/public/js/utils.js:1306
msgid "SLA is on hold since {0}"
msgstr ""
@@ -48327,8 +48446,8 @@ msgstr ""
#. Option for the 'Order Type' (Select) field in DocType 'Quotation'
#. Option for the 'Order Type' (Select) field in DocType 'Sales Order'
#. Label of the sales_details (Tab Break) field in DocType 'Item'
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:146
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:243
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:147
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:244
#: erpnext/accounts/doctype/item_tax_template/item_tax_template_dashboard.py:9
#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json
#: erpnext/accounts/doctype/payment_term/payment_term_dashboard.py:8
@@ -48337,13 +48456,13 @@ msgstr ""
#: erpnext/accounts/doctype/tax_category/tax_category_dashboard.py:9
#: erpnext/accounts/doctype/tax_rule/tax_rule.json
#: erpnext/crm/doctype/opportunity/opportunity.js:288
-#: erpnext/crm/doctype/opportunity/opportunity.py:157
+#: erpnext/crm/doctype/opportunity/opportunity.py:167
#: erpnext/projects/doctype/project/project_dashboard.py:15
#: erpnext/regional/report/vat_audit_report/vat_audit_report.py:143
#: erpnext/selling/doctype/quotation/quotation.json
#: erpnext/selling/doctype/sales_order/sales_order.json
-#: erpnext/setup/doctype/company/company.py:572
-#: erpnext/setup/doctype/company/company.py:765
+#: erpnext/setup/doctype/company/company.py:576
+#: erpnext/setup/doctype/company/company.py:769
#: erpnext/setup/doctype/company/company_dashboard.py:9
#: erpnext/setup/doctype/sales_person/sales_person_dashboard.py:12
#: erpnext/setup/install.py:414
@@ -48358,7 +48477,7 @@ msgstr ""
msgid "Sales & Purchase"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:765
+#: erpnext/setup/doctype/company/company.py:769
msgid "Sales Account"
msgstr ""
@@ -49196,22 +49315,22 @@ msgstr ""
#. Label of the sample_retention_warehouse (Link) field in DocType 'Company'
#: erpnext/setup/doctype/company/company.json
-#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1296
+#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1328
msgid "Sample Retention Warehouse"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1298
+#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1330
msgid "Sample Retention Warehouse Missing"
msgstr ""
#. Label of the sample_size (Float) field in DocType 'Quality Inspection'
#: erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py:93
-#: erpnext/public/js/controllers/transaction.js:2962
+#: erpnext/public/js/controllers/transaction.js:2970
#: erpnext/stock/doctype/quality_inspection/quality_inspection.json
msgid "Sample Size"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1281
+#: erpnext/stock/doctype/stock_entry/services/manufacturing.py:1313
msgid "Sample quantity {0} cannot be more than received quantity {1}"
msgstr ""
@@ -49221,7 +49340,7 @@ msgstr ""
msgid "Sanctioned"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:965
+#: erpnext/public/js/shop_floor/shop_floor.js:971
msgid "Save & Continue"
msgstr ""
@@ -49235,7 +49354,7 @@ msgstr ""
msgid "Save the currently opened form"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:926
+#: erpnext/public/js/shop_floor/shop_floor.js:932
msgid "Saving job card..."
msgstr ""
@@ -49292,7 +49411,7 @@ msgid "Scan Batch Nos"
msgstr ""
#: erpnext/public/js/shop_floor/shop_floor.js:88
-#: erpnext/public/js/shop_floor/shop_floor.js:1476
+#: erpnext/public/js/shop_floor/shop_floor.js:1482
msgid "Scan Job Card"
msgstr ""
@@ -49317,7 +49436,7 @@ msgstr ""
msgid "Scan barcode for item {0}"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1450
+#: erpnext/public/js/shop_floor/shop_floor.js:1456
msgid "Scan job card"
msgstr ""
@@ -49325,7 +49444,7 @@ msgstr ""
msgid "Scan mode enabled, existing quantity will not be fetched."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1479
+#: erpnext/public/js/shop_floor/shop_floor.js:1485
msgid "Scan or enter Job Card"
msgstr ""
@@ -49352,7 +49471,7 @@ msgstr ""
msgid "Schedule Date"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:556
+#: erpnext/public/js/controllers/transaction.js:561
msgid "Schedule Name"
msgstr ""
@@ -49537,7 +49656,7 @@ msgstr ""
msgid "Search by item code, serial number or barcode"
msgstr ""
-#: banking/src/components/features/BankReconciliation/CompanySelector.tsx:64
+#: banking/src/components/features/BankReconciliation/CompanySelector.tsx:77
msgid "Search company..."
msgstr ""
@@ -49550,7 +49669,7 @@ msgstr ""
msgid "Search values..."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1448
+#: erpnext/public/js/shop_floor/shop_floor.js:1454
msgid "Search work orders"
msgstr ""
@@ -49635,8 +49754,8 @@ msgstr ""
msgid "Secretary"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:181
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:306
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:183
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:311
msgid "Secured Loans"
msgstr ""
@@ -49779,7 +49898,7 @@ msgstr ""
msgid "Select Items based on Delivery Date"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:2997
+#: erpnext/public/js/controllers/transaction.js:3005
msgid "Select Items for Quality Inspection"
msgstr ""
@@ -49804,7 +49923,7 @@ msgstr ""
msgid "Select Job Worker Address"
msgstr ""
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1231
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1236
#: erpnext/selling/page/point_of_sale/pos_item_cart.js:966
msgid "Select Loyalty Program"
msgstr ""
@@ -49813,7 +49932,7 @@ msgstr ""
msgid "Select Operation Row"
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:542
+#: erpnext/public/js/controllers/transaction.js:547
msgid "Select Payment Schedule"
msgstr ""
@@ -49821,7 +49940,7 @@ msgstr ""
msgid "Select Possible Supplier"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1129
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1165
#: erpnext/stock/doctype/pick_list/pick_list.js:224
msgid "Select Quantity"
msgstr ""
@@ -49918,7 +50037,7 @@ msgstr ""
msgid "Select a company"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:449
+#: erpnext/public/js/shop_floor/shop_floor.js:455
msgid "Select a machine or work order to begin"
msgstr ""
@@ -49973,7 +50092,7 @@ msgstr ""
msgid "Select date"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1332
+#: erpnext/controllers/accounts_controller.py:1337
msgid "Select finance book for the item {0} at row {1}"
msgstr ""
@@ -50009,7 +50128,7 @@ msgstr ""
msgid "Select the Default Workstation where the Operation will be performed. This will be fetched in BOMs and Work Orders."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1242
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1294
msgid "Select the Item to be manufactured."
msgstr ""
@@ -50191,7 +50310,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:254
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:259
#: erpnext/workspace_sidebar/erpnext_settings.json
msgid "Selling Settings"
msgstr ""
@@ -50254,7 +50373,7 @@ msgid "Send Proforma Invoice"
msgstr ""
#. Label of the send_sms (Button) field in DocType 'SMS Center'
-#: erpnext/public/js/controllers/transaction.js:746
+#: erpnext/public/js/controllers/transaction.js:751
#: erpnext/selling/doctype/sms_center/sms_center.json
msgid "Send SMS"
msgstr ""
@@ -50443,7 +50562,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.json
#: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.js:74
#: erpnext/manufacturing/report/cost_of_poor_quality_report/cost_of_poor_quality_report.py:114
-#: erpnext/public/js/controllers/transaction.js:2975
+#: erpnext/public/js/controllers/transaction.js:2983
#: erpnext/public/js/utils/serial_batch_inline_editor.js:928
#: erpnext/public/js/utils/serial_no_batch_selector.js:433
#: erpnext/selling/doctype/installation_note_item/installation_note_item.json
@@ -50465,7 +50584,7 @@ msgstr ""
#: erpnext/stock/report/serial_no_and_batch_traceability/serial_no_and_batch_traceability.py:450
#: erpnext/stock/report/serial_no_ledger/serial_no_ledger.js:38
#: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:61
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:426
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:429
#: erpnext/stock/workspace/stock/stock.json
#: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
#: erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
@@ -50493,7 +50612,7 @@ msgstr ""
msgid "Serial No Bundle is mandatory for Item {0}"
msgstr ""
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:33
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:39
msgid "Serial No Count"
msgstr ""
@@ -50511,7 +50630,7 @@ msgstr ""
msgid "Serial No Range"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2783
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2833
msgid "Serial No Reserved"
msgstr ""
@@ -50568,7 +50687,7 @@ msgstr ""
msgid "Serial No and Batch Traceability"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1244
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1294
msgid "Serial No is mandatory"
msgstr ""
@@ -50576,6 +50695,10 @@ msgstr ""
msgid "Serial No is mandatory for Item {0}"
msgstr ""
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:111
+msgid "Serial No status sync has been queued. Reload the report after a few minutes."
+msgstr ""
+
#: erpnext/public/js/utils/serial_batch_inline_editor.js:724
msgid "Serial No {0} already added"
msgstr ""
@@ -50598,7 +50721,7 @@ msgstr ""
#: erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py:52
#: erpnext/selling/doctype/installation_note/installation_note.py:84
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3649
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:3699
msgid "Serial No {0} does not exist"
msgstr ""
@@ -50614,7 +50737,7 @@ msgstr ""
msgid "Serial No {0} is already assigned to customer {1}. Can only be returned against the customer {1}"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:484
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:534
msgid "Serial No {0} is not present in the {1} {2}, hence you can't return it against the {1} {2}"
msgstr ""
@@ -50653,11 +50776,11 @@ msgstr ""
msgid "Serial Nos / Batches"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2045
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2095
msgid "Serial Nos are created successfully"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2505
+#: erpnext/stock/stock_ledger.py:2548
msgid "Serial Nos are reserved in Stock Reservation Entries, you need to unreserve them before proceeding."
msgstr ""
@@ -50731,22 +50854,22 @@ msgstr ""
#: erpnext/stock/report/available_serial_no/available_serial_no.py:188
#: erpnext/stock/report/incorrect_serial_and_batch_bundle/incorrect_serial_and_batch_bundle.py:31
#: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:82
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:410
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:188
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:413
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:197
#: erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
#: erpnext/workspace_sidebar/stock.json
msgid "Serial and Batch Bundle"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1153
+#: erpnext/stock/doctype/item/item.py:1163
msgid "Serial and Batch Bundle Exists"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2282
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2332
msgid "Serial and Batch Bundle created"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2378
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2428
msgid "Serial and Batch Bundle updated"
msgstr ""
@@ -50754,12 +50877,12 @@ msgstr ""
msgid "Serial and Batch Bundle {0} is already used in {1} {2}."
msgstr ""
-#: erpnext/stock/serial_batch_bundle.py:394
+#: erpnext/stock/serial_batch_bundle.py:395
msgid "Serial and Batch Bundle {0} is not submitted"
msgstr ""
#: erpnext/stock/doctype/serial_and_batch_bundle/inline_editor.py:173
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2352
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2402
msgid "Serial and Batch Bundle {0} is submitted and its entries cannot be modified."
msgstr ""
@@ -51020,12 +51143,12 @@ msgid "Service Stop Date"
msgstr ""
#: erpnext/accounts/deferred_revenue.py:45
-#: erpnext/public/js/controllers/transaction.js:1827
+#: erpnext/public/js/controllers/transaction.js:1835
msgid "Service Stop Date cannot be after Service End Date"
msgstr ""
#: erpnext/accounts/deferred_revenue.py:42
-#: erpnext/public/js/controllers/transaction.js:1824
+#: erpnext/public/js/controllers/transaction.js:1832
msgid "Service Stop Date cannot be before Service Start Date"
msgstr ""
@@ -51095,11 +51218,11 @@ msgstr ""
msgid "Set Landed Cost Based on Purchase Invoice Rate"
msgstr ""
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1243
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1248
msgid "Set Loyalty Program"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:315
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js:314
msgid "Set New Release Date"
msgstr ""
@@ -51239,11 +51362,11 @@ msgstr ""
msgid "Set closing balance as per bank statement"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:662
+#: erpnext/setup/doctype/company/company.py:666
msgid "Set default inventory account for perpetual inventory"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:688
+#: erpnext/setup/doctype/company/company.py:692
msgid "Set default {0} account for non stock items"
msgstr ""
@@ -51275,7 +51398,7 @@ msgstr ""
msgid "Set targets Item Group-wise for this Sales Person."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1299
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1351
msgid "Set the Planned Start Date (an Estimated Date at which you want the Production to begin)"
msgstr ""
@@ -51385,7 +51508,7 @@ msgstr ""
msgid "Setting up company"
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:919
+#: erpnext/manufacturing/doctype/bom/bom.py:920
#: erpnext/manufacturing/doctype/work_order/work_order.py:935
msgid "Setting {0} is required"
msgstr ""
@@ -51786,8 +51909,8 @@ msgstr ""
msgid "Short-term Investments"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:179
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:301
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:181
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:306
msgid "Short-term Provisions"
msgstr ""
@@ -51829,7 +51952,7 @@ msgstr ""
msgid "Show Dimension Wise Stock"
msgstr ""
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js:29
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js:53
msgid "Show Disabled Items"
msgstr ""
@@ -52036,7 +52159,7 @@ msgstr ""
msgid "Show taxes as table in print"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1447
+#: erpnext/public/js/shop_floor/shop_floor.js:1453
msgid "Show this help"
msgstr ""
@@ -52148,11 +52271,11 @@ msgstr ""
msgid "Since there are active depreciable assets under this category, the following accounts are required.
"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:511
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:520
msgid "Since there is a process loss of {0} units for the finished good {1}, you should reduce the quantity by {0} units for the finished good {1} in the Items Table."
msgstr ""
-#: erpnext/manufacturing/doctype/bom/bom.py:355
+#: erpnext/manufacturing/doctype/bom/bom.py:356
msgid "Since you have enabled 'Track Semi Finished Goods', at least one operation must have 'Is Final Finished Good' checked. For that set the FG / Semi FG Item as {0} against an operation."
msgstr ""
@@ -52263,7 +52386,7 @@ msgstr ""
msgid "Solvency Ratios"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1613
+#: erpnext/controllers/accounts_controller.py:1618
msgid "Some required Company details are missing. You don't have permission to update them. Please contact your System Manager."
msgstr ""
@@ -52327,7 +52450,7 @@ msgstr ""
msgid "Source Location"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1039
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1070
msgid "Source Manufacture Entry"
msgstr ""
@@ -52336,7 +52459,7 @@ msgstr ""
msgid "Source Stock Entry (Manufacture)"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:531
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:540
msgid "Source Stock Entry {0} belongs to Work Order {1}, not {2}. Please use a manufacture entry from the same Work Order."
msgstr ""
@@ -52415,8 +52538,8 @@ msgstr ""
msgid "Source and target warehouse must be different"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:156
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:259
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:158
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:264
msgid "Source of Funds (Liabilities)"
msgstr ""
@@ -52677,7 +52800,7 @@ msgstr ""
msgid "Start / Resume"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1456
+#: erpnext/public/js/shop_floor/shop_floor.js:1462
msgid "Start / Resume job"
msgstr ""
@@ -52694,7 +52817,7 @@ msgid "Start Date should be lower than End Date"
msgstr ""
#: erpnext/manufacturing/doctype/job_card/job_card.js:670
-#: erpnext/public/js/shop_floor/shop_floor.js:710
+#: erpnext/public/js/shop_floor/shop_floor.js:716
#: erpnext/public/js/templates/shop_floor_template.html:728
msgid "Start Job"
msgstr ""
@@ -52745,10 +52868,6 @@ msgstr ""
msgid "Start date should be less than end date for task {0}"
msgstr ""
-#: erpnext/accounts/bulk_payment.py:39
-msgid "Started a background job to create {0} Grouped Payment Entries"
-msgstr ""
-
#: erpnext/utilities/bulk_transaction.py:42
msgid "Started a background job to create {1} {0}. {2}"
msgstr ""
@@ -52845,7 +52964,7 @@ msgstr ""
msgid "Status must be one of {0}"
msgstr ""
-#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:280
+#: erpnext/stock/doctype/quality_inspection/quality_inspection.py:283
msgid "Status set to rejected as there are one or more rejected readings."
msgstr ""
@@ -52962,11 +53081,27 @@ msgstr ""
msgid "Stock Closing Entry"
msgstr ""
-#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:78
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:242
+msgid "Stock Closing Entry In Progress"
+msgstr ""
+
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:260
+msgid "Stock Closing Entry Outdated"
+msgstr ""
+
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:234
+msgid "Stock Closing Entry Required"
+msgstr ""
+
+#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:120
msgid "Stock Closing Entry {0} already exists for the selected date range"
msgstr ""
-#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:99
+#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:142
+msgid "Stock Closing Entry {0} belongs to a closed accounting period. Cancel the Period Closing Voucher {1} first."
+msgstr ""
+
+#: erpnext/stock/doctype/stock_closing_entry/stock_closing_entry.py:157
msgid "Stock Closing Entry {0} has been queued for processing, the system will take some time to complete it."
msgstr ""
@@ -52984,7 +53119,7 @@ msgstr ""
msgid "Stock Delivered But Not Billed"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:222
+#: erpnext/setup/doctype/company/company.py:224
msgid "Stock Delivered But Not Billed Account cannot be changed or disabled since account {0} contains outstanding Delivery Notes: {1}"
msgstr ""
@@ -53085,6 +53220,10 @@ msgstr ""
msgid "Stock Expenses"
msgstr ""
+#: erpnext/stock/stock_ledger.py:125
+msgid "Stock Frozen"
+msgstr ""
+
#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:37
#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:60
msgid "Stock In Hand"
@@ -53118,7 +53257,7 @@ msgstr ""
#. Name of a DocType
#: erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
#: erpnext/stock/report/fifo_queue_vs_qty_after_transaction_comparison/fifo_queue_vs_qty_after_transaction_comparison.py:113
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:149
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:158
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:30
msgid "Stock Ledger Entry"
msgstr ""
@@ -53154,8 +53293,8 @@ msgstr ""
msgid "Stock Levels HTML"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:164
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:278
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:166
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:283
msgid "Stock Liabilities"
msgstr ""
@@ -53243,7 +53382,7 @@ msgstr ""
#: erpnext/stock/doctype/material_request_item/material_request_item.json
#: erpnext/stock/report/item_where_used/item_where_used.py:76
#: erpnext/stock/report/stock_qty_vs_batch_qty/stock_qty_vs_batch_qty.py:34
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:34
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:40
msgid "Stock Qty"
msgstr ""
@@ -53260,8 +53399,8 @@ msgstr ""
#. Option for the 'Account Type' (Select) field in DocType 'Account'
#. Label of the stock_received_but_not_billed (Link) field in DocType 'Company'
#: erpnext/accounts/doctype/account/account.json
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:165
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:279
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:167
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:284
#: erpnext/accounts/report/account_balance/account_balance.js:59
#: erpnext/setup/doctype/company/company.json
msgid "Stock Received But Not Billed"
@@ -53317,9 +53456,9 @@ msgstr ""
#: erpnext/manufacturing/doctype/production_plan/production_plan.js:315
#: erpnext/manufacturing/doctype/production_plan/production_plan.js:323
#: erpnext/manufacturing/doctype/production_plan/production_plan.js:329
-#: erpnext/manufacturing/doctype/work_order/work_order.js:952
-#: erpnext/manufacturing/doctype/work_order/work_order.js:961
-#: erpnext/manufacturing/doctype/work_order/work_order.js:968
+#: erpnext/manufacturing/doctype/work_order/work_order.js:963
+#: erpnext/manufacturing/doctype/work_order/work_order.js:972
+#: erpnext/manufacturing/doctype/work_order/work_order.js:979
#: erpnext/manufacturing/doctype/work_order/work_order_dashboard.py:14
#: erpnext/public/js/stock_reservation.js:12
#: erpnext/selling/doctype/sales_order/sales_order.js:109
@@ -53340,9 +53479,9 @@ msgstr ""
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1737
#: erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py:1754
#: erpnext/stock/doctype/stock_settings/stock_settings.json
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:211
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:223
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:237
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:216
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:228
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:242
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:181
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:194
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:206
@@ -53508,7 +53647,7 @@ msgstr ""
#: erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
#: erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
#: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:215
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:238
#: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:214
#: erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
#: erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
@@ -53538,7 +53677,7 @@ msgstr ""
#: erpnext/stock/report/item_where_used/item_where_used.py:82
#: erpnext/stock/report/reserved_stock/reserved_stock.py:110
#: erpnext/stock/report/stock_balance/stock_balance.py:510
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:295
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:298
#: erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json
#: erpnext/subcontracting/doctype/subcontracting_inward_order_received_item/subcontracting_inward_order_received_item.json
#: erpnext/subcontracting/doctype/subcontracting_inward_order_secondary_item/subcontracting_inward_order_secondary_item.json
@@ -53561,7 +53700,7 @@ msgstr ""
msgid "Stock Uom"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:594
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:604
msgid "Stock Update Not Allowed"
msgstr ""
@@ -53636,6 +53775,10 @@ msgstr ""
msgid "Stock Value"
msgstr ""
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:189
+msgid "Stock Value Mismatch"
+msgstr ""
+
#. Label of a chart in the Stock Workspace
#: erpnext/stock/workspace/stock/stock.json
msgid "Stock Value by Item Group"
@@ -53677,7 +53820,7 @@ msgstr ""
msgid "Stock cannot be updated because the invoice contains a drop shipping item. Please disable 'Update Stock' or remove the drop shipping item."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:591
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:601
msgid "Stock cannot be updated for Purchase Invoice {0} because a Purchase Receipt {1} has already been created for this transaction. Please disable the 'Update Stock' checkbox in the Purchase Invoice and save the invoice."
msgstr ""
@@ -53710,12 +53853,20 @@ msgstr ""
msgid "Stock transactions before {0} are frozen"
msgstr ""
+#: erpnext/stock/stock_ledger.py:119
+msgid "Stock transactions dated on or before {0} are frozen because the period is closed and the Stock Closing Entry {1} has been generated. To make changes, cancel the Period Closing Voucher first."
+msgstr ""
+
#. Description of the 'Freeze stocks older than (days)' (Int) field in DocType
#. 'Stock Settings'
#: erpnext/stock/doctype/stock_settings/stock_settings.json
msgid "Stock transactions that are older than the mentioned days cannot be modified."
msgstr ""
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:257
+msgid "Stock transactions were created or modified after the Stock Closing Entry {0} was generated. Regenerate it before submitting the Period Closing Voucher."
+msgstr ""
+
#. Description of the 'Auto reserve Stock for Sales Order on Purchase' (Check)
#. field in DocType 'Stock Settings'
#: erpnext/stock/doctype/stock_settings/stock_settings.json
@@ -53741,10 +53892,10 @@ msgstr ""
msgid "Stopped Work Order cannot be cancelled, Unstop it first to cancel"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:493
-#: erpnext/setup/doctype/company/company.py:525
+#: erpnext/setup/doctype/company/company.py:497
+#: erpnext/setup/doctype/company/company.py:529
#: erpnext/stock/doctype/item/item.py:330
-#: erpnext/stock/doctype/item/item.py:1776
+#: erpnext/stock/doctype/item/item.py:1786
msgid "Stores"
msgstr ""
@@ -53773,7 +53924,7 @@ msgstr ""
msgid "Sub Assemblies & Raw Materials"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:340
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:329
msgid "Sub Assembly Item"
msgstr ""
@@ -53789,7 +53940,7 @@ msgstr ""
msgid "Sub Assembly Item Reference"
msgstr ""
-#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:449
+#: erpnext/public/js/bom_configurator/bom_configurator.bundle.js:438
msgid "Sub Assembly Item is mandatory"
msgstr ""
@@ -54137,7 +54288,7 @@ msgstr ""
msgid "Submit Generated Invoices"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1049
+#: erpnext/public/js/shop_floor/shop_floor.js:1055
msgid "Submit Inspection"
msgstr ""
@@ -54147,11 +54298,11 @@ msgstr ""
msgid "Submit Journal entries"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1460
+#: erpnext/public/js/shop_floor/shop_floor.js:1466
msgid "Submit focused job card"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1143
+#: erpnext/public/js/shop_floor/shop_floor.js:1149
msgid "Submit job card {0}? This finalizes the job card."
msgstr ""
@@ -54167,8 +54318,8 @@ msgstr ""
msgid "Submitted Job Card cannot be processed."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:936
-#: erpnext/public/js/shop_floor/shop_floor.js:1148
+#: erpnext/public/js/shop_floor/shop_floor.js:942
+#: erpnext/public/js/shop_floor/shop_floor.js:1154
msgid "Submitting job card..."
msgstr ""
@@ -54208,11 +54359,11 @@ msgstr ""
msgid "Subscription End Date"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:443
+#: erpnext/accounts/doctype/subscription/subscription.py:446
msgid "Subscription End Date is mandatory to follow calendar months"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:433
+#: erpnext/accounts/doctype/subscription/subscription.py:436
msgid "Subscription End Date must be after {0} as per the subscription plan"
msgstr ""
@@ -54269,7 +54420,7 @@ msgstr ""
msgid "Subscription Start Date"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:849
+#: erpnext/accounts/doctype/subscription/subscription.py:852
msgid "Subscription for Future dates cannot be processed."
msgstr ""
@@ -54298,7 +54449,7 @@ msgstr ""
msgid "Successful"
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:611
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:612
msgid "Successfully Reconciled"
msgstr ""
@@ -54454,7 +54605,7 @@ msgstr ""
#: erpnext/accounts/doctype/supplier_item/supplier_item.json
#: erpnext/accounts/doctype/tax_rule/tax_rule.json
#: erpnext/accounts/report/accounts_payable/accounts_payable.html:113
-#: erpnext/accounts/report/accounts_payable/accounts_payable.js:257
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:273
#: erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.html:112
#: erpnext/accounts/report/accounts_payable_summary/accounts_payable_summary.html:134
#: erpnext/accounts/report/billed_items_to_be_received/billed_items_to_be_received.py:60
@@ -54486,7 +54637,7 @@ msgstr ""
#: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.js:51
#: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:195
#: erpnext/buying/workspace/buying/buying.json
-#: erpnext/controllers/trends.py:478 erpnext/crm/doctype/contract/contract.json
+#: erpnext/controllers/trends.py:529 erpnext/crm/doctype/contract/contract.json
#: erpnext/manufacturing/doctype/blanket_order/blanket_order.json
#: erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
#: erpnext/public/js/purchase_trends_filters.js:50
@@ -54613,7 +54764,7 @@ msgstr ""
#: erpnext/buying/doctype/supplier/supplier.json
#: erpnext/buying/report/item_wise_purchase_history/item_wise_purchase_history.py:107
#: erpnext/buying/workspace/buying/buying.json
-#: erpnext/controllers/trends.py:486 erpnext/controllers/trends.py:507
+#: erpnext/controllers/trends.py:537 erpnext/controllers/trends.py:556
#: erpnext/public/js/purchase_trends_filters.js:51
#: erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
#: erpnext/regional/report/irs_1099/irs_1099.js:26
@@ -54665,7 +54816,7 @@ msgstr ""
msgid "Supplier Invoice No"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:815
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:825
msgid "Supplier Invoice No exists in Purchase Invoice {0}"
msgstr ""
@@ -54715,7 +54866,7 @@ msgstr ""
#: erpnext/buying/doctype/supplier/supplier.json
#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
#: erpnext/buying/report/item_wise_purchase_history/item_wise_purchase_history.py:101
-#: erpnext/controllers/trends.py:484
+#: erpnext/controllers/trends.py:535
#: erpnext/manufacturing/doctype/blanket_order/blanket_order.json
#: erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
#: erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -54743,7 +54894,7 @@ msgstr ""
msgid "Supplier Numbers"
msgstr ""
-#: erpnext/accounts/report/accounts_payable/accounts_payable.js:293
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:310
msgid "Supplier Overview"
msgstr ""
@@ -55013,7 +55164,7 @@ msgstr ""
msgid "Switch Between Payment Modes"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1451
+#: erpnext/public/js/shop_floor/shop_floor.js:1457
msgid "Switch Board / Operator view"
msgstr ""
@@ -55021,7 +55172,7 @@ msgstr ""
msgid "Switch between light, dark, or system theme"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1452
+#: erpnext/public/js/shop_floor/shop_floor.js:1458
msgid "Switch board tab"
msgstr ""
@@ -55037,6 +55188,10 @@ msgstr ""
msgid "Sync Now"
msgstr ""
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js:6
+msgid "Sync Serial No Status"
+msgstr ""
+
#: erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js:36
msgid "Sync Started"
msgstr ""
@@ -55102,7 +55257,7 @@ msgstr ""
msgid "TDS Deducted"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:292
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:297
msgid "TDS Payable"
msgstr ""
@@ -55950,7 +56105,7 @@ msgstr ""
msgid "Template Item"
msgstr ""
-#: erpnext/stock/get_item_details.py:358
+#: erpnext/stock/get_item_details.py:438
msgid "Template Item Selected"
msgstr ""
@@ -56170,8 +56325,8 @@ msgstr ""
#: erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py:22
#: erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py:259
#: erpnext/accounts/report/sales_register/sales_register.py:223
-#: erpnext/controllers/trends.py:421 erpnext/controllers/trends.py:447
-#: erpnext/controllers/trends.py:522 erpnext/crm/doctype/lead/lead.json
+#: erpnext/controllers/trends.py:458 erpnext/controllers/trends.py:492
+#: erpnext/controllers/trends.py:571 erpnext/crm/doctype/lead/lead.json
#: erpnext/crm/doctype/opportunity/opportunity.json
#: erpnext/crm/doctype/prospect/prospect.json
#: erpnext/crm/report/lead_details/lead_details.js:46
@@ -56274,11 +56429,11 @@ msgstr ""
msgid "The Batch No {0} has not been supplied against the {1} {2}"
msgstr ""
-#: erpnext/stock/serial_batch_bundle.py:1591
+#: erpnext/stock/serial_batch_bundle.py:1678
msgid "The Batch {0} has negative batch quantity {1}. To fix this, go to the batch and click on Recalculate Batch Qty. If the issue still persists, create an inward entry."
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1656
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1706
msgid "The Batch {0} of 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 the batch {0} or in the 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."
msgstr ""
@@ -56298,15 +56453,15 @@ msgstr ""
msgid "The Excluded Fee is bigger than the Deposit it is deducted from."
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:190
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:309
msgid "The GL Entries and closing balances will be processed in the background, it can take a few minutes."
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:466
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:585
msgid "The GL Entries will be cancelled in the background, it can take a few minutes."
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1222
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1272
msgid "The Item {0} does not have Serial No or Batch No"
msgstr ""
@@ -56322,7 +56477,7 @@ msgstr ""
msgid "The Payment Term at row {0} is possibly a duplicate."
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:345
+#: erpnext/stock/doctype/pick_list/pick_list.py:385
msgid "The Pick List having Stock Reservation Entries cannot be updated. If you need to make changes, we recommend canceling the existing Stock Reservation Entries before updating the Pick List."
msgstr ""
@@ -56330,7 +56485,7 @@ msgstr ""
msgid "The Process Loss Qty has been reset as per the Job Card's Process Loss Qty"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:1437
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1468
msgid "The Process Loss Qty has been reset as per the job card's Process Loss Qty"
msgstr ""
@@ -56342,7 +56497,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:2780
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:2830
msgid "The Serial No {0} is reserved against the {1} {2} and cannot be used for any other transaction."
msgstr ""
@@ -56350,10 +56505,14 @@ msgstr ""
msgid "The Serial Nos {0} have not been supplied against the {1} {2}"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:1012
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1043
msgid "The Serial and Batch Bundle {0} is not valid for this transaction. The 'Type of Transaction' should be 'Outward' instead of 'Inward' in Serial and Batch Bundle {0}"
msgstr ""
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:239
+msgid "The Stock Closing Entry for {0} is not completed yet. Wait for it to complete before submitting the Period Closing Voucher."
+msgstr ""
+
#: erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.js:17
msgid "The Stock Entry of type 'Manufacture' is known as backflush. Raw materials being consumed to manufacture finished goods is known as backflushing.
When creating Manufacture Entry, raw-material items are backflushed based on BOM of production item. If you want raw-material items to be backflushed based on Material Transfer entry made against that Work Order instead, then you can set it under this field."
msgstr ""
@@ -56398,6 +56557,10 @@ msgstr ""
msgid "The batch {0} is reserved for {1} in the warehouse {2} and the remaining quantity is not enough to cover the reservations. So, cannot proceed with the {3} {4}."
msgstr ""
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:182
+msgid "The closing balance {0} of the Stock Asset accounts does not match the closing value {1} of the Stock Balance report as on {2}. Resolve the difference using the Stock Ledger Variance report before closing the period."
+msgstr ""
+
#: erpnext/regional/report/vat_audit_report/vat_audit_report.py:41
msgid "The company {0} is not in South Africa. VAT Audit Report is only available for companies in South Africa."
msgstr ""
@@ -56430,7 +56593,7 @@ msgstr ""
msgid "The date of the transaction"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1247
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1299
msgid "The default BOM for that item will be fetched by the system. You can also change the BOM."
msgstr ""
@@ -56467,7 +56630,7 @@ msgstr ""
msgid "The field {0} in row {1} is not set"
msgstr ""
-#: erpnext/stock/stock_ledger.py:475
+#: erpnext/stock/stock_ledger.py:502
msgid "The field {0} is required for reposting"
msgstr ""
@@ -56504,7 +56667,7 @@ msgstr ""
msgid "The following assets have failed to automatically post depreciation entries: {0}"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:309
+#: erpnext/stock/doctype/pick_list/pick_list.py:349
msgid "The following batches are expired, please restock them:
{0}"
msgstr ""
@@ -56512,7 +56675,7 @@ msgstr ""
msgid "The following cancelled repost entries exist for {0}:
{1}
Kindly delete these entries before continuing."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:956
+#: erpnext/stock/doctype/item/item.py:966
msgid "The following deleted attributes exist in Variants but not in the Template. You can either delete the Variants or keep the attribute(s) in template."
msgstr ""
@@ -56538,7 +56701,7 @@ msgstr ""
msgid "The following vouchers are not submitted: {0}"
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:605
+#: erpnext/stock/doctype/material_request/material_request.py:635
msgid "The following {0} were created: {1}"
msgstr ""
@@ -56678,7 +56841,7 @@ msgstr ""
msgid "The reference number of the transaction"
msgstr ""
-#: erpnext/public/js/utils.js:988
+#: erpnext/public/js/utils.js:1014
msgid "The reserved stock will be released when you update items. Are you certain you wish to proceed?"
msgstr ""
@@ -56735,7 +56898,7 @@ msgstr ""
msgid "The shares don't exist with the {0}"
msgstr ""
-#: erpnext/stock/stock_ledger.py:971
+#: erpnext/stock/stock_ledger.py:998
msgid "The stock for the item {0} in the {1} warehouse was negative on the {2}. You should create a positive entry {3} before the date {4} and time {5} to post the correct valuation rate. For more details, please read the documentation."
msgstr ""
@@ -56769,11 +56932,11 @@ msgstr ""
msgid "The task has been enqueued as a background job. In case there is any issue on processing in background, the system will add a comment about the error on this Stock Reconciliation and revert to the Submitted stage"
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:391
+#: erpnext/stock/doctype/material_request/material_request.py:408
msgid "The total Issue / Transfer quantity {0} in Material Request {1} cannot be greater than allowed requested quantity {2} for Item {3}"
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:398
+#: erpnext/stock/doctype/material_request/material_request.py:415
msgid "The total Issue / Transfer quantity {0} in Material Request {1} cannot be greater than requested quantity {2} for Item {3}"
msgstr ""
@@ -56817,15 +56980,15 @@ msgstr ""
msgid "The warehouse account(s) below are not of type 'Stock'. Please set a correct Stock asset account on the warehouse (Account Type must be 'Stock'):"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1275
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1327
msgid "The warehouse where you store finished Items before they are shipped."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1268
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1320
msgid "The warehouse where you store your raw materials. Each required item can have a separate source warehouse. Group warehouse also can be selected as source warehouse. On submission of the Work Order, the raw materials will be reserved in these warehouses for production usage."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1280
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1332
msgid "The warehouse where your Items will be transferred when you begin production. Group Warehouse can also be selected as a Work in Progress warehouse."
msgstr ""
@@ -56833,7 +56996,7 @@ msgstr ""
msgid "The withdrawal or deposit amounts - only required if there's no amount column."
msgstr ""
-#: erpnext/public/js/controllers/transaction.js:3465
+#: erpnext/public/js/controllers/transaction.js:3473
msgid "The {0} contains Unit Price Items."
msgstr ""
@@ -56841,7 +57004,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:611
+#: erpnext/stock/doctype/material_request/material_request.py:641
msgid "The {0} {1} created successfully"
msgstr ""
@@ -56849,7 +57012,7 @@ msgstr ""
msgid "The {0} {1} does not match with the {0} {2} in the {3} {4}"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1796
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1846
msgid "The {0} {1} is in submitted state, please cancel it first"
msgstr ""
@@ -56938,7 +57101,7 @@ msgstr ""
msgid "There is one unreconciled transaction before {0}."
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:949
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:980
msgid "There must be at least 1 Finished Good in this Stock Entry"
msgstr ""
@@ -57058,7 +57221,7 @@ msgstr ""
msgid "This covers all scorecards tied to this Setup"
msgstr ""
-#: erpnext/controllers/status_updater.py:502
+#: erpnext/controllers/status_updater.py:503
msgid "This document is over limit by {0} {1} for item {4}. Are you making another {3} against the same {2}?"
msgstr ""
@@ -57161,7 +57324,7 @@ msgstr ""
msgid "This is done to handle accounting for cases when Purchase Receipt is created after Purchase Invoice"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1261
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1313
msgid "This is enabled by default. If you want to plan materials for sub-assemblies of the Item you're manufacturing leave this enabled. If you plan and manufacture the sub-assemblies separately, you can disable this checkbox."
msgstr ""
@@ -57208,7 +57371,7 @@ msgstr ""
msgid "This link is valid for {0} minutes"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:699
+#: erpnext/public/js/shop_floor/shop_floor.js:705
msgid "This machine can run at most {0} job(s) in parallel. Pause or complete a running job before starting another."
msgstr ""
@@ -57226,7 +57389,7 @@ msgstr ""
msgid "This module is scheduled for deprecation and will be completely removed in version 17, please use Frappe Helpdesk instead."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:990
+#: erpnext/public/js/shop_floor/shop_floor.js:996
msgid "This operation requires a Quality Inspection but no template with parameters is configured. Set a Quality Inspection Template on Operation {0} to inspect from the Shop Floor."
msgstr ""
@@ -57375,6 +57538,10 @@ msgstr ""
msgid "This will restrict user access to other employee records"
msgstr ""
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js:16
+msgid "This will update the warehouse and status of Serial Nos counted in {0} to match the stock ledger. Continue?"
+msgstr ""
+
#: erpnext/controllers/selling_controller.py:901
msgid "This {0} will be treated as material transfer."
msgstr ""
@@ -57835,15 +58002,15 @@ msgstr ""
msgid "To add subcontracted Item's raw materials if include exploded items is disabled."
msgstr ""
-#: erpnext/controllers/status_updater.py:495
+#: erpnext/controllers/status_updater.py:496
msgid "To allow over billing, update \"Over Billing Allowance\" in Accounts Settings or the Item."
msgstr ""
-#: erpnext/controllers/status_updater.py:489
+#: erpnext/controllers/status_updater.py:490
msgid "To allow over ordering, update \"Over Order Allowance\" in Buying Settings."
msgstr ""
-#: erpnext/controllers/status_updater.py:491
+#: erpnext/controllers/status_updater.py:492
msgid "To allow over receipt / delivery, update \"Over Receipt/Delivery Allowance\" in Stock Settings or the Item."
msgstr ""
@@ -57910,11 +58077,11 @@ msgstr ""
msgid "To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings."
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:468
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:478
msgid "To submit the invoice without purchase order please set {0} as {1} in {2}"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:490
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:500
msgid "To submit the invoice without purchase receipt please set {0} as {1} in {2}"
msgstr ""
@@ -58834,7 +59001,7 @@ msgstr ""
msgid "Total allocated percentage for sales team should be 100"
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:203
+#: erpnext/selling/doctype/customer/customer.py:204
msgid "Total contribution percentage should be equal to 100"
msgstr ""
@@ -58997,7 +59164,7 @@ msgstr ""
msgid "Transaction Dates"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:1187
+#: erpnext/setup/doctype/company/company.py:1205
msgid "Transaction Deletion Document {0} has been triggered for company {1}"
msgstr ""
@@ -59276,7 +59443,7 @@ msgstr ""
msgid "Transfer and Issue"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1459
+#: erpnext/public/js/shop_floor/shop_floor.js:1465
msgid "Transfer materials"
msgstr ""
@@ -59436,7 +59603,7 @@ msgstr ""
msgid "Trial Period End Date"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:413
+#: erpnext/accounts/doctype/subscription/subscription.py:416
msgid "Trial Period End Date Cannot be before Trial Period Start Date"
msgstr ""
@@ -59445,7 +59612,7 @@ msgstr ""
msgid "Trial Period Start Date"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:419
+#: erpnext/accounts/doctype/subscription/subscription.py:422
msgid "Trial Period Start date cannot be after Subscription Start Date"
msgstr ""
@@ -59621,7 +59788,7 @@ msgstr ""
#: erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
#: erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
#: erpnext/buying/report/item_wise_purchase_history/item_wise_purchase_history.py:60
-#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:209
+#: erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py:232
#: erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py:210
#: erpnext/crm/doctype/opportunity_item/opportunity_item.json
#: erpnext/manufacturing/doctype/bom_creator/bom_creator.json
@@ -59637,7 +59804,7 @@ msgstr ""
#: erpnext/manufacturing/doctype/work_order_additional_item/work_order_additional_item.json
#: erpnext/manufacturing/report/bom_explorer/bom_explorer.py:90
#: erpnext/manufacturing/report/bom_operations_time/bom_operations_time.py:110
-#: erpnext/public/js/stock_analytics.js:94 erpnext/public/js/utils.js:865
+#: erpnext/public/js/stock_analytics.js:94 erpnext/public/js/utils.js:868
#: 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
@@ -59733,7 +59900,7 @@ msgstr ""
msgid "UOM Conversion Factor"
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:532
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:541
msgid "UOM Conversion factor ({0} -> {1}) not found for item: {2}"
msgstr ""
@@ -59752,7 +59919,7 @@ msgstr ""
msgid "UOM Name"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:1768
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:1799
msgid "UOM conversion factor required for UOM: {0} in Item: {1}"
msgstr ""
@@ -59932,7 +60099,7 @@ msgstr ""
msgid "Unit Of Measure"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:516
+#: erpnext/accounts/services/child_item_update.py:545
msgid "Unit Price"
msgstr ""
@@ -60093,7 +60260,7 @@ msgstr ""
msgid "Unreconciled Transactions"
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:959
+#: erpnext/manufacturing/doctype/work_order/work_order.js:970
#: erpnext/selling/doctype/sales_order/sales_order.js:122
#: erpnext/stock/doctype/pick_list/pick_list.js:166
#: erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.js:192
@@ -60133,8 +60300,8 @@ msgstr ""
msgid "Unscheduled"
msgstr ""
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:182
-#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:310
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py:184
+#: erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py:315
msgid "Unsecured Loans"
msgstr ""
@@ -60295,7 +60462,7 @@ msgstr ""
#: erpnext/buying/doctype/purchase_order/purchase_order.js:300
#: erpnext/buying/doctype/supplier_quotation/supplier_quotation.js:43
-#: erpnext/public/js/utils.js:967
+#: erpnext/public/js/utils.js:993
#: erpnext/selling/doctype/quotation/quotation.js:136
#: erpnext/selling/doctype/sales_order/sales_order.js:90
#: erpnext/selling/doctype/sales_order/sales_order.js:984
@@ -60393,11 +60560,11 @@ msgstr ""
msgid "Updating Costing and Billing fields against this Project..."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1544
+#: erpnext/stock/doctype/item/item.py:1554
msgid "Updating Variants..."
msgstr ""
-#: erpnext/manufacturing/doctype/work_order/work_order.js:1223
+#: erpnext/manufacturing/doctype/work_order/work_order.js:1275
msgid "Updating Work Order status"
msgstr ""
@@ -60405,7 +60572,7 @@ msgstr ""
msgid "Updating details."
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1197
+#: erpnext/public/js/shop_floor/shop_floor.js:1203
msgid "Updating job card..."
msgstr ""
@@ -60975,7 +61142,7 @@ msgstr ""
msgid "Valuation Method"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1077
+#: erpnext/stock/doctype/item/item.py:1087
msgid "Valuation Method cannot be changed to or from 'Standard Cost' for {0} because stock transactions already exist for it."
msgstr ""
@@ -61031,15 +61198,15 @@ msgstr ""
msgid "Valuation Rate (In / Out)"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2224
+#: erpnext/stock/stock_ledger.py:2267
msgid "Valuation Rate Missing"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1655
+#: erpnext/stock/doctype/item/item.py:1665
msgid "Valuation Rate cannot be negative."
msgstr ""
-#: erpnext/stock/stock_ledger.py:2202
+#: erpnext/stock/stock_ledger.py:2245
msgid "Valuation Rate for the Item {0}, is required to do accounting entries for {1} {2}."
msgstr ""
@@ -61207,7 +61374,7 @@ msgstr ""
msgid "Variant"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:971
+#: erpnext/stock/doctype/item/item.py:981
msgid "Variant Attribute Error"
msgstr ""
@@ -61226,7 +61393,7 @@ msgstr ""
msgid "Variant Based On"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:999
+#: erpnext/stock/doctype/item/item.py:1009
msgid "Variant Based On cannot be changed"
msgstr ""
@@ -61244,7 +61411,7 @@ msgstr ""
msgid "Variant Item"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:969
+#: erpnext/stock/doctype/item/item.py:979
msgid "Variant Items"
msgstr ""
@@ -61571,7 +61738,7 @@ msgstr ""
#: erpnext/stock/report/available_serial_no/available_serial_no.js:56
#: erpnext/stock/report/available_serial_no/available_serial_no.py:196
#: erpnext/stock/report/stock_ledger/stock_ledger.js:97
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:403
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:406
msgid "Voucher #"
msgstr ""
@@ -61670,12 +61837,12 @@ msgstr ""
#: erpnext/stock/report/serial_and_batch_summary/serial_and_batch_summary.py:114
#: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:34
#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:163
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:176
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:185
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:74
msgid "Voucher No"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1484
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1534
msgid "Voucher No is mandatory"
msgstr ""
@@ -61744,8 +61911,8 @@ msgstr ""
#: erpnext/stock/report/serial_no_and_batch_traceability/serial_no_and_batch_traceability.py:486
#: erpnext/stock/report/serial_no_ledger/serial_no_ledger.py:28
#: erpnext/stock/report/stock_and_account_value_comparison/stock_and_account_value_comparison.py:161
-#: erpnext/stock/report/stock_ledger/stock_ledger.py:401
-#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:170
+#: erpnext/stock/report/stock_ledger/stock_ledger.py:404
+#: erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py:179
#: erpnext/stock/report/stock_ledger_variance/stock_ledger_variance.py:68
msgid "Voucher Type"
msgstr ""
@@ -61922,7 +62089,7 @@ msgstr ""
msgid "Warehouse is mandatory"
msgstr ""
-#: erpnext/manufacturing/report/bom_stock_analysis/bom_stock_analysis.py:309
+#: erpnext/manufacturing/report/bom_stock_analysis/bom_stock_analysis.py:330
msgid "Warehouse is required to get producible FG Items"
msgstr ""
@@ -61944,7 +62111,7 @@ msgstr ""
msgid "Warehouse {0} can not be deleted as quantity exists for Item {1}"
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1660
+#: erpnext/stock/doctype/item/item.py:1670
#: erpnext/stock/doctype/putaway_rule/putaway_rule.py:67
msgid "Warehouse {0} does not belong to Company {1}."
msgstr ""
@@ -61954,6 +62121,7 @@ msgid "Warehouse {0} does not belong to company {1}"
msgstr ""
#: erpnext/stock/doctype/warehouse/warehouse.py:296
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:99
msgid "Warehouse {0} does not exist"
msgstr ""
@@ -61965,7 +62133,7 @@ msgstr ""
msgid "Warehouse {0} is not linked to any account, please mention the account in the warehouse record or set default inventory account in company {1}."
msgstr ""
-#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:20
+#: erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py:26
msgid "Warehouse: {0} does not belong to {1}"
msgstr ""
@@ -62074,7 +62242,7 @@ msgstr ""
msgid "Warning - Row {0}: Billing Hours are more than Actual Hours"
msgstr ""
-#: erpnext/stock/stock_ledger.py:981
+#: erpnext/stock/stock_ledger.py:1008
msgid "Warning on Negative Stock"
msgstr ""
@@ -62556,7 +62724,7 @@ msgstr ""
#: erpnext/assets/doctype/asset/asset_list.js:12
#: erpnext/manufacturing/doctype/job_card/job_card.json
#: erpnext/manufacturing/doctype/job_card_operation/job_card_operation.json
-#: erpnext/setup/doctype/company/company.py:494
+#: erpnext/setup/doctype/company/company.py:498
#: erpnext/support/doctype/warranty_claim/warranty_claim.json
msgid "Work In Progress"
msgstr ""
@@ -62600,7 +62768,7 @@ msgstr ""
#: erpnext/selling/doctype/sales_order/sales_order.js:1094
#: erpnext/stock/doctype/material_request/material_request.js:220
#: erpnext/stock/doctype/material_request/material_request.json
-#: erpnext/stock/doctype/material_request/material_request.py:612
+#: erpnext/stock/doctype/material_request/material_request.py:642
#: erpnext/stock/doctype/pick_list/pick_list.json
#: erpnext/stock/doctype/serial_no/serial_no.json
#: erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -62639,7 +62807,7 @@ msgstr ""
msgid "Work Order Item"
msgstr ""
-#: erpnext/stock/doctype/stock_entry/stock_entry.py:534
+#: erpnext/stock/doctype/stock_entry/stock_entry.py:543
msgid "Work Order Mismatch"
msgstr ""
@@ -62680,7 +62848,7 @@ msgstr ""
msgid "Work Order Summary Report"
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:618
+#: erpnext/stock/doctype/material_request/material_request.py:648
msgid "Work Order cannot be created for the following reason:
{0}"
msgstr ""
@@ -62714,7 +62882,7 @@ msgid "Work Order {0} must be submitted"
msgstr ""
#: erpnext/manufacturing/report/job_card_summary/job_card_summary.js:56
-#: erpnext/stock/doctype/material_request/material_request.py:606
+#: erpnext/stock/doctype/material_request/material_request.py:636
msgid "Work Orders"
msgstr ""
@@ -62879,7 +63047,7 @@ msgstr ""
#: erpnext/accounts/doctype/pos_profile/pos_profile.json
#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.json
-#: erpnext/setup/doctype/company/company.py:783
+#: erpnext/setup/doctype/company/company.py:787
msgid "Write Off"
msgstr ""
@@ -63032,7 +63200,7 @@ msgstr ""
msgid "You are importing data for the code list:"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:232
+#: erpnext/accounts/services/child_item_update.py:237
msgid "You are not allowed to update as per the conditions set in {0} Workflow."
msgstr ""
@@ -63052,7 +63220,11 @@ msgstr ""
msgid "You are not permitted to add or remove Company {0} in Allowed Companies"
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:544
+#: erpnext/projects/doctype/task/task.py:330
+msgid "You are not permitted to create a Task for Project {0}"
+msgstr ""
+
+#: erpnext/stock/doctype/pick_list/pick_list.py:594
msgid "You are picking more than required quantity for the item {0}. Check if there is any other pick list created for the sales order {1}."
msgstr ""
@@ -63089,7 +63261,7 @@ msgid "You can only have Plans with the same billing cycle in a Subscription"
msgstr ""
#: erpnext/accounts/doctype/pos_invoice/pos_invoice.js:423
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1044
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.js:1049
msgid "You can only redeem max {0} points in this order."
msgstr ""
@@ -63173,7 +63345,7 @@ msgstr ""
msgid "You cannot repost item valuation before {0}"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:833
+#: erpnext/accounts/doctype/subscription/subscription.py:836
msgid "You cannot restart a Subscription that is not cancelled."
msgstr ""
@@ -63189,11 +63361,11 @@ msgstr ""
msgid "You cannot update stock for a Debit Note. A Debit Note is a financial document that should not affect inventory. Please disable 'Update Stock'."
msgstr ""
-#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:118
+#: erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py:122
msgid "You cannot {0} this document because another Period Closing Entry {1} exists after {2}"
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:168
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:169
msgid "You do not have enough permission to access {0}: {1}"
msgstr ""
@@ -63206,7 +63378,7 @@ msgstr ""
msgid "You do not have permission to import bank transactions"
msgstr ""
-#: erpnext/accounts/services/child_item_update.py:210
+#: erpnext/accounts/services/child_item_update.py:215
msgid "You do not have permissions to {0} items in a {1}."
msgstr ""
@@ -63218,11 +63390,11 @@ msgstr ""
msgid "You don't have enough points to redeem."
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1688
+#: erpnext/controllers/accounts_controller.py:1693
msgid "You don't have permission to create a Company Address. Please contact your System Manager."
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1668
+#: erpnext/controllers/accounts_controller.py:1673
msgid "You don't have permission to update Company details. Please contact your System Manager."
msgstr ""
@@ -63230,7 +63402,7 @@ msgstr ""
msgid "You don't have permission to update Received Qty DocField for item {0}"
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1662
+#: erpnext/controllers/accounts_controller.py:1667
msgid "You don't have permission to update this document. Please contact your System Manager."
msgstr ""
@@ -63238,7 +63410,7 @@ msgstr ""
msgid "You had {0} errors while creating opening invoices. Check {1} for more details"
msgstr ""
-#: erpnext/public/js/utils.js:1067
+#: erpnext/public/js/utils.js:1093
msgid "You have already selected items from {0} {1}"
msgstr ""
@@ -63246,7 +63418,7 @@ msgstr ""
msgid "You have been invited to collaborate on the project {0}."
msgstr ""
-#: erpnext/stock/doctype/stock_settings/stock_settings.py:249
+#: erpnext/stock/doctype/stock_settings/stock_settings.py:254
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 ""
@@ -63266,7 +63438,7 @@ msgstr ""
msgid "You have not performed any reconciliations in this session yet."
msgstr ""
-#: erpnext/stock/doctype/item/item.py:1218
+#: erpnext/stock/doctype/item/item.py:1228
msgid "You have to enable auto re-order in Stock Settings to maintain re-order levels."
msgstr ""
@@ -63376,7 +63548,7 @@ msgstr ""
msgid "`Allow Negative rates for Items`"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2216
+#: erpnext/stock/stock_ledger.py:2259
msgid "after"
msgstr ""
@@ -63400,7 +63572,7 @@ msgstr ""
msgid "as a percentage of finished item quantity"
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1654
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1704
msgid "as of {0}"
msgstr ""
@@ -63416,7 +63588,7 @@ msgstr ""
msgid "by {}"
msgstr ""
-#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:338
+#: erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py:348
#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:846
msgid "dated {0}"
msgstr ""
@@ -63568,7 +63740,7 @@ msgstr ""
msgid "per hour"
msgstr ""
-#: erpnext/stock/stock_ledger.py:2217
+#: erpnext/stock/stock_ledger.py:2260
msgid "performing either one below:"
msgstr ""
@@ -63644,12 +63816,12 @@ msgstr ""
msgid "sold"
msgstr ""
-#: erpnext/accounts/doctype/subscription/subscription.py:810
+#: erpnext/accounts/doctype/subscription/subscription.py:813
msgid "subscription is already cancelled."
msgstr ""
-#: erpnext/controllers/status_updater.py:505
-#: erpnext/controllers/status_updater.py:524
+#: erpnext/controllers/status_updater.py:506
+#: erpnext/controllers/status_updater.py:525
msgid "target_ref_field"
msgstr ""
@@ -63667,7 +63839,7 @@ msgstr ""
msgid "to"
msgstr ""
-#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1265
+#: erpnext/accounts/doctype/sales_invoice/sales_invoice.py:1266
msgid "to unallocate the amount of this Return Invoice before cancelling it."
msgstr ""
@@ -63728,7 +63900,7 @@ msgstr ""
msgid "{0} {1} has submitted Assets. Remove Item {2} from table to continue."
msgstr ""
-#: erpnext/controllers/accounts_controller.py:1223
+#: erpnext/controllers/accounts_controller.py:1228
msgid "{0} Account not found against Customer {1}."
msgstr ""
@@ -63764,6 +63936,10 @@ msgstr ""
msgid "{0} Operations: {1}"
msgstr ""
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:368
+msgid "{0} Payment Entries"
+msgstr ""
+
#: erpnext/stock/doctype/material_request/material_request.py:271
msgid "{0} Request for {1}"
msgstr ""
@@ -63862,7 +64038,7 @@ msgstr ""
msgid "{0} completed job cards"
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:137
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:138
#: erpnext/manufacturing/doctype/production_plan/services/work_order_planning.py:214
#: erpnext/stock/doctype/material_request/mapper.py:271
#: erpnext/stock/doctype/pick_list/mapper.py:81
@@ -63874,7 +64050,7 @@ msgstr ""
msgid "{0} creation for the following records will be skipped."
msgstr ""
-#: erpnext/setup/doctype/company/company.py:405
+#: erpnext/setup/doctype/company/company.py:409
msgid "{0} currency must be same as company's default currency. Please select another account."
msgstr ""
@@ -63923,6 +64099,14 @@ msgstr ""
msgid "{0} entries fetched"
msgstr ""
+#: erpnext/accounts/bulk_payment.py:41
+msgid "{0} excluded (not payable)"
+msgstr ""
+
+#: erpnext/accounts/bulk_payment.py:43
+msgid "{0} failed (see Error Log)"
+msgstr ""
+
#: erpnext/accounts/utils.py:138
#: erpnext/projects/doctype/activity_cost/activity_cost.py:40
msgid "{0} for {1}"
@@ -63932,7 +64116,7 @@ msgstr ""
msgid "{0} has Payment Term based allocation enabled. Select a Payment Term for Row #{1} in Payment References section"
msgstr ""
-#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:852
+#: erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py:853
msgid "{0} has been modified after you pulled it. Please pull it again."
msgstr ""
@@ -63952,6 +64136,10 @@ msgstr ""
msgid "{0} in row {1}"
msgstr ""
+#: erpnext/accounts/report/accounts_payable/accounts_payable.js:389
+msgid "{0} invoice(s) excluded"
+msgstr ""
+
#: erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py:66
msgid "{0} is a child company."
msgstr ""
@@ -63978,7 +64166,7 @@ msgstr ""
msgid "{0} is added multiple times on rows: {1}"
msgstr ""
-#: erpnext/public/js/shop_floor/shop_floor.js:1561
+#: erpnext/public/js/shop_floor/shop_floor.js:1567
msgid "{0} is already in progress. Pause it or complete the session."
msgstr ""
@@ -64019,11 +64207,11 @@ msgstr ""
msgid "{0} is mandatory. Maybe Currency Exchange record is not created for {1} to {2}."
msgstr ""
-#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1900
+#: erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py:1950
msgid "{0} is not a CSV file."
msgstr ""
-#: erpnext/selling/doctype/customer/customer.py:249
+#: erpnext/selling/doctype/customer/customer.py:250
msgid "{0} is not a company bank account"
msgstr ""
@@ -64071,7 +64259,7 @@ msgstr ""
msgid "{0} is not supported for the inline Serial / Batch editor"
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:517
+#: erpnext/stock/doctype/material_request/material_request.py:547
msgid "{0} is not the default supplier for any items."
msgstr ""
@@ -64083,7 +64271,7 @@ msgstr ""
msgid "{0} is open. Close the POS or cancel the existing POS Opening Entry to create a new POS Opening Entry."
msgstr ""
-#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:179
+#: erpnext/manufacturing/doctype/production_plan/services/material_request.py:180
msgid "{0} is required to get raw materials when {1} is set."
msgstr ""
@@ -64123,7 +64311,7 @@ msgstr ""
msgid "{0} must be a group warehouse."
msgstr ""
-#: erpnext/controllers/sales_and_purchase_return.py:219
+#: erpnext/controllers/sales_and_purchase_return.py:237
msgid "{0} must be negative in return document"
msgstr ""
@@ -64151,10 +64339,6 @@ msgstr ""
msgid "{0} qty of Item {1} is being received into Warehouse {2} with capacity {3}."
msgstr ""
-#: erpnext/accounts/bulk_payment.py:80
-msgid "{0} skipped (see Error Log)"
-msgstr ""
-
#: erpnext/public/js/templates/shop_floor_template.html:1050
msgid "{0} submitted today"
msgstr ""
@@ -64172,11 +64356,11 @@ msgstr ""
msgid "{0} units are reserved for Item {1} in Warehouse {2}, please un-reserve the same to {3} the Stock Reconciliation."
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:1136
+#: erpnext/stock/doctype/pick_list/pick_list.py:1195
msgid "{0} units of Item {1} is not available in any of the warehouses."
msgstr ""
-#: erpnext/stock/doctype/pick_list/pick_list.py:1129
+#: erpnext/stock/doctype/pick_list/pick_list.py:1188
msgid "{0} units of Item {1} is not available in any of the warehouses. Other Pick Lists exist for this item."
msgstr ""
@@ -64184,16 +64368,16 @@ msgstr ""
msgid "{0} units of {1} are required in {2} with the inventory dimension: {3} on {4} {5} for {6} to complete the transaction."
msgstr ""
-#: erpnext/stock/stock_ledger.py:1863 erpnext/stock/stock_ledger.py:2388
-#: erpnext/stock/stock_ledger.py:2402
+#: erpnext/stock/stock_ledger.py:1906 erpnext/stock/stock_ledger.py:2431
+#: erpnext/stock/stock_ledger.py:2445
msgid "{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
msgstr ""
-#: erpnext/stock/stock_ledger.py:2492 erpnext/stock/stock_ledger.py:2537
+#: erpnext/stock/stock_ledger.py:2535 erpnext/stock/stock_ledger.py:2580
msgid "{0} units of {1} needed in {2} on {3} {4} to complete this transaction."
msgstr ""
-#: erpnext/stock/stock_ledger.py:1857
+#: erpnext/stock/stock_ledger.py:1900
msgid "{0} units of {1} needed in {2} to complete this transaction."
msgstr ""
@@ -64249,7 +64433,7 @@ msgstr ""
msgid "{0} {1} created"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:335
+#: erpnext/setup/doctype/company/company.py:337
msgid "{0} {1} does not belong to company {2}"
msgstr ""
@@ -64273,11 +64457,11 @@ msgstr ""
#: erpnext/buying/doctype/purchase_order/services/status.py:35
#: erpnext/selling/doctype/sales_order/services/status.py:45
-#: erpnext/stock/doctype/material_request/material_request.py:297
+#: erpnext/stock/doctype/material_request/material_request.py:312
msgid "{0} {1} has been modified. Please refresh."
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:324
+#: erpnext/stock/doctype/material_request/material_request.py:340
msgid "{0} {1} has not been submitted so the action cannot be completed"
msgstr ""
@@ -64302,16 +64486,20 @@ msgstr ""
msgid "{0} {1} is associated with {2}, but Party Account is {3}"
msgstr ""
+#: erpnext/accounts/doctype/journal_entry/services/reference_validator.py:209
+msgid "{0} {1} is blocked and on hold until {2}."
+msgstr ""
+
#: erpnext/controllers/selling_controller.py:509
#: erpnext/controllers/subcontracting_controller.py:1156
msgid "{0} {1} is cancelled or closed"
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:476
+#: erpnext/stock/doctype/material_request/material_request.py:506
msgid "{0} {1} is cancelled or stopped"
msgstr ""
-#: erpnext/stock/doctype/material_request/material_request.py:314
+#: erpnext/stock/doctype/material_request/material_request.py:330
msgid "{0} {1} is cancelled so the action cannot be completed"
msgstr ""
@@ -64348,7 +64536,7 @@ msgid "{0} {1} is not in any active Fiscal Year"
msgstr ""
#: erpnext/accounts/doctype/journal_entry/services/reference_validator.py:151
-#: erpnext/accounts/doctype/journal_entry/services/reference_validator.py:191
+#: erpnext/accounts/doctype/journal_entry/services/reference_validator.py:192
msgid "{0} {1} is not submitted"
msgstr ""
@@ -64440,7 +64628,7 @@ msgstr ""
msgid "{0}% of total invoice value will be given as discount."
msgstr ""
-#: erpnext/projects/doctype/task/task.py:130
+#: erpnext/projects/doctype/task/task.py:131
msgid "{0}'s {1} cannot be after {2}'s Expected End Date."
msgstr ""
@@ -64480,7 +64668,7 @@ msgstr ""
msgid "{0}: {1} does not exist"
msgstr ""
-#: erpnext/setup/doctype/company/company.py:392
+#: erpnext/setup/doctype/company/company.py:396
msgid "{0}: {1} is a group account."
msgstr ""
diff --git a/erpnext/locale/sv.po b/erpnext/locale/sv.po
index 5e9d142e629..ab150f22c2a 100644
--- a/erpnext/locale/sv.po
+++ b/erpnext/locale/sv.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: hello@frappe.io\n"
"POT-Creation-Date: 2026-08-02 10:09+0000\n"
-"PO-Revision-Date: 2026-08-04 09:44\n"
+"PO-Revision-Date: 2026-08-06 10:02\n"
"Last-Translator: hello@frappe.io\n"
"Language-Team: Swedish\n"
"MIME-Version: 1.0\n"
@@ -18542,7 +18542,7 @@ msgstr "Påminnelse Typ"
#: erpnext/accounts/doctype/pos_profile/pos_profile.py:178
msgid "Duplicate Customer Group"
-msgstr "Kopiera Kund Grupp"
+msgstr "Duplicera Kund Grupp"
#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:190
msgid "Duplicate DocType"
@@ -18554,11 +18554,11 @@ msgstr "Dubblett Post. Kontrollera Auktorisering Regel {0}"
#: erpnext/assets/doctype/asset/asset.py:418
msgid "Duplicate Finance Book"
-msgstr "Kopiera Bokslut Register"
+msgstr "Duplicera Bokslut Register"
#: erpnext/accounts/doctype/pos_profile/pos_profile.py:172
msgid "Duplicate Item Group"
-msgstr "Kopiera Artikel Grupp"
+msgstr "Duplicera Artikel Grupp"
#: erpnext/manufacturing/doctype/bom_creator/bom_creator.py:102
msgid "Duplicate Item Under Same Parent"
@@ -18576,7 +18576,7 @@ msgstr "Duplicera Kassa Fällt"
#: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:106
#: erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py:64
msgid "Duplicate POS Invoices found"
-msgstr "Kopia av Kassa Fakturor hittad"
+msgstr "Dubblett av Kassa Fakturor hittad"
#: erpnext/accounts/doctype/payment_request/payment_request.py:155
msgid "Duplicate Payment Schedule selected"
@@ -18584,7 +18584,7 @@ msgstr "Duplicerad Betalning Schema vald"
#: erpnext/projects/doctype/project/project.js:83
msgid "Duplicate Project with Tasks"
-msgstr "Kopiera Projekt med Uppgifter"
+msgstr "Duplicera Projekt med Uppgifter"
#: erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py:159
msgid "Duplicate Sales Invoices found"
@@ -18604,7 +18604,7 @@ msgstr "Kopia av Kund Grupp finns i Kund Grupp Tabell"
#: erpnext/stock/doctype/item_manufacturer/item_manufacturer.py:44
msgid "Duplicate entry against the item code {0} and manufacturer {1}"
-msgstr "Kopiera post mot Artikel Kod {0} och Producent {1}"
+msgstr "Duplicera post mot artikel kod {0} och producent {1}"
#: erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py:189
msgid "Duplicate entry: {0}{1}"
@@ -18612,19 +18612,19 @@ msgstr "Duplicerad post: {0}{1}"
#: erpnext/accounts/doctype/pos_profile/pos_profile.py:172
msgid "Duplicate item group found in the item group table"
-msgstr "Kopiera Artikel Grupp hittad i Artikel Grupp Tabell"
+msgstr "Dubblett av Artikel Grupp hittad i Artikel Grupp Tabell"
#: erpnext/accounts/doctype/dunning_type/dunning_type.py:133
msgid "Duplicate languages found on Dunning Letter Text. Keep only one of them."
-msgstr "Det finns flera språk i påminnelse brev. Behåll endast ett språk."
+msgstr "Det finns flera språk i Påminnelse Brev. Behåll endast ett språk."
#: erpnext/projects/doctype/project/project.js:186
msgid "Duplicate project has been created"
-msgstr "Kopia av Projekt är skapad"
+msgstr "Dubblett av Projekt är skapad"
#: erpnext/utilities/transaction_base.py:112
msgid "Duplicate row {0} with same {1}"
-msgstr "Kopiera Rad {0} med samma {1}"
+msgstr "Duplicera Rad {0} med samma {1}"
#: erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py:110
msgid "Duplicate vouchers found. Remove the duplicate vouchers to continue to repost."
@@ -18632,7 +18632,7 @@ msgstr "Dubbletter av verifikat hittades. Ta bort dubbletter för att fortsätta
#: erpnext/accounts/doctype/pricing_rule/pricing_rule.py:157
msgid "Duplicate {0} found in the table"
-msgstr "Kopia {0} hittades i Tabell"
+msgstr "Dubblett {0} hittades i Tabell"
#. Label of the duration (Int) field in DocType 'Task'
#: erpnext/projects/doctype/task/task.json
@@ -47176,7 +47176,7 @@ msgstr "Rad # #{0}: Avskrivning Start Datum erfordras"
#: erpnext/accounts/doctype/payment_entry/payment_entry.py:336
msgid "Row #{0}: Duplicate entry in References {1} {2}"
-msgstr "Rad # {0}: Duplikat Post i Referenser {1} {2}"
+msgstr "Rad #{0}: Dubblett Post i Referenser {1} {2}"
#: erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py:113
msgid "Row #{0}: Either Party ID or Party Name is required"
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 2717da14826..fb4884e33c4 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -314,6 +314,7 @@ class BOM(WebsiteGenerator):
self.clear_inspection()
self.validate_main_item()
self.validate_currency()
+ self.set_operation_finished_goods()
self.set_materials_based_on_operation_bom()
self.set_conversion_rate()
self.set_plc_conversion_rate()
@@ -340,15 +341,42 @@ class BOM(WebsiteGenerator):
self.set_fg_cost_allocation()
self.validate_total_cost_allocation()
+ def set_operation_finished_goods(self):
+ """Fill each operation's FG item where it is unambiguous: the final operation produces
+ this BOM's item, an operation with a BOM produces that BOM's item. Runs before
+ set_materials_based_on_operation_bom so derived rows get their materials expanded."""
+ if not self.track_semi_finished_goods:
+ return
+
+ for row in self.operations:
+ if row.is_final_finished_good and not row.finished_good:
+ row.finished_good = self.item
+ elif row.bom_no and not row.finished_good:
+ row.finished_good = frappe.get_cached_value("BOM", row.bom_no, "item")
+
def validate_semi_finished_goods(self):
if not self.track_semi_finished_goods or not self.operations:
return
fg_items = []
for row in self.operations:
+ if not row.finished_good:
+ frappe.throw(
+ _(
+ "Row #{0}: FG / Semi FG Item is required for the operation {1} as 'Track Semi Finished Goods' is enabled."
+ ).format(row.idx, bold(row.operation)),
+ )
+
if not row.is_final_finished_good:
continue
+ if row.finished_good != self.item:
+ frappe.throw(
+ _(
+ "Row #{0}: The operation {1} has 'Is Final Finished Good' checked, so its FG / Semi FG Item must be {2}."
+ ).format(row.idx, bold(row.operation), bold(self.item)),
+ )
+
fg_items.append(row.finished_good)
if not fg_items:
@@ -800,15 +828,10 @@ class BOM(WebsiteGenerator):
row.update(get_item_details(row.get("item_code")))
row.operation_row_id = operation_row_id
- item_row = self.get_item_data(row.name) if row.name else None
+ item_row = self.get_item_data(row.item_code, operation_row_id)
if item_row:
- item_row.update(
- {
- "item_code": row.get("item_code"),
- "qty": row.get("qty"),
- }
- )
+ item_row.qty = row.get("qty")
else:
row.idx = None
row.name = None
@@ -827,9 +850,9 @@ class BOM(WebsiteGenerator):
return False
- def get_item_data(self, name):
+ def get_item_data(self, item_code, operation_row_id):
for row in self.items:
- if row.item_code == name:
+ if row.item_code == item_code and cint(row.operation_row_id) == cint(operation_row_id):
return row
@frappe.whitelist()
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 1ac43b992f6..c61de349a99 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -7,7 +7,7 @@ from functools import partial
import frappe
from frappe.tests import timeout
-from frappe.utils import cstr, flt
+from frappe.utils import cint, cstr, flt
from erpnext.controllers.tests.test_subcontracting_controller import (
set_backflush_based_on,
@@ -919,6 +919,207 @@ class TestBOM(ERPNextTestSuite):
for row in bom.items:
self.assertEqual(row.stock_uom, "Kg")
+ @timeout
+ def test_track_semi_finished_goods_requires_finished_good_on_operations(self):
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
+
+ fg_item = make_item(properties={"is_stock_item": 1}).name
+ sfg_item = make_item(properties={"is_stock_item": 1}).name
+ rm_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 100.0}).name
+ make_workstation({"workstation": "_Test SFG Workstation"})
+ for operation in ("_Test SFG Operation", "_Test SFG Final Operation"):
+ make_operation({"operation": operation, "workstation": "_Test SFG Workstation"})
+
+ bom = frappe.new_doc("BOM")
+ bom.company = "_Test Company"
+ bom.item = fg_item
+ bom.quantity = 1
+ bom.with_operations = 1
+ bom.track_semi_finished_goods = 1
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ },
+ )
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Final Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ "is_final_finished_good": 1,
+ },
+ )
+ bom.append("items", {"item_code": rm_item, "qty": 1, "operation_row_id": 1})
+ bom.append("items", {"item_code": sfg_item, "qty": 1, "operation_row_id": 2})
+
+ # the first operation produces nothing derivable: no FG item, no BOM to take it from
+ self.assertRaises(frappe.ValidationError, bom.insert)
+
+ bom.operations[0].finished_good = sfg_item
+ bom.insert()
+
+ # the final operation's FG item is derived from the BOM's own item
+ self.assertEqual(bom.operations[1].finished_good, fg_item)
+
+ @timeout
+ def test_add_raw_materials_when_item_is_used_by_another_operation(self):
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
+
+ fg_item = make_item(properties={"is_stock_item": 1}).name
+ sfg_item = make_item(properties={"is_stock_item": 1}).name
+ rm_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 100.0}).name
+ make_workstation({"workstation": "_Test SFG Workstation"})
+ for operation in ("_Test SFG Operation", "_Test SFG Final Operation"):
+ make_operation({"operation": operation, "workstation": "_Test SFG Workstation"})
+
+ bom = frappe.new_doc("BOM")
+ bom.company = "_Test Company"
+ bom.item = fg_item
+ bom.quantity = 1
+ bom.with_operations = 1
+ bom.track_semi_finished_goods = 1
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ "finished_good": sfg_item,
+ },
+ )
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Final Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ "is_final_finished_good": 1,
+ },
+ )
+ bom.append("items", {"item_code": rm_item, "qty": 1, "operation_row_id": 1})
+ bom.append("items", {"item_code": sfg_item, "qty": 1, "operation_row_id": 2})
+ bom.insert()
+
+ def rows_for(item_code, operation_row_id):
+ return [
+ row
+ for row in bom.items
+ if row.item_code == item_code and cint(row.operation_row_id) == operation_row_id
+ ]
+
+ # the item already used by operation 1 gets its own new row under operation 2
+ bom.add_raw_materials(2, [{"item_code": rm_item, "qty": 3}])
+ self.assertEqual(len(rows_for(rm_item, 2)), 1)
+ self.assertEqual(flt(rows_for(rm_item, 2)[0].qty), 3.0)
+ self.assertEqual(flt(rows_for(rm_item, 1)[0].qty), 1.0)
+
+ # adding it again for the same operation updates the row instead of stacking another
+ bom.add_raw_materials(2, [{"item_code": rm_item, "qty": 5}])
+ self.assertEqual(len(rows_for(rm_item, 2)), 1)
+ self.assertEqual(flt(rows_for(rm_item, 2)[0].qty), 5.0)
+
+ @timeout
+ def test_operation_bom_materials_expand_on_single_pass_submit(self):
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
+
+ fg_item = make_item(properties={"is_stock_item": 1}).name
+ sfg_item = make_item(properties={"is_stock_item": 1}).name
+ rm_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 100.0}).name
+ make_workstation({"workstation": "_Test SFG Workstation"})
+ for operation in ("_Test SFG Operation", "_Test SFG Final Operation"):
+ make_operation({"operation": operation, "workstation": "_Test SFG Workstation"})
+
+ sfg_bom = frappe.new_doc("BOM", company="_Test Company", item=sfg_item, quantity=1)
+ sfg_bom.append("items", {"item_code": rm_item, "qty": 1})
+ sfg_bom.insert()
+ sfg_bom.submit()
+
+ bom = frappe.new_doc("BOM")
+ bom.company = "_Test Company"
+ bom.item = fg_item
+ bom.quantity = 1
+ bom.with_operations = 1
+ bom.track_semi_finished_goods = 1
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ "bom_no": sfg_bom.name,
+ },
+ )
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Final Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ "is_final_finished_good": 1,
+ },
+ )
+ bom.append("items", {"item_code": sfg_item, "qty": 1, "operation_row_id": 2})
+ bom.submit()
+
+ self.assertEqual(bom.docstatus, 1)
+ self.assertEqual(bom.operations[0].finished_good, sfg_item)
+ self.assertTrue(
+ any(row.item_code == rm_item and cint(row.operation_row_id) == 1 for row in bom.items)
+ )
+
+ @timeout
+ def test_final_operation_must_produce_the_bom_item(self):
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
+
+ fg_item = make_item(properties={"is_stock_item": 1}).name
+ sfg_item = make_item(properties={"is_stock_item": 1}).name
+ rm_item = make_item(properties={"is_stock_item": 1, "valuation_rate": 100.0}).name
+ make_workstation({"workstation": "_Test SFG Workstation"})
+ for operation in ("_Test SFG Operation", "_Test SFG Final Operation"):
+ make_operation({"operation": operation, "workstation": "_Test SFG Workstation"})
+
+ bom = frappe.new_doc("BOM")
+ bom.company = "_Test Company"
+ bom.item = fg_item
+ bom.quantity = 1
+ bom.with_operations = 1
+ bom.track_semi_finished_goods = 1
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ "finished_good": sfg_item,
+ },
+ )
+ bom.append(
+ "operations",
+ {
+ "operation": "_Test SFG Final Operation",
+ "workstation": "_Test SFG Workstation",
+ "time_in_mins": 30,
+ "is_final_finished_good": 1,
+ "finished_good": sfg_item,
+ },
+ )
+ bom.append("items", {"item_code": rm_item, "qty": 1, "operation_row_id": 1})
+ bom.append("items", {"item_code": sfg_item, "qty": 1, "operation_row_id": 2})
+
+ # the final operation claims to produce the semi FG, not this BOM's item
+ self.assertRaises(frappe.ValidationError, bom.insert)
+
+ bom.operations[1].finished_good = fg_item
+ bom.insert()
+
def get_default_bom(item_code="_Test FG Item 2"):
return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
diff --git a/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json b/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
index c5b39d88735..cadc8dfd8e2 100644
--- a/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
+++ b/erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
@@ -140,7 +140,8 @@
{
"fieldname": "conversion_factor",
"fieldtype": "Float",
- "label": "Conversion Factor"
+ "label": "Conversion Factor",
+ "precision": "9"
},
{
"fetch_from": "item_code.stock_uom",
@@ -264,7 +265,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2025-11-05 21:15:55.187671",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Creator Item",
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index 52e7d4da609..12d5090ef0e 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -177,7 +177,8 @@
{
"fieldname": "conversion_factor",
"fieldtype": "Float",
- "label": "Conversion Factor"
+ "label": "Conversion Factor",
+ "precision": "9"
},
{
"fieldname": "rate_amount_section",
@@ -327,7 +328,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2025-11-05 19:00:38.646539",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Item",
diff --git a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
index 86fcd7082fd..e6ac3ee474e 100644
--- a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
+++ b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
@@ -213,6 +213,7 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "FG / Semi FG Item",
+ "mandatory_depends_on": "eval:parent.track_semi_finished_goods === 1",
"options": "Item"
},
{
@@ -307,7 +308,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-05-25 17:15:42.044630",
+ "modified": "2026-08-08 12:00:00.000000",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Operation",
diff --git a/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json b/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json
index 5dd77d03578..d3ad50b169f 100644
--- a/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json
+++ b/erpnext/manufacturing/doctype/bom_secondary_item/bom_secondary_item.json
@@ -99,6 +99,7 @@
"fieldtype": "Float",
"label": "Conversion Factor",
"non_negative": 1,
+ "precision": "9",
"reqd": 1
},
{
@@ -217,7 +218,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-06-16 16:51:40.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Secondary Item",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index 1d9544d2651..1271f1b6117 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -891,6 +891,9 @@ class JobCard(Document):
frappe.msgprint(message, alert=True, indicator="orange")
def validate_transfer_qty(self):
+ if self.track_semi_finished_goods and self.skip_material_transfer:
+ return
+
if (
not self.finished_good
and not self.is_corrective_job_card
@@ -1111,6 +1114,9 @@ class JobCard(Document):
wo.calculate_operating_cost()
wo.set_actual_dates()
+ if wo.track_semi_finished_goods:
+ wo.set_process_loss_qty()
+
if time_data:
wo.status = "In Process"
@@ -1461,12 +1467,12 @@ class JobCard(Document):
)
if self.track_semi_finished_goods and previous_operations:
- manufactured_qty = self.get_manufactured_qty_per_operation(
- [row.name for row in previous_operations]
- )
+ totals = self.get_manufactured_qty_per_operation([row.name for row in previous_operations])
for row in previous_operations:
- row.manufactured_qty = flt(manufactured_qty.get(row.name))
+ operation_totals = totals.get(row.name)
+ row.manufactured_qty = flt(operation_totals and operation_totals.manufactured_qty)
+ row.process_loss_qty = flt(operation_totals and operation_totals.process_loss_qty)
return previous_operations
@@ -1475,7 +1481,11 @@ class JobCard(Document):
data = (
frappe.qb.from_(job_card)
- .select(job_card.operation_id, Sum(job_card.manufactured_qty))
+ .select(
+ job_card.operation_id,
+ Sum(job_card.manufactured_qty).as_("manufactured_qty"),
+ Sum(job_card.process_loss_qty).as_("process_loss_qty"),
+ )
.where(
(job_card.work_order == self.work_order)
& (job_card.docstatus == 1)
@@ -1483,9 +1493,9 @@ class JobCard(Document):
& (job_card.operation_id.isin(operation_ids))
)
.groupby(job_card.operation_id)
- ).run()
+ ).run(as_dict=True)
- return dict(data)
+ return {row.operation_id: row for row in data}
def get_current_operation_completed_qty(self):
current_operation_qty = 0.0
@@ -1537,19 +1547,35 @@ class JobCard(Document):
OperationSequenceError,
)
- if manufactured_qty < current_operation_qty:
+ if manufactured_qty >= current_operation_qty:
+ return
+
+ if manufactured_qty + flt(row.process_loss_qty) >= current_operation_qty:
frappe.throw(
_(
- "The completed quantity {0} of an operation {1} cannot be greater than the manufactured quantity {2} of a previous operation {3}. Submit the manufacturing entry for the operation {3} first."
+ "The completed quantity {0} of an operation {1} cannot be greater than the manufactured quantity {2} of a previous operation {3}, as {4} was booked as process loss there."
).format(
bold(self.get_qty_with_uom(current_operation_qty)),
bold(self.operation),
bold(self.get_qty_with_uom(manufactured_qty, row.finished_good)),
bold(row.operation),
+ bold(self.get_qty_with_uom(flt(row.process_loss_qty), row.finished_good)),
),
OperationSequenceError,
)
+ frappe.throw(
+ _(
+ "The completed quantity {0} of an operation {1} cannot be greater than the manufactured quantity {2} of a previous operation {3}. Submit the manufacturing entry for the operation {3} first."
+ ).format(
+ bold(self.get_qty_with_uom(current_operation_qty)),
+ bold(self.operation),
+ bold(self.get_qty_with_uom(manufactured_qty, row.finished_good)),
+ bold(row.operation),
+ ),
+ OperationSequenceError,
+ )
+
def validate_work_order(self):
if self.is_work_order_closed():
frappe.throw(_("You cannot make any changes to Job Card since Work Order is closed."))
@@ -1801,10 +1827,11 @@ class JobCard(Document):
def build_manufacture_stock_entry(self):
from erpnext.stock.doctype.stock_entry_type.stock_entry_type import ManufactureEntry
+ consumed_process_loss = self.get_consumed_process_loss()
return ManufactureEntry(
{
- "for_quantity": self.get_qty_to_produce() - self.manufactured_qty,
- "process_loss_qty": max(self.process_loss_qty - self.get_consumed_process_loss(), 0),
+ "for_quantity": self.get_qty_to_produce() - self.manufactured_qty - consumed_process_loss,
+ "process_loss_qty": max(self.process_loss_qty - consumed_process_loss, 0),
"job_card": self.name,
"skip_material_transfer": self.skip_material_transfer,
"backflush_from_wip_warehouse": self.backflush_from_wip_warehouse,
diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.py b/erpnext/manufacturing/doctype/job_card/test_job_card.py
index da1b40af076..ec95b935450 100644
--- a/erpnext/manufacturing/doctype/job_card/test_job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/test_job_card.py
@@ -1447,6 +1447,204 @@ class TestJobCard(ERPNextTestSuite):
self.assertEqual(flt(job_card.manufactured_qty), 3)
self.assertEqual(job_card.status, "Completed")
+ def test_semi_fg_process_loss_rolls_up_to_work_order(self):
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ warehouse = "Stores - _TC"
+ rm = make_item("Process Loss Rollup RM 1", {"is_stock_item": 1}).name
+ fg = make_item("Process Loss Rollup FG 1", {"is_stock_item": 1}).name
+
+ fg_bom = frappe.new_doc(
+ "BOM",
+ company="_Test Company",
+ item=fg,
+ quantity=1,
+ with_operations=1,
+ track_semi_finished_goods=1,
+ )
+ fg_bom.append("items", {"item_code": rm, "qty": 1, "operation_row_id": 1})
+
+ operation = {
+ "operation": "Process Loss Rollup Op A",
+ "workstation": "_Test Workstation A",
+ "finished_good": fg,
+ "finished_good_qty": 1,
+ "is_final_finished_good": 1,
+ "sequence_id": 1,
+ "time_in_mins": 60,
+ "source_warehouse": warehouse,
+ "fg_warehouse": warehouse,
+ "skip_material_transfer": 1,
+ }
+
+ make_workstation(operation)
+ make_operation(operation)
+ fg_bom.append("operations", operation)
+ fg_bom.insert()
+ fg_bom.submit()
+
+ work_order = make_wo_order_test_record(
+ item=fg,
+ qty=10,
+ source_warehouse=warehouse,
+ fg_warehouse=warehouse,
+ bom_no=fg_bom.name,
+ skip_transfer=1,
+ do_not_save=True,
+ )
+ work_order.operations[0].time_in_mins = 60
+ work_order.save()
+ work_order.submit()
+
+ make_stock_entry(item_code=rm, target=warehouse, qty=100, basic_rate=100)
+
+ job_card = self.get_first_job_card(work_order.name)
+ job_card.append("time_logs", {"from_time": "2024-05-01 08:00:00"})
+ job_card.save()
+
+ job_card.complete_job_card(
+ qty=8,
+ for_quantity=10,
+ pending_qty=0,
+ process_loss_qty=2,
+ end_time="2024-05-01 09:00:00",
+ )
+
+ job_card.reload()
+ self.assertEqual(flt(job_card.process_loss_qty), 2)
+
+ job_card.submit()
+ frappe.get_doc(job_card.make_stock_entry_for_semi_fg_item()).submit()
+
+ self.assertEqual(
+ flt(
+ frappe.db.get_value("Work Order Operation", work_order.operations[0].name, "process_loss_qty")
+ ),
+ 2,
+ )
+
+ work_order.reload()
+ self.assertEqual(flt(work_order.produced_qty), 8)
+ self.assertEqual(flt(work_order.process_loss_qty), 2)
+ self.assertEqual(work_order.status, "Completed")
+
+ def test_semi_fg_process_loss_of_an_intermediate_operation_rolls_up_to_work_order(self):
+ """Loss booked by an earlier operation shrinks what the final operation can produce,
+ so it has to show up on the work order even though the final operation loses nothing."""
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ warehouse = "Stores - _TC"
+ rm = make_item("Intermediate Loss RM 1", {"is_stock_item": 1}).name
+ sfg = make_item("Intermediate Loss SFG 1", {"is_stock_item": 1}).name
+ fg = make_item("Intermediate Loss FG 1", {"is_stock_item": 1}).name
+
+ sfg_bom = frappe.new_doc("BOM", company="_Test Company", item=sfg, quantity=1)
+ sfg_bom.append("items", {"item_code": rm, "qty": 1})
+ sfg_bom.insert()
+ sfg_bom.submit()
+
+ fg_bom = frappe.new_doc(
+ "BOM",
+ company="_Test Company",
+ item=fg,
+ quantity=1,
+ with_operations=1,
+ track_semi_finished_goods=1,
+ )
+
+ operations = [
+ {
+ "operation": "Intermediate Loss Op A",
+ "finished_good": sfg,
+ "bom_no": sfg_bom.name,
+ "sequence_id": 1,
+ },
+ {
+ "operation": "Intermediate Loss Op B",
+ "finished_good": fg,
+ "is_final_finished_good": 1,
+ "sequence_id": 2,
+ },
+ ]
+
+ for row in operations:
+ row.update(
+ {
+ "workstation": "_Test Workstation A",
+ "finished_good_qty": 1,
+ "time_in_mins": 60,
+ "source_warehouse": warehouse,
+ "fg_warehouse": warehouse,
+ "skip_material_transfer": 1,
+ }
+ )
+ make_workstation(row)
+ make_operation(row)
+ fg_bom.append("operations", row)
+
+ fg_bom.append("items", {"item_code": sfg, "qty": 1, "operation_row_id": 2})
+ fg_bom.insert()
+ fg_bom.submit()
+
+ work_order = make_wo_order_test_record(
+ item=fg,
+ qty=10,
+ source_warehouse=warehouse,
+ fg_warehouse=warehouse,
+ bom_no=fg_bom.name,
+ skip_transfer=1,
+ do_not_save=True,
+ )
+ for row in work_order.operations:
+ row.time_in_mins = 60
+ work_order.save()
+ work_order.submit()
+
+ make_stock_entry(item_code=rm, target=warehouse, qty=100, basic_rate=100)
+
+ def get_job_card(operation):
+ return frappe.get_doc(
+ "Job Card",
+ frappe.db.get_value(
+ "Job Card",
+ {"work_order": work_order.name, "operation": operation, "docstatus": 0},
+ "name",
+ ),
+ )
+
+ jc_a = get_job_card("Intermediate Loss Op A")
+ jc_a.append("time_logs", {"from_time": "2024-06-01 08:00:00"})
+ jc_a.save()
+ jc_a.complete_job_card(
+ qty=8, for_quantity=10, pending_qty=0, process_loss_qty=2, end_time="2024-06-01 09:00:00"
+ )
+ jc_a.reload()
+ jc_a.submit()
+ frappe.get_doc(jc_a.make_stock_entry_for_semi_fg_item()).submit()
+
+ work_order.reload()
+ self.assertEqual(flt(work_order.process_loss_qty), 2)
+
+ # Operation A handed over only 8 units, so the final operation works on 8.
+ jc_b = get_job_card("Intermediate Loss Op B")
+ jc_b.for_quantity = 8
+ for row in jc_b.items:
+ row.required_qty = 8
+ jc_b.append(
+ "time_logs",
+ {"from_time": "2024-06-02 08:00:00", "to_time": "2024-06-02 09:00:00", "completed_qty": 8},
+ )
+ jc_b.save()
+ jc_b.submit()
+ frappe.get_doc(jc_b.make_stock_entry_for_semi_fg_item()).submit()
+
+ work_order.reload()
+ self.assertEqual(flt(work_order.produced_qty), 8)
+ self.assertEqual(flt(work_order.process_loss_qty), 2)
+ self.assertEqual(work_order.status, "Completed")
+
def test_semi_fg_sequence_needs_previous_operations_manufactured(self):
from erpnext.manufacturing.doctype.operation.test_operation import make_operation
from erpnext.stock.doctype.item.test_item import make_item
@@ -1726,6 +1924,299 @@ class TestJobCard(ERPNextTestSuite):
consumed_batches = get_batches_from_bundle(sfg_consume_row.serial_and_batch_bundle)
self.assertEqual(set(consumed_batches.keys()), set(produced_batches.keys()))
+ def test_manufacture_entry_process_loss_not_taken_from_previous_operation(self):
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ warehouse = "Stores - _TC"
+ rm1 = make_item("PL Scope RM 1", {"is_stock_item": 1}).name
+ rm2 = make_item("PL Scope RM 2", {"is_stock_item": 1}).name
+ sfg = make_item("PL Scope SFG 1", {"is_stock_item": 1}).name
+ fg1 = make_item("PL Scope FG 1", {"is_stock_item": 1}).name
+
+ sfg_bom = frappe.new_doc("BOM", company="_Test Company", item=sfg, quantity=1)
+ sfg_bom.append("items", {"item_code": rm1, "qty": 1})
+ sfg_bom.insert()
+ sfg_bom.submit()
+
+ fg_bom = frappe.new_doc(
+ "BOM",
+ company="_Test Company",
+ item=fg1,
+ quantity=1,
+ with_operations=1,
+ track_semi_finished_goods=1,
+ )
+ operation1 = {
+ "operation": "PL Scope Op A",
+ "workstation": "_Test Workstation A",
+ "finished_good": sfg,
+ "bom_no": sfg_bom.name,
+ "finished_good_qty": 1,
+ "sequence_id": 1,
+ "time_in_mins": 60,
+ "source_warehouse": warehouse,
+ "fg_warehouse": warehouse,
+ "skip_material_transfer": 1,
+ }
+ operation2 = {
+ "operation": "PL Scope Op B",
+ "workstation": "_Test Workstation A",
+ "finished_good": fg1,
+ "finished_good_qty": 1,
+ "is_final_finished_good": 1,
+ "sequence_id": 2,
+ "time_in_mins": 60,
+ "source_warehouse": warehouse,
+ "fg_warehouse": warehouse,
+ "skip_material_transfer": 1,
+ }
+ make_workstation(operation1)
+ make_operation(operation1)
+ make_operation(operation2)
+ fg_bom.append("operations", operation1)
+ fg_bom.append("operations", operation2)
+ fg_bom.append("items", {"item_code": rm2, "qty": 1})
+ fg_bom.append("items", {"item_code": sfg, "qty": 1, "operation_row_id": 2})
+ fg_bom.insert()
+ fg_bom.submit()
+
+ work_order = make_wo_order_test_record(
+ item=fg1,
+ qty=5,
+ source_warehouse=warehouse,
+ fg_warehouse=warehouse,
+ bom_no=fg_bom.name,
+ skip_transfer=1,
+ )
+
+ make_stock_entry(item_code=rm1, target=warehouse, qty=10, basic_rate=100)
+ make_stock_entry(item_code=rm2, target=warehouse, qty=10, basic_rate=100)
+ make_stock_entry(item_code=sfg, target=warehouse, qty=10, basic_rate=100)
+
+ jc_a = frappe.get_doc(
+ "Job Card",
+ frappe.db.get_value(
+ "Job Card", {"work_order": work_order.name, "operation": "PL Scope Op A"}, "name"
+ ),
+ )
+ jc_a.append(
+ "time_logs",
+ {"from_time": "2024-01-01 08:00:00", "to_time": "2024-01-01 09:00:00", "completed_qty": 3},
+ )
+ jc_a.pending_qty = 0
+ jc_a.process_loss_qty = 2
+ jc_a.submit()
+ me_a = frappe.get_doc(jc_a.make_stock_entry_for_semi_fg_item())
+ me_a.submit()
+ self.assertEqual(flt(me_a.process_loss_qty), 2.0)
+
+ jc_b = frappe.get_doc(
+ "Job Card",
+ frappe.db.get_value(
+ "Job Card", {"work_order": work_order.name, "operation": "PL Scope Op B"}, "name"
+ ),
+ )
+ jc_b.append(
+ "time_logs",
+ {"from_time": "2024-02-01 08:00:00", "to_time": "2024-02-01 09:00:00", "completed_qty": 3},
+ )
+ jc_b.pending_qty = 2
+ jc_b.submit()
+ me_b = frappe.get_doc(jc_b.make_stock_entry_for_semi_fg_item())
+
+ # operation A's loss must not leak into operation B's entry
+ self.assertEqual(flt(me_b.process_loss_qty), 0.0)
+ fg_row = next(row for row in me_b.items if row.is_finished_item)
+ self.assertEqual(flt(fg_row.qty), 3.0)
+ me_b.submit()
+
+ def make_semi_fg_work_order(self, prefix, qty=5):
+ """Two-operation semi FG work order: Op A makes the SFG from RM 1, final Op B
+ consumes it. Both operations skip material transfer; stock is pre-seeded."""
+ from erpnext.manufacturing.doctype.operation.test_operation import make_operation
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ warehouse = "Stores - _TC"
+ rm1 = make_item(f"{prefix} RM 1", {"is_stock_item": 1}).name
+ rm2 = make_item(f"{prefix} RM 2", {"is_stock_item": 1}).name
+ sfg = make_item(f"{prefix} SFG 1", {"is_stock_item": 1}).name
+ fg1 = make_item(f"{prefix} FG 1", {"is_stock_item": 1}).name
+
+ sfg_bom = frappe.new_doc("BOM", company="_Test Company", item=sfg, quantity=1)
+ sfg_bom.append("items", {"item_code": rm1, "qty": 1})
+ sfg_bom.insert()
+ sfg_bom.submit()
+
+ fg_bom = frappe.new_doc(
+ "BOM",
+ company="_Test Company",
+ item=fg1,
+ quantity=1,
+ with_operations=1,
+ track_semi_finished_goods=1,
+ )
+ operation1 = {
+ "operation": f"{prefix} Op A",
+ "workstation": "_Test Workstation A",
+ "finished_good": sfg,
+ "bom_no": sfg_bom.name,
+ "finished_good_qty": 1,
+ "sequence_id": 1,
+ "time_in_mins": 60,
+ "source_warehouse": warehouse,
+ "fg_warehouse": warehouse,
+ "skip_material_transfer": 1,
+ }
+ operation2 = {
+ "operation": f"{prefix} Op B",
+ "workstation": "_Test Workstation A",
+ "finished_good": fg1,
+ "finished_good_qty": 1,
+ "is_final_finished_good": 1,
+ "sequence_id": 2,
+ "time_in_mins": 60,
+ "source_warehouse": warehouse,
+ "fg_warehouse": warehouse,
+ "skip_material_transfer": 1,
+ }
+ make_workstation(operation1)
+ make_operation(operation1)
+ make_operation(operation2)
+ fg_bom.append("operations", operation1)
+ fg_bom.append("operations", operation2)
+ fg_bom.append("items", {"item_code": rm2, "qty": 1})
+ fg_bom.append("items", {"item_code": sfg, "qty": 1, "operation_row_id": 2})
+ fg_bom.insert()
+ fg_bom.submit()
+
+ work_order = make_wo_order_test_record(
+ item=fg1,
+ qty=qty,
+ source_warehouse=warehouse,
+ fg_warehouse=warehouse,
+ bom_no=fg_bom.name,
+ skip_transfer=1,
+ )
+
+ for item_code in (rm1, rm2, sfg):
+ make_stock_entry(item_code=item_code, target=warehouse, qty=10, basic_rate=100)
+
+ return work_order
+
+ def get_semi_fg_job_card(self, work_order, operation):
+ return frappe.get_doc(
+ "Job Card",
+ frappe.db.get_value("Job Card", {"work_order": work_order.name, "operation": operation}, "name"),
+ )
+
+ def test_partial_manufacture_entry_then_finish(self):
+ work_order = self.make_semi_fg_work_order("PL Partial")
+
+ jc_a = self.get_semi_fg_job_card(work_order, "PL Partial Op A")
+ jc_a.append(
+ "time_logs",
+ {"from_time": "2024-01-01 08:00:00", "to_time": "2024-01-01 09:00:00", "completed_qty": 5},
+ )
+ jc_a.submit()
+ frappe.get_doc(jc_a.make_stock_entry_for_semi_fg_item()).submit()
+
+ jc_b = self.get_semi_fg_job_card(work_order, "PL Partial Op B")
+ jc_b.append(
+ "time_logs",
+ {"from_time": "2024-02-01 08:00:00", "to_time": "2024-02-01 09:00:00", "completed_qty": 3},
+ )
+ jc_b.pending_qty = 0
+ jc_b.process_loss_qty = 2
+ jc_b.submit()
+
+ # book 1 of the 3 finished units now; the full process loss goes with this first entry,
+ # so it accounts for 3 of 5 and its materials are trimmed to the same share
+ first = frappe.get_doc(jc_b.make_stock_entry_for_semi_fg_item())
+ fg_row = next(row for row in first.items if row.is_finished_item)
+ fg_row.qty = 1
+ for row in first.items:
+ if row.s_warehouse and not row.is_finished_item:
+ row.qty = flt(row.qty) * 3 / 5
+ first.save()
+ first.submit()
+
+ # the follow-up entry must be generated net of the already-booked loss and still submit
+ jc_b.reload()
+ second = frappe.get_doc(jc_b.make_stock_entry_for_semi_fg_item())
+ fg_row = next(row for row in second.items if row.is_finished_item)
+ self.assertEqual(flt(fg_row.qty), 2.0)
+ self.assertEqual(flt(second.process_loss_qty), 0.0)
+ second.submit()
+
+ jc_b.reload()
+ self.assertEqual(flt(jc_b.manufactured_qty), 3.0)
+
+ # across both entries, consumption adds up to the job card's requirement of 5, no more
+ consumed = frappe.get_all(
+ "Stock Entry Detail",
+ filters={"parent": ["in", [first.name, second.name]], "s_warehouse": ["is", "set"]},
+ fields=["item_code", {"SUM": "qty", "as": "qty"}],
+ group_by="item_code",
+ )
+ self.assertTrue(consumed)
+ for row in consumed:
+ self.assertEqual(flt(row.qty), 5.0, f"{row.item_code} mis-consumed across partial entries")
+
+ def test_update_after_submit_keeps_manufacture_entry_intact(self):
+ work_order = self.make_semi_fg_work_order("PL Update")
+
+ jc_a = self.get_semi_fg_job_card(work_order, "PL Update Op A")
+ jc_a.append(
+ "time_logs",
+ {"from_time": "2024-01-01 08:00:00", "to_time": "2024-01-01 09:00:00", "completed_qty": 3},
+ )
+ jc_a.pending_qty = 0
+ jc_a.process_loss_qty = 2
+ jc_a.submit()
+
+ entry = frappe.get_doc(jc_a.make_stock_entry_for_semi_fg_item())
+ entry.submit()
+
+ if not frappe.db.exists("Print Heading", "_Test SFG Heading"):
+ frappe.get_doc({"doctype": "Print Heading", "print_heading": "_Test SFG Heading"}).insert()
+
+ entry.reload()
+ entry.select_print_heading = "_Test SFG Heading"
+ entry.save()
+
+ entry.reload()
+ self.assertEqual(flt(entry.process_loss_qty), 2.0)
+
+ def test_stale_manufacture_draft_cannot_over_produce_without_operation_bom(self):
+ work_order = self.make_semi_fg_work_order("PL NoBom")
+
+ jc_a = self.get_semi_fg_job_card(work_order, "PL NoBom Op A")
+ jc_a.append(
+ "time_logs",
+ {"from_time": "2024-01-01 08:00:00", "to_time": "2024-01-01 09:00:00", "completed_qty": 5},
+ )
+ jc_a.submit()
+ frappe.get_doc(jc_a.make_stock_entry_for_semi_fg_item()).submit()
+
+ # Op B has no operation BOM, so its entries carry no For Quantity to validate against
+ jc_b = self.get_semi_fg_job_card(work_order, "PL NoBom Op B")
+ jc_b.append(
+ "time_logs",
+ {"from_time": "2024-02-01 08:00:00", "to_time": "2024-02-01 09:00:00", "completed_qty": 3},
+ )
+ jc_b.pending_qty = 0
+ jc_b.process_loss_qty = 2
+ jc_b.submit()
+
+ draft_one = frappe.get_doc(jc_b.make_stock_entry_for_semi_fg_item())
+ draft_two = frappe.get_doc(jc_b.make_stock_entry_for_semi_fg_item())
+
+ draft_one.submit()
+
+ stale = frappe.get_doc("Stock Entry", draft_two.name)
+ self.assertRaises(frappe.ValidationError, stale.submit)
+
def test_semi_fg_auto_pull_with_uom_conversion(self):
from erpnext.manufacturing.doctype.operation.test_operation import make_operation
from erpnext.stock.doctype.item.test_item import make_item
@@ -2302,3 +2793,43 @@ class TestJobCardLogic(ERPNextTestSuite):
self.assertTrue(jc.has_overlap(1, sequential))
self.assertFalse(jc.has_overlap(2, sequential))
self.assertTrue(jc.has_overlap(2, overlapping))
+
+ def test_previous_operation_shortfall_from_process_loss_gets_the_right_message(self):
+ jc = frappe.new_doc("Job Card")
+ jc.operation = "_Test Painting"
+ jc.stock_uom = "Nos"
+ row = frappe._dict(
+ operation="_Test Assembly", manufactured_qty=8, process_loss_qty=2, finished_good=None
+ )
+
+ with self.assertRaises(OperationSequenceError) as loss_error:
+ jc.validate_previous_operation_manufactured_qty(row, 10)
+ self.assertIn("process loss", str(loss_error.exception))
+
+ row.process_loss_qty = 0
+ with self.assertRaises(OperationSequenceError) as pending_error:
+ jc.validate_previous_operation_manufactured_qty(row, 10)
+ self.assertIn("Submit the manufacturing entry", str(pending_error.exception))
+
+ jc.validate_previous_operation_manufactured_qty(row, 8)
+
+ def test_semi_fg_job_card_is_exempt_from_transfer_qty_check(self):
+ jc = frappe.new_doc("Job Card")
+ jc.track_semi_finished_goods = 1
+ jc.skip_material_transfer = 1
+ jc.for_quantity = 10
+ jc.transferred_qty = 0
+ jc.append("items", {"item_code": "_Test Item"})
+
+ jc.validate_transfer_qty()
+
+ # with transfer enabled, a legacy card without an FG item keeps the strict check
+ jc.skip_material_transfer = 0
+ self.assertRaises(frappe.ValidationError, jc.validate_transfer_qty)
+
+ jc.finished_good = "_Test Item"
+ jc.validate_transfer_qty()
+
+ jc.finished_good = None
+ jc.track_semi_finished_goods = 0
+ self.assertRaises(frappe.ValidationError, jc.validate_transfer_qty)
diff --git a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
index 8bc37d2e02d..088338b4f2d 100644
--- a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
+++ b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
@@ -193,6 +193,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -266,7 +267,7 @@
"grid_page_length": 50,
"istable": 1,
"links": [],
- "modified": "2025-10-30 17:01:25.996352",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Material Request Plan Item",
diff --git a/erpnext/manufacturing/doctype/production_plan/services/material_request.py b/erpnext/manufacturing/doctype/production_plan/services/material_request.py
index 9e6d26bd963..7027c83af04 100644
--- a/erpnext/manufacturing/doctype/production_plan/services/material_request.py
+++ b/erpnext/manufacturing/doctype/production_plan/services/material_request.py
@@ -11,6 +11,7 @@ existing imports of ``...services.material_planning`` keep working through here.
import copy
import json
from collections import defaultdict
+from decimal import ROUND_CEILING, Decimal
import frappe
from frappe import _, msgprint
@@ -493,8 +494,16 @@ def get_material_request_items(
)
item_group_defaults = get_item_group_defaults(row.item_code, company)
conversion_factor = _mr_purchase_conversion_factor(row)
+ min_order_qty = flt(row.get("min_order_qty")) if doc.get("consider_minimum_order_qty") else 0
return _material_request_item_row(
- row, sales_order, target_warehouse, bin_dict, required_qty, conversion_factor, item_group_defaults
+ row,
+ sales_order,
+ target_warehouse,
+ bin_dict,
+ required_qty,
+ conversion_factor,
+ item_group_defaults,
+ min_order_qty,
)
@@ -533,13 +542,24 @@ def _adjust_required_qty_for_uom(row, required_qty):
row["purchase_uom"], row["stock_uom"], row.item_code
)
)
- required_qty = required_qty / row["conversion_factor"]
if frappe.db.get_value("UOM", row["purchase_uom"], "must_be_whole_number"):
required_qty = ceil(required_qty)
return required_qty
+def _quantity_in_purchase_uom(required_qty, conversion_factor, min_order_qty=0):
+ """Convert to purchase UOM; a binding minimum order qty takes the smallest
+ representable quantity whose stock equivalent still meets it."""
+ precision = frappe.get_precision("Material Request Plan Item", "quantity")
+ quantity = flt(required_qty / conversion_factor, precision)
+ if min_order_qty and quantity * conversion_factor < min_order_qty <= required_qty:
+ grid = Decimal(10) ** -precision
+ exact = Decimal(str(min_order_qty)) / Decimal(str(conversion_factor))
+ quantity = flt(exact.quantize(grid, rounding=ROUND_CEILING))
+ return quantity
+
+
def _mr_purchase_conversion_factor(row):
item_details = frappe.get_cached_value("Item", row.item_code, ["purchase_uom", "stock_uom"], as_dict=1)
if (
@@ -552,7 +572,14 @@ def _mr_purchase_conversion_factor(row):
def _material_request_item_row(
- row, sales_order, warehouse, bin_dict, required_qty, conversion_factor, item_group_defaults
+ row,
+ sales_order,
+ warehouse,
+ bin_dict,
+ required_qty,
+ conversion_factor,
+ item_group_defaults,
+ min_order_qty=0,
):
warehouse = (
warehouse
@@ -563,7 +590,7 @@ def _material_request_item_row(
return {
"item_code": row.item_code,
"item_name": row.item_name,
- "quantity": required_qty / conversion_factor,
+ "quantity": _quantity_in_purchase_uom(required_qty, conversion_factor, min_order_qty),
"conversion_factor": conversion_factor,
"required_bom_qty": row.get("qty"),
"stock_uom": row.get("stock_uom"),
@@ -640,7 +667,8 @@ def _add_remaining_purchase_request(item, new_mr_items, required_qty, consider_m
if frappe.db.get_value("UOM", purchase_uom, "must_be_whole_number"):
required_qty = ceil(required_qty)
- item["quantity"] = required_qty / item.get("conversion_factor")
+ min_order_qty = flt(item.get("min_order_qty")) if consider_minimum_order_qty else 0
+ item["quantity"] = _quantity_in_purchase_uom(required_qty, item.get("conversion_factor"), min_order_qty)
new_mr_items.append(item)
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index 5917804c411..2732aa7046e 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -1367,6 +1367,29 @@ class TestProductionPlan(ERPNextTestSuite):
self.assertEqual(row.uom, "Nos")
self.assertEqual(row.qty, 1)
+ def test_material_request_item_quantity_rounded_to_precision(self):
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ fg_item = make_item(properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1"}).name
+ bom_item = make_item(
+ properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1", "purchase_uom": "Nos"}
+ ).name
+
+ if not frappe.db.exists("UOM Conversion Detail", {"parent": bom_item, "uom": "Nos"}):
+ doc = frappe.get_doc("Item", bom_item)
+ doc.append("uoms", {"uom": "Nos", "conversion_factor": 3})
+ doc.save()
+
+ make_bom(item=fg_item, raw_materials=[bom_item], source_warehouse="_Test Warehouse - _TC")
+
+ pln = create_production_plan(
+ item_code=fg_item, planned_qty=10, ignore_existing_ordered_qty=1, stock_uom="_Test UOM 1"
+ )
+
+ precision = frappe.get_precision("Material Request Plan Item", "quantity")
+ self.assertEqual(len(pln.mr_items), 1)
+ self.assertEqual(pln.mr_items[0].quantity, flt(10 / 3, precision))
+
def test_material_request_for_sub_assembly_items(self):
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
@@ -2252,6 +2275,40 @@ class TestProductionPlan(ERPNextTestSuite):
self.assertEqual(row.get("uom"), "Nos")
self.assertEqual(row.get("conversion_factor"), 10.0)
+ def test_remaining_purchase_qty_rounded_to_precision(self):
+ from erpnext.stock.doctype.item.test_item import make_item
+ from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+
+ fg_item = make_item(properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1"}).name
+ bom_item = make_item(
+ properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1", "purchase_uom": "Nos"}
+ ).name
+
+ store_warehouse = create_warehouse("Store Warehouse", company="_Test Company")
+ rm_warehouse = create_warehouse("RM Warehouse", company="_Test Company")
+
+ make_stock_entry(item_code=bom_item, qty=4, target=store_warehouse, rate=100)
+
+ if not frappe.db.exists("UOM Conversion Detail", {"parent": bom_item, "uom": "Nos"}):
+ doc = frappe.get_doc("Item", bom_item)
+ doc.append("uoms", {"uom": "Nos", "conversion_factor": 3})
+ doc.save()
+
+ make_bom(item=fg_item, raw_materials=[bom_item], source_warehouse="_Test Warehouse - _TC")
+
+ pln = create_production_plan(
+ item_code=fg_item, planned_qty=30, stock_uom="_Test UOM 1", do_not_submit=1
+ )
+ pln.for_warehouse = rm_warehouse
+ pln.ignore_existing_ordered_qty = 1
+ items = get_items_for_material_requests(pln.as_dict(), warehouses=[{"warehouse": store_warehouse}])
+
+ rows_by_type = {row.get("material_request_type"): row for row in items}
+ self.assertEqual(rows_by_type["Material Transfer"].get("quantity"), 4)
+
+ precision = frappe.get_precision("Material Request Plan Item", "quantity")
+ self.assertEqual(rows_by_type["Purchase"].get("quantity"), flt(26 / 3, precision))
+
def test_unreserve_qty_on_closing_of_pp(self):
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
from erpnext.stock.utils import get_or_make_bin
@@ -2327,6 +2384,73 @@ class TestProductionPlan(ERPNextTestSuite):
self.assertEqual(items_by_type["Material Transfer"].get("quantity"), 7.0)
self.assertEqual(items_by_type["Purchase"].get("quantity"), 1000.0)
+ def test_min_order_qty_conversion_takes_grid_ceiling(self):
+ from erpnext.manufacturing.doctype.production_plan.services.material_request import (
+ _quantity_in_purchase_uom,
+ )
+
+ original_precision = frappe.db.get_default("float_precision")
+ frappe.db.set_default("float_precision", "3")
+ self.addCleanup(frappe.db.set_default, "float_precision", original_precision)
+
+ self.assertEqual(_quantity_in_purchase_uom(50000, 453.592292197, 50000), 110.232)
+ self.assertEqual(_quantity_in_purchase_uom(2000, 0.453592, 2000), 4409.249)
+ self.assertEqual(_quantity_in_purchase_uom(10, 0.5, 10), 20.0)
+ self.assertEqual(_quantity_in_purchase_uom(50000, 453.592292197), 110.231)
+
+ def test_min_order_qty_grid_ceiling_in_plan_items(self):
+ original_precision = frappe.db.get_default("float_precision")
+ frappe.db.set_default("float_precision", "3")
+ self.addCleanup(frappe.db.set_default, "float_precision", original_precision)
+
+ conversion_factor = 453.592292197
+ fg_item = make_item(properties={"is_stock_item": 1}).name
+ rm_item = make_item(
+ properties={"is_stock_item": 1, "min_order_qty": 50000, "purchase_uom": "_Test UOM 1"},
+ uoms=[{"uom": "_Test UOM 1", "conversion_factor": conversion_factor}],
+ ).name
+
+ make_bom(item=fg_item, raw_materials=[rm_item], source_warehouse="_Test Warehouse - _TC")
+
+ pln = create_production_plan(item_code=fg_item, planned_qty=1, do_not_submit=1)
+ pln.consider_minimum_order_qty = 1
+ mr_items = get_items_for_material_requests(pln.as_dict())
+
+ self.assertEqual(mr_items[0].get("quantity"), 110.232)
+ self.assertGreaterEqual(mr_items[0].get("quantity") * conversion_factor, 50000)
+
+ def test_min_order_qty_grid_ceiling_from_other_locations(self):
+ from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+
+ original_precision = frappe.db.get_default("float_precision")
+ frappe.db.set_default("float_precision", "3")
+ self.addCleanup(frappe.db.set_default, "float_precision", original_precision)
+
+ conversion_factor = 453.592292197
+ fg_item = make_item(properties={"is_stock_item": 1}).name
+ rm_item = make_item(
+ properties={"is_stock_item": 1, "min_order_qty": 50000, "purchase_uom": "_Test UOM 1"},
+ uoms=[{"uom": "_Test UOM 1", "conversion_factor": conversion_factor}],
+ ).name
+
+ rm_warehouse = create_warehouse("MOQ Ceiling RM Warehouse", company="_Test Company")
+ source_warehouse = create_warehouse("MOQ Ceiling Source Warehouse", company="_Test Company")
+ make_stock_entry(item_code=rm_item, qty=4, rate=100, target=source_warehouse)
+
+ make_bom(item=fg_item, raw_materials=[rm_item], source_warehouse="_Test Warehouse - _TC")
+
+ pln = create_production_plan(item_code=fg_item, planned_qty=10, do_not_submit=1)
+ pln.for_warehouse = rm_warehouse
+ pln.consider_minimum_order_qty = 1
+ pln.ignore_existing_ordered_qty = 1
+ mr_items = get_items_for_material_requests(
+ pln.as_dict(), warehouses=[{"warehouse": source_warehouse}]
+ )
+
+ rows_by_type = {d.get("material_request_type"): d for d in mr_items}
+ self.assertEqual(rows_by_type["Material Transfer"].get("quantity"), 4)
+ self.assertEqual(rows_by_type["Purchase"].get("quantity"), 110.232)
+
def test_fg_item_quantity(self):
fg_item = make_item(properties={"is_stock_item": 1}).name
rm_item = make_item(properties={"is_stock_item": 1}).name
diff --git a/erpnext/manufacturing/doctype/work_order/mapper.py b/erpnext/manufacturing/doctype/work_order/mapper.py
index c726b9e38fc..7287a9ecb74 100644
--- a/erpnext/manufacturing/doctype/work_order/mapper.py
+++ b/erpnext/manufacturing/doctype/work_order/mapper.py
@@ -9,6 +9,7 @@ the controller; work_order.py re-exports them for backward compatibility.
"""
import json
+import math
from functools import partial
import frappe
@@ -476,42 +477,104 @@ def create_pick_list(
):
frappe.has_permission("Pick List", "create", throw=True)
- for_qty = for_qty or frappe.parse_json(target_doc).get("for_qty")
- max_finished_goods_qty = frappe.db.get_value("Work Order", source_name, "qty")
- postprocess = partial(
- _set_pick_list_item_qty, for_qty=for_qty, max_finished_goods_qty=max_finished_goods_qty
- )
+ if for_qty is None:
+ for_qty = frappe.parse_json(target_doc or "{}").get("for_qty")
- doc = get_mapped_doc("Work Order", source_name, _pick_list_mapping(postprocess), target_doc)
+ for_qty = _validated_for_qty(for_qty)
+ work_order = frappe.get_doc("Work Order", source_name)
+ allocation = _allocate_material_demand(work_order, for_qty / flt(work_order.qty))
+ postprocess = partial(_set_pick_list_item_qty, allocation_by_item=allocation)
+
+ doc = get_mapped_doc("Work Order", source_name, _pick_list_mapping(postprocess, allocation), target_doc)
+ _validate_material_is_pending(doc.locations)
doc.purpose = "Material Transfer for Manufacture"
doc.for_qty = for_qty
doc.set_item_locations()
return doc
-def _pick_list_mapping(postprocess):
+def _pick_list_mapping(postprocess, allocation):
return {
"Work Order": {"doctype": "Pick List", "validation": {"docstatus": ["=", 1]}},
"Work Order Item": {
"doctype": "Pick List Item",
"field_no_map": ["transferred_qty"],
"postprocess": postprocess,
- "condition": lambda doc: abs(doc.transferred_qty) < abs(doc.required_qty),
+ "condition": lambda doc: _allocation_key(doc) in allocation,
},
}
-def _set_pick_list_item_qty(source, target, source_parent, for_qty, max_finished_goods_qty):
- pending_to_issue = flt(source.required_qty) - flt(source.transferred_qty)
- desire_to_transfer = flt(source.required_qty) / max_finished_goods_qty * flt(for_qty)
+def _allocate_material_demand(work_order, fraction):
+ """Fraction of each (item, warehouse, operation row) group's requirement, capped
+ at the group's proportional share of the item's pending pool."""
+ required_by_item = {}
+ covered_by_item = {}
+ required_by_group = {}
+ for row in work_order.required_items:
+ required_by_item[row.item_code] = required_by_item.get(row.item_code, 0.0) + flt(row.required_qty)
+ covered_by_item.setdefault(
+ row.item_code,
+ flt(row.transferred_qty) + flt(row.requested_qty) + flt(row.picked_qty),
+ )
+ key = _allocation_key(row)
+ required_by_group[key] = required_by_group.get(key, 0.0) + flt(row.required_qty)
- qty = 0
- if desire_to_transfer <= pending_to_issue:
- qty = desire_to_transfer
- elif pending_to_issue > 0:
- qty = pending_to_issue
+ pending_pool = {
+ item_code: required_qty - covered_by_item[item_code]
+ for item_code, required_qty in required_by_item.items()
+ }
- if not qty:
+ allocation = {}
+ for key, required_qty in required_by_group.items():
+ item_code = key[0]
+ if required_by_item[item_code] <= 0:
+ continue
+
+ pool_share = pending_pool[item_code] * required_qty / required_by_item[item_code]
+ qty = min(required_qty * fraction, pool_share)
+ if qty > 0:
+ allocation[key] = qty
+ return allocation
+
+
+def _allocation_key(row):
+ """Manual rows have no operation_row_id; their operation label splits them."""
+ return (row.item_code, row.source_warehouse, cint(row.operation_row_id) or row.operation)
+
+
+def _merge_allocation_per_item(allocation):
+ """Material Request rejects repeated item codes unless Buying Settings allows them."""
+ merged = {}
+ key_by_item = {}
+ for key, qty in allocation.items():
+ item_code = key[0]
+ if item_code in key_by_item:
+ merged[key_by_item[item_code]] += qty
+ else:
+ key_by_item[item_code] = key
+ merged[key] = qty
+ return merged
+
+
+def _validated_for_qty(for_qty):
+ qty = flt(for_qty)
+ if not math.isfinite(qty) or qty <= 0:
+ frappe.throw(_("Quantity must be greater than zero."))
+ return qty
+
+
+def _validate_material_is_pending(rows):
+ if not rows:
+ frappe.throw(
+ _("All required items have already been transferred, requested or picked."),
+ title=_("No Pending Materials"),
+ )
+
+
+def _set_pick_list_item_qty(source, target, source_parent, allocation_by_item):
+ qty = allocation_by_item.pop(_allocation_key(source), 0.0)
+ if qty <= 0:
target.delete()
return
@@ -523,15 +586,32 @@ def _set_pick_list_item_qty(source, target, source_parent, for_qty, max_finished
@frappe.whitelist()
-def make_material_request(source_name: str, target_doc: str | dict | Document | None = None):
+def make_material_request(
+ source_name: str, target_doc: str | dict | Document | None = None, for_qty: float | None = None
+):
frappe.has_permission("Material Request", "create", throw=True)
- doc = get_mapped_doc("Work Order", source_name, _material_request_mapping(), target_doc)
+ if for_qty is None and frappe.flags.args:
+ for_qty = frappe.flags.args.for_qty
+
+ work_order = frappe.get_doc("Work Order", source_name)
+ fraction = 1.0
+ if for_qty is not None:
+ fraction = _validated_for_qty(for_qty) / flt(work_order.qty)
+
+ allocation = _allocate_material_demand(work_order, fraction)
+ if not cint(frappe.db.get_single_value("Buying Settings", "allow_multiple_items")):
+ allocation = _merge_allocation_per_item(allocation)
+ postprocess = partial(_set_material_request_item, allocation_by_item=allocation)
+ doc = get_mapped_doc(
+ "Work Order", source_name, _material_request_mapping(postprocess, allocation), target_doc
+ )
+ _validate_material_is_pending(doc.items)
doc.material_request_type = "Material Transfer"
return doc
-def _material_request_mapping():
+def _material_request_mapping(postprocess, allocation):
return {
"Work Order": {
"doctype": "Material Request",
@@ -541,19 +621,23 @@ def _material_request_mapping():
"Work Order Item": {
"doctype": "Material Request Item",
"field_map": [
- ("required_qty", "qty"),
("stock_uom", "uom"),
("source_warehouse", "from_warehouse"),
],
- "postprocess": _set_material_request_item,
- "condition": lambda doc: abs(doc.transferred_qty) < abs(doc.required_qty),
+ "postprocess": postprocess,
+ "condition": lambda doc: _allocation_key(doc) in allocation,
},
}
-def _set_material_request_item(source, target, source_parent):
+def _set_material_request_item(source, target, source_parent, allocation_by_item):
+ qty = allocation_by_item.pop(_allocation_key(source), 0.0)
+ if qty <= 0:
+ target.delete()
+ return
+
target.warehouse = source_parent.wip_warehouse
- target.qty = flt(source.required_qty) - flt(source.transferred_qty)
+ target.qty = qty
target.schedule_date = nowdate()
diff --git a/erpnext/manufacturing/doctype/work_order/services/required_items.py b/erpnext/manufacturing/doctype/work_order/services/required_items.py
index c1c55977583..09f0e3ab32c 100644
--- a/erpnext/manufacturing/doctype/work_order/services/required_items.py
+++ b/erpnext/manufacturing/doctype/work_order/services/required_items.py
@@ -9,6 +9,7 @@ callers and the whitelisted entry point keep working unchanged.
"""
import frappe
+from frappe import _
from frappe.utils import flt
from pypika import functions as fn
@@ -198,6 +199,97 @@ class RequiredItemsService:
for row in self.doc.required_items:
row.db_set("returned_qty", (returned_dict.get(row.item_code) or 0.0), update_modified=False)
+ def validate_incoming_material_demand(self, incoming_qty_by_item):
+ """Reject demand exceeding the pending requirement; callers must hold the
+ work order row lock (for_update=True)."""
+ required_by_item = {}
+ uom_by_item = {}
+ for row in self.doc.required_items:
+ required_by_item[row.item_code] = required_by_item.get(row.item_code, 0.0) + flt(row.required_qty)
+ uom_by_item.setdefault(row.item_code, row.stock_uom)
+
+ transferred = self._material_transfer_qty_by_item(is_return=0)
+ requested = self._material_request_pending_qty_by_item()
+ picked = self._pick_list_pending_qty_by_item()
+
+ for item_code, incoming_qty in incoming_qty_by_item.items():
+ if item_code not in required_by_item:
+ continue
+
+ pending = (
+ required_by_item[item_code]
+ - flt(transferred.get(item_code))
+ - flt(requested.get(item_code))
+ - flt(picked.get(item_code))
+ )
+ if flt(incoming_qty - pending, 6) > 0:
+ frappe.throw(
+ _("Only {0} {1} of {2} is pending in Work Order {3}.").format(
+ max(pending, 0.0), uom_by_item[item_code], item_code, self.doc.name
+ ),
+ title=_("Exceeds Pending Qty"),
+ )
+
+ def update_requested_qty_for_required_items(self):
+ """Refresh per-row qty requested via open Material Requests but not yet transferred."""
+ requested_items = self._material_request_pending_qty_by_item()
+ for row in self.doc.required_items:
+ row.db_set("requested_qty", (requested_items.get(row.item_code) or 0.0), update_modified=False)
+
+ def _material_request_pending_qty_by_item(self):
+ mr = frappe.qb.DocType("Material Request")
+ mr_item = frappe.qb.DocType("Material Request Item")
+ query = (
+ frappe.qb.from_(mr)
+ .inner_join(mr_item)
+ .on(mr_item.parent == mr.name)
+ .select(mr_item.item_code, fn.Sum(mr_item.stock_qty - mr_item.ordered_qty).as_("qty"))
+ .where(
+ (mr.docstatus == 1)
+ & (mr.work_order == self.doc.name)
+ & (mr.material_request_type == "Material Transfer")
+ & (mr.status != "Stopped")
+ & (mr_item.stock_qty > mr_item.ordered_qty)
+ )
+ .groupby(mr_item.item_code)
+ )
+ return frappe._dict({d.item_code: flt(d.qty) for d in query.run(as_dict=1)})
+
+ def update_picked_qty_for_required_items(self):
+ """Refresh per-row qty picked but not yet transferred. Rows of a live material
+ request count as requested_qty instead, until that request stops or cancels."""
+ picked_items = self._pick_list_pending_qty_by_item()
+ for row in self.doc.required_items:
+ row.db_set("picked_qty", (picked_items.get(row.item_code) or 0.0), update_modified=False)
+
+ def _pick_list_pending_qty_by_item(self):
+ pick_list = frappe.qb.DocType("Pick List")
+ pick_list_item = frappe.qb.DocType("Pick List Item")
+ mr = frappe.qb.DocType("Material Request")
+ query = (
+ frappe.qb.from_(pick_list)
+ .inner_join(pick_list_item)
+ .on(pick_list_item.parent == pick_list.name)
+ .left_join(mr)
+ .on(pick_list_item.material_request == mr.name)
+ .select(
+ pick_list_item.item_code,
+ fn.Sum(pick_list_item.picked_qty - pick_list_item.transferred_qty).as_("qty"),
+ )
+ .where(
+ (pick_list.docstatus == 1)
+ & (pick_list.work_order == self.doc.name)
+ & (pick_list_item.picked_qty > pick_list_item.transferred_qty)
+ & (
+ (fn.Coalesce(pick_list_item.material_request_item, "") == "")
+ | (mr.docstatus != 1)
+ | (mr.status == "Stopped")
+ )
+ )
+ .groupby(pick_list_item.item_code)
+ )
+ return frappe._dict({d.item_code: flt(d.qty) for d in query.run(as_dict=1)})
+
def _material_transfer_qty_by_item(self, is_return):
ste = frappe.qb.DocType("Stock Entry")
ste_child = frappe.qb.DocType("Stock Entry Detail")
diff --git a/erpnext/manufacturing/doctype/work_order/services/status.py b/erpnext/manufacturing/doctype/work_order/services/status.py
index eb074a4cc8b..74f204acd40 100644
--- a/erpnext/manufacturing/doctype/work_order/services/status.py
+++ b/erpnext/manufacturing/doctype/work_order/services/status.py
@@ -291,6 +291,12 @@ class StatusService:
)
def set_process_loss_qty(self):
+ self.doc.db_set("process_loss_qty", self._process_loss_qty())
+
+ def _process_loss_qty(self):
+ if self.doc.track_semi_finished_goods:
+ return flt(sum(flt(row.process_loss_qty) for row in self.doc.operations))
+
table = frappe.qb.DocType("Stock Entry")
process_loss_qty = (
frappe.qb.from_(table)
@@ -302,7 +308,7 @@ class StatusService:
)
).run()[0][0]
- self.doc.db_set("process_loss_qty", flt(process_loss_qty))
+ return flt(process_loss_qty)
def update_production_plan_status(self):
production_plan = frappe.get_doc("Production Plan", self.doc.production_plan)
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 427a89df811..eead67fb458 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -1638,6 +1638,359 @@ class TestWorkOrder(ERPNextTestSuite):
self.assertEqual(work_order.material_transferred_for_manufacturing, 0.0)
self.assertEqual(work_order.status, "In Process")
+ def test_material_request_qty_scales_with_requested_qty(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ required_qty = {row.item_code: flt(row.required_qty) for row in work_order.required_items}
+
+ mr = make_material_request(work_order.name, for_qty=4)
+ self.assertEqual(len(mr.items), len(required_qty))
+ for row in mr.items:
+ self.assertEqual(row.qty, required_qty[row.item_code] * 4 / 10)
+
+ mr = make_material_request(work_order.name)
+ for row in mr.items:
+ self.assertEqual(row.qty, required_qty[row.item_code])
+
+ def test_material_request_qty_capped_at_pending_qty(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ partially_transferred = work_order.required_items[0]
+ partially_transferred.db_set("transferred_qty", flt(partially_transferred.required_qty) - 1)
+ work_order.reload()
+
+ mr = make_material_request(work_order.name, for_qty=10)
+ requested_qty = {row.item_code: row.qty for row in mr.items}
+ self.assertEqual(requested_qty[partially_transferred.item_code], 1)
+
+ def test_material_request_maps_only_selected_rows(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ selected = work_order.required_items[0]
+
+ try:
+ frappe.flags.selected_children = {"required_items": [selected.name]}
+ mr = make_material_request(work_order.name, for_qty=4)
+ finally:
+ frappe.flags.selected_children = None
+
+ self.assertEqual([row.item_code for row in mr.items], [selected.item_code])
+ self.assertEqual(mr.items[0].qty, flt(selected.required_qty) * 4 / 10)
+
+ def test_material_request_rejects_nonpositive_qty(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ self.assertRaises(frappe.ValidationError, make_material_request, work_order.name, for_qty=0)
+ self.assertRaises(frappe.ValidationError, make_material_request, work_order.name, for_qty=-1)
+ self.assertRaises(
+ frappe.ValidationError, make_material_request, work_order.name, for_qty=float("inf")
+ )
+ self.assertRaises(
+ frappe.ValidationError, make_material_request, work_order.name, for_qty=float("nan")
+ )
+
+ def test_pick_list_rejects_nonpositive_qty(self):
+ from erpnext.manufacturing.doctype.work_order.mapper import create_pick_list
+
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ self.assertRaises(frappe.ValidationError, create_pick_list, work_order.name, for_qty=0)
+ self.assertRaises(frappe.ValidationError, create_pick_list, work_order.name, for_qty=-1)
+ self.assertRaises(frappe.ValidationError, create_pick_list, work_order.name, for_qty=float("inf"))
+ self.assertRaises(frappe.ValidationError, create_pick_list, work_order.name, for_qty=float("nan"))
+ self.assertRaises(frappe.ValidationError, create_pick_list, work_order.name)
+
+ def submit_material_request(self, work_order_name, for_qty=None):
+ mr = make_material_request(work_order_name, for_qty=for_qty)
+ mr.schedule_date = today()
+ for item in mr.items:
+ item.schedule_date = today()
+ mr.insert()
+ mr.submit()
+ return mr
+
+ def receive_test_fg_raw_materials(self):
+ test_stock_entry.make_stock_entry(
+ item_code="_Test Item", target="Stores - _TC", qty=100, basic_rate=5000.0
+ )
+ test_stock_entry.make_stock_entry(
+ item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=100, basic_rate=1000.0
+ )
+
+ def test_requested_qty_tracks_open_material_requests(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ mr = self.submit_material_request(work_order.name, for_qty=4)
+ mr_qty = {row.item_code: flt(row.qty) for row in mr.items}
+
+ work_order.reload()
+ for row in work_order.required_items:
+ self.assertEqual(row.requested_qty, mr_qty[row.item_code])
+
+ remainder_mr = make_material_request(work_order.name, for_qty=10)
+ for row in remainder_mr.items:
+ required_row = next(item for item in work_order.required_items if item.item_code == row.item_code)
+ self.assertEqual(row.qty, flt(required_row.required_qty) - mr_qty[row.item_code])
+
+ mr.cancel()
+ work_order.reload()
+ for row in work_order.required_items:
+ self.assertEqual(row.requested_qty, 0)
+
+ def test_requested_qty_moves_to_transferred_qty_on_stock_entry(self):
+ from erpnext.stock.doctype.material_request.mapper import make_stock_entry as mr_to_stock_entry
+
+ self.receive_test_fg_raw_materials()
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ mr = self.submit_material_request(work_order.name, for_qty=4)
+ mr_qty = {row.item_code: flt(row.qty) for row in mr.items}
+
+ stock_entry = frappe.get_doc(mr_to_stock_entry(mr.name))
+ stock_entry.insert()
+ stock_entry.submit()
+
+ work_order.reload()
+ for row in work_order.required_items:
+ self.assertEqual(row.requested_qty, 0)
+ self.assertEqual(row.transferred_qty, mr_qty[row.item_code])
+
+ remainder_mr = make_material_request(work_order.name)
+ for row in remainder_mr.items:
+ required_row = next(item for item in work_order.required_items if item.item_code == row.item_code)
+ self.assertEqual(row.qty, flt(required_row.required_qty) - mr_qty[row.item_code])
+
+ def test_picked_qty_tracks_open_pick_lists(self):
+ from erpnext.manufacturing.doctype.work_order.mapper import create_pick_list
+
+ self.receive_test_fg_raw_materials()
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ pick_list = create_pick_list(work_order.name, for_qty=4)
+ pick_list.insert()
+ pick_list.submit()
+ picked_qty = {row.item_code: flt(row.stock_qty) for row in pick_list.locations}
+
+ work_order.reload()
+ for row in work_order.required_items:
+ self.assertEqual(row.picked_qty, picked_qty[row.item_code])
+
+ remainder_pick_list = create_pick_list(work_order.name, for_qty=10)
+ for row in remainder_pick_list.locations:
+ required_row = next(item for item in work_order.required_items if item.item_code == row.item_code)
+ self.assertEqual(row.qty, flt(required_row.required_qty) - picked_qty[row.item_code])
+
+ remainder_pick_list.insert()
+ remainder_pick_list.submit()
+ self.assertRaises(frappe.ValidationError, create_pick_list, work_order.name, for_qty=10)
+
+ def test_material_request_submit_rejects_exceeding_pending_qty(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ def full_draft():
+ mr = make_material_request(work_order.name)
+ mr.schedule_date = today()
+ for item in mr.items:
+ item.schedule_date = today()
+ mr.insert()
+ return mr
+
+ first, second = full_draft(), full_draft()
+ first.submit()
+ self.assertRaises(frappe.ValidationError, second.submit)
+
+ def test_picked_qty_counts_pick_list_of_stopped_material_request(self):
+ from erpnext.stock.doctype.material_request.mapper import create_pick_list as mr_to_pick_list
+
+ self.receive_test_fg_raw_materials()
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ mr = self.submit_material_request(work_order.name, for_qty=4)
+ mr_qty = {row.item_code: flt(row.qty) for row in mr.items}
+
+ pick_list = mr_to_pick_list(mr.name)
+ pick_list.insert()
+ pick_list.submit()
+
+ work_order.reload()
+ for row in work_order.required_items:
+ self.assertEqual(row.requested_qty, mr_qty[row.item_code])
+ self.assertEqual(row.picked_qty, 0)
+
+ mr.reload()
+ mr.update_status("Stopped")
+
+ work_order.reload()
+ for row in work_order.required_items:
+ self.assertEqual(row.requested_qty, 0)
+ self.assertEqual(row.picked_qty, mr_qty[row.item_code])
+
+ def test_pending_demand_shared_across_duplicate_item_rows(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ first = work_order.required_items[0]
+ duplicate = work_order.append(
+ "required_items",
+ {
+ "item_code": first.item_code,
+ "required_qty": 5,
+ "stock_uom": first.stock_uom,
+ "source_warehouse": first.source_warehouse,
+ "docstatus": 1,
+ },
+ )
+ duplicate.db_insert()
+ work_order.reload()
+ total_required = flt(first.required_qty) + 5
+
+ mr = self.submit_material_request(work_order.name, for_qty=4)
+ requested = sum(flt(row.qty) for row in mr.items if row.item_code == first.item_code)
+ self.assertAlmostEqual(requested, total_required * 4 / 10, places=6)
+
+ work_order.reload()
+ for row in work_order.required_items:
+ if row.item_code == first.item_code:
+ self.assertAlmostEqual(row.requested_qty, requested, places=6)
+
+ remainder_mr = make_material_request(work_order.name, for_qty=10)
+ remainder = sum(flt(row.qty) for row in remainder_mr.items if row.item_code == first.item_code)
+ self.assertAlmostEqual(remainder, total_required - requested, places=6)
+
+ def test_allocation_splits_by_source_warehouse(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ first = work_order.required_items[0]
+ duplicate = work_order.append(
+ "required_items",
+ {
+ "item_code": first.item_code,
+ "required_qty": 5,
+ "stock_uom": first.stock_uom,
+ "source_warehouse": "_Test Warehouse 1 - _TC",
+ "docstatus": 1,
+ },
+ )
+ duplicate.db_insert()
+ work_order.reload()
+
+ with self.change_settings("Buying Settings", {"allow_multiple_items": 1}):
+ mr = make_material_request(work_order.name, for_qty=4)
+ rows = {row.from_warehouse: flt(row.qty) for row in mr.items if row.item_code == first.item_code}
+ self.assertEqual(len(rows), 2)
+ self.assertAlmostEqual(rows["Stores - _TC"], flt(first.required_qty) * 4 / 10, places=6)
+ self.assertAlmostEqual(rows["_Test Warehouse 1 - _TC"], 5 * 4 / 10, places=6)
+
+ def test_allocation_collapses_groups_when_multiple_items_disallowed(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ first = work_order.required_items[0]
+ duplicate = work_order.append(
+ "required_items",
+ {
+ "item_code": first.item_code,
+ "required_qty": 5,
+ "stock_uom": first.stock_uom,
+ "source_warehouse": "_Test Warehouse 1 - _TC",
+ "docstatus": 1,
+ },
+ )
+ duplicate.db_insert()
+ work_order.reload()
+
+ mr = self.submit_material_request(work_order.name, for_qty=4)
+ rows = [row for row in mr.items if row.item_code == first.item_code]
+ self.assertEqual(len(rows), 1)
+ self.assertAlmostEqual(flt(rows[0].qty), (flt(first.required_qty) + 5) * 4 / 10, places=6)
+
+ def test_remainder_allocation_splits_proportionally_across_groups(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ first = work_order.required_items[0]
+ duplicate = work_order.append(
+ "required_items",
+ {
+ "item_code": first.item_code,
+ "required_qty": 5,
+ "stock_uom": first.stock_uom,
+ "source_warehouse": "_Test Warehouse 1 - _TC",
+ "docstatus": 1,
+ },
+ )
+ duplicate.db_insert()
+ work_order.reload()
+
+ with self.change_settings("Buying Settings", {"allow_multiple_items": 1}):
+ self.submit_material_request(work_order.name, for_qty=4)
+ work_order.reload()
+ remainder = make_material_request(work_order.name, for_qty=10)
+ rows = {
+ row.from_warehouse: flt(row.qty) for row in remainder.items if row.item_code == first.item_code
+ }
+ self.assertAlmostEqual(rows["Stores - _TC"], flt(first.required_qty) * 6 / 10, places=6)
+ self.assertAlmostEqual(rows["_Test Warehouse 1 - _TC"], 5 * 6 / 10, places=6)
+
+ def test_allocation_splits_manual_rows_by_operation_label(self):
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+ first = work_order.required_items[0]
+ for operation in ("_Test Operation A", "_Test Operation B"):
+ row = work_order.append(
+ "required_items",
+ {
+ "item_code": first.item_code,
+ "required_qty": 5,
+ "stock_uom": first.stock_uom,
+ "source_warehouse": first.source_warehouse,
+ "operation": operation,
+ "docstatus": 1,
+ },
+ )
+ row.db_insert()
+ work_order.reload()
+
+ with self.change_settings("Buying Settings", {"allow_multiple_items": 1}):
+ mr = make_material_request(work_order.name, for_qty=4)
+ rows = [flt(row.qty) for row in mr.items if row.item_code == first.item_code]
+ self.assertEqual(len(rows), 3)
+ self.assertAlmostEqual(sum(rows), (flt(first.required_qty) + 10) * 4 / 10, places=6)
+
+ def test_pick_list_rejects_over_pick_against_material_request(self):
+ from erpnext.stock.doctype.material_request.mapper import create_pick_list as mr_to_pick_list
+
+ self.receive_test_fg_raw_materials()
+ work_order = make_wo_order_test_record(
+ planned_start_date=now(), qty=10, source_warehouse="Stores - _TC"
+ )
+
+ mr = self.submit_material_request(work_order.name, for_qty=4)
+ pick_list = mr_to_pick_list(mr.name)
+ pick_list.insert()
+ pick_list.locations[0].picked_qty = flt(pick_list.locations[0].stock_qty) + 1
+
+ self.assertRaises(frappe.ValidationError, pick_list.submit)
+
def test_backflushed_batch_raw_materials_based_on_transferred(self):
frappe.db.set_single_value(
"Manufacturing Settings",
@@ -5108,6 +5461,24 @@ class TestWorkOrder(ERPNextTestSuite):
self.assertEqual(flt(qty_by_item.get(item_a)), 10.0)
self.assertEqual(flt(qty_by_item.get(item_b)), 10.0)
+ def test_wip_warehouse_required_when_tracking_semi_finished_goods(self):
+ wo = frappe.new_doc("Work Order")
+ wo.track_semi_finished_goods = 1
+ wo.skip_transfer = 0
+ wo.fg_warehouse = "_Test Warehouse 1 - _TC"
+
+ self.assertRaises(frappe.ValidationError, wo.validate_warehouse)
+
+ wo.wip_warehouse = "_Test Warehouse - _TC"
+ wo.validate_warehouse()
+
+ # the top-level target warehouse stays optional; operations may carry their own
+ wo.fg_warehouse = None
+ wo.validate_warehouse()
+
+ wo.track_semi_finished_goods = 0
+ self.assertRaises(frappe.ValidationError, wo.validate_warehouse)
+
def get_reserved_entries(voucher_no, warehouse=None):
doctype = frappe.qb.DocType("Stock Reservation Entry")
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index 612c9794230..079b2831e78 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -5,7 +5,7 @@ frappe.ui.form.on("Work Order", {
setup: function (frm) {
frm.custom_make_buttons = {
"Stock Entry": "Start",
- "Pick List": "Create Pick List",
+ "Pick List": "Pick List",
"Job Card": "Create Job Card",
};
@@ -818,13 +818,21 @@ erpnext.work_order = {
if (pending_to_transfer && frm.doc.status != "Stopped") {
frm.has_start_btn = true;
- frm.add_custom_button(__("Create Pick List"), function () {
- erpnext.work_order.create_pick_list(frm);
- });
+ frm.add_custom_button(
+ __("Pick List"),
+ function () {
+ erpnext.work_order.create_pick_list(frm);
+ },
+ __("Create")
+ );
- frm.add_custom_button(__("Material Request"), function () {
- erpnext.work_order.make_material_request(frm);
- });
+ frm.add_custom_button(
+ __("Material Request"),
+ function () {
+ erpnext.work_order.make_material_request(frm);
+ },
+ __("Create")
+ );
var start_btn = frm.add_custom_button(__("Start"), function () {
erpnext.work_order.make_se(frm, "Material Transfer for Manufacture");
@@ -844,7 +852,10 @@ erpnext.work_order = {
function () {
let purpose = "Material Transfer for Manufacture";
erpnext.work_order
- .show_prompt_for_qty_input(frm, purpose, qty, 1)
+ .show_prompt_for_qty_input(frm, purpose, {
+ qty: qty,
+ additional_transfer_entry: 1,
+ })
.then((data) => {
return frappe.xcall(
"erpnext.manufacturing.doctype.work_order.mapper.make_stock_entry",
@@ -861,7 +872,7 @@ erpnext.work_order = {
frappe.set_route("Form", stock_entry.doctype, stock_entry.name);
});
},
- __("Make")
+ __("Create")
);
}
}
@@ -895,7 +906,7 @@ erpnext.work_order = {
backflush_raw_materials_based_on
);
},
- __("Make")
+ __("Create")
);
}
}
@@ -1030,6 +1041,26 @@ erpnext.work_order = {
return flt(max, precision("qty"));
},
+ get_max_requestable_qty: (frm) => {
+ const required = {};
+ const covered = {};
+ (frm.doc.required_items || []).forEach((row) => {
+ required[row.item_code] = (required[row.item_code] || 0) + flt(row.required_qty);
+ if (!(row.item_code in covered)) {
+ covered[row.item_code] =
+ flt(row.transferred_qty) + flt(row.requested_qty) + flt(row.picked_qty);
+ }
+ });
+
+ let max_fraction = 0;
+ Object.keys(required).forEach((item_code) => {
+ if (required[item_code] <= 0) return;
+ const pending = required[item_code] - covered[item_code];
+ max_fraction = Math.max(max_fraction, pending / required[item_code]);
+ });
+ return flt(max_fraction * flt(frm.doc.qty), precision("qty"));
+ },
+
show_disassembly_prompt: function (frm) {
let max_qty = flt(frm.doc.produced_qty - frm.doc.disassembled_qty);
@@ -1084,20 +1115,20 @@ erpnext.work_order = {
});
},
- show_prompt_for_qty_input: function (frm, purpose, qty, additional_transfer_entry) {
- let max = !additional_transfer_entry ? this.get_max_transferable_qty(frm, purpose) : qty;
+ show_prompt_for_qty_input: function (frm, purpose, { qty, additional_transfer_entry, target } = {}) {
+ let max = qty == null ? this.get_max_transferable_qty(frm, purpose) : qty;
let fields = [
{
fieldtype: "Float",
- label: __("Qty for {0}", [__(purpose)]),
+ label: __("Qty for {0}", [target || __(purpose)]),
fieldname: "qty",
description: __("Max: {0}", [max]),
default: max,
},
];
- if (!additional_transfer_entry) {
+ if (!additional_transfer_entry && !target) {
fields.push({
fieldtype: "Check",
label: __("Consider Process Loss"),
@@ -1119,6 +1150,11 @@ erpnext.work_order = {
(data) => {
max += (frm.doc.qty * (frm.doc.__onload.overproduction_percentage || 0.0)) / 100;
+ if (!data.qty || data.qty <= 0) {
+ frappe.msgprint(__("Quantity must be greater than zero."));
+ reject();
+ return;
+ }
if (data.qty > max) {
frappe.msgprint(__("Quantity must not be more than {0}", [max]));
reject();
@@ -1161,15 +1197,32 @@ erpnext.work_order = {
}
},
- make_material_request: function (frm) {
- frappe.model.open_mapped_doc({
- method: "erpnext.manufacturing.doctype.work_order.mapper.make_material_request",
- frm,
- });
+ make_material_request: function (frm, purpose = "Material Transfer for Manufacture") {
+ const max = this.get_max_requestable_qty(frm);
+ if (max <= 0) {
+ frappe.msgprint(__("All required items have already been transferred, requested or picked."));
+ return;
+ }
+
+ const get_material_request = (for_qty) =>
+ frappe.model.open_mapped_doc({
+ method: "erpnext.manufacturing.doctype.work_order.mapper.make_material_request",
+ frm,
+ args: { for_qty: for_qty },
+ });
+
+ this.show_prompt_for_qty_input(frm, purpose, {
+ qty: max,
+ target: __("Material Request"),
+ }).then((data) => get_material_request(data.qty));
},
create_pick_list: function (frm, purpose = "Material Transfer for Manufacture") {
- const max = this.get_max_transferable_qty(frm, purpose);
+ const max = this.get_max_requestable_qty(frm);
+ if (max <= 0) {
+ frappe.msgprint(__("All required items have already been transferred, requested or picked."));
+ return;
+ }
const get_pick_list = (for_qty) =>
frappe
@@ -1182,11 +1235,10 @@ erpnext.work_order = {
frappe.set_route("Form", pick_list.doctype, pick_list.name);
});
- if (max <= 0) {
- get_pick_list(frm.doc.qty);
- } else {
- this.show_prompt_for_qty_input(frm, purpose).then((data) => get_pick_list(data.qty));
- }
+ this.show_prompt_for_qty_input(frm, purpose, {
+ qty: max,
+ target: __("Pick List"),
+ }).then((data) => get_pick_list(data.qty));
},
make_consumption_se: function (frm, backflush_raw_materials_based_on) {
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index 04b970be3e1..cfe140726df 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -272,7 +272,7 @@
"fieldtype": "Link",
"label": "Work-in-Progress Warehouse",
"link_filters": "[[\"Warehouse\",\"disabled\",\"=\",0],[\"Warehouse\",\"is_group\",\"=\",0]]",
- "mandatory_depends_on": "eval:(!doc.skip_transfer || doc.from_wip_warehouse) && !doc.track_semi_finished_goods",
+ "mandatory_depends_on": "eval:!doc.skip_transfer || doc.from_wip_warehouse",
"options": "Warehouse"
},
{
@@ -739,7 +739,7 @@
"image_field": "image",
"is_submittable": 1,
"links": [],
- "modified": "2026-06-03 21:35:34.175667",
+ "modified": "2026-08-08 12:00:00.000000",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order",
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 8846aae59d0..39fc7d16171 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -601,12 +601,9 @@ class WorkOrder(Document):
)
def validate_warehouse(self):
- if self.track_semi_finished_goods:
- return
-
if not self.wip_warehouse and not self.skip_transfer:
frappe.throw(_("Work-in-Progress Warehouse is required before Submit"))
- if not self.fg_warehouse:
+ if not self.fg_warehouse and not self.track_semi_finished_goods:
frappe.throw(_("Target Warehouse is required before Submit"))
def before_submit(self):
diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
index dec4934ea4f..208215b7a5e 100644
--- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
+++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
@@ -22,6 +22,8 @@
"amount",
"column_break_11",
"transferred_qty",
+ "requested_qty",
+ "picked_qty",
"consumed_qty",
"returned_qty",
"section_break_idhr",
@@ -93,6 +95,22 @@
"label": "Transferred Qty",
"read_only": 1
},
+ {
+ "depends_on": "eval:!parent.skip_transfer",
+ "fieldname": "requested_qty",
+ "fieldtype": "Float",
+ "label": "Requested Qty",
+ "no_copy": 1,
+ "read_only": 1
+ },
+ {
+ "depends_on": "eval:!parent.skip_transfer",
+ "fieldname": "picked_qty",
+ "fieldtype": "Float",
+ "label": "Picked Qty",
+ "no_copy": 1,
+ "read_only": 1
+ },
{
"default": "0",
"depends_on": "eval:!parent.subcontracting_inward_order",
@@ -209,7 +227,7 @@
"grid_page_length": 50,
"istable": 1,
"links": [],
- "modified": "2026-05-12 12:05:16.687866",
+ "modified": "2026-08-07 10:00:00.000000",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order Item",
diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.py b/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
index 4c40e9d688a..c4f2fc4d916 100644
--- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
+++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.py
@@ -31,8 +31,10 @@ class WorkOrderItem(Document):
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
+ picked_qty: DF.Float
rate: DF.Currency
required_qty: DF.Float
+ requested_qty: DF.Float
returned_qty: DF.Float
source_warehouse: DF.Link | None
stock_reserved_qty: DF.Float
diff --git a/erpnext/manufacturing/doctype_settings_map/blanket_order_(standard)/blanket_order_(standard).json b/erpnext/manufacturing/doctype_settings_map/blanket_order.json
similarity index 92%
rename from erpnext/manufacturing/doctype_settings_map/blanket_order_(standard)/blanket_order_(standard).json
rename to erpnext/manufacturing/doctype_settings_map/blanket_order.json
index b0862892ac9..66f125688bc 100644
--- a/erpnext/manufacturing/doctype_settings_map/blanket_order_(standard)/blanket_order_(standard).json
+++ b/erpnext/manufacturing/doctype_settings_map/blanket_order.json
@@ -19,6 +19,6 @@
"modified": "2026-07-10 11:01:49.066530",
"modified_by": "Administrator",
"module": "Manufacturing",
- "name": "Blanket Order (Standard)",
+ "name": "Blanket Order - Manufacturing",
"owner": "Administrator"
}
diff --git a/erpnext/manufacturing/doctype_settings_map/bom_(standard)/bom_(standard).json b/erpnext/manufacturing/doctype_settings_map/bom.json
similarity index 95%
rename from erpnext/manufacturing/doctype_settings_map/bom_(standard)/bom_(standard).json
rename to erpnext/manufacturing/doctype_settings_map/bom.json
index 295bf681cd2..f05b1a55ff3 100644
--- a/erpnext/manufacturing/doctype_settings_map/bom_(standard)/bom_(standard).json
+++ b/erpnext/manufacturing/doctype_settings_map/bom.json
@@ -23,6 +23,6 @@
"modified": "2026-07-10 11:47:13.281237",
"modified_by": "Administrator",
"module": "Manufacturing",
- "name": "BOM (Standard)",
+ "name": "BOM - Manufacturing",
"owner": "Administrator"
}
diff --git a/erpnext/manufacturing/doctype_settings_map/production_plan_(standard)/production_plan_(standard).json b/erpnext/manufacturing/doctype_settings_map/production_plan.json
similarity index 92%
rename from erpnext/manufacturing/doctype_settings_map/production_plan_(standard)/production_plan_(standard).json
rename to erpnext/manufacturing/doctype_settings_map/production_plan.json
index c112ea5b631..ab1d1142344 100644
--- a/erpnext/manufacturing/doctype_settings_map/production_plan_(standard)/production_plan_(standard).json
+++ b/erpnext/manufacturing/doctype_settings_map/production_plan.json
@@ -19,6 +19,6 @@
"modified": "2026-07-10 11:31:40.252142",
"modified_by": "Administrator",
"module": "Manufacturing",
- "name": "Production Plan (Standard)",
+ "name": "Production Plan - Manufacturing",
"owner": "Administrator"
}
diff --git a/erpnext/manufacturing/doctype_settings_map/work_order_(standard)/work_order_(standard).json b/erpnext/manufacturing/doctype_settings_map/work_order.json
similarity index 96%
rename from erpnext/manufacturing/doctype_settings_map/work_order_(standard)/work_order_(standard).json
rename to erpnext/manufacturing/doctype_settings_map/work_order.json
index e8f2c48141b..4a3ac606267 100644
--- a/erpnext/manufacturing/doctype_settings_map/work_order_(standard)/work_order_(standard).json
+++ b/erpnext/manufacturing/doctype_settings_map/work_order.json
@@ -43,6 +43,6 @@
"modified": "2026-07-20 17:58:35.816693",
"modified_by": "Administrator",
"module": "Manufacturing",
- "name": "Work Order (Standard)",
+ "name": "Work Order - Manufacturing",
"owner": "Administrator"
}
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index f2c2a447817..fa1838c4345 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -508,3 +508,5 @@ erpnext.patches.v16_0.move_warehouse_defaults_to_company
erpnext.patches.v16_0.backfill_repost_accounting_ledger_status
erpnext.patches.v16_0.merge_seeded_item_group_root
erpnext.patches.v16_0.set_stock_uom_in_job_card
+erpnext.patches.v16_0.set_work_order_requested_and_picked_qty
+erpnext.patches.v16_0.rename_italy_customer_name_fields
diff --git a/erpnext/patches/v14_0/clear_reconciliation_values_from_singles.py b/erpnext/patches/v14_0/clear_reconciliation_values_from_singles.py
index c1f5b60a406..21b31e3bda9 100644
--- a/erpnext/patches/v14_0/clear_reconciliation_values_from_singles.py
+++ b/erpnext/patches/v14_0/clear_reconciliation_values_from_singles.py
@@ -1,3 +1,4 @@
+import frappe
from frappe import qb
@@ -13,5 +14,8 @@ def execute():
"Payment Reconciliation Allocation",
]
for x in doctypes:
+ # child tables may not exist yet on sites where this pre-model-sync patch runs first
+ if not frappe.db.table_exists(x):
+ continue
dt = qb.DocType(x)
qb.from_(dt).delete().run()
diff --git a/erpnext/patches/v16_0/rename_italy_customer_name_fields.py b/erpnext/patches/v16_0/rename_italy_customer_name_fields.py
new file mode 100644
index 00000000000..4e1b13a947b
--- /dev/null
+++ b/erpnext/patches/v16_0/rename_italy_customer_name_fields.py
@@ -0,0 +1,53 @@
+import frappe
+
+RENAMED_FIELDS = {
+ "first_name": "italy_customer_first_name",
+ "last_name": "italy_customer_last_name",
+}
+
+
+def execute():
+ """Rename Italy's Customer name fields, which clash with the standard quick-entry
+ first_name/last_name fields, and restore any Italy custom field columns that a
+ previously interrupted fixture run left missing."""
+ if not has_italy_fixtures():
+ return
+
+ duplicate_fieldnames = [
+ fieldname for fieldname in RENAMED_FIELDS if frappe.db.exists("Custom Field", f"Customer-{fieldname}")
+ ]
+
+ from erpnext.regional.italy.setup import get_custom_fields, make_custom_fields
+
+ make_custom_fields()
+ for doctype in get_custom_fields():
+ frappe.clear_cache(doctype=doctype)
+ frappe.db.updatedb(doctype)
+
+ for old_fieldname, new_fieldname in RENAMED_FIELDS.items():
+ copy_customer_names(old_fieldname, new_fieldname)
+
+ for old_fieldname in duplicate_fieldnames:
+ frappe.delete_doc("Custom Field", f"Customer-{old_fieldname}", force=True)
+
+ if duplicate_fieldnames:
+ frappe.clear_cache(doctype="Customer")
+
+
+def has_italy_fixtures():
+ return bool(
+ frappe.db.exists("Company", {"country": "Italy"})
+ or frappe.db.exists("Custom Field", "Company-fiscal_regime")
+ )
+
+
+def copy_customer_names(old_fieldname, new_fieldname):
+ customer = frappe.qb.DocType("Customer")
+ old_column = customer[old_fieldname]
+ new_column = customer[new_fieldname]
+ (
+ frappe.qb.update(customer)
+ .set(new_column, old_column)
+ .where(old_column.isnotnull() & (old_column != ""))
+ .where(new_column.isnull() | (new_column == ""))
+ ).run()
diff --git a/erpnext/patches/v16_0/set_work_order_requested_and_picked_qty.py b/erpnext/patches/v16_0/set_work_order_requested_and_picked_qty.py
new file mode 100644
index 00000000000..9f30b5142a4
--- /dev/null
+++ b/erpnext/patches/v16_0/set_work_order_requested_and_picked_qty.py
@@ -0,0 +1,38 @@
+import frappe
+
+from erpnext.manufacturing.doctype.work_order.services.required_items import RequiredItemsService
+
+
+def execute():
+ """Backfill requested_qty and picked_qty for work orders with open demand;
+ fulfilled documents leave the zero default."""
+ work_orders = set(
+ frappe.get_all(
+ "Material Request",
+ filters={
+ "docstatus": 1,
+ "material_request_type": "Material Transfer",
+ "work_order": ("is", "set"),
+ "status": ("!=", "Stopped"),
+ "per_ordered": ("<", 100),
+ },
+ pluck="work_order",
+ distinct=True,
+ )
+ )
+ work_orders.update(
+ frappe.get_all(
+ "Pick List",
+ filters={"docstatus": 1, "work_order": ("is", "set"), "status": ("!=", "Completed")},
+ pluck="work_order",
+ distinct=True,
+ )
+ )
+
+ for name in work_orders:
+ if frappe.db.get_value("Work Order", name, "docstatus") != 1:
+ continue
+
+ service = RequiredItemsService(frappe.get_doc("Work Order", name))
+ service.update_requested_qty_for_required_items()
+ service.update_picked_qty_for_required_items()
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index f128a77beb0..fd575427706 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -90,6 +90,7 @@ class Task(NestedSet):
self.validate_completed_on()
self.set_default_end_date_if_missing()
self.validate_parent_is_group()
+ self.validate_web_form_project_permission()
def validate_dates(self):
self.validate_from_to_dates("exp_start_date", "exp_end_date")
@@ -313,6 +314,23 @@ class Task(NestedSet):
if project_user:
return True
+ def validate_web_form_project_permission(self):
+ project_unchanged = not self.is_new() and self.project == self.get_db_value("project")
+
+ if (
+ not frappe.flags.in_web_form
+ or not self.project
+ or project_unchanged
+ or frappe.has_permission("Project", "write", doc=self.project)
+ or self.has_webform_permission()
+ ):
+ return
+
+ frappe.throw(
+ _("You are not permitted to create a Task for Project {0}").format(self.project),
+ frappe.PermissionError,
+ )
+
def populate_depends_on(self):
if self.parent_task:
parent = frappe.get_doc("Task", self.parent_task)
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index bc63ba79a80..3408c8f1843 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -456,7 +456,7 @@ const set_employee_and_company = function (frm) {
const options = { user_id: frappe.session.user };
const fields = ["name", "company"];
frappe.db.get_value("Employee", options, fields).then(({ message }) => {
- if (message) {
+ if (message.name && message.company) {
// there is an employee with the currently logged in user_id
frm.set_value("employee", message.name);
frm.set_value("company", message.company);
diff --git a/erpnext/projects/doctype_settings_map/timesheet_(standard)/timesheet_(standard).json b/erpnext/projects/doctype_settings_map/timesheet.json
similarity index 94%
rename from erpnext/projects/doctype_settings_map/timesheet_(standard)/timesheet_(standard).json
rename to erpnext/projects/doctype_settings_map/timesheet.json
index 2c6f7e8e2e1..c24a94a4341 100644
--- a/erpnext/projects/doctype_settings_map/timesheet_(standard)/timesheet_(standard).json
+++ b/erpnext/projects/doctype_settings_map/timesheet.json
@@ -19,6 +19,6 @@
"modified": "2026-07-10 10:37:54.591039",
"modified_by": "Administrator",
"module": "Projects",
- "name": "Timesheet (Standard)",
+ "name": "Timesheet - Projects",
"owner": "Administrator"
}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 615d3302c5e..5ecbd839156 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1802,7 +1802,10 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
let item = frappe.get_doc(cdt, cdn);
item.conversion_factor = 1.0;
if (item.stock_qty) {
- item.conversion_factor = flt(item.stock_qty) / flt(item.qty);
+ item.conversion_factor = flt(
+ flt(item.stock_qty) / flt(item.qty),
+ precision("conversion_factor", item)
+ );
}
refresh_field("conversion_factor", item.name, item.parentfield);
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index acaf7fb056e..66a634336e8 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -742,6 +742,7 @@ erpnext.utils.update_child_items = function (opts) {
qty: d.qty,
rate: d.rate,
uom: d.uom,
+ warehouse: d.warehouse,
fg_item: d.fg_item,
fg_item_qty: d.fg_item_qty,
description: d.description,
@@ -829,6 +830,7 @@ erpnext.utils.update_child_items = function (opts) {
item_name,
bom_no,
description,
+ warehouse,
} = r.message;
const row = dialog.fields_dict.trans_items.df.data.find(
(row) => row.name == me.doc.name
@@ -842,6 +844,7 @@ erpnext.utils.update_child_items = function (opts) {
item_name: item_name,
bom_no: bom_no,
description: me.doc.description || description,
+ warehouse: me.doc.docname ? me.doc.warehouse : warehouse,
});
dialog.fields_dict.trans_items.grid.refresh();
}
@@ -929,6 +932,29 @@ erpnext.utils.update_child_items = function (opts) {
});
}
+ const warehouse_df = child_meta.fields.find((f) => f.fieldname == "warehouse");
+ if (warehouse_df) {
+ fields.splice(3, 0, {
+ fieldtype: "Link",
+ fieldname: "warehouse",
+ options: "Warehouse",
+ in_list_view: 1,
+ label: __(warehouse_df.label),
+ // only new rows may set it, existing rows would leave their
+ // reserved qty stranded in the previous warehouse's bin
+ read_only_depends_on: "eval:doc.docname",
+ get_query: () => {
+ return {
+ filters: {
+ company: frm.doc.company,
+ is_group: 0,
+ disabled: 0,
+ },
+ };
+ },
+ });
+ }
+
if (["Purchase Order", "Sales Order"].includes(frm.doc.doctype) && frm.doc.is_subcontracted) {
fields.push(
{
diff --git a/erpnext/regional/italy/e-invoice.xml b/erpnext/regional/italy/e-invoice.xml
index ef1e94ff27b..713e85a556e 100644
--- a/erpnext/regional/italy/e-invoice.xml
+++ b/erpnext/regional/italy/e-invoice.xml
@@ -99,8 +99,8 @@
{%- if doc.customer_data.customer_type == "Individual" %}
{{ doc.customer_data.fiscal_code }}
- {{ doc.customer_data.first_name }}
- {{ doc.customer_data.last_name }}
+ {{ doc.customer_data.italy_customer_first_name }}
+ {{ doc.customer_data.italy_customer_last_name }}
{%- else %}
diff --git a/erpnext/regional/italy/setup.py b/erpnext/regional/italy/setup.py
index 9f9115ca12d..a21be948650 100644
--- a/erpnext/regional/italy/setup.py
+++ b/erpnext/regional/italy/setup.py
@@ -23,6 +23,10 @@ def setup(company=None, patch=True):
def make_custom_fields(update=True):
+ create_custom_fields(get_custom_fields(), ignore_validate=frappe.flags.in_patch, update=update)
+
+
+def get_custom_fields():
invoice_item_fields = [
dict(
fieldname="tax_rate",
@@ -96,7 +100,7 @@ def make_custom_fields(update=True):
),
]
- custom_fields = {
+ return {
"Company": [
dict(
fieldname="sb_e_invoicing",
@@ -232,18 +236,18 @@ def make_custom_fields(update=True):
depends_on='eval:doc.customer_type=="Company"',
),
dict(
- fieldname="first_name",
+ fieldname="italy_customer_first_name",
label="First Name",
fieldtype="Data",
- insert_after="salutation",
+ insert_after="customer_type",
print_hide=1,
depends_on='eval:doc.customer_type!="Company"',
),
dict(
- fieldname="last_name",
+ fieldname="italy_customer_last_name",
label="Last Name",
fieldtype="Data",
- insert_after="first_name",
+ insert_after="italy_customer_first_name",
print_hide=1,
depends_on='eval:doc.customer_type!="Company"',
),
@@ -461,8 +465,6 @@ def make_custom_fields(update=True):
],
}
- create_custom_fields(custom_fields, ignore_validate=frappe.flags.in_patch, update=update)
-
def setup_report():
report_name = "Electronic Invoice Register"
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 2d7a562715f..dd60d11301c 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -199,7 +199,8 @@ class Customer(TransactionBase):
self.loyalty_program_tier = customer.loyalty_program_tier
if self.sales_team:
- if sum(member.allocated_percentage or 0 for member in self.sales_team) != 100:
+ total = sum(flt(member.allocated_percentage) for member in self.sales_team)
+ if flt(total, self.precision("allocated_percentage", "sales_team")) != 100:
frappe.throw(_("Total contribution percentage should be equal to 100"))
@frappe.whitelist(methods=["POST"])
diff --git a/erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json b/erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json
index 908251ea343..6db056bec04 100644
--- a/erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json
+++ b/erpnext/selling/doctype/delivery_schedule_item/delivery_schedule_item.json
@@ -38,6 +38,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -106,7 +107,7 @@
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2025-08-21 18:11:30.134073",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Selling",
"name": "Delivery Schedule Item",
diff --git a/erpnext/selling/doctype/product_bundle/product_bundle.js b/erpnext/selling/doctype/product_bundle/product_bundle.js
index 763fbcb56c9..4c73e8d8930 100644
--- a/erpnext/selling/doctype/product_bundle/product_bundle.js
+++ b/erpnext/selling/doctype/product_bundle/product_bundle.js
@@ -9,6 +9,11 @@ frappe.ui.form.on("Product Bundle", {
query: "erpnext.selling.doctype.product_bundle.product_bundle.get_new_item_code",
};
});
+ frm.set_query("item_code", "items", () => {
+ return {
+ query: "erpnext.controllers.queries.item_query",
+ };
+ });
// A submitted bundle is immutable. To change it, create a new version
// (a fresh draft copied from this one) and submit that instead.
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index 4ef5bdd928a..c70bddba2d5 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -216,6 +216,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"read_only": 1,
"reqd": 1
@@ -729,7 +730,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-06-08 19:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation Item",
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index cec1114b1f3..b85e3438022 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -36,6 +36,7 @@ from erpnext.selling.doctype.sales_order.sales_order import (
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
from erpnext.stock.get_item_details import get_bin_details
+from erpnext.stock.utils import InvalidWarehouseCompany
from erpnext.tests.utils import ERPNextTestSuite
@@ -159,6 +160,38 @@ class TestSalesOrder(ERPNextTestSuite):
)
update_child_qty_rate("Sales Order", trans_item, so.name)
+ @ERPNextTestSuite.change_settings("Selling Settings", {"allow_negative_rates_for_items": 0})
+ def test_sales_order_negative_grand_total_blocked_without_setting(self):
+ so = make_sales_order(qty=1, rate=100, do_not_save=True)
+ so.append("items", {"item_code": "_Test Item 2", "qty": 1, "rate": -150})
+ self.assertRaises(frappe.ValidationError, so.save)
+
+ @ERPNextTestSuite.change_settings("Selling Settings", {"allow_negative_rates_for_items": 1})
+ def test_sales_order_negative_grand_total_allowed_with_setting(self):
+ """Use a negative rate to represent a credit while order quantities remain positive."""
+ so = make_sales_order(qty=1, rate=100, do_not_save=True)
+ so.append("items", {"item_code": "_Test Item 2", "qty": 1, "rate": -150})
+ so.save()
+ so.submit()
+ self.assertEqual(so.docstatus, 1)
+ self.assertTrue(so.base_grand_total < 0)
+
+ @ERPNextTestSuite.change_settings("Selling Settings", {"allow_negative_rates_for_items": 0})
+ def test_sales_order_negative_rate_error_links_to_selling_settings(self):
+ so = make_sales_order(qty=1, rate=100, do_not_save=True)
+ so.append("items", {"item_code": "_Test Item 2", "qty": 1, "rate": -10})
+ so.save()
+
+ with self.assertRaises(frappe.ValidationError) as error:
+ so.submit()
+
+ self.assertIn("selling-settings", str(error.exception))
+
+ @ERPNextTestSuite.change_settings("Selling Settings", {"allow_negative_rates_for_items": 1})
+ def test_sales_order_negative_rate_setting_does_not_allow_negative_quantity(self):
+ so = make_sales_order(qty=-1, rate=100, do_not_save=True)
+ self.assertRaises(frappe.NonNegativeError, so.save)
+
@ERPNextTestSuite.change_settings("Selling Settings", {"allow_multiple_items": 1})
def test_sales_order_qty(self):
so = make_sales_order(qty=1, do_not_save=True)
@@ -587,6 +620,116 @@ class TestSalesOrder(ERPNextTestSuite):
self.assertEqual(updated_total, prev_total + 1400)
self.assertNotEqual(updated_total_in_words, prev_total_in_words)
+ def test_update_child_adding_new_item_with_warehouse(self):
+ so = make_sales_order(item_code="_Test Item", qty=4)
+
+ first_item_of_so = so.get("items")[0]
+ self.assertNotEqual(first_item_of_so.warehouse, "_Test Warehouse 2 - _TC")
+
+ def get_trans_item(warehouse):
+ return json.dumps(
+ [
+ {
+ "item_code": first_item_of_so.item_code,
+ "rate": first_item_of_so.rate,
+ "qty": first_item_of_so.qty,
+ "docname": first_item_of_so.name,
+ "warehouse": warehouse,
+ },
+ {"item_code": "_Test Item 2", "rate": 200, "qty": 7, "warehouse": warehouse},
+ ]
+ )
+
+ self.assertRaises(
+ InvalidWarehouseCompany,
+ update_child_qty_rate,
+ "Sales Order",
+ get_trans_item("_Test Warehouse 2 - _TC1"),
+ so.name,
+ )
+
+ self.assertRaisesRegex(
+ frappe.ValidationError,
+ "Group node warehouse",
+ update_child_qty_rate,
+ "Sales Order",
+ get_trans_item("_Test Warehouse Group - _TC"),
+ so.name,
+ )
+
+ if not frappe.db.exists("Warehouse", "_Test Disabled Warehouse - _TC"):
+ frappe.get_doc(
+ {
+ "doctype": "Warehouse",
+ "warehouse_name": "_Test Disabled Warehouse",
+ "company": "_Test Company",
+ "disabled": 1,
+ }
+ ).insert()
+
+ self.assertRaisesRegex(
+ frappe.ValidationError,
+ "Disabled Warehouse",
+ update_child_qty_rate,
+ "Sales Order",
+ get_trans_item("_Test Disabled Warehouse - _TC"),
+ so.name,
+ )
+
+ update_child_qty_rate("Sales Order", get_trans_item("_Test Warehouse 2 - _TC"), so.name)
+
+ so.reload()
+ # the new row picks up the warehouse selected in the dialog
+ self.assertEqual(so.get("items")[-1].item_code, "_Test Item 2")
+ self.assertEqual(so.get("items")[-1].warehouse, "_Test Warehouse 2 - _TC")
+ # existing rows keep theirs, so their reserved qty stays in the same bin
+ self.assertEqual(so.get("items")[0].warehouse, first_item_of_so.warehouse)
+
+ def test_update_child_adding_new_item_without_any_default_warehouse(self):
+ item_code = make_item("_Test Item Without Default Warehouse", {"is_stock_item": 1}).name
+ so = make_sales_order(item_code="_Test Item", qty=4)
+ existing_item = so.get("items")[0]
+
+ # a company gets a default warehouse when its warehouses are created
+ company_default = frappe.db.get_value("Company", so.company, "default_warehouse")
+ frappe.db.set_value("Company", so.company, "default_warehouse", None)
+ self.addCleanup(frappe.db.set_value, "Company", so.company, "default_warehouse", company_default)
+
+ def get_trans_items(warehouse=None):
+ new_row = {"item_code": item_code, "rate": 200, "qty": 7}
+ if warehouse:
+ new_row["warehouse"] = warehouse
+
+ return json.dumps(
+ [
+ {
+ "item_code": existing_item.item_code,
+ "rate": existing_item.rate,
+ "qty": existing_item.qty,
+ "docname": existing_item.name,
+ },
+ new_row,
+ ]
+ )
+
+ # no default in the Item Master, Item Group, Brand or Company
+ self.assertRaisesRegex(
+ frappe.ValidationError,
+ "Cannot find a default warehouse",
+ update_child_qty_rate,
+ "Sales Order",
+ get_trans_items(),
+ so.name,
+ )
+
+ update_child_qty_rate("Sales Order", get_trans_items("_Test Warehouse - _TC"), so.name)
+
+ so.reload()
+ self.assertEqual(len(so.get("items")), 2)
+ self.assertEqual(so.get("items")[0].warehouse, existing_item.warehouse)
+ self.assertEqual(so.get("items")[-1].item_code, item_code)
+ self.assertEqual(so.get("items")[-1].warehouse, "_Test Warehouse - _TC")
+
def test_update_child_removing_item(self):
so = make_sales_order(**{"item_list": [{"item_code": "_Test Item", "qty": 5, "rate": 1000}]})
create_dn_against_so(so.name, 2)
@@ -3104,6 +3247,17 @@ class TestSalesOrder(ERPNextTestSuite):
so.save()
self.assertEqual(sum(d.allocated_percentage for d in so.sales_team), 100)
+ with self.subTest("floating-point drift in the total is tolerated"):
+ # 10.0 + 58.02 + 31.98 accumulates to 100.00000000000001 in binary floating point
+ so = make_sales_order(do_not_save=True)
+ for sales_person, percentage in (
+ ("_Test Sales Person", 10.0),
+ ("_Test Sales Person 1", 58.02),
+ ("_Test Sales Person 2", 31.98),
+ ):
+ so.append("sales_team", {"sales_person": sales_person, "allocated_percentage": percentage})
+ so.save()
+
def test_sales_team_disabled_sales_person_rejected(self):
frappe.db.set_value("Sales Person", "_Test Sales Person 2", "enabled", 0)
try:
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
index df5d4b76617..4105878df42 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -271,6 +271,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"read_only": 1,
"reqd": 1
@@ -1055,7 +1056,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-06-08 20:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order Item",
diff --git a/erpnext/selling/doctype_settings_map/product_bundle_(standard)/product_bundle_(standard).json b/erpnext/selling/doctype_settings_map/product_bundle.json
similarity index 91%
rename from erpnext/selling/doctype_settings_map/product_bundle_(standard)/product_bundle_(standard).json
rename to erpnext/selling/doctype_settings_map/product_bundle.json
index 6866ca99a76..372db742222 100644
--- a/erpnext/selling/doctype_settings_map/product_bundle_(standard)/product_bundle_(standard).json
+++ b/erpnext/selling/doctype_settings_map/product_bundle.json
@@ -15,6 +15,6 @@
"modified": "2026-06-30 15:37:04.244159",
"modified_by": "Administrator",
"module": "Selling",
- "name": "Product Bundle (Standard)",
+ "name": "Product Bundle - Selling",
"owner": "Administrator"
}
diff --git a/erpnext/selling/doctype_settings_map/quotation_(standard)/quotation_(standard).json b/erpnext/selling/doctype_settings_map/quotation.json
similarity index 94%
rename from erpnext/selling/doctype_settings_map/quotation_(standard)/quotation_(standard).json
rename to erpnext/selling/doctype_settings_map/quotation.json
index 04182cbfa23..8b07b94a585 100644
--- a/erpnext/selling/doctype_settings_map/quotation_(standard)/quotation_(standard).json
+++ b/erpnext/selling/doctype_settings_map/quotation.json
@@ -19,6 +19,6 @@
"modified": "2026-07-20 15:34:21.043827",
"modified_by": "Administrator",
"module": "Selling",
- "name": "Quotation (Standard)",
+ "name": "Quotation - Selling",
"owner": "Administrator"
}
diff --git a/erpnext/selling/doctype_settings_map/sales_order_(standard)/sales_order_(standard).json b/erpnext/selling/doctype_settings_map/sales_order.json
similarity index 98%
rename from erpnext/selling/doctype_settings_map/sales_order_(standard)/sales_order_(standard).json
rename to erpnext/selling/doctype_settings_map/sales_order.json
index 66830c6a26f..91c35c69e5d 100644
--- a/erpnext/selling/doctype_settings_map/sales_order_(standard)/sales_order_(standard).json
+++ b/erpnext/selling/doctype_settings_map/sales_order.json
@@ -79,6 +79,6 @@
"modified": "2026-07-20 14:52:59.147895",
"modified_by": "Administrator",
"module": "Selling",
- "name": "Sales Order (Standard)",
+ "name": "Sales Order - Selling",
"owner": "Administrator"
}
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 4dc23d4b1e6..f8c4205e574 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -309,6 +309,8 @@ erpnext.company.setup_queries = function (frm) {
["discount_allowed_account", { root_type: "Expense" }],
["discount_received_account", { root_type: "Income" }],
["exchange_gain_loss_account", { root_type: ["in", ["Expense", "Income"]] }],
+ ["exchange_gain_account", { root_type: ["in", ["Expense", "Income"]] }],
+ ["exchange_loss_account", { root_type: ["in", ["Expense", "Income"]] }],
[
"unrealized_exchange_gain_loss_account",
{ root_type: ["in", ["Expense", "Income", "Equity", "Liability"]] },
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 84d1a161b87..5b85f1ff18e 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -65,6 +65,8 @@
"default_finance_book",
"exchange_gain__loss_section",
"exchange_gain_loss_account",
+ "exchange_gain_account",
+ "exchange_loss_account",
"column_break_sttp",
"unrealized_exchange_gain_loss_account",
"round_off_section",
@@ -397,6 +399,24 @@
"no_copy": 1,
"options": "Account"
},
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "exchange_gain_account",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Exchange Gain Account",
+ "no_copy": 1,
+ "options": "Account"
+ },
+ {
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "exchange_loss_account",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Exchange Loss Account",
+ "no_copy": 1,
+ "options": "Account"
+ },
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "unrealized_exchange_gain_loss_account",
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 34022033aec..441751bf984 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -103,7 +103,9 @@ class Company(NestedSet):
enable_provisional_accounting_for_non_stock_items: DF.Check
enable_stock_delivered_but_not_billed: DF.Check
exception_budget_approver_role: DF.Link | None
+ exchange_gain_account: DF.Link | None
exchange_gain_loss_account: DF.Link | None
+ exchange_loss_account: DF.Link | None
existing_company: DF.Link | None
expenses_added_to_stock_account: DF.Link | None
expenses_added_to_stock_contra_account: DF.Link | None
@@ -369,6 +371,8 @@ class Company(NestedSet):
["Default Payment Discount Account", "default_discount_account"],
["Unrealized Profit / Loss Account", "unrealized_profit_loss_account"],
["Exchange Gain / Loss Account", "exchange_gain_loss_account"],
+ ["Exchange Gain Account", "exchange_gain_account"],
+ ["Exchange Loss Account", "exchange_loss_account"],
["Unrealized Exchange Gain / Loss Account", "unrealized_exchange_gain_loss_account"],
["Round Off Account", "round_off_account"],
["Default Deferred Revenue Account", "default_deferred_revenue_account"],
@@ -792,6 +796,20 @@ class Company(NestedSet):
self.db_set("exchange_gain_loss_account", exchange_gain_loss_acct)
+ if not self.exchange_gain_account:
+ exchange_gain_acct = frappe.db.get_value(
+ "Account", {"account_name": _("Exchange Gain"), "company": self.name, "is_group": 0}
+ )
+
+ self.db_set("exchange_gain_account", exchange_gain_acct)
+
+ if not self.exchange_loss_account:
+ exchange_loss_acct = frappe.db.get_value(
+ "Account", {"account_name": _("Exchange Loss"), "company": self.name, "is_group": 0}
+ )
+
+ self.db_set("exchange_loss_account", exchange_loss_acct)
+
if not self.disposal_account:
disposal_acct = frappe.db.get_value(
"Account",
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
index 5dd6d3d6d5c..671cd33d298 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
@@ -257,6 +257,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"read_only": 1,
"reqd": 1
@@ -982,7 +983,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note Item",
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index 907cdac76d0..b110651ced9 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -430,7 +430,7 @@ def notify_customers(delivery_trip: str):
frappe.sendmail(
recipients=contact_info.email_id,
subject=dispatch_template.subject,
- message=frappe.render_template(dispatch_template.response, context),
+ message=frappe.render_template(dispatch_template.response, context, restrict_globals=True),
attachments=get_attachments(stop),
)
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index a82e1c2d527..0d3b549e5f4 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -1508,7 +1508,7 @@ def get_uom_conv_factor(uom: str | None, stock_uom: str | None):
"UOM Conversion Factor", {"to_uom": from_uom, "from_uom": to_uom}, ["value"], as_dict=1
)
if inverse_match:
- return 1 / inverse_match.value
+ return flt(1 / inverse_match.value, frappe.get_precision("UOM Conversion Factor", "value"))
# This attempts to try and get conversion from intermediate UOM.
# case:
@@ -1528,7 +1528,7 @@ def get_uom_conv_factor(uom: str | None, stock_uom: str | None):
)
if intermediate_match:
- return intermediate_match[0].value
+ return flt(intermediate_match[0].value, frappe.get_precision("UOM Conversion Factor", "value"))
@frappe.whitelist()
diff --git a/erpnext/stock/doctype/material_request/mapper.py b/erpnext/stock/doctype/material_request/mapper.py
index 26569f58cec..ea6fd98fdca 100644
--- a/erpnext/stock/doctype/material_request/mapper.py
+++ b/erpnext/stock/doctype/material_request/mapper.py
@@ -288,51 +288,6 @@ def get_items_based_on_default_supplier(supplier: str):
return supplier_items
-@frappe.whitelist()
-def make_purchase_order_based_on_supplier(
- source_name: str, target_doc: str | dict | Document | None = None, args: dict | None = None
-):
- mr = source_name
-
- supplier_items = get_items_based_on_default_supplier(args.get("supplier"))
-
- def postprocess(source, target_doc):
- target_doc.supplier = args.get("supplier")
- if getdate(target_doc.schedule_date) < getdate(nowdate()):
- target_doc.schedule_date = None
- target_doc.set(
- "items",
- [d for d in target_doc.get("items") if d.get("item_code") in supplier_items and d.get("qty") > 0],
- )
-
- set_missing_values(source, target_doc)
-
- target_doc = get_mapped_doc(
- "Material Request",
- mr,
- {
- "Material Request": {
- "doctype": "Purchase Order",
- },
- "Material Request Item": {
- "doctype": "Purchase Order Item",
- "field_map": [
- ["name", "material_request_item"],
- ["parent", "material_request"],
- ["uom", "stock_uom"],
- ["uom", "uom"],
- ],
- "postprocess": update_item,
- "condition": lambda doc: doc.ordered_qty < doc.qty,
- },
- },
- target_doc,
- postprocess,
- )
-
- return target_doc
-
-
@frappe.whitelist()
def make_supplier_quotation(source_name: str, target_doc: str | dict | Document | None = None):
def postprocess(source, target_doc):
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index 1c6d7db5296..922b40325c8 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -315,7 +315,8 @@
"fieldtype": "Link",
"label": "Work Order",
"options": "Work Order",
- "read_only": 1
+ "read_only": 1,
+ "search_index": 1
},
{
"fieldname": "terms_tab",
@@ -376,7 +377,7 @@
"idx": 70,
"is_submittable": 1,
"links": [],
- "modified": "2026-07-30 11:04:31.517204",
+ "modified": "2026-08-07 10:30:00.000000",
"modified_by": "Administrator",
"module": "Stock",
"name": "Material Request",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 72760c55972..4350f33c468 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -273,6 +273,7 @@ class MaterialRequest(BuyingController):
def on_submit(self):
self.update_requested_qty_in_production_plan()
self.update_requested_qty()
+ self.update_requested_qty_in_work_order()
if self.material_request_type == "Purchase":
self.update_prevdoc_status()
if frappe.db.exists("Budget", {"applicable_on_material_request": 1, "docstatus": 1}):
@@ -283,6 +284,20 @@ class MaterialRequest(BuyingController):
def before_submit(self):
self.set_status(update=True)
+ self.validate_pending_qty_in_work_order()
+
+ def validate_pending_qty_in_work_order(self):
+ if not self.work_order or self.material_request_type != "Material Transfer":
+ return
+
+ from erpnext.manufacturing.doctype.work_order.services.required_items import RequiredItemsService
+
+ work_order = frappe.get_doc("Work Order", self.work_order, for_update=True)
+ incoming = {}
+ for row in self.items:
+ incoming[row.item_code] = incoming.get(row.item_code, 0.0) + flt(row.stock_qty)
+
+ RequiredItemsService(work_order).validate_incoming_material_demand(incoming)
def before_cancel(self):
# if MRQ is already closed, no point saving the document
@@ -301,6 +316,7 @@ class MaterialRequest(BuyingController):
self.status_can_change(status)
self.set_status(update=True, status=status)
self.update_requested_qty()
+ self.update_requested_qty_in_work_order()
def status_can_change(self, status):
"""
@@ -330,6 +346,7 @@ class MaterialRequest(BuyingController):
def on_cancel(self):
self.update_requested_qty_in_production_plan(cancel=True)
self.update_requested_qty()
+ self.update_requested_qty_in_work_order()
if self.material_request_type == "Purchase":
self.update_prevdoc_status()
@@ -417,6 +434,19 @@ class MaterialRequest(BuyingController):
update_modified,
)
+ self.update_requested_qty_in_work_order()
+
+ def update_requested_qty_in_work_order(self):
+ """Refresh both counters: stop and cancel also flip pick list coverage."""
+ if not self.work_order or self.material_request_type != "Material Transfer":
+ return
+
+ from erpnext.manufacturing.doctype.work_order.services.required_items import RequiredItemsService
+
+ service = RequiredItemsService(frappe.get_doc("Work Order", self.work_order))
+ service.update_requested_qty_for_required_items()
+ service.update_picked_qty_for_required_items()
+
def update_requested_qty(self, mr_item_rows=None):
"""update requested qty (before ordered_qty is updated)"""
item_wh_list = []
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 5f38ffc7462..4e7027f11db 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -159,6 +159,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"print_hide": 1,
"reqd": 1
},
@@ -545,7 +546,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-01-06 20:47:27.317226",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Material Request Item",
diff --git a/erpnext/stock/doctype/packed_item/packed_item.json b/erpnext/stock/doctype/packed_item/packed_item.json
index 0a8944580c3..62e70aa3c16 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.json
+++ b/erpnext/stock/doctype/packed_item/packed_item.json
@@ -243,7 +243,8 @@
{
"fieldname": "conversion_factor",
"fieldtype": "Float",
- "label": "Conversion Factor"
+ "label": "Conversion Factor",
+ "precision": "9"
},
{
"fieldname": "rate",
@@ -349,7 +350,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Packed Item",
diff --git a/erpnext/stock/doctype/pick_list/pick_list.json b/erpnext/stock/doctype/pick_list/pick_list.json
index 55e66f74b3c..c0898c7182f 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.json
+++ b/erpnext/stock/doctype/pick_list/pick_list.json
@@ -80,7 +80,8 @@
"fieldname": "work_order",
"fieldtype": "Link",
"label": "Work Order",
- "options": "Work Order"
+ "options": "Work Order",
+ "search_index": 1
},
{
"fieldname": "locations",
@@ -278,7 +279,7 @@
],
"is_submittable": 1,
"links": [],
- "modified": "2026-07-01 14:27:50.617011",
+ "modified": "2026-08-07 10:30:00.000000",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List",
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index 50a3a0ebfb4..3cf7c25307f 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -240,6 +240,45 @@ class PickList(TransactionBase):
def before_submit(self):
self.validate_sales_order()
self.validate_picked_items()
+ self.validate_pending_qty_in_work_order()
+
+ def validate_pending_qty_in_work_order(self):
+ """Rows covered by a live material request must stay within that request;
+ every other row must fit the work order's pending requirement."""
+ if not self.work_order:
+ return
+
+ from erpnext.manufacturing.doctype.work_order.services.required_items import RequiredItemsService
+
+ work_order = frappe.get_doc("Work Order", self.work_order, for_update=True)
+ live_requests = {}
+ request_pending = {}
+ incoming = {}
+
+ for row in self.locations:
+ if row.material_request not in live_requests:
+ live_requests[row.material_request] = is_live_material_request(row.material_request)
+
+ if not (row.material_request_item and live_requests[row.material_request]):
+ incoming[row.item_code] = incoming.get(row.item_code, 0.0) + flt(row.picked_qty)
+ continue
+
+ if row.material_request_item not in request_pending:
+ stock_qty, ordered_qty = frappe.db.get_value(
+ "Material Request Item", row.material_request_item, ["stock_qty", "ordered_qty"]
+ )
+ request_pending[row.material_request_item] = flt(stock_qty) - flt(ordered_qty)
+
+ if flt(row.picked_qty - request_pending[row.material_request_item], 6) > 0:
+ frappe.throw(
+ _("Row #{0}: picked qty {1} {2} exceeds the pending qty in Material Request {3}.").format(
+ row.idx, row.picked_qty, row.stock_uom, row.material_request
+ ),
+ title=_("Exceeds Requested Qty"),
+ )
+ request_pending[row.material_request_item] -= flt(row.picked_qty)
+
+ RequiredItemsService(work_order).validate_incoming_material_demand(incoming)
def validate_sales_order(self):
"""Raises an exception if the `Sales Order` has reserved stock."""
@@ -281,6 +320,7 @@ class PickList(TransactionBase):
self.update_bundle_picked_qty()
self.update_reference_qty()
self.update_sales_order_picking_status()
+ self.update_picked_qty_in_work_order()
self.update_prevdoc_status()
def validate_expired_batches(self):
@@ -358,6 +398,7 @@ class PickList(TransactionBase):
self.update_bundle_picked_qty()
self.update_reference_qty()
self.update_sales_order_picking_status()
+ self.update_picked_qty_in_work_order()
self.delink_serial_and_batch_bundle()
self.update_prevdoc_status()
@@ -494,6 +535,15 @@ class PickList(TransactionBase):
for sales_order in sales_orders:
frappe.get_doc("Sales Order", sales_order, for_update=True).update_picking_status()
+ def update_picked_qty_in_work_order(self):
+ if not self.work_order:
+ return
+
+ from erpnext.manufacturing.doctype.work_order.services.required_items import RequiredItemsService
+
+ work_order = frappe.get_doc("Work Order", self.work_order)
+ RequiredItemsService(work_order).update_picked_qty_for_required_items()
+
@frappe.whitelist()
def create_stock_reservation_entries(self, notify: bool = True) -> None:
"""Creates Stock Reservation Entries for Sales Order Items against Pick List."""
@@ -936,6 +986,15 @@ def update_pick_list_status(pick_list):
if pick_list:
doc = frappe.get_doc("Pick List", pick_list)
doc.run_method("update_status")
+ doc.update_picked_qty_in_work_order()
+
+
+def is_live_material_request(material_request):
+ if not material_request:
+ return False
+
+ docstatus, status = frappe.db.get_value("Material Request", material_request, ["docstatus", "status"])
+ return docstatus == 1 and status != "Stopped"
def get_picked_items_qty(items, contains_packed_items=False) -> list[dict]:
diff --git a/erpnext/stock/doctype/pick_list_item/pick_list_item.json b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
index 50713795fd0..d391667cc17 100644
--- a/erpnext/stock/doctype/pick_list_item/pick_list_item.json
+++ b/erpnext/stock/doctype/pick_list_item/pick_list_item.json
@@ -126,6 +126,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "UOM Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -307,7 +308,7 @@
],
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Pick List Item",
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index e08335878e1..83dbeaa5886 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -5545,6 +5545,66 @@ class TestPurchaseReceipt(ERPNextTestSuite):
self.assertEqual(frappe.parse_json(stock_queue), [[20, 0.0]])
+ def test_purchase_return_valuation_for_batchwise_valuation_batch(self):
+ from erpnext.controllers.sales_and_purchase_return import make_return_doc
+ from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
+
+ item_code = make_item(
+ "Test Purchase Return Batchwise Valn Item",
+ {
+ "is_stock_item": 1,
+ "has_batch_no": 1,
+ "batch_number_series": "BN-TPRBWV-.#####",
+ },
+ ).name
+
+ batch_no = "BN-TPRBWV-00001"
+ batch = frappe.new_doc("Batch").update({"batch_id": batch_no, "item": item_code}).insert()
+ self.assertEqual(batch.use_batchwise_valuation, 1)
+
+ warehouse = "_Test Warehouse - _TC"
+ pr = make_purchase_receipt(
+ item_code=item_code,
+ qty=100,
+ rate=1000,
+ warehouse=warehouse,
+ batch_no=batch_no,
+ use_serial_batch_fields=1,
+ )
+ make_purchase_receipt(
+ item_code=item_code,
+ qty=100,
+ rate=400,
+ warehouse=warehouse,
+ batch_no=batch_no,
+ use_serial_batch_fields=1,
+ )
+ create_delivery_note(
+ item_code=item_code,
+ qty=100,
+ warehouse=warehouse,
+ batch_no=batch_no,
+ use_serial_batch_fields=1,
+ )
+
+ return_pr = make_return_doc("Purchase Receipt", pr.name)
+ return_pr.submit()
+
+ sle = frappe.db.get_value(
+ "Stock Ledger Entry",
+ {"voucher_no": return_pr.name, "is_cancelled": 0},
+ ["stock_value_difference", "qty_after_transaction", "stock_value", "serial_and_batch_bundle"],
+ as_dict=True,
+ )
+ self.assertEqual(flt(sle.qty_after_transaction), 0.0)
+ self.assertEqual(flt(sle.stock_value_difference, 2), -70000.0)
+ self.assertEqual(flt(sle.stock_value, 2), 0.0)
+
+ rate = frappe.db.get_value(
+ "Serial and Batch Entry", {"parent": sle.serial_and_batch_bundle}, "incoming_rate"
+ )
+ self.assertEqual(flt(rate, 2), 700.0)
+
def test_negative_stock_error_for_purchase_return(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index ce445d75470..6b9e105fa34 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -291,6 +291,7 @@
"label": "Conversion Factor",
"oldfieldname": "conversion_factor",
"oldfieldtype": "Currency",
+ "precision": "9",
"print_hide": 1,
"print_width": "100px",
"reqd": 1,
@@ -1144,7 +1145,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-16 15:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/putaway_rule/putaway_rule.json b/erpnext/stock/doctype/putaway_rule/putaway_rule.json
index 90f486f2352..38ef543632a 100644
--- a/erpnext/stock/doctype/putaway_rule/putaway_rule.json
+++ b/erpnext/stock/doctype/putaway_rule/putaway_rule.json
@@ -106,12 +106,13 @@
"fieldtype": "Float",
"label": "Conversion Factor",
"no_copy": 1,
+ "precision": "9",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2024-07-08 09:19:26.711470",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Putaway Rule",
diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
index c00d1809868..743d065ba27 100644
--- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py
+++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py
@@ -265,6 +265,9 @@ class QualityInspection(Document):
self.modified,
)
+ if self.reference_type and self.reference_name:
+ frappe.get_lazy_doc(self.reference_type, self.reference_name).notify_update()
+
def inspect_and_set_status(self):
for reading in self.readings:
if not reading.manual_inspection: # dont auto set status if manual
diff --git a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py
index 2ce6d4fe338..d4aed819a1c 100644
--- a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py
+++ b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py
@@ -2,6 +2,7 @@
# See license.txt
from contextlib import contextmanager
+from unittest.mock import patch
import frappe
from frappe.utils import nowdate
@@ -78,6 +79,27 @@ class TestQualityInspection(ERPNextTestSuite):
qa.delete()
dn.delete()
+ def test_doc_update_published_for_reference_on_submit(self):
+ """Submitting a QI publishes doc_update so open reference forms resync their timestamp."""
+ dn = create_delivery_note(item_code="_Test Item with QA", do_not_submit=True)
+ qa = create_quality_inspection(
+ reference_type="Delivery Note", reference_name=dn.name, do_not_submit=True
+ )
+
+ with patch.object(frappe, "publish_realtime") as publish_realtime:
+ qa.submit()
+
+ reference_updates = [
+ call
+ for call in publish_realtime.call_args_list
+ if call.args and call.args[0] == "doc_update" and call.kwargs.get("docname") == dn.name
+ ]
+ self.assertEqual(len(reference_updates), 1)
+
+ message = reference_updates[0].args[1]
+ self.assertEqual(message["doctype"], "Delivery Note")
+ self.assertEqual(message["modified"], frappe.db.get_value("Delivery Note", dn.name, "modified"))
+
def test_value_based_qi_readings(self):
# Test QI based on acceptance values (Non formula)
dn = create_delivery_note(item_code="_Test Item with QA", do_not_submit=True)
diff --git a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
index 5c5aabf2d85..ba1003f1b12 100644
--- a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
@@ -653,6 +653,55 @@ class TestRepostItemValuation(ERPNextTestSuite, StockTestMixin):
# incoming rate after reposting should be 150
self.assertSLEs(se, [{"incoming_rate": 150}])
+ def test_repost_multi_line_moving_average_return(self):
+ from erpnext.controllers.sales_and_purchase_return import make_return_doc
+
+ item = self.make_item(properties={"valuation_method": "Moving Average"}).name
+ warehouse = "_Test Warehouse - _TC"
+
+ make_purchase_receipt(item_code=item, qty=100, rate=100, warehouse=warehouse)
+
+ pr = make_purchase_receipt(item_code=item, qty=400, rate=200, warehouse=warehouse, do_not_submit=1)
+ for qty in (100, 300, 100):
+ pr.append(
+ "items",
+ {
+ "item_code": item,
+ "warehouse": warehouse,
+ "qty": qty,
+ "received_qty": qty,
+ "rate": 200,
+ "uom": pr.items[0].uom,
+ "conversion_factor": 1.0,
+ },
+ )
+ pr.save()
+ pr.submit()
+
+ return_pr = make_return_doc(pr.doctype, pr.name)
+ return_pr.save()
+ return_pr.submit()
+
+ expected_sles = [
+ {"outgoing_rate": 190.0, "valuation_rate": 190.0, "qty_after_transaction": 600.0},
+ {"outgoing_rate": 190.0, "valuation_rate": 190.0, "qty_after_transaction": 500.0},
+ {"outgoing_rate": 190.0, "valuation_rate": 190.0, "qty_after_transaction": 200.0},
+ {"outgoing_rate": 190.0, "valuation_rate": 190.0, "qty_after_transaction": 100.0},
+ ]
+
+ for _ in range(2):
+ riv = frappe.get_doc(
+ doctype="Repost Item Valuation",
+ based_on="Transaction",
+ voucher_type=pr.doctype,
+ voucher_no=pr.name,
+ posting_date=pr.posting_date,
+ posting_time=pr.posting_time,
+ )
+ riv.submit()
+
+ self.assertSLEs(return_pr, expected_sles)
+
def test_remove_attached_file(self):
item_code = make_item("_Test Remove Attached File Item", properties={"is_stock_item": 1})
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 6a2e835f670..4a29c693860 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
@@ -414,6 +414,13 @@ class SerialandBatchBundle(Document):
valuation_method = get_valuation_method(self.item_code, self.company)
+ # An outward return must go out at the batch's current average rate for a
+ # batchwise valuation batch. The original receipt rate is only correct while
+ # the batch still holds stock at that rate; once other receipts have changed
+ # the average, removing at the original rate strands a residue in the batch
+ # value (negative when returning the costlier receipt).
+ batchwise_avg_rates = self.get_batchwise_return_avg_rates()
+
stock_queue = []
non_batchwise_batches = []
if not self.has_serial_no and valuation_method == "FIFO":
@@ -447,6 +454,12 @@ class SerialandBatchBundle(Document):
batches = sorted(list(valuation_details["batches"].keys()))
valuation_rate = valuation_details["batches"].get(batches[cint(row.idx) - 1])
+ # a batch with an available balance goes out at its current average rate (a
+ # valid 0.0 included); the original receipt rate applies only when there is
+ # no balance to average
+ if not row.serial_no and row.batch_no in batchwise_avg_rates:
+ valuation_rate = batchwise_avg_rates[row.batch_no]
+
row.incoming_rate = flt(valuation_rate)
row.stock_value_difference = flt(row.qty) * flt(row.incoming_rate)
@@ -475,6 +488,43 @@ class SerialandBatchBundle(Document):
elif self.type_of_transaction == "Inward":
self.set_incoming_rate_for_inward_transaction(row, save, prev_sle=prev_sle)
+ def get_batchwise_return_avg_rates(self):
+ from erpnext.stock.utils import get_valuation_method
+
+ if self.type_of_transaction != "Outward" or self.has_serial_no:
+ return {}
+
+ batch_nos = [d.batch_no for d in self.entries if d.batch_no]
+ if not batch_nos:
+ return {}
+
+ if get_valuation_method(
+ self.item_code, self.company
+ ) == "Moving Average" and frappe.db.get_single_value(
+ "Stock Settings", "do_not_use_batchwise_valuation"
+ ):
+ return {}
+
+ batchwise_batches = frappe.get_all(
+ "Batch",
+ filters={"name": ("in", batch_nos), "use_batchwise_valuation": 1},
+ pluck="name",
+ )
+ if not batchwise_batches:
+ return {}
+
+ # scoped to batchwise batches only, so BatchNoValuation's non-batchwise
+ # machinery never runs for them
+ sle = self.get_sle_for_outward_transaction()
+ sle.batch_nos = {batch_no: sle.batch_nos[batch_no] for batch_no in batchwise_batches}
+ sle.batchwise_valuation_batches = batchwise_batches
+ sn_obj = BatchNoValuation(sle=sle, item_code=self.item_code, warehouse=self.warehouse)
+ return {
+ batch_no: abs(flt(sn_obj.batch_avg_rate.get(batch_no)))
+ for batch_no in batchwise_batches
+ if flt(sn_obj.available_qty.get(batch_no))
+ }
+
def validate_returned_serial_batch_no(self, return_against, row, original_inv_details):
if frappe.flags.through_repost_item_valuation and not frappe.in_test:
return
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index b7417eb72e1..8d798e2c1c6 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -319,6 +319,7 @@ class StockEntry(StockController, SubcontractingInwardController):
self.validate_batch()
self.validate_inspection()
self.validate_fg_completed_qty()
+ self.validate_job_card_pending_production()
self.validate_difference_account()
self.validate_job_card_item()
self.set_purpose_for_stock_entry()
@@ -1452,23 +1453,15 @@ class StockEntry(StockController, SubcontractingInwardController):
return
precision = self.precision("process_loss_qty")
- if self.work_order:
- data = frappe.get_all(
- "Work Order Operation",
- filters={"parent": self.work_order},
- fields=[{"MAX": "process_loss_qty", "as": "process_loss_qty"}],
+ process_loss_qty = self.get_pending_process_loss_qty()
+ if process_loss_qty and flt(self.process_loss_qty, precision) != flt(process_loss_qty, precision):
+ self.process_loss_qty = flt(process_loss_qty, precision)
+
+ frappe.msgprint(
+ _("The Process Loss Qty has been reset as per the job card's Process Loss Qty"),
+ alert=True,
)
- if data and data[0].process_loss_qty:
- process_loss_qty = data[0].process_loss_qty
- if flt(self.process_loss_qty, precision) != flt(process_loss_qty, precision):
- self.process_loss_qty = flt(process_loss_qty, precision)
-
- frappe.msgprint(
- _("The Process Loss Qty has been reset as per the job card's Process Loss Qty"),
- alert=True,
- )
-
if not self.process_loss_percentage and not self.process_loss_qty:
self.process_loss_percentage = frappe.get_cached_value(
"BOM", self.bom_no, "process_loss_percentage"
@@ -1483,6 +1476,60 @@ class StockEntry(StockController, SubcontractingInwardController):
(flt(self.process_loss_qty) / flt(self.fg_completed_qty)) * 100
)
+ def validate_job_card_pending_production(self):
+ """A draft created before other entries were submitted must not book more than the job
+ card still has left; without this, a stale draft over-produces the finished good."""
+ if self.purpose != "Manufacture" or not self.job_card:
+ return
+
+ if self._action == "update_after_submit":
+ return
+
+ job_card = frappe.get_doc("Job Card", self.job_card)
+ if job_card.is_corrective_job_card or job_card.is_subcontracted:
+ return
+
+ precision = frappe.get_precision("Stock Entry Detail", "qty")
+ pending_qty = flt(
+ flt(job_card.get_qty_to_produce())
+ - flt(job_card.manufactured_qty)
+ - flt(job_card.get_consumed_process_loss()),
+ precision,
+ )
+ finished_qty = flt(sum(flt(d.transfer_qty) for d in self.items if d.is_finished_item), precision)
+ entry_qty = flt(finished_qty + flt(self.process_loss_qty), precision)
+
+ if entry_qty > pending_qty:
+ uom = job_card.stock_uom
+ frappe.throw(
+ _(
+ "The Job Card {0} has only {1} left to produce, but this entry books {2} ({3} finished goods and {4} process loss). Cancel or update its other manufacture entries first."
+ ).format(
+ frappe.bold(self.job_card),
+ frappe.bold(f"{pending_qty} {uom}"),
+ frappe.bold(f"{entry_qty} {uom}"),
+ f"{finished_qty} {uom}",
+ f"{flt(self.process_loss_qty, precision)} {uom}",
+ )
+ )
+
+ def get_pending_process_loss_qty(self):
+ """Loss this entry should still book: the job card's unbooked loss when the entry
+ belongs to one, else the largest operation loss on the work order (legacy flow)."""
+ if self.job_card:
+ job_card = frappe.get_doc("Job Card", self.job_card)
+ return max(flt(job_card.process_loss_qty) - flt(job_card.get_consumed_process_loss()), 0)
+
+ if self.work_order:
+ data = frappe.get_all(
+ "Work Order Operation",
+ filters={"parent": self.work_order},
+ fields=[{"MAX": "process_loss_qty", "as": "process_loss_qty"}],
+ )
+ return flt(data[0].process_loss_qty) if data else 0
+
+ return 0
+
def set_work_order_details(self):
if self.work_order:
# common validations
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
index 126daf21389..396d68487b6 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
@@ -257,6 +257,7 @@
"label": "Conversion Factor",
"oldfieldname": "conversion_factor",
"oldfieldtype": "Currency",
+ "precision": "9",
"print_hide": 1,
"reqd": 1
},
@@ -700,7 +701,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Entry Detail",
diff --git a/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py b/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py
index a10441106e0..d9ea63a9f82 100644
--- a/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py
+++ b/erpnext/stock/doctype/stock_entry_type/stock_entry_type.py
@@ -126,6 +126,7 @@ class ManufactureEntry:
if backflush_based_on != "BOM":
available_serial_batches = self.get_transferred_serial_batches()
+ production_share = self.get_production_share()
for item_code, _dict in item_dict.items():
_dict.s_warehouse = self.source_wh.get(item_code) or self.wip_warehouse
_dict.t_warehouse = ""
@@ -140,11 +141,29 @@ class ManufactureEntry:
_dict.qty = calculated_qty
self.update_available_serial_batches(_dict, available_serial_batches)
- elif self.skip_material_transfer:
- set_previous_operation_serial_batch(self.stock_entry, _dict)
+ else:
+ remaining_qty = max(flt(_dict.qty) - flt(_dict.consumed_qty), 0)
+ _dict.qty = min(flt(_dict.qty) * production_share, remaining_qty)
+ if not _dict.qty:
+ continue
+
+ if self.skip_material_transfer:
+ set_previous_operation_serial_batch(self.stock_entry, _dict)
self.stock_entry.append("items", _dict)
+ def get_production_share(self):
+ """Fraction of the job card's production this entry accounts for; raw materials are
+ generated proportionally so several partial entries never consume more than required."""
+ for_quantity, pending_qty = frappe.db.get_value(
+ "Job Card", self.job_card, ["for_quantity", "pending_qty"]
+ )
+ qty_to_produce = flt(for_quantity) - flt(pending_qty)
+ if not qty_to_produce:
+ return 1
+
+ return min(flt(self.for_quantity) / qty_to_produce, 1)
+
def parse_available_serial_batches(self, item_dict, available_serial_batches):
key = (item_dict.item_code, item_dict.from_warehouse)
if key not in available_serial_batches:
diff --git a/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.json b/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.json
index 2ab7f5e6600..90bf08be897 100644
--- a/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.json
+++ b/erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.json
@@ -28,7 +28,8 @@
"label": "Conversion Factor",
"non_negative": 1,
"oldfieldname": "conversion_factor",
- "oldfieldtype": "Float"
+ "oldfieldtype": "Float",
+ "precision": "9"
},
{
"fieldname": "column_break_nmeg",
@@ -38,7 +39,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-06-11 23:02:54.800673",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Stock",
"name": "UOM Conversion Detail",
diff --git a/erpnext/stock/doctype_settings_map/batch_(standard)/batch_(standard).json b/erpnext/stock/doctype_settings_map/batch.json
similarity index 94%
rename from erpnext/stock/doctype_settings_map/batch_(standard)/batch_(standard).json
rename to erpnext/stock/doctype_settings_map/batch.json
index bd6c1ce7415..b8578795bdd 100644
--- a/erpnext/stock/doctype_settings_map/batch_(standard)/batch_(standard).json
+++ b/erpnext/stock/doctype_settings_map/batch.json
@@ -19,6 +19,6 @@
"modified": "2026-07-10 11:02:55.870708",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Batch (Standard)",
+ "name": "Batch - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/delivery_note_(standard)/delivery_note_(standard).json b/erpnext/stock/doctype_settings_map/delivery_note.json
similarity index 96%
rename from erpnext/stock/doctype_settings_map/delivery_note_(standard)/delivery_note_(standard).json
rename to erpnext/stock/doctype_settings_map/delivery_note.json
index fce18cba200..8eb5a46019b 100644
--- a/erpnext/stock/doctype_settings_map/delivery_note_(standard)/delivery_note_(standard).json
+++ b/erpnext/stock/doctype_settings_map/delivery_note.json
@@ -43,6 +43,6 @@
"modified": "2026-07-20 15:19:29.595043",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Delivery Note (Standard)",
+ "name": "Delivery Note - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/delivery_trip_(standard)/delivery_trip_(standard).json b/erpnext/stock/doctype_settings_map/delivery_trip.json
similarity index 94%
rename from erpnext/stock/doctype_settings_map/delivery_trip_(standard)/delivery_trip_(standard).json
rename to erpnext/stock/doctype_settings_map/delivery_trip.json
index 81bd01b7924..01ec982f1de 100644
--- a/erpnext/stock/doctype_settings_map/delivery_trip_(standard)/delivery_trip_(standard).json
+++ b/erpnext/stock/doctype_settings_map/delivery_trip.json
@@ -27,6 +27,6 @@
"modified": "2026-07-09 15:07:54.781814",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Delivery Trip (Standard)",
+ "name": "Delivery Trip - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/item_(standard)/item_(standard).json b/erpnext/stock/doctype_settings_map/item.json
similarity index 97%
rename from erpnext/stock/doctype_settings_map/item_(standard)/item_(standard).json
rename to erpnext/stock/doctype_settings_map/item.json
index b07d359d89b..177b2cf9683 100644
--- a/erpnext/stock/doctype_settings_map/item_(standard)/item_(standard).json
+++ b/erpnext/stock/doctype_settings_map/item.json
@@ -35,6 +35,6 @@
"modified": "2026-07-20 15:03:19.905964",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Item (Standard)",
+ "name": "Item - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/item_price_(standard)/item_price_(standard).json b/erpnext/stock/doctype_settings_map/item_price.json
similarity index 94%
rename from erpnext/stock/doctype_settings_map/item_price_(standard)/item_price_(standard).json
rename to erpnext/stock/doctype_settings_map/item_price.json
index c037d47035e..3f46b2a8942 100644
--- a/erpnext/stock/doctype_settings_map/item_price_(standard)/item_price_(standard).json
+++ b/erpnext/stock/doctype_settings_map/item_price.json
@@ -23,6 +23,6 @@
"modified": "2026-07-03 14:18:10.406964",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Item Price (Standard)",
+ "name": "Item Price - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/item_variant_(standard)/item_variant_(standard).json b/erpnext/stock/doctype_settings_map/item_variant.json
similarity index 92%
rename from erpnext/stock/doctype_settings_map/item_variant_(standard)/item_variant_(standard).json
rename to erpnext/stock/doctype_settings_map/item_variant.json
index 6d40b1da469..ff43ed4a698 100644
--- a/erpnext/stock/doctype_settings_map/item_variant_(standard)/item_variant_(standard).json
+++ b/erpnext/stock/doctype_settings_map/item_variant.json
@@ -15,6 +15,6 @@
"modified": "2026-07-09 13:46:50.401488",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Item Variant (Standard)",
+ "name": "Item Variant - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/material_request_(standard)/material_request_(standard).json b/erpnext/stock/doctype_settings_map/material_request.json
similarity index 94%
rename from erpnext/stock/doctype_settings_map/material_request_(standard)/material_request_(standard).json
rename to erpnext/stock/doctype_settings_map/material_request.json
index e42fb3e4558..6dbebbe4183 100644
--- a/erpnext/stock/doctype_settings_map/material_request_(standard)/material_request_(standard).json
+++ b/erpnext/stock/doctype_settings_map/material_request.json
@@ -27,6 +27,6 @@
"modified": "2026-07-20 16:04:40.139121",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Material Request (Standard)",
+ "name": "Material Request - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/pick_list_(standard)/pick_list_(standard).json b/erpnext/stock/doctype_settings_map/pick_list.json
similarity index 94%
rename from erpnext/stock/doctype_settings_map/pick_list_(standard)/pick_list_(standard).json
rename to erpnext/stock/doctype_settings_map/pick_list.json
index f3ae9ed32a2..8e0e652934c 100644
--- a/erpnext/stock/doctype_settings_map/pick_list_(standard)/pick_list_(standard).json
+++ b/erpnext/stock/doctype_settings_map/pick_list.json
@@ -19,6 +19,6 @@
"modified": "2026-07-20 16:05:15.546016",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Pick List (Standard)",
+ "name": "Pick List - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/purchase_receipt_(standard)/purchase_receipt_(standard).json b/erpnext/stock/doctype_settings_map/purchase_receipt.json
similarity index 97%
rename from erpnext/stock/doctype_settings_map/purchase_receipt_(standard)/purchase_receipt_(standard).json
rename to erpnext/stock/doctype_settings_map/purchase_receipt.json
index 16c2ce5161a..95c19f8a2cd 100644
--- a/erpnext/stock/doctype_settings_map/purchase_receipt_(standard)/purchase_receipt_(standard).json
+++ b/erpnext/stock/doctype_settings_map/purchase_receipt.json
@@ -59,6 +59,6 @@
"modified": "2026-07-20 16:02:40.647761",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Purchase Receipt (Standard)",
+ "name": "Purchase Receipt - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/repost_item_valuation_(standard)/repost_item_valuation_(standard).json b/erpnext/stock/doctype_settings_map/repost_item_valuation.json
similarity index 96%
rename from erpnext/stock/doctype_settings_map/repost_item_valuation_(standard)/repost_item_valuation_(standard).json
rename to erpnext/stock/doctype_settings_map/repost_item_valuation.json
index ac0f0580b0b..f54fad172da 100644
--- a/erpnext/stock/doctype_settings_map/repost_item_valuation_(standard)/repost_item_valuation_(standard).json
+++ b/erpnext/stock/doctype_settings_map/repost_item_valuation.json
@@ -43,6 +43,6 @@
"modified": "2026-07-09 11:45:29.543363",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Repost Item Valuation (Standard)",
+ "name": "Repost Item Valuation - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/stock_entry_(standard)/stock_entry_(standard).json b/erpnext/stock/doctype_settings_map/stock_entry.json
similarity index 98%
rename from erpnext/stock/doctype_settings_map/stock_entry_(standard)/stock_entry_(standard).json
rename to erpnext/stock/doctype_settings_map/stock_entry.json
index 6f62d24b497..1350e3e602e 100644
--- a/erpnext/stock/doctype_settings_map/stock_entry_(standard)/stock_entry_(standard).json
+++ b/erpnext/stock/doctype_settings_map/stock_entry.json
@@ -67,6 +67,6 @@
"modified": "2026-07-20 17:43:38.321292",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Stock Entry (Standard)",
+ "name": "Stock Entry - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/stock_ledger_entry_(standard)/stock_ledger_entry_(standard).json b/erpnext/stock/doctype_settings_map/stock_ledger_entry.json
similarity index 94%
rename from erpnext/stock/doctype_settings_map/stock_ledger_entry_(standard)/stock_ledger_entry_(standard).json
rename to erpnext/stock/doctype_settings_map/stock_ledger_entry.json
index 63557df864a..cf28dfa6ede 100644
--- a/erpnext/stock/doctype_settings_map/stock_ledger_entry_(standard)/stock_ledger_entry_(standard).json
+++ b/erpnext/stock/doctype_settings_map/stock_ledger_entry.json
@@ -27,6 +27,6 @@
"modified": "2026-07-10 11:41:15.124849",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Stock Ledger Entry (Standard)",
+ "name": "Stock Ledger Entry - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/doctype_settings_map/stock_reservation_entry_(standard)/stock_reservation_entry_(standard).json b/erpnext/stock/doctype_settings_map/stock_reservation_entry.json
similarity index 94%
rename from erpnext/stock/doctype_settings_map/stock_reservation_entry_(standard)/stock_reservation_entry_(standard).json
rename to erpnext/stock/doctype_settings_map/stock_reservation_entry.json
index e4b93cd37e9..48c68b0ebb1 100644
--- a/erpnext/stock/doctype_settings_map/stock_reservation_entry_(standard)/stock_reservation_entry_(standard).json
+++ b/erpnext/stock/doctype_settings_map/stock_reservation_entry.json
@@ -27,6 +27,6 @@
"modified": "2026-07-10 11:44:00.765222",
"modified_by": "Administrator",
"module": "Stock",
- "name": "Stock Reservation Entry (Standard)",
+ "name": "Stock Reservation Entry - Stock",
"owner": "Administrator"
}
diff --git a/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py b/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py
index ed06c27a1ef..9ebf3c11528 100644
--- a/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py
+++ b/erpnext/stock/report/stock_ledger_invariant_check/stock_ledger_invariant_check.py
@@ -7,6 +7,8 @@ import frappe
from frappe import _
from frappe.utils import cint, flt, get_link_to_form, parse_json
+from erpnext.stock.utils import get_valuation_method
+
SLE_FIELDS = (
"name",
"posting_date",
@@ -53,6 +55,9 @@ def add_invariant_check_fields(sles, filters):
balance_qty = 0.0
balance_stock_value = 0.0
+ company = frappe.get_cached_value("Warehouse", filters.warehouse, "company")
+ valuation_method = get_valuation_method(filters.item_code, company)
+
incorrect_idx = None
float_precision = cint(frappe.db.get_single_value("System Settings", "float_precision")) or 3
currency_precision = (
@@ -90,7 +95,7 @@ def add_invariant_check_fields(sles, filters):
)
sle.diff_value_diff = sle.stock_value_from_diff - sle.stock_value
- if maintains_fifo_queue(sle):
+ if maintains_fifo_queue(sle, valuation_method):
add_fifo_fields(sle, sles[idx - 1] if idx else None)
if incorrect_idx is None and not is_sle_has_correct_data(sle, float_precision, currency_precision):
@@ -104,8 +109,10 @@ def add_invariant_check_fields(sles, filters):
return sles
-def maintains_fifo_queue(sle):
- # no queue is maintained for serialized/batchwise-valued stock
+def maintains_fifo_queue(sle, valuation_method):
+ if valuation_method == "Moving Average":
+ return False
+
return not (
sle.serial_and_batch_bundle or sle.serial_no or (sle.batch_no and sle.use_batchwise_valuation)
)
@@ -138,6 +145,8 @@ def is_sle_has_correct_data(sle, float_precision, currency_precision):
return (
flt(sle.difference_in_qty, float_precision) == 0.0
and flt(sle.diff_value_diff, currency_precision) == 0.0
+ and flt(sle.fifo_qty_diff, float_precision) == 0.0
+ and flt(sle.fifo_value_diff, currency_precision) == 0.0
)
diff --git a/erpnext/stock/report/stock_ledger_invariant_check/test_stock_ledger_invariant_check.py b/erpnext/stock/report/stock_ledger_invariant_check/test_stock_ledger_invariant_check.py
index 0f71a8834b2..ae692617a77 100644
--- a/erpnext/stock/report/stock_ledger_invariant_check/test_stock_ledger_invariant_check.py
+++ b/erpnext/stock/report/stock_ledger_invariant_check/test_stock_ledger_invariant_check.py
@@ -1,6 +1,8 @@
# Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
+import json
+
import frappe
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
@@ -59,6 +61,34 @@ class TestStockLedgerInvariantCheck(ERPNextTestSuite):
self.assertEqual(len(data), 2) # incorrect entry + one before it for context
self.assertEqual(data[-1].name, sle.name)
+ def test_show_incorrect_entries_catches_queue_mismatch(self):
+ item = self.make_movements()
+
+ sle = frappe.get_last_doc(
+ "Stock Ledger Entry", {"item_code": item, "warehouse": WAREHOUSE, "is_cancelled": 0}
+ )
+ tampered_queue = json.dumps([[sle.qty_after_transaction + 5, 100]])
+ frappe.db.set_value("Stock Ledger Entry", sle.name, "stock_queue", tampered_queue)
+
+ data = self.run_report(item_code=item, show_incorrect_entries=1)
+ self.assertEqual(len(data), 2)
+ self.assertEqual(data[-1].name, sle.name)
+
+ def test_moving_average_item_skips_fifo_queue_checks(self):
+ from erpnext.stock.doctype.item.test_item import make_item
+
+ item = make_item(properties={"valuation_method": "Moving Average"}).name
+ make_stock_entry(item_code=item, to_warehouse=WAREHOUSE, qty=10, rate=100)
+ make_stock_entry(item_code=item, from_warehouse=WAREHOUSE, qty=4)
+
+ data = self.run_report(item_code=item)
+ self.assertTrue(data)
+ for row in data:
+ self.assertIsNone(row.fifo_qty_diff)
+ self.assertIsNone(row.fifo_value_diff)
+
+ self.assertEqual(self.run_report(item_code=item, show_incorrect_entries=1), [])
+
def test_batch_item_skips_fifo_queue_checks(self):
from erpnext.stock.doctype.item.test_item import make_item
diff --git a/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js b/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js
index c38f0237436..6df8458fd3c 100644
--- a/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js
+++ b/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.js
@@ -2,6 +2,30 @@
// For license information, please see license.txt
frappe.query_reports["Stock Qty vs Serial No Count"] = {
+ onload: function (report) {
+ report.page.add_inner_button(__("Sync Serial No Status"), () => {
+ const warehouse = report.get_filter_value("warehouse");
+ if (!warehouse) {
+ frappe.msgprint(__("Please select a warehouse first."));
+ return;
+ }
+
+ frappe.confirm(
+ __(
+ "This will update the warehouse and status of Serial Nos counted in {0} to match the stock ledger. Continue?",
+ [warehouse.bold()]
+ ),
+ () => {
+ frappe.call({
+ method: "erpnext.stock.report.stock_qty_vs_serial_no_count.stock_qty_vs_serial_no_count.sync_serial_no_status",
+ args: { warehouse: warehouse },
+ freeze: true,
+ });
+ }
+ );
+ });
+ },
+
filters: [
{
fieldname: "company",
diff --git a/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py b/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py
index 6087c747374..2ea732180ad 100644
--- a/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py
+++ b/erpnext/stock/report/stock_qty_vs_serial_no_count/stock_qty_vs_serial_no_count.py
@@ -4,6 +4,12 @@
import frappe
from frappe import _
+from frappe.query_builder import Order
+from frappe.query_builder.functions import Coalesce
+from frappe.utils import cstr, flt
+from pypika import analytics as an
+
+from erpnext.stock.serial_batch_bundle import get_serial_no_status
def execute(filters=None):
@@ -77,3 +83,172 @@ def get_data(warehouse, show_disabled_items):
data.append(row)
return data
+
+
+SYNC_CHUNK_SIZE = 1000
+
+
+@frappe.whitelist(methods=["POST"])
+def sync_serial_no_status(warehouse: str, item_code: str | None = None):
+ if not frappe.has_permission("Serial No", "write"):
+ frappe.throw(_("Not permitted to update Serial No"), frappe.PermissionError)
+
+ warehouse = cstr(warehouse)
+ item_code = cstr(item_code) if item_code else None
+ if not frappe.db.exists("Warehouse", warehouse):
+ frappe.throw(_("Warehouse {0} does not exist").format(warehouse))
+
+ if item_code and not frappe.db.exists("Item", item_code):
+ frappe.throw(_("Item {0} does not exist").format(item_code))
+
+ frappe.enqueue(
+ sync_serial_no_status_for_warehouse,
+ queue="long",
+ warehouse=warehouse,
+ item_code=item_code,
+ )
+ frappe.msgprint(
+ _("Serial No status sync has been queued. Reload the report after a few minutes."),
+ alert=True,
+ )
+
+
+def sync_serial_no_status_for_warehouse(warehouse, item_code=None):
+ filters = {"has_serial_no": 1}
+ if item_code:
+ filters["name"] = item_code
+
+ for item in frappe.get_all("Item", filters=filters, pluck="name"):
+ sync_serial_no_status_for_item(item, warehouse)
+
+
+def sync_serial_no_status_for_item(item_code, warehouse):
+ """Correct Serial No records this report counts in the warehouse but whose last
+ stock ledger movement says the stock left it. Reposting rebuilds qty and valuation
+ from the ledger but never rewrites Serial No warehouse/status, so records orphaned
+ by cancelled or amended vouchers keep inflating the serial count."""
+ serial_nos = frappe.get_all(
+ "Serial No",
+ filters={"item_code": item_code, "warehouse": warehouse, "status": ("in", ["Active", "Expired"])},
+ pluck="name",
+ )
+ if not serial_nos:
+ return
+
+ last_moves = get_last_ledger_moves(item_code, serial_nos)
+ for serial_no in serial_nos:
+ row = last_moves.get(serial_no)
+ if row and flt(row.qty) > 0 and row.warehouse == warehouse:
+ continue
+
+ set_serial_no_state_from_ledger(serial_no, row)
+
+
+def set_serial_no_state_from_ledger(serial_no, row):
+ if not row:
+ frappe.db.set_value(
+ "Serial No", serial_no, {"warehouse": None, "status": "Inactive"}, update_modified=False
+ )
+ return
+
+ status = get_serial_no_status(
+ frappe._dict(
+ actual_qty=flt(row.qty),
+ warehouse=row.warehouse,
+ voucher_type=row.voucher_type,
+ voucher_no=row.voucher_no,
+ is_cancelled=0,
+ )
+ )
+ warehouse = row.warehouse if status == "Active" else None
+ frappe.db.set_value(
+ "Serial No", serial_no, {"warehouse": warehouse, "status": status}, update_modified=False
+ )
+
+
+def get_last_ledger_moves(item_code, serial_nos):
+ last_moves = get_last_bundle_moves(item_code, serial_nos)
+ if missing := [serial_no for serial_no in serial_nos if serial_no not in last_moves]:
+ set_legacy_last_moves(item_code, missing, last_moves)
+
+ return last_moves
+
+
+def get_last_bundle_moves(item_code, serial_nos):
+ last_moves = {}
+ for start in range(0, len(serial_nos), SYNC_CHUNK_SIZE):
+ for row in get_last_bundle_moves_chunk(item_code, serial_nos[start : start + SYNC_CHUNK_SIZE]):
+ last_moves[row.serial_no] = row
+
+ return last_moves
+
+
+def get_last_bundle_moves_chunk(item_code, serial_nos):
+ """A bundle can be created much before its Stock Ledger Entry, so same-posting-datetime
+ ties are broken on the creation of the bundle's own SLE. The SLE join also keeps only
+ real stock movements - reservation bundles (Pick List) carry no SLE."""
+ entry = frappe.qb.DocType("Serial and Batch Entry")
+ bundle = frappe.qb.DocType("Serial and Batch Bundle")
+ sle = frappe.qb.DocType("Stock Ledger Entry")
+
+ row_number = (
+ an.RowNumber()
+ .over(entry.serial_no)
+ .orderby(Coalesce(entry.posting_datetime, bundle.posting_datetime), order=Order.desc)
+ .orderby(sle.creation, order=Order.desc)
+ )
+
+ ranked = (
+ frappe.qb.from_(entry)
+ .inner_join(bundle)
+ .on(entry.parent == bundle.name)
+ .inner_join(sle)
+ .on(sle.serial_and_batch_bundle == bundle.name)
+ .select(
+ entry.serial_no,
+ entry.qty,
+ Coalesce(entry.warehouse, bundle.warehouse).as_("warehouse"),
+ bundle.voucher_type,
+ bundle.voucher_no,
+ row_number.as_("row_no"),
+ )
+ .where(
+ (bundle.docstatus == 1)
+ & (Coalesce(bundle.is_cancelled, 0) == 0)
+ & (sle.is_cancelled == 0)
+ & (bundle.item_code == item_code)
+ & (entry.serial_no.isin(serial_nos))
+ )
+ ).as_("ranked")
+
+ return (
+ frappe.qb.from_(ranked)
+ .select(ranked.serial_no, ranked.qty, ranked.warehouse, ranked.voucher_type, ranked.voucher_no)
+ .where(ranked.row_no == 1)
+ .run(as_dict=True)
+ )
+
+
+def set_legacy_last_moves(item_code, serial_nos, last_moves):
+ """Movements posted before Serial and Batch Bundle exist only as newline-separated
+ text on Stock Ledger Entry."""
+ from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
+
+ pending = set(serial_nos)
+ rows = frappe.get_all(
+ "Stock Ledger Entry",
+ filters={"item_code": item_code, "is_cancelled": 0, "serial_no": ("is", "set")},
+ fields=["serial_no", "actual_qty", "warehouse", "voucher_type", "voucher_no"],
+ order_by="posting_datetime asc, creation asc",
+ )
+
+ for row in rows:
+ qty = 1 if flt(row.actual_qty) > 0 else -1
+ for serial_no in get_serial_nos(row.serial_no):
+ if serial_no in pending:
+ last_moves[serial_no] = frappe._dict(
+ qty=qty,
+ warehouse=row.warehouse,
+ voucher_type=row.voucher_type,
+ voucher_no=row.voucher_no,
+ )
diff --git a/erpnext/stock/report/stock_qty_vs_serial_no_count/test_stock_qty_vs_serial_no_count.py b/erpnext/stock/report/stock_qty_vs_serial_no_count/test_stock_qty_vs_serial_no_count.py
index 021d7d0f3c6..8a2340cb5e8 100644
--- a/erpnext/stock/report/stock_qty_vs_serial_no_count/test_stock_qty_vs_serial_no_count.py
+++ b/erpnext/stock/report/stock_qty_vs_serial_no_count/test_stock_qty_vs_serial_no_count.py
@@ -46,3 +46,35 @@ class TestStockQtyVsSerialNoCount(ERPNextTestSuite):
}
)
)
+
+ def test_sync_serial_no_status(self):
+ from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
+ from erpnext.stock.report.stock_qty_vs_serial_no_count.stock_qty_vs_serial_no_count import (
+ sync_serial_no_status_for_warehouse,
+ )
+
+ item = "_Test Serialized Item With Series"
+ warehouse = "Stores - _TC"
+ se = make_stock_entry(item_code=item, to_warehouse=warehouse, qty=2, rate=100)
+ serial_no = frappe.get_all(
+ "Serial and Batch Entry",
+ {"parent": se.items[0].serial_and_batch_bundle},
+ pluck="serial_no",
+ )[0]
+
+ create_delivery_note(
+ item_code=item,
+ warehouse=warehouse,
+ qty=1,
+ serial_no=serial_no,
+ use_serial_batch_fields=1,
+ )
+ self.assertEqual(frappe.db.get_value("Serial No", serial_no, "status"), "Delivered")
+
+ frappe.db.set_value("Serial No", serial_no, {"status": "Active", "warehouse": warehouse})
+
+ sync_serial_no_status_for_warehouse(warehouse, item_code=item)
+
+ details = frappe.db.get_value("Serial No", serial_no, ["status", "warehouse"], as_dict=True)
+ self.assertEqual(details.status, "Delivered")
+ self.assertFalse(details.warehouse)
diff --git a/erpnext/stock/serial_batch_bundle.py b/erpnext/stock/serial_batch_bundle.py
index e18f2759ffd..090f6098817 100644
--- a/erpnext/stock/serial_batch_bundle.py
+++ b/erpnext/stock/serial_batch_bundle.py
@@ -988,6 +988,11 @@ class BatchNoValuation(DeprecatedBatchNoValuation):
self.batchwise_valuation_batches = []
self.non_batchwise_valuation_batches = []
+ if batchwise_batches := self.sle.get("batchwise_valuation_batches"):
+ self.batchwise_valuation_batches = list(batchwise_batches)
+ self.non_batchwise_valuation_batches = list(set(self.batches) - set(batchwise_batches))
+ return
+
if get_valuation_method(
self.sle.item_code, self.sle.company
) == "Moving Average" and frappe.get_single_value("Stock Settings", "do_not_use_batchwise_valuation"):
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 5f826e8f0c6..9cb3f272ff5 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -38,7 +38,6 @@ from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry impor
from erpnext.stock.utils import (
get_combine_datetime,
get_incoming_outgoing_rate_for_cancel,
- get_incoming_rate,
get_or_make_bin,
get_serial_nos_data,
get_stock_balance,
@@ -1460,23 +1459,7 @@ class update_entries_after:
and not sle.get("batch_no")
and not sle.get("serial_and_batch_bundle")
):
- rate = get_incoming_rate(
- {
- "item_code": sle.item_code,
- "warehouse": sle.warehouse,
- "posting_date": sle.posting_date,
- "posting_time": sle.posting_time,
- "qty": sle.actual_qty,
- "serial_no": sle.get("serial_no"),
- "batch_no": sle.get("batch_no"),
- "serial_and_batch_bundle": sle.get("serial_and_batch_bundle"),
- "company": sle.company,
- "voucher_type": sle.voucher_type,
- "voucher_no": sle.voucher_no,
- "allow_zero_valuation": self.allow_zero_rate,
- "sle": sle.name,
- }
- )
+ rate = self.get_moving_average_rate_for_return(sle)
if not rate and sle.voucher_type in ["Delivery Note", "Sales Invoice"]:
rate = get_rate_for_return(
@@ -1544,6 +1527,38 @@ class update_entries_after:
return rate
+ def get_moving_average_rate_for_return(self, sle):
+ """Rate just before this entry, taken from the in-memory running state so a
+ multi-line return never reads a sibling row of its own voucher."""
+ rate = flt(self.wh_data.valuation_rate)
+ if rate:
+ return rate
+
+ previous_sle = get_previous_sle_of_current_voucher(
+ frappe._dict(
+ item_code=sle.item_code,
+ warehouse=sle.warehouse,
+ posting_date=sle.posting_date,
+ posting_time=sle.posting_time,
+ voucher_no=sle.voucher_no,
+ ),
+ exclude_current_voucher=True,
+ )
+
+ rate = previous_sle.get("valuation_rate")
+ if rate is None:
+ rate = get_valuation_rate(
+ sle.item_code,
+ sle.warehouse,
+ sle.voucher_type,
+ sle.voucher_no,
+ self.allow_zero_rate,
+ currency=erpnext.get_company_currency(sle.company),
+ company=sle.company,
+ )
+
+ return flt(rate)
+
def update_outgoing_rate_on_transaction(self, sle):
"""
Update outgoing rate in Stock Entry, Delivery Note, Sales Invoice and Sales Return
diff --git a/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.json b/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.json
index b55f02f9f52..e51a4ea6bf3 100644
--- a/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.json
+++ b/erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.json
@@ -107,6 +107,7 @@
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -128,7 +129,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2024-03-27 13:10:45.904619",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Subcontracting",
"name": "Subcontracting BOM",
diff --git a/erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json b/erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json
index 11da413fc14..9b20def35c2 100644
--- a/erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_inward_order_item/subcontracting_inward_order_item.json
@@ -87,6 +87,7 @@
"fieldtype": "Float",
"hidden": 1,
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -186,7 +187,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2025-10-18 18:04:04.204651",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Subcontracting",
"name": "Subcontracting Inward Order Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json b/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
index 44ec2185ce6..19df4007581 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
@@ -174,6 +174,7 @@
"fieldtype": "Float",
"hidden": 1,
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -425,7 +426,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-02-27 23:03:36.436504",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Subcontracting",
"name": "Subcontracting Order Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json b/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json
index acd6aae6220..8a1c41ed499 100644
--- a/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json
@@ -63,6 +63,7 @@
"fieldtype": "Float",
"hidden": 1,
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -176,7 +177,7 @@
"hide_toolbar": 1,
"istable": 1,
"links": [],
- "modified": "2025-10-30 16:00:43.379828",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Subcontracting",
"name": "Subcontracting Order Supplied Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
index 4a0f1176c69..6ba81c05c15 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
@@ -205,6 +205,7 @@
"fieldtype": "Float",
"hidden": 1,
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -657,7 +658,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Subcontracting",
"name": "Subcontracting Receipt Item",
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
index 8d26da40863..ec10fd07146 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
@@ -134,6 +134,7 @@
"fieldtype": "Float",
"hidden": 1,
"label": "Conversion Factor",
+ "precision": "9",
"read_only": 1
},
{
@@ -275,7 +276,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2026-07-18 10:00:00.000000",
+ "modified": "2026-08-07 17:31:31.732720",
"modified_by": "Administrator",
"module": "Subcontracting",
"name": "Subcontracting Receipt Supplied Item",
diff --git a/erpnext/subcontracting/doctype_settings_map/subcontracting_inward_order_(standard)/subcontracting_inward_order_(standard).json b/erpnext/subcontracting/doctype_settings_map/subcontracting_inward_order.json
similarity index 90%
rename from erpnext/subcontracting/doctype_settings_map/subcontracting_inward_order_(standard)/subcontracting_inward_order_(standard).json
rename to erpnext/subcontracting/doctype_settings_map/subcontracting_inward_order.json
index 10308ef06a9..3ee97242394 100644
--- a/erpnext/subcontracting/doctype_settings_map/subcontracting_inward_order_(standard)/subcontracting_inward_order_(standard).json
+++ b/erpnext/subcontracting/doctype_settings_map/subcontracting_inward_order.json
@@ -19,6 +19,6 @@
"modified": "2026-07-03 13:03:18.132340",
"modified_by": "Administrator",
"module": "Subcontracting",
- "name": "Subcontracting Inward Order (Standard)",
+ "name": "Subcontracting Inward Order - Subcontracting",
"owner": "Administrator"
}
diff --git a/erpnext/subcontracting/doctype_settings_map/subcontracting_order_(standard)/subcontracting_order_(standard).json b/erpnext/subcontracting/doctype_settings_map/subcontracting_order.json
similarity index 93%
rename from erpnext/subcontracting/doctype_settings_map/subcontracting_order_(standard)/subcontracting_order_(standard).json
rename to erpnext/subcontracting/doctype_settings_map/subcontracting_order.json
index bed24ffb9bd..aea0a8c2072 100644
--- a/erpnext/subcontracting/doctype_settings_map/subcontracting_order_(standard)/subcontracting_order_(standard).json
+++ b/erpnext/subcontracting/doctype_settings_map/subcontracting_order.json
@@ -27,6 +27,6 @@
"modified": "2026-07-21 17:10:04.037735",
"modified_by": "Administrator",
"module": "Subcontracting",
- "name": "Subcontracting Order (Standard)",
+ "name": "Subcontracting Order - Subcontracting",
"owner": "Administrator"
}
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index e49660f33c0..07e9c40ebd7 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -618,13 +618,13 @@ def validate_uom_is_integer(doc, uom_field, qty_fields, child_dt=None):
for f in qty_fields:
qty = d.get(f)
if qty:
- precision = d.precision(f)
- if abs(cint(qty) - flt(qty, precision)) > 0.0000001:
+ qty = flt(qty, d.precision(f))
+ if qty != cint(qty):
frappe.throw(
_(
"Row {1}: Quantity ({0}) cannot be a fraction. To allow this, disable '{2}' in UOM {3}."
).format(
- flt(qty, precision),
+ qty,
d.idx,
frappe.bold(_("Must be Whole Number")),
frappe.bold(d.get(uom_field)),