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:
" @@ -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)),