Merge pull request #36434 from ruthra-kumar/replace_get_cached_with_get_single_value
fix: incorrect usage `get_cached_value` on single doctypes
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js
index 2fa1d53..2f53f7b 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.js
@@ -15,6 +15,17 @@
};
});
+ frm.set_query("offsetting_account", "dimension_defaults", function(doc, cdt, cdn) {
+ let d = locals[cdt][cdn];
+ return {
+ filters: {
+ company: d.company,
+ root_type: ["in", ["Asset", "Liability"]],
+ is_group: 0
+ }
+ }
+ });
+
if (!frm.is_new()) {
frm.add_custom_button(__('Show {0}', [frm.doc.document_type]), function () {
frappe.set_route("List", frm.doc.document_type);
diff --git a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
index 15c84d4..cfe5e6e 100644
--- a/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
+++ b/erpnext/accounts/doctype/accounting_dimension/accounting_dimension.py
@@ -39,6 +39,8 @@
if not self.is_new():
self.validate_document_type_change()
+ self.validate_dimension_defaults()
+
def validate_document_type_change(self):
doctype_before_save = frappe.db.get_value("Accounting Dimension", self.name, "document_type")
if doctype_before_save != self.document_type:
@@ -46,6 +48,14 @@
message += _("Please create a new Accounting Dimension if required.")
frappe.throw(message)
+ def validate_dimension_defaults(self):
+ companies = []
+ for default in self.get("dimension_defaults"):
+ if default.company not in companies:
+ companies.append(default.company)
+ else:
+ frappe.throw(_("Company {0} is added more than once").format(frappe.bold(default.company)))
+
def after_insert(self):
if frappe.flags.in_test:
make_dimension_in_accounting_doctypes(doc=self)
diff --git a/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.json b/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.json
index e9e1f43..7b6120a 100644
--- a/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.json
+++ b/erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.json
@@ -8,7 +8,10 @@
"reference_document",
"default_dimension",
"mandatory_for_bs",
- "mandatory_for_pl"
+ "mandatory_for_pl",
+ "column_break_lqns",
+ "automatically_post_balancing_accounting_entry",
+ "offsetting_account"
],
"fields": [
{
@@ -50,6 +53,23 @@
"fieldtype": "Check",
"in_list_view": 1,
"label": "Mandatory For Profit and Loss Account"
+ },
+ {
+ "default": "0",
+ "fieldname": "automatically_post_balancing_accounting_entry",
+ "fieldtype": "Check",
+ "label": "Automatically post balancing accounting entry"
+ },
+ {
+ "fieldname": "offsetting_account",
+ "fieldtype": "Link",
+ "label": "Offsetting Account",
+ "mandatory_depends_on": "eval: doc.automatically_post_balancing_accounting_entry",
+ "options": "Account"
+ },
+ {
+ "fieldname": "column_break_lqns",
+ "fieldtype": "Column Break"
}
],
"istable": 1,
diff --git a/erpnext/accounts/doctype/loyalty_program/loyalty_program.py b/erpnext/accounts/doctype/loyalty_program/loyalty_program.py
index 48a25ad..a134f74 100644
--- a/erpnext/accounts/doctype/loyalty_program/loyalty_program.py
+++ b/erpnext/accounts/doctype/loyalty_program/loyalty_program.py
@@ -141,7 +141,7 @@
)
if points_to_redeem > loyalty_program_details.loyalty_points:
- frappe.throw(_("You don't have enought Loyalty Points to redeem"))
+ frappe.throw(_("You don't have enough Loyalty Points to redeem"))
loyalty_amount = flt(points_to_redeem * loyalty_program_details.conversion_factor)
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index ed18fea..44474d9 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -903,12 +903,12 @@
if(frm.doc.payment_type == "Receive"
&& frm.doc.base_total_allocated_amount < frm.doc.base_received_amount + total_deductions
&& frm.doc.total_allocated_amount < frm.doc.paid_amount + (total_deductions / frm.doc.source_exchange_rate)) {
- unallocated_amount = (frm.doc.base_received_amount + total_deductions + frm.doc.base_total_taxes_and_charges
+ unallocated_amount = (frm.doc.base_received_amount + total_deductions + flt(frm.doc.base_total_taxes_and_charges)
- frm.doc.base_total_allocated_amount) / frm.doc.source_exchange_rate;
} else if (frm.doc.payment_type == "Pay"
&& frm.doc.base_total_allocated_amount < frm.doc.base_paid_amount - total_deductions
&& frm.doc.total_allocated_amount < frm.doc.received_amount + (total_deductions / frm.doc.target_exchange_rate)) {
- unallocated_amount = (frm.doc.base_paid_amount + frm.doc.base_total_taxes_and_charges - (total_deductions
+ unallocated_amount = (frm.doc.base_paid_amount + flt(frm.doc.base_total_taxes_and_charges) - (total_deductions
+ frm.doc.base_total_allocated_amount)) / frm.doc.target_exchange_rate;
}
}
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index 8c96480..486e01e 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -1736,6 +1736,61 @@
rate = flt(sle.stock_value_difference) / flt(sle.actual_qty)
self.assertAlmostEqual(returned_inv.items[0].rate, rate)
+ def test_offsetting_entries_for_accounting_dimensions(self):
+ from erpnext.accounts.doctype.account.test_account import create_account
+ from erpnext.accounts.report.trial_balance.test_trial_balance import (
+ clear_dimension_defaults,
+ create_accounting_dimension,
+ disable_dimension,
+ )
+
+ create_account(
+ account_name="Offsetting",
+ company="_Test Company",
+ parent_account="Temporary Accounts - _TC",
+ )
+
+ create_accounting_dimension(company="_Test Company", offsetting_account="Offsetting - _TC")
+
+ branch1 = frappe.new_doc("Branch")
+ branch1.branch = "Location 1"
+ branch1.insert(ignore_if_duplicate=True)
+ branch2 = frappe.new_doc("Branch")
+ branch2.branch = "Location 2"
+ branch2.insert(ignore_if_duplicate=True)
+
+ pi = make_purchase_invoice(
+ company="_Test Company",
+ customer="_Test Supplier",
+ do_not_save=True,
+ do_not_submit=True,
+ rate=1000,
+ price_list_rate=1000,
+ qty=1,
+ )
+ pi.branch = branch1.branch
+ pi.items[0].branch = branch2.branch
+ pi.save()
+ pi.submit()
+
+ expected_gle = [
+ ["_Test Account Cost for Goods Sold - _TC", 1000, 0.0, nowdate(), branch2.branch],
+ ["Creditors - _TC", 0.0, 1000, nowdate(), branch1.branch],
+ ["Offsetting - _TC", 1000, 0.0, nowdate(), branch1.branch],
+ ["Offsetting - _TC", 0.0, 1000, nowdate(), branch2.branch],
+ ]
+
+ check_gl_entries(
+ self,
+ pi.name,
+ expected_gle,
+ nowdate(),
+ voucher_type="Purchase Invoice",
+ additional_columns=["branch"],
+ )
+ clear_dimension_defaults("Branch")
+ disable_dimension()
+
def set_advance_flag(company, flag, default_account):
frappe.db.set_value(
@@ -1748,9 +1803,16 @@
)
-def check_gl_entries(doc, voucher_no, expected_gle, posting_date, voucher_type="Purchase Invoice"):
+def check_gl_entries(
+ doc,
+ voucher_no,
+ expected_gle,
+ posting_date,
+ voucher_type="Purchase Invoice",
+ additional_columns=None,
+):
gl = frappe.qb.DocType("GL Entry")
- q = (
+ query = (
frappe.qb.from_(gl)
.select(gl.account, gl.debit, gl.credit, gl.posting_date)
.where(
@@ -1761,7 +1823,12 @@
)
.orderby(gl.posting_date, gl.account, gl.creation)
)
- gl_entries = q.run(as_dict=True)
+
+ if additional_columns:
+ for col in additional_columns:
+ query = query.select(gl[col])
+
+ gl_entries = query.run(as_dict=True)
for i, gle in enumerate(gl_entries):
doc.assertEqual(expected_gle[i][0], gle.account)
@@ -1769,6 +1836,12 @@
doc.assertEqual(expected_gle[i][2], gle.credit)
doc.assertEqual(getdate(expected_gle[i][3]), gle.posting_date)
+ if additional_columns:
+ j = 4
+ for col in additional_columns:
+ doc.assertEqual(expected_gle[i][j], gle[col])
+ j += 1
+
def create_tax_witholding_category(category_name, company, account):
from erpnext.accounts.utils import get_fiscal_year
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 974a876..f5ee228 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1833,7 +1833,7 @@
doc = frappe.get_doc(ref_doc, inter_company_reference)
ref_party = doc.supplier if doctype in ["Sales Invoice", "Sales Order"] else doc.customer
if not frappe.db.get_value(partytype, {"represents_company": doc.company}, "name") == party:
- frappe.throw(_("Invalid {0} for Inter Company Transaction.").format(partytype))
+ frappe.throw(_("Invalid {0} for Inter Company Transaction.").format(_(partytype)))
if not frappe.get_cached_value(ref_partytype, ref_party, "represents_company") == company:
frappe.throw(_("Invalid Company for Inter Company Transaction."))
@@ -1847,7 +1847,7 @@
if not company in companies:
frappe.throw(
_("{0} not allowed to transact with {1}. Please change the Company.").format(
- partytype, company
+ _(partytype), company
)
)
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index b942a0c..3803836 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -28,6 +28,7 @@
):
if gl_map:
if not cancel:
+ make_acc_dimensions_offsetting_entry(gl_map)
validate_accounting_period(gl_map)
validate_disabled_accounts(gl_map)
gl_map = process_gl_map(gl_map, merge_entries)
@@ -51,6 +52,63 @@
make_reverse_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
+def make_acc_dimensions_offsetting_entry(gl_map):
+ accounting_dimensions_to_offset = get_accounting_dimensions_for_offsetting_entry(
+ gl_map, gl_map[0].company
+ )
+ no_of_dimensions = len(accounting_dimensions_to_offset)
+ if no_of_dimensions == 0:
+ return
+
+ offsetting_entries = []
+
+ for gle in gl_map:
+ for dimension in accounting_dimensions_to_offset:
+ offsetting_entry = gle.copy()
+ debit = flt(gle.credit) / no_of_dimensions if gle.credit != 0 else 0
+ credit = flt(gle.debit) / no_of_dimensions if gle.debit != 0 else 0
+ offsetting_entry.update(
+ {
+ "account": dimension.offsetting_account,
+ "debit": debit,
+ "credit": credit,
+ "debit_in_account_currency": debit,
+ "credit_in_account_currency": credit,
+ "remarks": _("Offsetting for Accounting Dimension") + " - {0}".format(dimension.name),
+ "against_voucher": None,
+ }
+ )
+ offsetting_entry["against_voucher_type"] = None
+ offsetting_entries.append(offsetting_entry)
+
+ gl_map += offsetting_entries
+
+
+def get_accounting_dimensions_for_offsetting_entry(gl_map, company):
+ acc_dimension = frappe.qb.DocType("Accounting Dimension")
+ dimension_detail = frappe.qb.DocType("Accounting Dimension Detail")
+
+ acc_dimensions = (
+ frappe.qb.from_(acc_dimension)
+ .inner_join(dimension_detail)
+ .on(acc_dimension.name == dimension_detail.parent)
+ .select(acc_dimension.fieldname, acc_dimension.name, dimension_detail.offsetting_account)
+ .where(
+ (acc_dimension.disabled == 0)
+ & (dimension_detail.company == company)
+ & (dimension_detail.automatically_post_balancing_accounting_entry == 1)
+ )
+ ).run(as_dict=True)
+
+ accounting_dimensions_to_offset = []
+ for acc_dimension in acc_dimensions:
+ values = set([entry.get(acc_dimension.fieldname) for entry in gl_map])
+ if len(values) > 1:
+ accounting_dimensions_to_offset.append(acc_dimension)
+
+ return accounting_dimensions_to_offset
+
+
def validate_disabled_accounts(gl_map):
accounts = [d.account for d in gl_map if d.account]
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index 0b583a1..7c2ebe1 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -6,6 +6,7 @@
import frappe
from frappe import _
+from frappe.query_builder import Criterion
from frappe.utils import flt, getdate
import erpnext
@@ -359,6 +360,7 @@
accounts_by_name,
accounts,
ignore_closing_entries=False,
+ root_type=root_type,
)
calculate_values(accounts_by_name, gl_entries_by_account, companies, filters, fiscal_year)
@@ -603,6 +605,7 @@
accounts_by_name,
accounts,
ignore_closing_entries=False,
+ root_type=None,
):
"""Returns a dict like { "account": [gl entries], ... }"""
@@ -610,7 +613,6 @@
"Company", filters.get("company"), ["lft", "rgt"]
)
- additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters)
companies = frappe.db.sql(
""" select name, default_currency from `tabCompany`
where lft >= %(company_lft)s and rgt <= %(company_rgt)s""",
@@ -626,27 +628,42 @@
)
for d in companies:
- gl_entries = frappe.db.sql(
- """select gl.posting_date, gl.account, gl.debit, gl.credit, gl.is_opening, gl.company,
- gl.fiscal_year, gl.debit_in_account_currency, gl.credit_in_account_currency, gl.account_currency,
- acc.account_name, acc.account_number
- from `tabGL Entry` gl, `tabAccount` acc where acc.name = gl.account and gl.company = %(company)s and gl.is_cancelled = 0
- {additional_conditions} and gl.posting_date <= %(to_date)s and acc.lft >= %(lft)s and acc.rgt <= %(rgt)s
- order by gl.account, gl.posting_date""".format(
- additional_conditions=additional_conditions
- ),
- {
- "from_date": from_date,
- "to_date": to_date,
- "lft": root_lft,
- "rgt": root_rgt,
- "company": d.name,
- "finance_book": filters.get("finance_book"),
- "company_fb": frappe.get_cached_value("Company", d.name, "default_finance_book"),
- },
- as_dict=True,
+ gle = frappe.qb.DocType("GL Entry")
+ account = frappe.qb.DocType("Account")
+ query = (
+ frappe.qb.from_(gle)
+ .inner_join(account)
+ .on(account.name == gle.account)
+ .select(
+ gle.posting_date,
+ gle.account,
+ gle.debit,
+ gle.credit,
+ gle.is_opening,
+ gle.company,
+ gle.fiscal_year,
+ gle.debit_in_account_currency,
+ gle.credit_in_account_currency,
+ gle.account_currency,
+ account.account_name,
+ account.account_number,
+ )
+ .where(
+ (gle.company == d.name)
+ & (gle.is_cancelled == 0)
+ & (gle.posting_date <= to_date)
+ & (account.lft >= root_lft)
+ & (account.rgt <= root_rgt)
+ & (account.root_type <= root_type)
+ )
+ .orderby(gle.account, gle.posting_date)
)
+ additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters, d)
+ if additional_conditions:
+ query = query.where(Criterion.all(additional_conditions))
+ gl_entries = query.run(as_dict=True)
+
if filters and filters.get("presentation_currency") != d.default_currency:
currency_info["company"] = d.name
currency_info["company_currency"] = d.default_currency
@@ -716,23 +733,25 @@
accounts.insert(idx + 1, args)
-def get_additional_conditions(from_date, ignore_closing_entries, filters):
+def get_additional_conditions(from_date, ignore_closing_entries, filters, d):
+ gle = frappe.qb.DocType("GL Entry")
additional_conditions = []
if ignore_closing_entries:
- additional_conditions.append("gl.voucher_type != 'Period Closing Voucher'")
+ additional_conditions.append((gle.voucher_type != "Period Closing Voucher"))
if from_date:
- additional_conditions.append("gl.posting_date >= %(from_date)s")
+ additional_conditions.append(gle.posting_date >= from_date)
+
+ finance_book = filters.get("finance_book")
+ company_fb = frappe.get_cached_value("Company", d.name, "default_finance_book")
if filters.get("include_default_book_entries"):
- additional_conditions.append(
- "(finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)"
- )
+ additional_conditions.append((gle.finance_book.isin([finance_book, company_fb, "", None])))
else:
- additional_conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)")
+ additional_conditions.append((gle.finance_book.isin([finance_book, "", None])))
- return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
+ return additional_conditions
def add_total_row(out, root_type, balance_must_be, companies, company_currency):
diff --git a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py
index c84b843..28d0c20 100644
--- a/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py
+++ b/erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py
@@ -2,6 +2,7 @@
import frappe
from frappe import qb
+from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import nowdate
from erpnext.accounts.doctype.account.test_account import create_account
@@ -10,16 +11,15 @@
from erpnext.accounts.report.deferred_revenue_and_expense.deferred_revenue_and_expense import (
Deferred_Revenue_and_Expense_Report,
)
+from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
from erpnext.accounts.utils import get_fiscal_year
from erpnext.buying.doctype.supplier.test_supplier import create_supplier
from erpnext.stock.doctype.item.test_item import create_item
-class TestDeferredRevenueAndExpense(unittest.TestCase):
+class TestDeferredRevenueAndExpense(FrappeTestCase, AccountsTestMixin):
@classmethod
def setUpClass(self):
- clear_accounts_and_items()
- create_company()
self.maxDiff = None
def clear_old_entries(self):
@@ -51,55 +51,58 @@
if deferred_invoices:
qb.from_(pinv).delete().where(pinv.name.isin(deferred_invoices)).run()
- def test_deferred_revenue(self):
- self.clear_old_entries()
+ def setup_deferred_accounts_and_items(self):
+ # created deferred expense accounts, if not found
+ self.deferred_revenue_account = create_account(
+ account_name="Deferred Revenue",
+ parent_account="Current Liabilities - " + self.company_abbr,
+ company=self.company,
+ )
# created deferred expense accounts, if not found
- deferred_revenue_account = create_account(
- account_name="Deferred Revenue",
- parent_account="Current Liabilities - _CD",
- company="_Test Company DR",
+ self.deferred_expense_account = create_account(
+ account_name="Deferred Expense",
+ parent_account="Current Assets - " + self.company_abbr,
+ company=self.company,
)
- acc_settings = frappe.get_doc("Accounts Settings", "Accounts Settings")
- acc_settings.book_deferred_entries_based_on = "Months"
- acc_settings.save()
+ def setUp(self):
+ self.create_company()
+ self.create_customer("_Test Customer")
+ self.create_supplier("_Test Furniture Supplier")
+ self.setup_deferred_accounts_and_items()
+ self.clear_old_entries()
- customer = frappe.new_doc("Customer")
- customer.customer_name = "_Test Customer DR"
- customer.type = "Individual"
- customer.insert()
+ def tearDown(self):
+ frappe.db.rollback()
- item = create_item(
- "_Test Internet Subscription",
- is_stock_item=0,
- warehouse="All Warehouses - _CD",
- company="_Test Company DR",
- )
+ @change_settings("Accounts Settings", {"book_deferred_entries_based_on": "Months"})
+ def test_deferred_revenue(self):
+ self.create_item("_Test Internet Subscription", 0, self.warehouse, self.company)
+ item = frappe.get_doc("Item", self.item)
item.enable_deferred_revenue = 1
- item.deferred_revenue_account = deferred_revenue_account
+ item.deferred_revenue_account = self.deferred_revenue_account
item.no_of_months = 3
item.save()
si = create_sales_invoice(
- item=item.name,
- company="_Test Company DR",
- customer="_Test Customer DR",
- debit_to="Debtors - _CD",
+ item=self.item,
+ company=self.company,
+ customer=self.customer,
+ debit_to=self.debit_to,
posting_date="2021-05-01",
- parent_cost_center="Main - _CD",
- cost_center="Main - _CD",
+ parent_cost_center=self.cost_center,
+ cost_center=self.cost_center,
do_not_save=True,
rate=300,
price_list_rate=300,
)
- si.items[0].income_account = "Sales - _CD"
+ si.items[0].income_account = self.income_account
si.items[0].enable_deferred_revenue = 1
si.items[0].service_start_date = "2021-05-01"
si.items[0].service_end_date = "2021-08-01"
- si.items[0].deferred_revenue_account = deferred_revenue_account
- si.items[0].income_account = "Sales - _CD"
+ si.items[0].deferred_revenue_account = self.deferred_revenue_account
si.save()
si.submit()
@@ -110,7 +113,7 @@
start_date="2021-05-01",
end_date="2021-08-01",
type="Income",
- company="_Test Company DR",
+ company=self.company,
)
)
pda.insert()
@@ -120,7 +123,7 @@
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2021-05-01"))
self.filters = frappe._dict(
{
- "company": frappe.defaults.get_user_default("Company"),
+ "company": self.company,
"filter_based_on": "Date Range",
"period_start_date": "2021-05-01",
"period_end_date": "2021-08-01",
@@ -142,57 +145,36 @@
]
self.assertEqual(report.period_total, expected)
+ @change_settings("Accounts Settings", {"book_deferred_entries_based_on": "Months"})
def test_deferred_expense(self):
- self.clear_old_entries()
-
- # created deferred expense accounts, if not found
- deferred_expense_account = create_account(
- account_name="Deferred Expense",
- parent_account="Current Assets - _CD",
- company="_Test Company DR",
- )
-
- acc_settings = frappe.get_doc("Accounts Settings", "Accounts Settings")
- acc_settings.book_deferred_entries_based_on = "Months"
- acc_settings.save()
-
- supplier = create_supplier(
- supplier_name="_Test Furniture Supplier", supplier_group="Local", supplier_type="Company"
- )
- supplier.save()
-
- item = create_item(
- "_Test Office Desk",
- is_stock_item=0,
- warehouse="All Warehouses - _CD",
- company="_Test Company DR",
- )
+ self.create_item("_Test Office Desk", 0, self.warehouse, self.company)
+ item = frappe.get_doc("Item", self.item)
item.enable_deferred_expense = 1
- item.deferred_expense_account = deferred_expense_account
+ item.deferred_expense_account = self.deferred_expense_account
item.no_of_months_exp = 3
item.save()
pi = make_purchase_invoice(
- item=item.name,
- company="_Test Company DR",
- supplier="_Test Furniture Supplier",
+ item=self.item,
+ company=self.company,
+ supplier=self.supplier,
is_return=False,
update_stock=False,
posting_date=frappe.utils.datetime.date(2021, 5, 1),
- parent_cost_center="Main - _CD",
- cost_center="Main - _CD",
+ parent_cost_center=self.cost_center,
+ cost_center=self.cost_center,
do_not_save=True,
rate=300,
price_list_rate=300,
- warehouse="All Warehouses - _CD",
+ warehouse=self.warehouse,
qty=1,
)
pi.set_posting_time = True
pi.items[0].enable_deferred_expense = 1
pi.items[0].service_start_date = "2021-05-01"
pi.items[0].service_end_date = "2021-08-01"
- pi.items[0].deferred_expense_account = deferred_expense_account
- pi.items[0].expense_account = "Office Maintenance Expenses - _CD"
+ pi.items[0].deferred_expense_account = self.deferred_expense_account
+ pi.items[0].expense_account = self.expense_account
pi.save()
pi.submit()
@@ -203,7 +185,7 @@
start_date="2021-05-01",
end_date="2021-08-01",
type="Expense",
- company="_Test Company DR",
+ company=self.company,
)
)
pda.insert()
@@ -213,7 +195,7 @@
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2021-05-01"))
self.filters = frappe._dict(
{
- "company": frappe.defaults.get_user_default("Company"),
+ "company": self.company,
"filter_based_on": "Date Range",
"period_start_date": "2021-05-01",
"period_end_date": "2021-08-01",
@@ -235,52 +217,31 @@
]
self.assertEqual(report.period_total, expected)
+ @change_settings("Accounts Settings", {"book_deferred_entries_based_on": "Months"})
def test_zero_months(self):
- self.clear_old_entries()
- # created deferred expense accounts, if not found
- deferred_revenue_account = create_account(
- account_name="Deferred Revenue",
- parent_account="Current Liabilities - _CD",
- company="_Test Company DR",
- )
-
- acc_settings = frappe.get_doc("Accounts Settings", "Accounts Settings")
- acc_settings.book_deferred_entries_based_on = "Months"
- acc_settings.save()
-
- customer = frappe.new_doc("Customer")
- customer.customer_name = "_Test Customer DR"
- customer.type = "Individual"
- customer.insert()
-
- item = create_item(
- "_Test Internet Subscription",
- is_stock_item=0,
- warehouse="All Warehouses - _CD",
- company="_Test Company DR",
- )
+ self.create_item("_Test Internet Subscription", 0, self.warehouse, self.company)
+ item = frappe.get_doc("Item", self.item)
item.enable_deferred_revenue = 1
- item.deferred_revenue_account = deferred_revenue_account
+ item.deferred_revenue_account = self.deferred_revenue_account
item.no_of_months = 0
item.save()
si = create_sales_invoice(
item=item.name,
- company="_Test Company DR",
- customer="_Test Customer DR",
- debit_to="Debtors - _CD",
+ company=self.company,
+ customer=self.customer,
+ debit_to=self.debit_to,
posting_date="2021-05-01",
- parent_cost_center="Main - _CD",
- cost_center="Main - _CD",
+ parent_cost_center=self.cost_center,
+ cost_center=self.cost_center,
do_not_save=True,
rate=300,
price_list_rate=300,
)
si.items[0].enable_deferred_revenue = 1
- si.items[0].income_account = "Sales - _CD"
- si.items[0].deferred_revenue_account = deferred_revenue_account
- si.items[0].income_account = "Sales - _CD"
+ si.items[0].income_account = self.income_account
+ si.items[0].deferred_revenue_account = self.deferred_revenue_account
si.save()
si.submit()
@@ -291,7 +252,7 @@
start_date="2021-05-01",
end_date="2021-08-01",
type="Income",
- company="_Test Company DR",
+ company=self.company,
)
)
pda.insert()
@@ -301,7 +262,7 @@
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2021-05-01"))
self.filters = frappe._dict(
{
- "company": frappe.defaults.get_user_default("Company"),
+ "company": self.company,
"filter_based_on": "Date Range",
"period_start_date": "2021-05-01",
"period_end_date": "2021-08-01",
@@ -322,30 +283,3 @@
{"key": "aug_2021", "total": 0, "actual": 0},
]
self.assertEqual(report.period_total, expected)
-
-
-def create_company():
- company = frappe.db.exists("Company", "_Test Company DR")
- if not company:
- company = frappe.new_doc("Company")
- company.company_name = "_Test Company DR"
- company.default_currency = "INR"
- company.chart_of_accounts = "Standard"
- company.insert()
-
-
-def clear_accounts_and_items():
- item = qb.DocType("Item")
- account = qb.DocType("Account")
- customer = qb.DocType("Customer")
- supplier = qb.DocType("Supplier")
-
- qb.from_(account).delete().where(
- (account.account_name == "Deferred Revenue")
- | (account.account_name == "Deferred Expense") & (account.company == "_Test Company DR")
- ).run()
- qb.from_(item).delete().where(
- (item.item_code == "_Test Internet Subscription") | (item.item_code == "_Test Office Rent")
- ).run()
- qb.from_(customer).delete().where(customer.customer_name == "_Test Customer DR").run()
- qb.from_(supplier).delete().where(supplier.supplier_name == "_Test Furniture Supplier").run()
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 26bf315..a76dea6 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -188,6 +188,7 @@
filters,
gl_entries_by_account,
ignore_closing_entries=ignore_closing_entries,
+ root_type=root_type,
)
calculate_values(
@@ -417,13 +418,28 @@
gl_entries_by_account,
ignore_closing_entries=False,
ignore_opening_entries=False,
+ root_type=None,
):
"""Returns a dict like { "account": [gl entries], ... }"""
gl_entries = []
+ account_filters = {
+ "company": company,
+ "is_group": 0,
+ "lft": (">=", root_lft),
+ "rgt": ("<=", root_rgt),
+ }
+
+ if root_type:
+ account_filters.update(
+ {
+ "root_type": root_type,
+ }
+ )
+
accounts_list = frappe.db.get_all(
"Account",
- filters={"company": company, "is_group": 0, "lft": (">=", root_lft), "rgt": ("<=", root_rgt)},
+ filters=account_filters,
pluck="name",
)
diff --git a/erpnext/accounts/report/trial_balance/test_trial_balance.py b/erpnext/accounts/report/trial_balance/test_trial_balance.py
new file mode 100644
index 0000000..4682ac4
--- /dev/null
+++ b/erpnext/accounts/report/trial_balance/test_trial_balance.py
@@ -0,0 +1,118 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
+# MIT License. See license.txt
+
+import frappe
+from frappe.tests.utils import FrappeTestCase
+from frappe.utils import today
+
+from erpnext.accounts.report.trial_balance.trial_balance import execute
+
+
+class TestTrialBalance(FrappeTestCase):
+ def setUp(self):
+ from erpnext.accounts.doctype.account.test_account import create_account
+ from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
+ from erpnext.accounts.utils import get_fiscal_year
+
+ self.company = create_company()
+ create_cost_center(
+ cost_center_name="Test Cost Center",
+ company="Trial Balance Company",
+ parent_cost_center="Trial Balance Company - TBC",
+ )
+ create_account(
+ account_name="Offsetting",
+ company="Trial Balance Company",
+ parent_account="Temporary Accounts - TBC",
+ )
+ self.fiscal_year = get_fiscal_year(today(), company="Trial Balance Company")[0]
+ create_accounting_dimension()
+
+ def test_offsetting_entries_for_accounting_dimensions(self):
+ """
+ Checks if Trial Balance Report is balanced when filtered using a particular Accounting Dimension
+ """
+ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
+
+ frappe.db.sql("delete from `tabSales Invoice` where company='Trial Balance Company'")
+ frappe.db.sql("delete from `tabGL Entry` where company='Trial Balance Company'")
+
+ branch1 = frappe.new_doc("Branch")
+ branch1.branch = "Location 1"
+ branch1.insert(ignore_if_duplicate=True)
+ branch2 = frappe.new_doc("Branch")
+ branch2.branch = "Location 2"
+ branch2.insert(ignore_if_duplicate=True)
+
+ si = create_sales_invoice(
+ company=self.company,
+ debit_to="Debtors - TBC",
+ cost_center="Test Cost Center - TBC",
+ income_account="Sales - TBC",
+ do_not_submit=1,
+ )
+ si.branch = "Location 1"
+ si.items[0].branch = "Location 2"
+ si.save()
+ si.submit()
+
+ filters = frappe._dict(
+ {"company": self.company, "fiscal_year": self.fiscal_year, "branch": ["Location 1"]}
+ )
+ total_row = execute(filters)[1][-1]
+ self.assertEqual(total_row["debit"], total_row["credit"])
+
+ def tearDown(self):
+ clear_dimension_defaults("Branch")
+ disable_dimension()
+
+
+def create_company(**args):
+ args = frappe._dict(args)
+ company = frappe.get_doc(
+ {
+ "doctype": "Company",
+ "company_name": args.company_name or "Trial Balance Company",
+ "country": args.country or "India",
+ "default_currency": args.currency or "INR",
+ }
+ )
+ company.insert(ignore_if_duplicate=True)
+ return company.name
+
+
+def create_accounting_dimension(**args):
+ args = frappe._dict(args)
+ document_type = args.document_type or "Branch"
+ if frappe.db.exists("Accounting Dimension", document_type):
+ accounting_dimension = frappe.get_doc("Accounting Dimension", document_type)
+ accounting_dimension.disabled = 0
+ else:
+ accounting_dimension = frappe.new_doc("Accounting Dimension")
+ accounting_dimension.document_type = document_type
+ accounting_dimension.insert()
+
+ accounting_dimension.set("dimension_defaults", [])
+ accounting_dimension.append(
+ "dimension_defaults",
+ {
+ "company": args.company or "Trial Balance Company",
+ "automatically_post_balancing_accounting_entry": 1,
+ "offsetting_account": args.offsetting_account or "Offsetting - TBC",
+ },
+ )
+ accounting_dimension.save()
+
+
+def disable_dimension(**args):
+ args = frappe._dict(args)
+ document_type = args.document_type or "Branch"
+ dimension = frappe.get_doc("Accounting Dimension", document_type)
+ dimension.disabled = 1
+ dimension.save()
+
+
+def clear_dimension_defaults(dimension_name):
+ accounting_dimension = frappe.get_doc("Accounting Dimension", dimension_name)
+ accounting_dimension.dimension_defaults = []
+ accounting_dimension.save()
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 5a9e950..376571f 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -259,7 +259,7 @@
lft, rgt = frappe.db.get_value("Cost Center", filters.cost_center, ["lft", "rgt"])
cost_center = frappe.qb.DocType("Cost Center")
opening_balance = opening_balance.where(
- closing_balance.cost_center.in_(
+ closing_balance.cost_center.isin(
frappe.qb.from_(cost_center)
.select("name")
.where((cost_center.lft >= lft) & (cost_center.rgt <= rgt))
diff --git a/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py
index 5ab3611..bd9e9fc 100644
--- a/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py
+++ b/erpnext/accounts/report/voucher_wise_balance/voucher_wise_balance.py
@@ -46,6 +46,7 @@
.select(
gle.voucher_type, gle.voucher_no, Sum(gle.debit).as_("debit"), Sum(gle.credit).as_("credit")
)
+ .where(gle.is_cancelled == 0)
.groupby(gle.voucher_no)
)
query = apply_filters(query, filters, gle)
diff --git a/erpnext/accounts/test/accounts_mixin.py b/erpnext/accounts/test/accounts_mixin.py
new file mode 100644
index 0000000..c82164e
--- /dev/null
+++ b/erpnext/accounts/test/accounts_mixin.py
@@ -0,0 +1,80 @@
+import frappe
+
+from erpnext.stock.doctype.item.test_item import create_item
+
+
+class AccountsTestMixin:
+ def create_customer(self, customer_name, currency=None):
+ if not frappe.db.exists("Customer", customer_name):
+ customer = frappe.new_doc("Customer")
+ customer.customer_name = customer_name
+ customer.type = "Individual"
+
+ if currency:
+ customer.default_currency = currency
+ customer.save()
+ self.customer = customer.name
+ else:
+ self.customer = customer_name
+
+ def create_supplier(self, supplier_name, currency=None):
+ if not frappe.db.exists("Supplier", supplier_name):
+ supplier = frappe.new_doc("Supplier")
+ supplier.supplier_name = supplier_name
+ supplier.supplier_type = "Individual"
+ supplier.supplier_group = "Local"
+
+ if currency:
+ supplier.default_currency = currency
+ supplier.save()
+ self.supplier = supplier.name
+ else:
+ self.supplier = supplier_name
+
+ def create_item(self, item_name, is_stock=0, warehouse=None, company=None):
+ item = create_item(item_name, is_stock_item=is_stock, warehouse=warehouse, company=company)
+ self.item = item.name
+
+ def create_company(self, company_name="_Test Company", abbr="_TC"):
+ self.company_abbr = abbr
+ if frappe.db.exists("Company", company_name):
+ company = frappe.get_doc("Company", company_name)
+ else:
+ company = frappe.get_doc(
+ {
+ "doctype": "Company",
+ "company_name": company_name,
+ "country": "India",
+ "default_currency": "INR",
+ "create_chart_of_accounts_based_on": "Standard Template",
+ "chart_of_accounts": "Standard",
+ }
+ )
+ company = company.save()
+
+ self.company = company.name
+ self.cost_center = company.cost_center
+ self.warehouse = "Stores - " + abbr
+ self.finished_warehouse = "Finished Goods - " + abbr
+ self.income_account = "Sales - " + abbr
+ self.expense_account = "Cost of Goods Sold - " + abbr
+ self.debit_to = "Debtors - " + abbr
+ self.debit_usd = "Debtors USD - " + abbr
+ self.cash = "Cash - " + abbr
+ self.creditors = "Creditors - " + abbr
+
+ # create bank account
+ bank_account = "HDFC - " + abbr
+ if frappe.db.exists("Account", bank_account):
+ self.bank = bank_account
+ else:
+ bank_acc = frappe.get_doc(
+ {
+ "doctype": "Account",
+ "account_name": "HDFC",
+ "parent_account": "Bank Accounts - " + abbr,
+ "company": self.company,
+ }
+ )
+ bank_acc.save()
+ self.bank = bank_acc.name
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index ab15704..a7f0304 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -65,7 +65,7 @@
get_materials_from_supplier: function(frm) {
let po_details = [];
- if (frm.doc.supplied_items && (frm.doc.per_received == 100 || frm.doc.status === 'Closed')) {
+ if (frm.doc.supplied_items && (flt(frm.doc.per_received, 2) == 100 || frm.doc.status === 'Closed')) {
frm.doc.supplied_items.forEach(d => {
if (d.total_supplied_qty && d.total_supplied_qty != d.consumed_qty) {
po_details.push(d.name)
@@ -184,7 +184,7 @@
}
if(!in_list(["Closed", "Delivered"], doc.status)) {
- if(this.frm.doc.status !== 'Closed' && flt(this.frm.doc.per_received) < 100 && flt(this.frm.doc.per_billed) < 100) {
+ if(this.frm.doc.status !== 'Closed' && flt(this.frm.doc.per_received, 2) < 100 && flt(this.frm.doc.per_billed, 2) < 100) {
// Don't add Update Items button if the PO is following the new subcontracting flow.
if (!(this.frm.doc.is_subcontracted && !this.frm.doc.is_old_subcontracting_flow)) {
this.frm.add_custom_button(__('Update Items'), () => {
@@ -198,7 +198,7 @@
}
}
if (this.frm.has_perm("submit")) {
- if(flt(doc.per_billed, 6) < 100 || flt(doc.per_received, 6) < 100) {
+ if(flt(doc.per_billed, 2) < 100 || flt(doc.per_received, 2) < 100) {
if (doc.status != "On Hold") {
this.frm.add_custom_button(__('Hold'), () => this.hold_purchase_order(), __("Status"));
} else{
@@ -221,7 +221,7 @@
}
if(doc.status != "Closed") {
if (doc.status != "On Hold") {
- if(flt(doc.per_received) < 100 && allow_receipt) {
+ if(flt(doc.per_received, 2) < 100 && allow_receipt) {
cur_frm.add_custom_button(__('Purchase Receipt'), this.make_purchase_receipt, __('Create'));
if (doc.is_subcontracted) {
if (doc.is_old_subcontracting_flow) {
@@ -234,11 +234,11 @@
}
}
}
- if(flt(doc.per_billed) < 100)
+ if(flt(doc.per_billed, 2) < 100)
cur_frm.add_custom_button(__('Purchase Invoice'),
this.make_purchase_invoice, __('Create'));
- if(flt(doc.per_billed) < 100 && doc.status != "Delivered") {
+ if(flt(doc.per_billed, 2) < 100 && doc.status != "Delivered") {
this.frm.add_custom_button(
__('Payment'),
() => this.make_payment_entry(),
@@ -246,7 +246,7 @@
);
}
- if(flt(doc.per_billed) < 100) {
+ if(flt(doc.per_billed, 2) < 100) {
this.frm.add_custom_button(__('Payment Request'),
function() { me.make_payment_request() }, __('Create'));
}
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index 642722a..01b6f5c 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -206,9 +206,11 @@
)
if doc.get("per_delivered"):
- doc.status_percent += flt(doc.per_delivered)
+ doc.status_percent += flt(doc.per_delivered, 2)
doc.status_display.append(
- _("Delivered") if doc.per_delivered == 100 else _("{0}% Delivered").format(doc.per_delivered)
+ _("Delivered")
+ if flt(doc.per_delivered, 2) == 100
+ else _("{0}% Delivered").format(doc.per_delivered)
)
if hasattr(doc, "set_indicator"):
diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
index 17b5aae..e986746 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
@@ -93,6 +93,7 @@
else:
frappe.enqueue(
method="erpnext.manufacturing.doctype.bom_update_log.bom_update_log.process_boms_cost_level_wise",
+ queue="long",
update_doc=self,
now=frappe.flags.in_test,
enqueue_after_commit=True,
diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
index b90cfd9..a2919b7 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
@@ -157,12 +157,19 @@
def get_leaf_boms() -> List[str]:
"Get BOMs that have no dependencies."
- return frappe.db.sql_list(
- """select name from `tabBOM` bom
- where docstatus=1 and is_active=1
- and not exists(select bom_no from `tabBOM Item`
- where parent=bom.name and bom_no !='')"""
- )
+ bom = frappe.qb.DocType("BOM")
+ bom_item = frappe.qb.DocType("BOM Item")
+
+ boms = (
+ frappe.qb.from_(bom)
+ .left_join(bom_item)
+ .on((bom.name == bom_item.parent) & (bom_item.bom_no != ""))
+ .select(bom.name)
+ .where((bom.docstatus == 1) & (bom.is_active == 1) & (bom_item.bom_no.isnull()))
+ .distinct()
+ ).run(pluck=True)
+
+ return boms
def _generate_dependence_map() -> defaultdict:
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index 80bdfd5..db6bc80 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -544,12 +544,12 @@
if self.for_quantity and flt(total_completed_qty, precision) != flt(
self.for_quantity, precision
):
- total_completed_qty = bold(_("Total Completed Qty"))
+ total_completed_qty_label = bold(_("Total Completed Qty"))
qty_to_manufacture = bold(_("Qty to Manufacture"))
frappe.throw(
_("The {0} ({1}) must be equal to {2} ({3})").format(
- total_completed_qty,
+ total_completed_qty_label,
bold(flt(total_completed_qty, precision)),
qty_to_manufacture,
bold(self.for_quantity),
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js
index 4898691..46c554c 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js
@@ -9,19 +9,25 @@
item.temporary_name = item.name;
});
},
+
setup(frm) {
+ frm.trigger("setup_queries");
+
frm.custom_make_buttons = {
'Work Order': 'Work Order / Subcontract PO',
'Material Request': 'Material Request',
};
+ },
- frm.fields_dict['po_items'].grid.get_field('warehouse').get_query = function(doc) {
+ setup_queries(frm) {
+ frm.set_query("sales_order", "sales_orders", () => {
return {
+ query: "erpnext.manufacturing.doctype.production_plan.production_plan.sales_order_query",
filters: {
- company: doc.company
+ company: frm.doc.company,
}
}
- }
+ });
frm.set_query('for_warehouse', function(doc) {
return {
@@ -42,32 +48,40 @@
};
});
- frm.fields_dict['po_items'].grid.get_field('item_code').get_query = function(doc) {
+ frm.set_query("item_code", "po_items", (doc, cdt, cdn) => {
return {
query: "erpnext.controllers.queries.item_query",
filters:{
'is_stock_item': 1,
}
}
- }
+ });
- frm.fields_dict['po_items'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) {
+ frm.set_query("bom_no", "po_items", (doc, cdt, cdn) => {
var d = locals[cdt][cdn];
if (d.item_code) {
return {
query: "erpnext.controllers.queries.bom",
- filters:{'item': cstr(d.item_code), 'docstatus': 1}
+ filters:{'item': d.item_code, 'docstatus': 1}
}
} else frappe.msgprint(__("Please enter Item first"));
- }
+ });
- frm.fields_dict['mr_items'].grid.get_field('warehouse').get_query = function(doc) {
+ frm.set_query("warehouse", "mr_items", (doc) => {
return {
filters: {
company: doc.company
}
}
- }
+ });
+
+ frm.set_query("warehouse", "po_items", (doc) => {
+ return {
+ filters: {
+ company: doc.company
+ }
+ }
+ });
},
refresh(frm) {
@@ -436,7 +450,7 @@
}
});
}
- }
+ },
});
frappe.ui.form.on("Material Request Plan Item", {
@@ -467,31 +481,36 @@
frappe.ui.form.on("Production Plan Sales Order", {
sales_order(frm, cdt, cdn) {
- const { sales_order } = locals[cdt][cdn];
+ let row = locals[cdt][cdn];
+ const sales_order = row.sales_order;
if (!sales_order) {
return;
}
- frappe.call({
- method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_so_details",
- args: { sales_order },
- callback(r) {
- const {transaction_date, customer, grand_total} = r.message;
- frappe.model.set_value(cdt, cdn, 'sales_order_date', transaction_date);
- frappe.model.set_value(cdt, cdn, 'customer', customer);
- frappe.model.set_value(cdt, cdn, 'grand_total', grand_total);
- }
- });
+
+ if (row.sales_order) {
+ frm.call({
+ method: "validate_sales_orders",
+ doc: frm.doc,
+ args: {
+ sales_order: row.sales_order,
+ },
+ callback(r) {
+ frappe.call({
+ method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_so_details",
+ args: { sales_order },
+ callback(r) {
+ const {transaction_date, customer, grand_total} = r.message;
+ frappe.model.set_value(cdt, cdn, 'sales_order_date', transaction_date);
+ frappe.model.set_value(cdt, cdn, 'customer', customer);
+ frappe.model.set_value(cdt, cdn, 'grand_total', grand_total);
+ }
+ });
+ }
+ });
+ }
}
});
-cur_frm.fields_dict['sales_orders'].grid.get_field("sales_order").get_query = function() {
- return{
- filters: [
- ['Sales Order','docstatus', '=' ,1]
- ]
- }
-};
-
frappe.tour['Production Plan'] = [
{
fieldname: "get_items_from",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json
index 232f1cb..0d0fd5e 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.json
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json
@@ -228,10 +228,10 @@
},
{
"default": "0",
- "description": "To know more about projected quantity, <a href=\"https://erpnext.com/docs/user/manual/en/stock/projected-quantity\" style=\"text-decoration: underline;\" target=\"_blank\">click here</a>.",
+ "description": "If enabled, the system won't create material requests for the available items.",
"fieldname": "ignore_existing_ordered_qty",
"fieldtype": "Check",
- "label": "Ignore Existing Projected Quantity"
+ "label": "Ignore Available Stock"
},
{
"fieldname": "column_break_25",
@@ -339,7 +339,7 @@
"depends_on": "eval:doc.get_items_from == 'Sales Order'",
"fieldname": "combine_items",
"fieldtype": "Check",
- "label": "Consolidate Items"
+ "label": "Consolidate Sales Order Items"
},
{
"fieldname": "section_break_25",
@@ -399,7 +399,7 @@
},
{
"default": "0",
- "description": "System consider the projected quantity to check available or will be available sub-assembly items ",
+ "description": "If this checkbox is enabled, then the system won\u2019t run the MRP for the available sub-assembly items.",
"fieldname": "skip_available_sub_assembly_item",
"fieldtype": "Check",
"label": "Skip Available Sub Assembly Items"
@@ -422,7 +422,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2023-05-22 23:36:31.770517",
+ "modified": "2023-07-28 13:37:43.926686",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index d8cc8f6..261aa76 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -39,6 +39,36 @@
self.set_status()
self._rename_temporary_references()
validate_uom_is_integer(self, "stock_uom", "planned_qty")
+ self.validate_sales_orders()
+
+ @frappe.whitelist()
+ def validate_sales_orders(self, sales_order=None):
+ sales_orders = []
+
+ if sales_order:
+ sales_orders.append(sales_order)
+ else:
+ sales_orders = [row.sales_order for row in self.sales_orders if row.sales_order]
+
+ data = sales_order_query(filters={"company": self.company, "sales_orders": sales_orders})
+
+ title = _("Production Plan Already Submitted")
+ if not data:
+ msg = _("No items are available in the sales order {0} for production").format(sales_orders[0])
+ if len(sales_orders) > 1:
+ sales_orders = ", ".join(sales_orders)
+ msg = _("No items are available in sales orders {0} for production").format(sales_orders)
+
+ frappe.throw(msg, title=title)
+
+ data = [d[0] for d in data]
+
+ for sales_order in sales_orders:
+ if sales_order not in data:
+ frappe.throw(
+ _("No items are available in the sales order {0} for production").format(sales_order),
+ title=title,
+ )
def set_pending_qty_in_row_without_reference(self):
"Set Pending Qty in independent rows (not from SO or MR)."
@@ -205,6 +235,7 @@
).as_("pending_qty"),
so_item.description,
so_item.name,
+ so_item.bom_no,
)
.distinct()
.where(
@@ -342,7 +373,7 @@
"item_code": data.item_code,
"description": data.description or item_details.description,
"stock_uom": item_details and item_details.stock_uom or "",
- "bom_no": item_details and item_details.bom_no or "",
+ "bom_no": data.bom_no or item_details and item_details.bom_no or "",
"planned_qty": data.pending_qty,
"pending_qty": data.pending_qty,
"planned_start_date": now_datetime(),
@@ -401,11 +432,50 @@
def on_submit(self):
self.update_bin_qty()
+ self.update_sales_order()
def on_cancel(self):
self.db_set("status", "Cancelled")
self.delete_draft_work_order()
self.update_bin_qty()
+ self.update_sales_order()
+
+ def update_sales_order(self):
+ sales_orders = [row.sales_order for row in self.po_items if row.sales_order]
+ if sales_orders:
+ so_wise_planned_qty = self.get_so_wise_planned_qty(sales_orders)
+
+ for row in self.po_items:
+ if not row.sales_order and not row.sales_order_item:
+ continue
+
+ key = (row.sales_order, row.sales_order_item)
+ frappe.db.set_value(
+ "Sales Order Item",
+ row.sales_order_item,
+ "production_plan_qty",
+ flt(so_wise_planned_qty.get(key)),
+ )
+
+ @staticmethod
+ def get_so_wise_planned_qty(sales_orders):
+ so_wise_planned_qty = frappe._dict()
+ data = frappe.get_all(
+ "Production Plan Item",
+ fields=["sales_order", "sales_order_item", "SUM(planned_qty) as qty"],
+ filters={
+ "sales_order": ("in", sales_orders),
+ "docstatus": 1,
+ "sales_order_item": ("is", "set"),
+ },
+ group_by="sales_order, sales_order_item",
+ )
+
+ for row in data:
+ key = (row.sales_order, row.sales_order_item)
+ so_wise_planned_qty[key] = row.qty
+
+ return so_wise_planned_qty
def update_bin_qty(self):
for d in self.mr_items:
@@ -719,6 +789,9 @@
sub_assembly_items_store = [] # temporary store to process all subassembly items
for row in self.po_items:
+ if self.skip_available_sub_assembly_item and not row.warehouse:
+ frappe.throw(_("Row #{0}: Please select the FG Warehouse in Assembly Items").format(row.idx))
+
if not row.item_code:
frappe.throw(_("Row #{0}: Please select Item Code in Assembly Items").format(row.idx))
@@ -1142,7 +1215,7 @@
& (so.docstatus == 1)
& (so.status.notin(["Stopped", "Closed"]))
& (so.company == self.company)
- & (so_item.qty > so_item.work_order_qty)
+ & (so_item.qty > so_item.production_plan_qty)
)
)
@@ -1566,7 +1639,6 @@
def get_raw_materials_of_sub_assembly_items(
item_details, company, bom_no, include_non_stock_items, sub_assembly_items, planned_qty=1
):
-
bei = frappe.qb.DocType("BOM Item")
bom = frappe.qb.DocType("BOM")
item = frappe.qb.DocType("Item")
@@ -1609,7 +1681,10 @@
for item in items:
key = (item.item_code, item.bom_no)
- if item.bom_no and key in sub_assembly_items:
+ if item.bom_no and key not in sub_assembly_items:
+ continue
+
+ if item.bom_no:
planned_qty = flt(sub_assembly_items[key])
get_raw_materials_of_sub_assembly_items(
item_details,
@@ -1626,3 +1701,42 @@
item_details.setdefault(item.get("item_code"), item)
return item_details
+
+
+@frappe.whitelist()
+def sales_order_query(
+ doctype=None, txt=None, searchfield=None, start=None, page_len=None, filters=None
+):
+ frappe.has_permission("Production Plan", throw=True)
+
+ if not filters:
+ filters = {}
+
+ so_table = frappe.qb.DocType("Sales Order")
+ table = frappe.qb.DocType("Sales Order Item")
+
+ query = (
+ frappe.qb.from_(so_table)
+ .join(table)
+ .on(table.parent == so_table.name)
+ .select(table.parent)
+ .distinct()
+ .where((table.qty > table.production_plan_qty) & (table.docstatus == 1))
+ )
+
+ if filters.get("company"):
+ query = query.where(so_table.company == filters.get("company"))
+
+ if filters.get("sales_orders"):
+ query = query.where(so_table.name.isin(filters.get("sales_orders")))
+
+ if txt:
+ query = query.where(table.item_code.like(f"{txt}%"))
+
+ if page_len:
+ query = query.limit(page_len)
+
+ if start:
+ query = query.offset(start)
+
+ return query.run()
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index f60dbfc..2871a29 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -225,6 +225,102 @@
self.assertEqual(sales_orders, [])
+ def test_donot_allow_to_make_multiple_pp_against_same_so(self):
+ item = "Test SO Production Item 1"
+ create_item(item)
+
+ raw_material = "Test SO RM Production Item 1"
+ create_item(raw_material)
+
+ if not frappe.db.get_value("BOM", {"item": item}):
+ make_bom(item=item, raw_materials=[raw_material])
+
+ so = make_sales_order(item_code=item, qty=4)
+ pln = frappe.new_doc("Production Plan")
+ pln.company = so.company
+ pln.get_items_from = "Sales Order"
+
+ pln.append(
+ "sales_orders",
+ {
+ "sales_order": so.name,
+ "sales_order_date": so.transaction_date,
+ "customer": so.customer,
+ "grand_total": so.grand_total,
+ },
+ )
+
+ pln.get_so_items()
+ pln.submit()
+
+ pln = frappe.new_doc("Production Plan")
+ pln.company = so.company
+ pln.get_items_from = "Sales Order"
+
+ pln.append(
+ "sales_orders",
+ {
+ "sales_order": so.name,
+ "sales_order_date": so.transaction_date,
+ "customer": so.customer,
+ "grand_total": so.grand_total,
+ },
+ )
+
+ pln.get_so_items()
+ self.assertRaises(frappe.ValidationError, pln.save)
+
+ def test_so_based_bill_of_material(self):
+ item = "Test SO Production Item 1"
+ create_item(item)
+
+ raw_material = "Test SO RM Production Item 1"
+ create_item(raw_material)
+
+ bom1 = make_bom(item=item, raw_materials=[raw_material])
+
+ so = make_sales_order(item_code=item, qty=4)
+
+ # Create new BOM and assign to new sales order
+ bom2 = make_bom(item=item, raw_materials=[raw_material])
+ so2 = make_sales_order(item_code=item, qty=4)
+
+ pln1 = frappe.new_doc("Production Plan")
+ pln1.company = so.company
+ pln1.get_items_from = "Sales Order"
+
+ pln1.append(
+ "sales_orders",
+ {
+ "sales_order": so.name,
+ "sales_order_date": so.transaction_date,
+ "customer": so.customer,
+ "grand_total": so.grand_total,
+ },
+ )
+
+ pln1.get_so_items()
+
+ self.assertEqual(pln1.po_items[0].bom_no, bom1.name)
+
+ pln2 = frappe.new_doc("Production Plan")
+ pln2.company = so2.company
+ pln2.get_items_from = "Sales Order"
+
+ pln2.append(
+ "sales_orders",
+ {
+ "sales_order": so2.name,
+ "sales_order_date": so2.transaction_date,
+ "customer": so2.customer,
+ "grand_total": so2.grand_total,
+ },
+ )
+
+ pln2.get_so_items()
+
+ self.assertEqual(pln2.po_items[0].bom_no, bom2.name)
+
def test_production_plan_combine_items(self):
"Test combining FG items in Production Plan."
item = "Test Production Item 1"
diff --git a/erpnext/manufacturing/doctype/workstation/workstation.py b/erpnext/manufacturing/doctype/workstation/workstation.py
index d5b6d37..ac271b7 100644
--- a/erpnext/manufacturing/doctype/workstation/workstation.py
+++ b/erpnext/manufacturing/doctype/workstation/workstation.py
@@ -114,7 +114,7 @@
if schedule_date in tuple(get_holidays(self.holiday_list)):
schedule_date = add_days(schedule_date, 1)
- self.validate_workstation_holiday(schedule_date, skip_holiday_list_check=True)
+ return self.validate_workstation_holiday(schedule_date, skip_holiday_list_check=True)
return schedule_date
diff --git a/erpnext/patches/v12_0/update_bom_in_so_mr.py b/erpnext/patches/v12_0/update_bom_in_so_mr.py
index 114f65d..d35b4bc 100644
--- a/erpnext/patches/v12_0/update_bom_in_so_mr.py
+++ b/erpnext/patches/v12_0/update_bom_in_so_mr.py
@@ -6,7 +6,9 @@
frappe.reload_doc("selling", "doctype", "sales_order_item")
for doctype in ["Sales Order", "Material Request"]:
- condition = " and child_doc.stock_qty > child_doc.produced_qty and doc.per_delivered < 100"
+ condition = (
+ " and child_doc.stock_qty > child_doc.produced_qty and ROUND(doc.per_delivered, 2) < 100"
+ )
if doctype == "Material Request":
condition = " and doc.per_ordered < 100 and doc.material_request_type = 'Manufacture'"
diff --git a/erpnext/quality_management/doctype/non_conformance/non_conformance.json b/erpnext/quality_management/doctype/non_conformance/non_conformance.json
index 8dfe2d6..e6b8744 100644
--- a/erpnext/quality_management/doctype/non_conformance/non_conformance.json
+++ b/erpnext/quality_management/doctype/non_conformance/non_conformance.json
@@ -62,10 +62,10 @@
"fieldtype": "Column Break"
},
{
- "fetch_from": "process_owner.full_name",
+ "fetch_from": "procedure.process_owner_full_name",
"fieldname": "full_name",
"fieldtype": "Data",
- "hidden": 1,
+ "read_only": 1,
"label": "Full Name"
},
{
@@ -81,7 +81,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2021-02-26 15:27:47.247814",
+ "modified": "2023-07-31 08:10:47.247814",
"modified_by": "Administrator",
"module": "Quality Management",
"name": "Non Conformance",
diff --git a/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.json b/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.json
index e3dbd66..010888d 100644
--- a/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.json
+++ b/erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"autoname": "format:{####}",
"creation": "2019-05-26 15:03:43.996455",
"doctype": "DocType",
@@ -12,7 +13,6 @@
],
"fields": [
{
- "fetch_from": "goal.objective",
"fieldname": "objective",
"fieldtype": "Text",
"in_list_view": 1,
@@ -38,14 +38,17 @@
}
],
"istable": 1,
- "modified": "2019-05-26 16:12:54.832058",
+ "links": [],
+ "modified": "2023-07-28 18:10:23.351246",
"modified_by": "Administrator",
"module": "Quality Management",
"name": "Quality Goal Objective",
+ "naming_rule": "Expression",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
+ "states": [],
"track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json b/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json
index 3a750c2..5ddf0f2 100644
--- a/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json
+++ b/erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json
@@ -56,6 +56,7 @@
"fieldtype": "Column Break"
},
{
+ "default": "Open",
"columns": 2,
"fieldname": "status",
"fieldtype": "Select",
@@ -67,7 +68,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2020-10-27 16:28:20.908637",
+ "modified": "2023-07-31 09:20:20.908637",
"modified_by": "Administrator",
"module": "Quality Management",
"name": "Quality Review Objective",
@@ -76,4 +77,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index fd3f9fa..27163db 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -52,7 +52,7 @@
refresh: function(frm) {
if(frm.doc.docstatus === 1) {
- if (frm.doc.status !== 'Closed' && flt(frm.doc.per_delivered, 6) < 100 && flt(frm.doc.per_billed, 6) < 100) {
+ if (frm.doc.status !== 'Closed' && flt(frm.doc.per_delivered, 2) < 100 && flt(frm.doc.per_billed, 2) < 100) {
frm.add_custom_button(__('Update Items'), () => {
erpnext.utils.update_child_items({
frm: frm,
@@ -309,7 +309,7 @@
me.frm.cscript.update_status('Resume', 'Draft')
}, __("Status"));
- if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
+ if(flt(doc.per_delivered, 2) < 100 || flt(doc.per_billed, 2) < 100) {
// close
this.frm.add_custom_button(__('Close'), () => this.close_sales_order(), __("Status"))
}
@@ -327,7 +327,7 @@
&& !this.frm.doc.skip_delivery_note
if (this.frm.has_perm("submit")) {
- if(flt(doc.per_delivered, 6) < 100 || flt(doc.per_billed) < 100) {
+ if(flt(doc.per_delivered, 2) < 100 || flt(doc.per_billed, 2) < 100) {
// hold
this.frm.add_custom_button(__('Hold'), () => this.hold_sales_order(), __("Status"))
// close
@@ -335,7 +335,7 @@
}
}
- if (flt(doc.per_picked, 6) < 100 && flt(doc.per_delivered, 6) < 100) {
+ if (flt(doc.per_picked, 2) < 100 && flt(doc.per_delivered, 2) < 100) {
this.frm.add_custom_button(__('Pick List'), () => this.create_pick_list(), __('Create'));
}
@@ -345,18 +345,18 @@
const order_is_a_custom_sale = ["Sales", "Shopping Cart", "Maintenance"].indexOf(doc.order_type) === -1;
// delivery note
- if(flt(doc.per_delivered, 6) < 100 && (order_is_a_sale || order_is_a_custom_sale) && allow_delivery) {
+ if(flt(doc.per_delivered, 2) < 100 && (order_is_a_sale || order_is_a_custom_sale) && allow_delivery) {
this.frm.add_custom_button(__('Delivery Note'), () => this.make_delivery_note_based_on_delivery_date(), __('Create'));
this.frm.add_custom_button(__('Work Order'), () => this.make_work_order(), __('Create'));
}
// sales invoice
- if(flt(doc.per_billed, 6) < 100) {
+ if(flt(doc.per_billed, 2) < 100) {
this.frm.add_custom_button(__('Sales Invoice'), () => me.make_sales_invoice(), __('Create'));
}
// material request
- if(!doc.order_type || (order_is_a_sale || order_is_a_custom_sale) && flt(doc.per_delivered, 6) < 100) {
+ if(!doc.order_type || (order_is_a_sale || order_is_a_custom_sale) && flt(doc.per_delivered, 2) < 100) {
this.frm.add_custom_button(__('Material Request'), () => this.make_material_request(), __('Create'));
this.frm.add_custom_button(__('Request for Raw Materials'), () => this.make_raw_material_request(), __('Create'));
}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 0fb4860..ca669f6 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -733,7 +733,7 @@
# qty is for packed items, because packed items don't have stock_qty field
qty = source.get("qty")
target.project = source_parent.project
- target.qty = qty - requested_item_qty.get(source.name, 0) - source.delivered_qty
+ target.qty = qty - requested_item_qty.get(source.name, 0) - flt(source.get("delivered_qty"))
target.stock_qty = flt(target.qty) * flt(target.conversion_factor)
args = target.as_dict().copy()
@@ -767,7 +767,7 @@
"doctype": "Material Request Item",
"field_map": {"name": "sales_order_item", "parent": "sales_order"},
"condition": lambda doc: not frappe.db.exists("Product Bundle", doc.item_code)
- and (doc.stock_qty - doc.delivered_qty) > requested_item_qty.get(doc.name, 0),
+ and (doc.stock_qty - flt(doc.get("delivered_qty"))) > requested_item_qty.get(doc.name, 0),
"postprocess": update_item,
},
},
diff --git a/erpnext/selling/doctype/sales_order/sales_order_list.js b/erpnext/selling/doctype/sales_order/sales_order_list.js
index 64c58ef..518f018 100644
--- a/erpnext/selling/doctype/sales_order/sales_order_list.js
+++ b/erpnext/selling/doctype/sales_order/sales_order_list.js
@@ -10,7 +10,7 @@
return [__("On Hold"), "orange", "status,=,On Hold"];
} else if (doc.status === "Completed") {
return [__("Completed"), "green", "status,=,Completed"];
- } else if (!doc.skip_delivery_note && flt(doc.per_delivered, 6) < 100) {
+ } else if (!doc.skip_delivery_note && flt(doc.per_delivered, 2) < 100) {
if (frappe.datetime.get_diff(doc.delivery_date) < 0) {
// not delivered & overdue
return [__("Overdue"), "red",
@@ -19,7 +19,7 @@
// not delivered (zeroount order)
return [__("To Deliver"), "orange",
"per_delivered,<,100|grand_total,=,0|status,!=,Closed"];
- } else if (flt(doc.per_billed, 6) < 100) {
+ } else if (flt(doc.per_billed, 2) < 100) {
// not delivered & not billed
return [__("To Deliver and Bill"), "orange",
"per_delivered,<,100|per_billed,<,100|status,!=,Closed"];
@@ -28,12 +28,12 @@
return [__("To Deliver"), "orange",
"per_delivered,<,100|per_billed,=,100|status,!=,Closed"];
}
- } else if ((flt(doc.per_delivered, 6) === 100) && flt(doc.grand_total) !== 0
- && flt(doc.per_billed, 6) < 100) {
+ } else if ((flt(doc.per_delivered, 2) === 100) && flt(doc.grand_total) !== 0
+ && flt(doc.per_billed, 2) < 100) {
// to bill
return [__("To Bill"), "orange",
"per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
- } else if (doc.skip_delivery_note && flt(doc.per_billed, 6) < 100){
+ } else if (doc.skip_delivery_note && flt(doc.per_billed, 2) < 100){
return [__("To Bill"), "orange", "per_billed,<,100|status,!=,Closed"];
}
},
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 796e258..c85a4fb 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -549,6 +549,26 @@
workflow.is_active = 0
workflow.save()
+ def test_material_request_for_product_bundle(self):
+ # Create the Material Request from the sales order for the Packing Items
+ # Check whether the material request has the correct packing item or not.
+ if not frappe.db.exists("Item", "_Test Product Bundle Item New 1"):
+ bundle_item = make_item("_Test Product Bundle Item New 1", {"is_stock_item": 0})
+ bundle_item.append(
+ "item_defaults", {"company": "_Test Company", "default_warehouse": "_Test Warehouse - _TC"}
+ )
+ bundle_item.save(ignore_permissions=True)
+
+ make_item("_Packed Item New 2", {"is_stock_item": 1})
+ make_product_bundle("_Test Product Bundle Item New 1", ["_Packed Item New 2"], 2)
+
+ so = make_sales_order(
+ item_code="_Test Product Bundle Item New 1",
+ )
+
+ mr = make_material_request(so.name)
+ self.assertEqual(mr.items[0].item_code, "_Packed Item New 2")
+
def test_bin_details_of_packed_item(self):
# test Update Items with product bundle
if not frappe.db.exists("Item", "_Test Product Bundle Item New"):
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 5c7e10a..07565c3 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json
@@ -84,6 +84,7 @@
"actual_qty",
"ordered_qty",
"planned_qty",
+ "production_plan_qty",
"column_break_69",
"work_order_qty",
"delivered_qty",
@@ -882,12 +883,19 @@
"print_hide": 1,
"read_only": 1,
"report_hide": 1
+ },
+ {
+ "fieldname": "production_plan_qty",
+ "fieldtype": "Float",
+ "label": "Production Plan Qty",
+ "no_copy": 1,
+ "read_only": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2023-04-04 10:44:05.707488",
+ "modified": "2023-07-28 14:56:42.031636",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order Item",
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index 8b37e40..720d142 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -605,7 +605,6 @@
i => i.item_code === item_code
&& (!has_batch_no || (has_batch_no && i.batch_no === batch_no))
&& (i.uom === uom)
- && (i.rate == rate)
);
}
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index ef4155e..aff9587 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -395,16 +395,16 @@
def validate_warehouse_for_reorder(self):
"""Validate Reorder level table for duplicate and conditional mandatory"""
- warehouse = []
+ warehouse_material_request_type: list[tuple[str, str]] = []
for d in self.get("reorder_levels"):
if not d.warehouse_group:
d.warehouse_group = d.warehouse
- if d.get("warehouse") and d.get("warehouse") not in warehouse:
- warehouse += [d.get("warehouse")]
+ if (d.get("warehouse"), d.get("material_request_type")) not in warehouse_material_request_type:
+ warehouse_material_request_type += [(d.get("warehouse"), d.get("material_request_type"))]
else:
frappe.throw(
- _("Row {0}: An Reorder entry already exists for this warehouse {1}").format(
- d.idx, d.warehouse
+ _("Row #{0}: A reorder entry already exists for warehouse {1} with reorder type {2}.").format(
+ d.idx, d.warehouse, d.material_request_type
),
DuplicateReorderRows,
)
diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
index bdc9d74..176a215 100644
--- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
+++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
@@ -17,7 +17,7 @@
if not filters:
filters = {}
- sle_count = frappe.db.count("Stock Ledger Entry", {"is_cancelled": 0})
+ sle_count = frappe.db.count("Stock Ledger Entry")
if sle_count > SLE_COUNT_LIMIT and not filters.get("item_code") and not filters.get("warehouse"):
frappe.throw(_("Please select either the Item or Warehouse filter to generate the report."))
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index f2c2e27..d60e9b5 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -446,10 +446,9 @@
{
"label": _("Valuation Rate"),
"fieldname": "val_rate",
- "fieldtype": "Currency",
+ "fieldtype": "Float",
"width": 90,
"convertible": "rate",
- "options": "currency",
},
{
"label": _("Reserved Stock"),
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index 77bc4e0..ed28ed3 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -196,7 +196,7 @@
{
"label": _("Avg Rate (Balance Stock)"),
"fieldname": "valuation_rate",
- "fieldtype": "Currency",
+ "fieldtype": "Float",
"width": 180,
"options": "Company:company:default_currency",
"convertible": "rate",
@@ -204,7 +204,7 @@
{
"label": _("Valuation Rate"),
"fieldname": "in_out_rate",
- "fieldtype": "Currency",
+ "fieldtype": "Float",
"width": 140,
"options": "Company:company:default_currency",
"convertible": "rate",
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 5abb8e8..248b705 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -358,6 +358,8 @@
"current_index": index,
"total_reposting_count": len(args),
},
+ doctype=doc.doctype,
+ docname=doc.name,
)
diff --git a/erpnext/templates/form_grid/item_grid.html b/erpnext/templates/form_grid/item_grid.html
index c596890..027046f 100644
--- a/erpnext/templates/form_grid/item_grid.html
+++ b/erpnext/templates/form_grid/item_grid.html
@@ -17,7 +17,7 @@
title = "Warehouse",
actual_qty = (frm.doc.doctype==="Sales Order"
? doc.projected_qty : doc.actual_qty);
- if(flt(frm.doc.per_delivered) < 100
+ if(flt(frm.doc.per_delivered, 2) < 100
&& in_list(["Sales Order Item", "Delivery Note Item"], doc.doctype)) {
if(actual_qty != undefined) {
if(actual_qty >= doc.qty) {
diff --git a/erpnext/translations/af.csv b/erpnext/translations/af.csv
index 35ccbb6..417f1ec 100644
--- a/erpnext/translations/af.csv
+++ b/erpnext/translations/af.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Jy kan nie projektipe 'eksterne' uitvee nie,
You cannot edit root node.,U kan nie wortelknoop wysig nie.,
You cannot restart a Subscription that is not cancelled.,U kan nie 'n intekening herlaai wat nie gekanselleer is nie.,
-You don't have enought Loyalty Points to redeem,U het nie genoeg lojaliteitspunte om te verkoop nie,
+You don't have enough Loyalty Points to redeem,U het nie genoeg lojaliteitspunte om te verkoop nie,
You have already assessed for the assessment criteria {}.,U het reeds geassesseer vir die assesseringskriteria ().,
You have already selected items from {0} {1},Jy het reeds items gekies van {0} {1},
You have been invited to collaborate on the project: {0},U is genooi om saam te werk aan die projek: {0},
diff --git a/erpnext/translations/am.csv b/erpnext/translations/am.csv
index da865b8..b5abbbf 100644
--- a/erpnext/translations/am.csv
+++ b/erpnext/translations/am.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',የፕሮጀክት አይነት «ውጫዊ» ን መሰረዝ አይችሉም.,
You cannot edit root node.,የስር ሥፍራ ማረም አይችሉም.,
You cannot restart a Subscription that is not cancelled.,የማይሰረዝ የደንበኝነት ምዝገባን ዳግም ማስጀመር አይችሉም.,
-You don't have enought Loyalty Points to redeem,ለማስመለስ በቂ የታማኝነት ነጥቦች የሉዎትም,
+You don't have enough Loyalty Points to redeem,ለማስመለስ በቂ የታማኝነት ነጥቦች የሉዎትም,
You have already assessed for the assessment criteria {}.,ቀድሞውንም ግምገማ መስፈርት ከገመገምን {}.,
You have already selected items from {0} {1},ከዚህ ቀደም ከ ንጥሎች ተመርጠዋል ሊሆን {0} {1},
You have been invited to collaborate on the project: {0},እርስዎ ፕሮጀክት ላይ ተባበር ተጋብዘዋል: {0},
diff --git a/erpnext/translations/ar.csv b/erpnext/translations/ar.csv
index 17d4386..550b5f2 100644
--- a/erpnext/translations/ar.csv
+++ b/erpnext/translations/ar.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',لا يمكنك حذف مشروع من نوع 'خارجي',
You cannot edit root node.,لا يمكنك تحرير عقدة الجذر.,
You cannot restart a Subscription that is not cancelled.,لا يمكنك إعادة تشغيل اشتراك غير ملغى.,
-You don't have enought Loyalty Points to redeem,ليس لديك ما يكفي من نقاط الولاء لاستردادها,
+You don't have enough Loyalty Points to redeem,ليس لديك ما يكفي من نقاط الولاء لاستردادها,
You have already assessed for the assessment criteria {}.,لقد سبق أن قيمت معايير التقييم {}.,
You have already selected items from {0} {1},لقد حددت العناصر من {0} {1},
You have been invited to collaborate on the project: {0},لقد وجهت الدعوة إلى التعاون في هذا المشروع: {0},
diff --git a/erpnext/translations/bg.csv b/erpnext/translations/bg.csv
index 5fc10c4..baee526 100644
--- a/erpnext/translations/bg.csv
+++ b/erpnext/translations/bg.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Не можете да изтриете Тип на проекта "Външен",
You cannot edit root node.,Не можете да редактирате корен възел.,
You cannot restart a Subscription that is not cancelled.,"Не можете да рестартирате абонамент, който не е анулиран.",
-You don't have enought Loyalty Points to redeem,"Нямате достатъчно точки за лоялност, за да осребрите",
+You don't have enough Loyalty Points to redeem,"Нямате достатъчно точки за лоялност, за да осребрите",
You have already assessed for the assessment criteria {}.,Вече оценихте критериите за оценка {}.,
You have already selected items from {0} {1},Вие вече сте избрали елементи от {0} {1},
You have been invited to collaborate on the project: {0},Вие сте били поканени да си сътрудничат по проекта: {0},
diff --git a/erpnext/translations/bn.csv b/erpnext/translations/bn.csv
index 1da9bb6..266bd16 100644
--- a/erpnext/translations/bn.csv
+++ b/erpnext/translations/bn.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',আপনি প্রকল্প প্রকার 'বহিরাগত' মুছে ফেলতে পারবেন না,
You cannot edit root node.,আপনি রুট নোড সম্পাদনা করতে পারবেন না।,
You cannot restart a Subscription that is not cancelled.,আপনি সাবস্ক্রিপশনটি বাতিল না করা পুনরায় শুরু করতে পারবেন না,
-You don't have enought Loyalty Points to redeem,আপনি বিক্রি করার জন্য আনুগত্য পয়েন্ট enought না,
+You don't have enough Loyalty Points to redeem,আপনি বিক্রি করার জন্য আনুগত্য পয়েন্ট enough না,
You have already assessed for the assessment criteria {}.,"আপনি ইতিমধ্যে মূল্যায়ন মানদণ্ডের জন্য মূল্যায়ন করে নিলে, {}।",
You have already selected items from {0} {1},আপনি ইতিমধ্যে থেকে আইটেম নির্বাচন করা আছে {0} {1},
You have been invited to collaborate on the project: {0},আপনি প্রকল্পের সহযোগীতা করার জন্য আমন্ত্রণ জানানো হয়েছে: {0},
diff --git a/erpnext/translations/bs.csv b/erpnext/translations/bs.csv
index cab9c83..53e9d93 100644
--- a/erpnext/translations/bs.csv
+++ b/erpnext/translations/bs.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Ne možete obrisati tip projekta 'Spoljni',
You cannot edit root node.,Ne možete uređivati root čvor.,
You cannot restart a Subscription that is not cancelled.,Ne možete ponovo pokrenuti pretplatu koja nije otkazana.,
-You don't have enought Loyalty Points to redeem,Ne iskoristite Loyalty Points za otkup,
+You don't have enough Loyalty Points to redeem,Ne iskoristite Loyalty Points za otkup,
You have already assessed for the assessment criteria {}.,Ste već ocijenili za kriterije procjene {}.,
You have already selected items from {0} {1},Vi ste već odabrane stavke iz {0} {1},
You have been invited to collaborate on the project: {0},Vi ste pozvani da surađuju na projektu: {0},
diff --git a/erpnext/translations/ca.csv b/erpnext/translations/ca.csv
index 0e16a74..4ca1435 100644
--- a/erpnext/translations/ca.csv
+++ b/erpnext/translations/ca.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',No es pot eliminar el tipus de projecte 'Extern',
You cannot edit root node.,No podeu editar el node arrel.,
You cannot restart a Subscription that is not cancelled.,No podeu reiniciar una subscripció que no es cancel·la.,
-You don't have enought Loyalty Points to redeem,No teniu punts de fidelització previstos per bescanviar,
+You don't have enough Loyalty Points to redeem,No teniu punts de fidelització previstos per bescanviar,
You have already assessed for the assessment criteria {}.,Vostè ja ha avaluat pels criteris d'avaluació {}.,
You have already selected items from {0} {1},Ja ha seleccionat articles de {0} {1},
You have been invited to collaborate on the project: {0},Se li ha convidat a col·laborar en el projecte: {0},
diff --git a/erpnext/translations/cs.csv b/erpnext/translations/cs.csv
index 3cef0de..26b8bf1 100644
--- a/erpnext/translations/cs.csv
+++ b/erpnext/translations/cs.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Nelze odstranit typ projektu "Externí",
You cannot edit root node.,Nelze upravit kořenový uzel.,
You cannot restart a Subscription that is not cancelled.,"Nelze znovu spustit odběr, který není zrušen.",
-You don't have enought Loyalty Points to redeem,Nemáte dostatečné věrnostní body k uplatnění,
+You don't have enough Loyalty Points to redeem,Nemáte dostatečné věrnostní body k uplatnění,
You have already assessed for the assessment criteria {}.,Již jste hodnotili kritéria hodnocení {}.,
You have already selected items from {0} {1},Již jste vybrané položky z {0} {1},
You have been invited to collaborate on the project: {0},Byli jste pozváni ke spolupráci na projektu: {0},
diff --git a/erpnext/translations/da.csv b/erpnext/translations/da.csv
index c58065a..09aaa15 100644
--- a/erpnext/translations/da.csv
+++ b/erpnext/translations/da.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Du kan ikke slette Project Type 'Ekstern',
You cannot edit root node.,Du kan ikke redigere root node.,
You cannot restart a Subscription that is not cancelled.,"Du kan ikke genstarte en abonnement, der ikke annulleres.",
-You don't have enought Loyalty Points to redeem,Du har ikke nok loyalitetspoint til at indløse,
+You don't have enough Loyalty Points to redeem,Du har ikke nok loyalitetspoint til at indløse,
You have already assessed for the assessment criteria {}.,Du har allerede vurderet for bedømmelseskriterierne {}.,
You have already selected items from {0} {1},Du har allerede valgt elementer fra {0} {1},
You have been invited to collaborate on the project: {0},Du er blevet inviteret til at samarbejde om sag: {0},
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index 28a123e..e2c7467 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -1063,6 +1063,7 @@
Get Items from Product Bundle,Artikel aus dem Produkt-Bundle übernehmen,
Get Suppliers,Holen Sie sich Lieferanten,
Get Suppliers By,Holen Sie sich Lieferanten durch,
+Get Supplier Group Details,Werte aus Lieferantengruppe übernehmen,
Get Updates,Newsletter abonnieren,
Get customers from,Holen Sie Kunden von,
Get from Patient Encounter,Von der Patientenbegegnung erhalten,
@@ -3106,7 +3107,7 @@
You cannot delete Project Type 'External',Sie können den Projekttyp 'Extern' nicht löschen,
You cannot edit root node.,Sie können den Stammknoten nicht bearbeiten.,
You cannot restart a Subscription that is not cancelled.,Sie können ein nicht abgebrochenes Abonnement nicht neu starten.,
-You don't have enought Loyalty Points to redeem,Sie haben nicht genügend Treuepunkte zum Einlösen,
+You don't have enough Loyalty Points to redeem,Sie haben nicht genügend Treuepunkte zum Einlösen,
You have already assessed for the assessment criteria {}.,Sie haben bereits für die Bewertungskriterien beurteilt.,
You have already selected items from {0} {1},Sie haben bereits Elemente aus {0} {1} gewählt,
You have been invited to collaborate on the project: {0},Sie wurden zur Zusammenarbeit für das Projekt {0} eingeladen.,
@@ -4726,6 +4727,7 @@
Party Account Currency,Währung des Kontos der Partei,
Against Expense Account,Zu Aufwandskonto,
Inter Company Invoice Reference,Unternehmensübergreifende Rechnungsreferenz,
+Internal Supplier,Interner Lieferant,
Is Internal Supplier,Ist interner Lieferant,
Start date of current invoice's period,Startdatum der laufenden Rechnungsperiode,
End date of current invoice's period,Schlußdatum der laufenden Eingangsrechnungsperiode,
@@ -5172,6 +5174,8 @@
Ref SQ,Ref-SQ,
Inter Company Order Reference,Inter Company Bestellreferenz,
Supplier Part Number,Lieferanten-Artikelnummer,
+Supplier Primary Contact,Hauptkontakt des Lieferanten,
+Supplier Primary Address,Hauptadresse des Lieferanten,
Billed Amt,Rechnungsbetrag,
Warehouse and Reference,Lager und Referenz,
To be delivered to customer,Zur Auslieferung an den Kunden,
@@ -6773,7 +6777,7 @@
Allow Sales Invoice Creation Without Sales Order,Ermöglichen Sie die Erstellung von Kundenrechnungen ohne Auftrag,
Allow Sales Invoice Creation Without Delivery Note,Ermöglichen Sie die Erstellung einer Ausgangsrechnung ohne Lieferschein,
Default Price List,Standardpreisliste,
-Primary Address and Contact Detail,Primäre Adresse und Kontaktdetails,
+Primary Address and Contact,Hauptadresse und -kontakt,
"Select, to make the customer searchable with these fields","Wählen Sie, um den Kunden mit diesen Feldern durchsuchbar zu machen",
Customer Primary Contact,Hauptkontakt des Kunden,
"Reselect, if the chosen contact is edited after save","Wählen Sie erneut, wenn der ausgewählte Kontakt nach dem Speichern bearbeitet wird",
diff --git a/erpnext/translations/el.csv b/erpnext/translations/el.csv
index 9d15e61..ae72c26 100644
--- a/erpnext/translations/el.csv
+++ b/erpnext/translations/el.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Δεν μπορείτε να διαγράψετε τον τύπο έργου 'Εξωτερικό',
You cannot edit root node.,Δεν μπορείτε να επεξεργαστείτε τον κόμβο ρίζας.,
You cannot restart a Subscription that is not cancelled.,Δεν μπορείτε να κάνετε επανεκκίνηση μιας συνδρομής που δεν ακυρώνεται.,
-You don't have enought Loyalty Points to redeem,Δεν διαθέτετε σημεία αφοσίωσης για εξαργύρωση,
+You don't have enough Loyalty Points to redeem,Δεν διαθέτετε σημεία αφοσίωσης για εξαργύρωση,
You have already assessed for the assessment criteria {}.,Έχετε ήδη αξιολογήσει τα κριτήρια αξιολόγησης {}.,
You have already selected items from {0} {1},Έχετε ήδη επιλεγμένα αντικείμενα από {0} {1},
You have been invited to collaborate on the project: {0},Έχετε προσκληθεί να συνεργαστούν για το έργο: {0},
diff --git a/erpnext/translations/es.csv b/erpnext/translations/es.csv
index 50074d2..d931429 100644
--- a/erpnext/translations/es.csv
+++ b/erpnext/translations/es.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',No puede eliminar Tipo de proyecto 'Externo',
You cannot edit root node.,No puedes editar el nodo raíz.,
You cannot restart a Subscription that is not cancelled.,No puede reiniciar una suscripción que no está cancelada.,
-You don't have enought Loyalty Points to redeem,No tienes suficientes puntos de lealtad para canjear,
+You don't have enough Loyalty Points to redeem,No tienes suficientes puntos de lealtad para canjear,
You have already assessed for the assessment criteria {}.,Ya ha evaluado los criterios de evaluación {}.,
You have already selected items from {0} {1},Ya ha seleccionado artículos de {0} {1},
You have been invited to collaborate on the project: {0},Se le ha invitado a colaborar en el proyecto: {0},
diff --git a/erpnext/translations/et.csv b/erpnext/translations/et.csv
index a9f6c6c..29e599b 100644
--- a/erpnext/translations/et.csv
+++ b/erpnext/translations/et.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Te ei saa projekti tüübi "Väline" kustutada,
You cannot edit root node.,Sa ei saa redigeerida juursõlme.,
You cannot restart a Subscription that is not cancelled.,Te ei saa tellimust uuesti katkestada.,
-You don't have enought Loyalty Points to redeem,"Teil pole lojaalsuspunkte, mida soovite lunastada",
+You don't have enough Loyalty Points to redeem,"Teil pole lojaalsuspunkte, mida soovite lunastada",
You have already assessed for the assessment criteria {}.,Olete juba hinnanud hindamise kriteeriumid {}.,
You have already selected items from {0} {1},Olete juba valitud objektide {0} {1},
You have been invited to collaborate on the project: {0},Sind on kutsutud koostööd projekti: {0},
diff --git a/erpnext/translations/fa.csv b/erpnext/translations/fa.csv
index 35a42e8..4c5ab80 100644
--- a/erpnext/translations/fa.csv
+++ b/erpnext/translations/fa.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',شما نمیتوانید نوع پروژه «خارجی» را حذف کنید,
You cannot edit root node.,نمی توانید گره ریشه را ویرایش کنید,
You cannot restart a Subscription that is not cancelled.,شما نمی توانید اشتراک را لغو کنید.,
-You don't have enought Loyalty Points to redeem,شما نمیتوانید امتیازات وفاداری خود را به دست آورید,
+You don't have enough Loyalty Points to redeem,شما نمیتوانید امتیازات وفاداری خود را به دست آورید,
You have already assessed for the assessment criteria {}.,شما در حال حاضر برای معیارهای ارزیابی ارزیابی {}.,
You have already selected items from {0} {1},شما در حال حاضر اقلام از انتخاب {0} {1},
You have been invited to collaborate on the project: {0},از شما دعوت شده برای همکاری در این پروژه: {0},
diff --git a/erpnext/translations/fi.csv b/erpnext/translations/fi.csv
index 9d7bf8b..c26441b 100644
--- a/erpnext/translations/fi.csv
+++ b/erpnext/translations/fi.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Et voi poistaa projektityyppiä "Ulkoinen",
You cannot edit root node.,Et voi muokata juurisolmua.,
You cannot restart a Subscription that is not cancelled.,"Et voi uudelleenkäynnistää tilausta, jota ei peruuteta.",
-You don't have enought Loyalty Points to redeem,Sinulla ei ole tarpeeksi Loyalty Pointsia lunastettavaksi,
+You don't have enough Loyalty Points to redeem,Sinulla ei ole tarpeeksi Loyalty Pointsia lunastettavaksi,
You have already assessed for the assessment criteria {}.,Olet jo arvioitu arviointikriteerit {}.,
You have already selected items from {0} {1},Olet jo valitut kohteet {0} {1},
You have been invited to collaborate on the project: {0},Sinut on kutsuttu yhteistyöhön projektissa {0},
diff --git a/erpnext/translations/fr.csv b/erpnext/translations/fr.csv
index 6d5505b..801604a 100644
--- a/erpnext/translations/fr.csv
+++ b/erpnext/translations/fr.csv
@@ -3093,7 +3093,7 @@
You cannot delete Project Type 'External',Vous ne pouvez pas supprimer le Type de Projet 'Externe',
You cannot edit root node.,Vous ne pouvez pas modifier le nœud racine.,
You cannot restart a Subscription that is not cancelled.,Vous ne pouvez pas redémarrer un abonnement qui n'est pas annulé.,
-You don't have enought Loyalty Points to redeem,Vous n'avez pas assez de points de fidélité à échanger,
+You don't have enough Loyalty Points to redeem,Vous n'avez pas assez de points de fidélité à échanger,
You have already assessed for the assessment criteria {}.,Vous avez déjà évalué les critères d'évaluation {}.,
You have already selected items from {0} {1},Vous avez déjà choisi des articles de {0} {1},
You have been invited to collaborate on the project: {0},Vous avez été invité à collaborer sur le projet : {0},
diff --git a/erpnext/translations/gu.csv b/erpnext/translations/gu.csv
index 025ec89..5691597 100644
--- a/erpnext/translations/gu.csv
+++ b/erpnext/translations/gu.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',તમે 'બાહ્ય' પ્રોજેક્ટ પ્રકારને કાઢી શકતા નથી,
You cannot edit root node.,તમે રૂટ નોડને સંપાદિત કરી શકતા નથી.,
You cannot restart a Subscription that is not cancelled.,તમે સબ્સ્ક્રિપ્શન ફરીથી શરૂ કરી શકતા નથી કે જે રદ કરવામાં આવી નથી.,
-You don't have enought Loyalty Points to redeem,તમારી પાસે રિડીમ કરવા માટે વફાદારીના પોઇંટ્સ નથી,
+You don't have enough Loyalty Points to redeem,તમારી પાસે રિડીમ કરવા માટે વફાદારીના પોઇંટ્સ નથી,
You have already assessed for the assessment criteria {}.,જો તમે પહેલાથી જ આકારણી માપદંડ માટે આકારણી છે {}.,
You have already selected items from {0} {1},જો તમે પહેલાથી જ વસ્તુઓ પસંદ કરેલ {0} {1},
You have been invited to collaborate on the project: {0},તમે આ પ્રોજેક્ટ પર સહયોગ કરવા માટે આમંત્રિત કરવામાં આવ્યા છે: {0},
diff --git a/erpnext/translations/he.csv b/erpnext/translations/he.csv
index 43bac41..9aa152c 100644
--- a/erpnext/translations/he.csv
+++ b/erpnext/translations/he.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',אינך יכול למחוק את סוג הפרויקט 'חיצוני',
You cannot edit root node.,אינך יכול לערוך צומת שורש.,
You cannot restart a Subscription that is not cancelled.,אינך יכול להפעיל מחדש מנוי שאינו מבוטל.,
-You don't have enought Loyalty Points to redeem,אין לך מספיק נקודות נאמנות למימוש,
+You don't have enough Loyalty Points to redeem,אין לך מספיק נקודות נאמנות למימוש,
You have already assessed for the assessment criteria {}.,כבר הערכת את קריטריוני ההערכה {}.,
You have already selected items from {0} {1},בחרת כבר פריטים מ- {0} {1},
You have been invited to collaborate on the project: {0},הוזמנת לשתף פעולה על הפרויקט: {0},
diff --git a/erpnext/translations/hi.csv b/erpnext/translations/hi.csv
index 00747d4..d56dcec 100644
--- a/erpnext/translations/hi.csv
+++ b/erpnext/translations/hi.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',आप परियोजना प्रकार 'बाहरी' को नहीं हटा सकते,
You cannot edit root node.,आप रूट नोड संपादित नहीं कर सकते हैं।,
You cannot restart a Subscription that is not cancelled.,आप एक सदस्यता को पुनरारंभ नहीं कर सकते जो रद्द नहीं किया गया है।,
-You don't have enought Loyalty Points to redeem,आपने रिडीम करने के लिए वफादारी अंक नहीं खरीदे हैं,
+You don't have enough Loyalty Points to redeem,आपने रिडीम करने के लिए वफादारी अंक नहीं खरीदे हैं,
You have already assessed for the assessment criteria {}.,आप मूल्यांकन मानदंड के लिए पहले से ही मूल्यांकन कर चुके हैं {},
You have already selected items from {0} {1},आप पहले से ही से आइटम का चयन किया है {0} {1},
You have been invited to collaborate on the project: {0},आप इस परियोजना पर सहयोग करने के लिए आमंत्रित किया गया है: {0},
diff --git a/erpnext/translations/hr.csv b/erpnext/translations/hr.csv
index ec24026..827ae2c 100644
--- a/erpnext/translations/hr.csv
+++ b/erpnext/translations/hr.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Ne možete izbrisati vrstu projekta 'Vanjski',
You cannot edit root node.,Ne možete uređivati root čvor.,
You cannot restart a Subscription that is not cancelled.,Ne možete ponovo pokrenuti pretplatu koja nije otkazana.,
-You don't have enought Loyalty Points to redeem,Nemate dovoljno bodova lojalnosti za otkup,
+You don't have enough Loyalty Points to redeem,Nemate dovoljno bodova lojalnosti za otkup,
You have already assessed for the assessment criteria {}.,Već ste ocijenili kriterije procjene {}.,
You have already selected items from {0} {1},Već ste odabrali stavke iz {0} {1},
You have been invited to collaborate on the project: {0},Pozvani ste za suradnju na projektu: {0},
diff --git a/erpnext/translations/hu.csv b/erpnext/translations/hu.csv
index f92946a..e68b56f 100644
--- a/erpnext/translations/hu.csv
+++ b/erpnext/translations/hu.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',"A ""Külső"" projekttípust nem törölheti",
You cannot edit root node.,Nem szerkesztheti a fő csomópontot.,
You cannot restart a Subscription that is not cancelled.,"Nem indíthatja el az Előfizetést, amelyet nem zárt le.",
-You don't have enought Loyalty Points to redeem,Nincs elegendő hűségpontjaid megváltáshoz,
+You don't have enough Loyalty Points to redeem,Nincs elegendő hűségpontjaid megváltáshoz,
You have already assessed for the assessment criteria {}.,Már értékelte ezekkel az értékelési kritériumokkal: {}.,
You have already selected items from {0} {1},Már választott ki elemeket innen {0} {1},
You have been invited to collaborate on the project: {0},Ön meghívást kapott ennek a projeknek a közreműködéséhez: {0},
diff --git a/erpnext/translations/id.csv b/erpnext/translations/id.csv
index 8ba9e66..67311a1 100644
--- a/erpnext/translations/id.csv
+++ b/erpnext/translations/id.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Anda tidak bisa menghapus Jenis Proyek 'External',
You cannot edit root node.,Anda tidak dapat mengedit simpul root.,
You cannot restart a Subscription that is not cancelled.,Anda tidak dapat memulai ulang Langganan yang tidak dibatalkan.,
-You don't have enought Loyalty Points to redeem,Anda tidak memiliki Poin Loyalitas yang cukup untuk ditukarkan,
+You don't have enough Loyalty Points to redeem,Anda tidak memiliki Poin Loyalitas yang cukup untuk ditukarkan,
You have already assessed for the assessment criteria {}.,Anda telah memberikan penilaian terhadap kriteria penilaian {}.,
You have already selected items from {0} {1},Anda sudah memilih item dari {0} {1},
You have been invited to collaborate on the project: {0},Anda telah diundang untuk berkolaborasi pada proyek: {0},
diff --git a/erpnext/translations/is.csv b/erpnext/translations/is.csv
index 9802592..1bf6b4c 100644
--- a/erpnext/translations/is.csv
+++ b/erpnext/translations/is.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Þú getur ekki eytt verkefnisgerðinni 'ytri',
You cannot edit root node.,Þú getur ekki breytt rótarkóði.,
You cannot restart a Subscription that is not cancelled.,Þú getur ekki endurræst áskrift sem ekki er lokað.,
-You don't have enought Loyalty Points to redeem,Þú hefur ekki nóg hollusta stig til að innleysa,
+You don't have enough Loyalty Points to redeem,Þú hefur ekki nóg hollusta stig til að innleysa,
You have already assessed for the assessment criteria {}.,Þú hefur nú þegar metið mat á viðmiðunum {}.,
You have already selected items from {0} {1},Þú hefur nú þegar valið hluti úr {0} {1},
You have been invited to collaborate on the project: {0},Þér hefur verið boðið að vinna að verkefninu: {0},
diff --git a/erpnext/translations/it.csv b/erpnext/translations/it.csv
index 064f16b..f96b1aa 100644
--- a/erpnext/translations/it.csv
+++ b/erpnext/translations/it.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Non è possibile eliminare il tipo di progetto 'Esterno',
You cannot edit root node.,Non è possibile modificare il nodo principale.,
You cannot restart a Subscription that is not cancelled.,Non è possibile riavviare una sottoscrizione che non è stata annullata.,
-You don't have enought Loyalty Points to redeem,Non hai abbastanza Punti fedeltà da riscattare,
+You don't have enough Loyalty Points to redeem,Non hai abbastanza Punti fedeltà da riscattare,
You have already assessed for the assessment criteria {}.,Hai già valutato i criteri di valutazione {}.,
You have already selected items from {0} {1},Hai già selezionato elementi da {0} {1},
You have been invited to collaborate on the project: {0},Sei stato invitato a collaborare al progetto: {0},
diff --git a/erpnext/translations/ja.csv b/erpnext/translations/ja.csv
index b5064f6..e5ebeb3 100644
--- a/erpnext/translations/ja.csv
+++ b/erpnext/translations/ja.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',プロジェクトタイプ「外部」を削除することはできません,
You cannot edit root node.,ルートノードは編集できません。,
You cannot restart a Subscription that is not cancelled.,キャンセルされていないサブスクリプションを再起動することはできません。,
-You don't have enought Loyalty Points to redeem,あなたは交換するのに十分なロイヤリティポイントがありません,
+You don't have enough Loyalty Points to redeem,あなたは交換するのに十分なロイヤリティポイントがありません,
You have already assessed for the assessment criteria {}.,評価基準{}は評価済です。,
You have already selected items from {0} {1},項目を選択済みです {0} {1},
You have been invited to collaborate on the project: {0},プロジェクト:{0} の共同作業に招待されました,
diff --git a/erpnext/translations/km.csv b/erpnext/translations/km.csv
index 31dcdc0..0dbecca 100644
--- a/erpnext/translations/km.csv
+++ b/erpnext/translations/km.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',អ្នកមិនអាចលុបប្រភេទគម្រោង 'ខាងក្រៅ',
You cannot edit root node.,អ្នកមិនអាចកែថ្នាំង root បានទេ។,
You cannot restart a Subscription that is not cancelled.,អ្នកមិនអាចចាប់ផ្តើមឡើងវិញនូវការជាវដែលមិនត្រូវបានលុបចោលទេ។,
-You don't have enought Loyalty Points to redeem,អ្នកមិនមានពិន្ទុភាពស្មោះត្រង់គ្រប់គ្រាន់ដើម្បីលោះទេ,
+You don't have enough Loyalty Points to redeem,អ្នកមិនមានពិន្ទុភាពស្មោះត្រង់គ្រប់គ្រាន់ដើម្បីលោះទេ,
You have already assessed for the assessment criteria {}.,អ្នកបានវាយតម្លែរួចទៅហើយសម្រាប់លក្ខណៈវិនិច្ឆ័យវាយតម្លៃនេះ {} ។,
You have already selected items from {0} {1},អ្នកបានជ្រើសរួចហើយចេញពីធាតុ {0} {1},
You have been invited to collaborate on the project: {0},អ្នកបានត្រូវអញ្ជើញដើម្បីសហការគ្នាលើគម្រោងនេះ: {0},
diff --git a/erpnext/translations/kn.csv b/erpnext/translations/kn.csv
index f01e386..b929e29 100644
--- a/erpnext/translations/kn.csv
+++ b/erpnext/translations/kn.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',ನೀವು ಪ್ರಾಜೆಕ್ಟ್ ಕೌಟುಂಬಿಕತೆ 'ಬಾಹ್ಯ' ಅನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ,
You cannot edit root node.,ನೀವು ರೂಟ್ ನೋಡ್ ಅನ್ನು ಸಂಪಾದಿಸಲಾಗುವುದಿಲ್ಲ.,
You cannot restart a Subscription that is not cancelled.,ರದ್ದುಪಡಿಸದ ಚಂದಾದಾರಿಕೆಯನ್ನು ನೀವು ಮರುಪ್ರಾರಂಭಿಸಬಾರದು.,
-You don't have enought Loyalty Points to redeem,ರಿಡೀಮ್ ಮಾಡಲು ನೀವು ಲಾಯಲ್ಟಿ ಪಾಯಿಂಟುಗಳನ್ನು ಹೊಂದಿದ್ದೀರಿ,
+You don't have enough Loyalty Points to redeem,ರಿಡೀಮ್ ಮಾಡಲು ನೀವು ಲಾಯಲ್ಟಿ ಪಾಯಿಂಟುಗಳನ್ನು ಹೊಂದಿದ್ದೀರಿ,
You have already assessed for the assessment criteria {}.,ನೀವು ಈಗಾಗಲೇ ಮೌಲ್ಯಮಾಪನ ಮಾನದಂಡದ ನಿರ್ಣಯಿಸುವ {}.,
You have already selected items from {0} {1},ನೀವು ಈಗಾಗಲೇ ಆಯ್ಕೆ ಐಟಂಗಳನ್ನು ಎಂದು {0} {1},
You have been invited to collaborate on the project: {0},ನೀವು ಯೋಜನೆಯ ಸಹಯೋಗಿಸಲು ಆಮಂತ್ರಿಸಲಾಗಿದೆ: {0},
diff --git a/erpnext/translations/ko.csv b/erpnext/translations/ko.csv
index dffcaa8..1c8020f 100644
--- a/erpnext/translations/ko.csv
+++ b/erpnext/translations/ko.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',프로젝트 유형 '외부'를 삭제할 수 없습니다.,
You cannot edit root node.,루트 노드는 편집 할 수 없습니다.,
You cannot restart a Subscription that is not cancelled.,취소되지 않은 구독은 다시 시작할 수 없습니다.,
-You don't have enought Loyalty Points to redeem,사용하기에 충성도 포인트가 충분하지 않습니다.,
+You don't have enough Loyalty Points to redeem,사용하기에 충성도 포인트가 충분하지 않습니다.,
You have already assessed for the assessment criteria {}.,이미 평가 기준 {}을 (를) 평가했습니다.,
You have already selected items from {0} {1},이미에서 항목을 선택한 {0} {1},
You have been invited to collaborate on the project: {0},당신은 프로젝트 공동 작업에 초대되었습니다 : {0},
diff --git a/erpnext/translations/ku.csv b/erpnext/translations/ku.csv
index 047ee89..f4d1197 100644
--- a/erpnext/translations/ku.csv
+++ b/erpnext/translations/ku.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Hûn nikarin jêbirinê hilbijêre 'External',
You cannot edit root node.,Hûn nikarin node root root biguherînin.,
You cannot restart a Subscription that is not cancelled.,Hûn nikarin endamê peymana ku destûr nabe.,
-You don't have enought Loyalty Points to redeem,Hûn pisporên dilsozî ne ku hûn bistînin,
+You don't have enough Loyalty Points to redeem,Hûn pisporên dilsozî ne ku hûn bistînin,
You have already assessed for the assessment criteria {}.,Tu niha ji bo nirxandina nirxandin {}.,
You have already selected items from {0} {1},Jixwe te tomar ji hilbijartî {0} {1},
You have been invited to collaborate on the project: {0},Hûn hatine vexwendin ji bo hevkariyê li ser vê projeyê: {0},
diff --git a/erpnext/translations/lo.csv b/erpnext/translations/lo.csv
index c94bc25..9e77b51 100644
--- a/erpnext/translations/lo.csv
+++ b/erpnext/translations/lo.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',ທ່ານບໍ່ສາມາດລຶບປະເພດໂຄງການ 'ພາຍນອກ',
You cannot edit root node.,ທ່ານບໍ່ສາມາດແກ້ໄຂຮາກຮາກ.,
You cannot restart a Subscription that is not cancelled.,ທ່ານບໍ່ສາມາດເລີ່ມຕົ້ນລະບົບຈອງໃຫມ່ທີ່ບໍ່ໄດ້ຖືກຍົກເລີກ.,
-You don't have enought Loyalty Points to redeem,ທ່ານບໍ່ມີຈຸດປະສົງອັນຄົບຖ້ວນພໍທີ່ຈະຊື້,
+You don't have enough Loyalty Points to redeem,ທ່ານບໍ່ມີຈຸດປະສົງອັນຄົບຖ້ວນພໍທີ່ຈະຊື້,
You have already assessed for the assessment criteria {}.,ທ່ານໄດ້ປະເມີນແລ້ວສໍາລັບມາດຕະຖານການປະເມີນຜົນ {}.,
You have already selected items from {0} {1},ທ່ານໄດ້ຄັດເລືອກເອົາແລ້ວລາຍການຈາກ {0} {1},
You have been invited to collaborate on the project: {0},ທ່ານໄດ້ຖືກເຊື້ອເຊີນເພື່ອເຮັດວຽກຮ່ວມກັນກ່ຽວກັບໂຄງການ: {0},
diff --git a/erpnext/translations/lt.csv b/erpnext/translations/lt.csv
index 731638c..66215c1 100644
--- a/erpnext/translations/lt.csv
+++ b/erpnext/translations/lt.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Negalite ištrinti projekto tipo "Išorinis",
You cannot edit root node.,Jūs negalite redaguoti šakninis mazgas.,
You cannot restart a Subscription that is not cancelled.,"Jūs negalite iš naujo paleisti Prenumeratos, kuri nėra atšaukta.",
-You don't have enought Loyalty Points to redeem,Jūs neturite nusipirkti lojalumo taškų išpirkti,
+You don't have enough Loyalty Points to redeem,Jūs neturite nusipirkti lojalumo taškų išpirkti,
You have already assessed for the assessment criteria {}.,Jūs jau įvertintas vertinimo kriterijus {}.,
You have already selected items from {0} {1},Jūs jau pasirinkote elementus iš {0} {1},
You have been invited to collaborate on the project: {0},Jūs buvote pakviestas bendradarbiauti su projektu: {0},
diff --git a/erpnext/translations/lv.csv b/erpnext/translations/lv.csv
index 71b51f4..1409719 100644
--- a/erpnext/translations/lv.csv
+++ b/erpnext/translations/lv.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Jūs nevarat izdzēst projekta veidu "Ārējais",
You cannot edit root node.,Jūs nevarat rediģēt saknes mezglu.,
You cannot restart a Subscription that is not cancelled.,"Jūs nevarat atsākt Abonementu, kas nav atcelts.",
-You don't have enought Loyalty Points to redeem,Jums nav lojalitātes punktu atpirkt,
+You don't have enough Loyalty Points to redeem,Jums nav lojalitātes punktu atpirkt,
You have already assessed for the assessment criteria {}.,Jūs jau izvērtēta vērtēšanas kritērijiem {}.,
You have already selected items from {0} {1},Jūs jau atsevišķus posteņus {0} {1},
You have been invited to collaborate on the project: {0},Jūs esat uzaicināts sadarboties projektam: {0},
diff --git a/erpnext/translations/mk.csv b/erpnext/translations/mk.csv
index 2dcef0c..06d7e65 100644
--- a/erpnext/translations/mk.csv
+++ b/erpnext/translations/mk.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Не можете да го избришете Типот на проектот 'External',
You cannot edit root node.,Не можете да уредувате корен јазол.,
You cannot restart a Subscription that is not cancelled.,Не можете да ја рестартирате претплатата која не е откажана.,
-You don't have enought Loyalty Points to redeem,Вие не сте донеле лојални точки за откуп,
+You don't have enough Loyalty Points to redeem,Вие не сте донеле лојални точки за откуп,
You have already assessed for the assessment criteria {}.,Веќе сте се проценува за критериумите за оценување {}.,
You have already selected items from {0} {1},Веќе сте одбрале предмети од {0} {1},
You have been invited to collaborate on the project: {0},Вие сте поканети да соработуваат на проектот: {0},
diff --git a/erpnext/translations/ml.csv b/erpnext/translations/ml.csv
index 46629a3..22684b6 100644
--- a/erpnext/translations/ml.csv
+++ b/erpnext/translations/ml.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',നിങ്ങൾക്ക് പദ്ധതി തരം 'ബാഹ്യ' ഇല്ലാതാക്കാൻ കഴിയില്ല,
You cannot edit root node.,നിങ്ങൾക്ക് റൂട്ട് നോഡ് എഡിറ്റുചെയ്യാൻ കഴിയില്ല.,
You cannot restart a Subscription that is not cancelled.,നിങ്ങൾക്ക് റദ്ദാക്കാത്ത ഒരു സബ്സ്ക്രിപ്ഷൻ പുനഃരാരംഭിക്കാൻ കഴിയില്ല.,
-You don't have enought Loyalty Points to redeem,നിങ്ങൾക്ക് വീണ്ടെടുക്കാനുള്ള വിശ്വസ്ത ടയറുകൾ ആവശ്യമില്ല,
+You don't have enough Loyalty Points to redeem,നിങ്ങൾക്ക് വീണ്ടെടുക്കാനുള്ള വിശ്വസ്ത ടയറുകൾ ആവശ്യമില്ല,
You have already assessed for the assessment criteria {}.,ഇതിനകം നിങ്ങൾ വിലയിരുത്തൽ മാനദണ്ഡങ്ങൾ {} വേണ്ടി വിലയിരുത്തി ചെയ്തു.,
You have already selected items from {0} {1},നിങ്ങൾ ഇതിനകം നിന്ന് {0} {1} ഇനങ്ങൾ തിരഞ്ഞെടുത്തു,
You have been invited to collaborate on the project: {0},നിങ്ങൾ പദ്ധതി സഹകരിക്കുക ക്ഷണിച്ചു: {0},
diff --git a/erpnext/translations/mr.csv b/erpnext/translations/mr.csv
index 7f1c5e2..87e0fdd 100644
--- a/erpnext/translations/mr.csv
+++ b/erpnext/translations/mr.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',आपण प्रोजेक्ट प्रकार 'बाह्य' हटवू शकत नाही,
You cannot edit root node.,आपण मूळ नोड संपादित करू शकत नाही.,
You cannot restart a Subscription that is not cancelled.,आपण रद्द न केलेली सबस्क्रिप्शन पुन्हा सुरू करू शकत नाही.,
-You don't have enought Loyalty Points to redeem,आपण परत विकत घेण्यासाठी निष्ठावान बिंदू नाहीत,
+You don't have enough Loyalty Points to redeem,आपण परत विकत घेण्यासाठी निष्ठावान बिंदू नाहीत,
You have already assessed for the assessment criteria {}.,आपण मूल्यांकन निकष आधीच मूल्यमापन आहे {}.,
You have already selected items from {0} {1},आपण आधीच आयटम निवडले आहेत {0} {1},
You have been invited to collaborate on the project: {0},आपण प्रकल्प सहयोग करण्यासाठी आमंत्रित आहेत: {0},
diff --git a/erpnext/translations/ms.csv b/erpnext/translations/ms.csv
index 0dfc55b..8e1ac51 100644
--- a/erpnext/translations/ms.csv
+++ b/erpnext/translations/ms.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Anda tidak boleh memadam Jenis Projek 'Luar',
You cannot edit root node.,Anda tidak boleh mengedit nod akar.,
You cannot restart a Subscription that is not cancelled.,Anda tidak boleh memulakan semula Langganan yang tidak dibatalkan.,
-You don't have enought Loyalty Points to redeem,Anda tidak mempunyai mata Kesetiaan yang cukup untuk menebusnya,
+You don't have enough Loyalty Points to redeem,Anda tidak mempunyai mata Kesetiaan yang cukup untuk menebusnya,
You have already assessed for the assessment criteria {}.,Anda telah pun dinilai untuk kriteria penilaian {}.,
You have already selected items from {0} {1},Anda telah memilih barangan dari {0} {1},
You have been invited to collaborate on the project: {0},Anda telah dijemput untuk bekerjasama dalam projek: {0},
diff --git a/erpnext/translations/my.csv b/erpnext/translations/my.csv
index c0c0c45..6da5860 100644
--- a/erpnext/translations/my.csv
+++ b/erpnext/translations/my.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',သငျသညျစီမံကိန်းအမျိုးအစား '' ပြင်ပ '' မဖျက်နိုင်ပါ,
You cannot edit root node.,သငျသညျအမြစ် node ကိုတည်းဖြတ်မရနိုင်ပါ။,
You cannot restart a Subscription that is not cancelled.,သငျသညျဖျက်သိမ်းမပေးကြောင်းတစ် Subscription ပြန်လည်စတင်ရန်လို့မရပါဘူး။,
-You don't have enought Loyalty Points to redeem,သငျသညျကိုရှေးနှုတျမှ enought သစ္စာရှိမှုအမှတ်ရှိသည်မဟုတ်ကြဘူး,
+You don't have enough Loyalty Points to redeem,သငျသညျကိုရှေးနှုတျမှ enough သစ္စာရှိမှုအမှတ်ရှိသည်မဟုတ်ကြဘူး,
You have already assessed for the assessment criteria {}.,သငျသညျပြီးသား {} အဆိုပါအကဲဖြတ်သတ်မှတ်ချက်အဘို့အအကဲဖြတ်ပါပြီ။,
You have already selected items from {0} {1},သငျသညျပြီးသား {0} {1} ကနေပစ္စည်းကိုရှေးခယျြခဲ့ကြ,
You have been invited to collaborate on the project: {0},သငျသညျစီမံကိန်းကိုအပေါ်ပူးပေါင်းဖို့ဖိတ်ခေါ်ခဲ့ကြ: {0},
diff --git a/erpnext/translations/nl.csv b/erpnext/translations/nl.csv
index 4d81095..96d1770 100644
--- a/erpnext/translations/nl.csv
+++ b/erpnext/translations/nl.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',U kunt projecttype 'extern' niet verwijderen,
You cannot edit root node.,U kunt het basisknooppunt niet bewerken.,
You cannot restart a Subscription that is not cancelled.,U kunt een Abonnement dat niet is geannuleerd niet opnieuw opstarten.,
-You don't have enought Loyalty Points to redeem,Je hebt geen genoeg loyaliteitspunten om in te wisselen,
+You don't have enough Loyalty Points to redeem,Je hebt geen genoeg loyaliteitspunten om in te wisselen,
You have already assessed for the assessment criteria {}.,U heeft al beoordeeld op de beoordelingscriteria {}.,
You have already selected items from {0} {1},U heeft reeds geselecteerde items uit {0} {1},
You have been invited to collaborate on the project: {0},U bent uitgenodigd om mee te werken aan het project: {0},
diff --git a/erpnext/translations/no.csv b/erpnext/translations/no.csv
index 0ee6ed6..f285e48 100644
--- a/erpnext/translations/no.csv
+++ b/erpnext/translations/no.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Du kan ikke slette Project Type 'External',
You cannot edit root node.,Du kan ikke redigere rotknutepunktet.,
You cannot restart a Subscription that is not cancelled.,Du kan ikke starte en abonnement som ikke er kansellert.,
-You don't have enought Loyalty Points to redeem,Du har ikke nok lojalitetspoeng til å innløse,
+You don't have enough Loyalty Points to redeem,Du har ikke nok lojalitetspoeng til å innløse,
You have already assessed for the assessment criteria {}.,Du har allerede vurdert for vurderingskriteriene {}.,
You have already selected items from {0} {1},Du har allerede valgt elementer fra {0} {1},
You have been invited to collaborate on the project: {0},Du har blitt invitert til å samarbeide om prosjektet: {0},
diff --git a/erpnext/translations/pl.csv b/erpnext/translations/pl.csv
index e0ecec5..82cc64d 100644
--- a/erpnext/translations/pl.csv
+++ b/erpnext/translations/pl.csv
@@ -3069,7 +3069,7 @@
You cannot delete Project Type 'External',Nie można usunąć typu projektu "zewnętrzny",
You cannot edit root node.,Nie można edytować węzła głównego.,
You cannot restart a Subscription that is not cancelled.,"Nie można ponownie uruchomić subskrypcji, która nie zostanie anulowana.",
-You don't have enought Loyalty Points to redeem,"Nie masz wystarczającej liczby Punktów Lojalnościowych, aby je wykorzystać",
+You don't have enough Loyalty Points to redeem,"Nie masz wystarczającej liczby Punktów Lojalnościowych, aby je wykorzystać",
You have already assessed for the assessment criteria {}.,Oceniałeś już kryteria oceny {}.,
You have already selected items from {0} {1},Już wybrane pozycje z {0} {1},
You have been invited to collaborate on the project: {0},Zostałeś zaproszony do współpracy przy projekcie: {0},
diff --git a/erpnext/translations/ps.csv b/erpnext/translations/ps.csv
index 8788bcb..27df03c 100644
--- a/erpnext/translations/ps.csv
+++ b/erpnext/translations/ps.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',تاسو د پروژې ډول 'بهرني' نه ړنګولی شئ,
You cannot edit root node.,تاسو د ریډ نوډ سمون نشو کولی.,
You cannot restart a Subscription that is not cancelled.,تاسو نشي کولی هغه یو بل ریکارډ بیا پیل کړئ چې رد شوی نه وي.,
-You don't have enought Loyalty Points to redeem,تاسو د ژغورلو لپاره د وفادارۍ ټکي نلرئ,
+You don't have enough Loyalty Points to redeem,تاسو د ژغورلو لپاره د وفادارۍ ټکي نلرئ,
You have already assessed for the assessment criteria {}.,تاسو مخکې د ارزونې معیارونه ارزول {}.,
You have already selected items from {0} {1},تاسو وخته ټاکل څخه توکي {0} د {1},
You have been invited to collaborate on the project: {0},تاسو ته په دغه پروژه کې همکاري بلل شوي دي: {0},
diff --git a/erpnext/translations/pt-BR.csv b/erpnext/translations/pt-BR.csv
index 3aa00ba..c07082e 100644
--- a/erpnext/translations/pt-BR.csv
+++ b/erpnext/translations/pt-BR.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Você não pode excluir o Tipo de Projeto ';Externo';,
You cannot edit root node.,Você não pode editar o nó raiz.,
You cannot restart a Subscription that is not cancelled.,Você não pode reiniciar uma Assinatura que não seja cancelada.,
-You don't have enought Loyalty Points to redeem,Você não tem suficientes pontos de lealdade para resgatar,
+You don't have enough Loyalty Points to redeem,Você não tem suficientes pontos de lealdade para resgatar,
You have already assessed for the assessment criteria {}.,Você já avaliou os critérios de avaliação {}.,
You have already selected items from {0} {1},Já selecionou itens de {0} {1},
You have been invited to collaborate on the project: {0},Você foi convidado para colaborar com o projeto: {0},
diff --git a/erpnext/translations/pt.csv b/erpnext/translations/pt.csv
index f52ed55..9b7a854 100644
--- a/erpnext/translations/pt.csv
+++ b/erpnext/translations/pt.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Você não pode excluir o Tipo de Projeto 'Externo',
You cannot edit root node.,Você não pode editar o nó raiz.,
You cannot restart a Subscription that is not cancelled.,Você não pode reiniciar uma Assinatura que não seja cancelada.,
-You don't have enought Loyalty Points to redeem,Você não tem suficientes pontos de lealdade para resgatar,
+You don't have enough Loyalty Points to redeem,Você não tem suficientes pontos de lealdade para resgatar,
You have already assessed for the assessment criteria {}.,Você já avaliou os critérios de avaliação {}.,
You have already selected items from {0} {1},Já selecionou itens de {0} {1},
You have been invited to collaborate on the project: {0},Foi convidado para colaborar com o projeto: {0},
diff --git a/erpnext/translations/ro.csv b/erpnext/translations/ro.csv
index d3e2685..6c81419 100644
--- a/erpnext/translations/ro.csv
+++ b/erpnext/translations/ro.csv
@@ -3093,7 +3093,7 @@
You cannot delete Project Type 'External',Nu puteți șterge tipul de proiect "extern",
You cannot edit root node.,Nu puteți edita nodul rădăcină.,
You cannot restart a Subscription that is not cancelled.,Nu puteți reporni o abonament care nu este anulat.,
-You don't have enought Loyalty Points to redeem,Nu aveți puncte de loialitate pentru a răscumpăra,
+You don't have enough Loyalty Points to redeem,Nu aveți puncte de loialitate pentru a răscumpăra,
You have already assessed for the assessment criteria {}.,Ați evaluat deja criteriile de evaluare {}.,
You have already selected items from {0} {1},Ați selectat deja un produs de la {0} {1},
You have been invited to collaborate on the project: {0},Ați fost invitat să colaboreze la proiect: {0},
diff --git a/erpnext/translations/ru.csv b/erpnext/translations/ru.csv
index 405ce46..92442cd 100644
--- a/erpnext/translations/ru.csv
+++ b/erpnext/translations/ru.csv
@@ -3092,7 +3092,7 @@
You cannot delete Project Type 'External',"Вы не можете удалить проект типа ""Внешний""",
You cannot edit root node.,Вы не можете редактировать корневой узел.,
You cannot restart a Subscription that is not cancelled.,"Вы не можете перезапустить подписку, которая не отменена.",
-You don't have enought Loyalty Points to redeem,У вас недостаточно очков лояльности для выкупа,
+You don't have enough Loyalty Points to redeem,У вас недостаточно очков лояльности для выкупа,
You have already assessed for the assessment criteria {}.,Вы уже оценили критерии оценки {}.,
You have already selected items from {0} {1},Вы уже выбрали продукты из {0} {1},
You have been invited to collaborate on the project: {0},Вы были приглашены для совместной работы над проектом: {0},
diff --git a/erpnext/translations/rw.csv b/erpnext/translations/rw.csv
index ecad4f5..55b79fe 100644
--- a/erpnext/translations/rw.csv
+++ b/erpnext/translations/rw.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Ntushobora gusiba Ubwoko bwumushinga 'Hanze',
You cannot edit root node.,Ntushobora guhindura imizi.,
You cannot restart a Subscription that is not cancelled.,Ntushobora gutangira Kwiyandikisha bidahagaritswe.,
-You don't have enought Loyalty Points to redeem,Ntabwo ufite amanota ahagije yo gucungura,
+You don't have enough Loyalty Points to redeem,Ntabwo ufite amanota ahagije yo gucungura,
You have already assessed for the assessment criteria {}.,Mumaze gusuzuma ibipimo ngenderwaho {}.,
You have already selected items from {0} {1},Mumaze guhitamo ibintu kuva {0} {1},
You have been invited to collaborate on the project: {0},Watumiwe gufatanya kumushinga: {0},
diff --git a/erpnext/translations/si.csv b/erpnext/translations/si.csv
index 568f892..b43af74 100644
--- a/erpnext/translations/si.csv
+++ b/erpnext/translations/si.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',ඔබට ව්යාපෘති වර්ගය 'බාහිර',
You cannot edit root node.,ඔබට root node සංස්කරණය කළ නොහැක.,
You cannot restart a Subscription that is not cancelled.,අවලංගු නොකළ දායකත්ව නැවත ආරම්භ කළ නොහැක.,
-You don't have enought Loyalty Points to redeem,ඔබ මුදා හැරීමට පක්ෂපාතීත්වයේ පොත්වලට ඔබ කැමති නැත,
+You don't have enough Loyalty Points to redeem,ඔබ මුදා හැරීමට පක්ෂපාතීත්වයේ පොත්වලට ඔබ කැමති නැත,
You have already assessed for the assessment criteria {}.,තක්සේරු නිර්ණායක {} සඳහා ඔබ දැනටමත් තක්සේරු කර ඇත.,
You have already selected items from {0} {1},ඔබ මේ වන විටත් {0} {1} සිට භාණ්ඩ තෝරාගෙන ඇති,
You have been invited to collaborate on the project: {0},ඔබ මෙම ව්යාපෘතිය පිළිබඳව සහයෝගයෙන් කටයුතු කිරීමට ආරාධනා කර ඇත: {0},
diff --git a/erpnext/translations/sk.csv b/erpnext/translations/sk.csv
index a97f6c0..451b882 100644
--- a/erpnext/translations/sk.csv
+++ b/erpnext/translations/sk.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Nemôžete odstrániť typ projektu "Externé",
You cannot edit root node.,Nemôžete upraviť koreňový uzol.,
You cannot restart a Subscription that is not cancelled.,"Predplatné, ktoré nie je zrušené, nemôžete reštartovať.",
-You don't have enought Loyalty Points to redeem,Nemáte dostatok vernostných bodov na vykúpenie,
+You don't have enough Loyalty Points to redeem,Nemáte dostatok vernostných bodov na vykúpenie,
You have already assessed for the assessment criteria {}.,Vyhodnotili ste kritériá hodnotenia {}.,
You have already selected items from {0} {1},Už ste vybrané položky z {0} {1},
You have been invited to collaborate on the project: {0},Boli ste pozvaní k spolupráci na projekte: {0},
diff --git a/erpnext/translations/sl.csv b/erpnext/translations/sl.csv
index b653990..0cb7a6f 100644
--- a/erpnext/translations/sl.csv
+++ b/erpnext/translations/sl.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Ne morete izbrisati vrste projekta "Zunanji",
You cannot edit root node.,Rootnega vozlišča ne morete urejati.,
You cannot restart a Subscription that is not cancelled.,"Naročnino, ki ni preklican, ne morete znova zagnati.",
-You don't have enought Loyalty Points to redeem,Za unovčevanje niste prejeli točk za zvestobo,
+You don't have enough Loyalty Points to redeem,Za unovčevanje niste prejeli točk za zvestobo,
You have already assessed for the assessment criteria {}.,Ste že ocenili za ocenjevalnih meril {}.,
You have already selected items from {0} {1},Ste že izbrane postavke iz {0} {1},
You have been invited to collaborate on the project: {0},Ti so bili povabljeni k sodelovanju na projektu: {0},
diff --git a/erpnext/translations/sq.csv b/erpnext/translations/sq.csv
index 964c840..742dfcc 100644
--- a/erpnext/translations/sq.csv
+++ b/erpnext/translations/sq.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Ju nuk mund të fshini llojin e projektit 'Jashtë',
You cannot edit root node.,Nuk mund të ndryshosh nyjen e rrënjës.,
You cannot restart a Subscription that is not cancelled.,Nuk mund të rifilloni një Abonimi që nuk anulohet.,
-You don't have enought Loyalty Points to redeem,Ju nuk keni shumë pikat e Besnikërisë për të shpenguar,
+You don't have enough Loyalty Points to redeem,Ju nuk keni shumë pikat e Besnikërisë për të shpenguar,
You have already assessed for the assessment criteria {}.,Ju kanë vlerësuar tashmë me kriteret e vlerësimit {}.,
You have already selected items from {0} {1},Ju keni zgjedhur tashmë artikuj nga {0} {1},
You have been invited to collaborate on the project: {0},Ju keni qenë të ftuar për të bashkëpunuar në këtë projekt: {0},
diff --git a/erpnext/translations/sr-SP.csv b/erpnext/translations/sr-SP.csv
index 25223db..bb28353 100644
--- a/erpnext/translations/sr-SP.csv
+++ b/erpnext/translations/sr-SP.csv
@@ -503,7 +503,7 @@
Price List Rate,Cijena,
Discount Amount,Vrijednost popusta,
Sales Invoice Trends,Trendovi faktura prodaje,
-You don't have enought Loyalty Points to redeem,Немате довољно Бодова Лојалности.
+You don't have enough Loyalty Points to redeem,Немате довољно Бодова Лојалности.
Tax Breakup,Porez po pozicijama,
Task,Zadatak,
Add / Edit Prices,Dodaj / Izmijeni cijene,
diff --git a/erpnext/translations/sr.csv b/erpnext/translations/sr.csv
index b8428d0..c5662ad 100644
--- a/erpnext/translations/sr.csv
+++ b/erpnext/translations/sr.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Не можете обрисати тип пројекта 'Спољни',
You cannot edit root node.,Не можете уређивати роот чвор.,
You cannot restart a Subscription that is not cancelled.,Не можете поново покренути претплату која није отказана.,
-You don't have enought Loyalty Points to redeem,Не искористите Лоиалти Поинтс за откуп,
+You don't have enough Loyalty Points to redeem,Не искористите Лоиалти Поинтс за откуп,
You have already assessed for the assessment criteria {}.,Већ сте оцијенили за критеријуми за оцењивање {}.,
You have already selected items from {0} {1},Који сте изабрали ставке из {0} {1},
You have been invited to collaborate on the project: {0},Позвани сте да сарађују на пројекту: {0},
diff --git a/erpnext/translations/sr_sp.csv b/erpnext/translations/sr_sp.csv
index c121e6a..2383c6e 100644
--- a/erpnext/translations/sr_sp.csv
+++ b/erpnext/translations/sr_sp.csv
@@ -545,7 +545,7 @@
You cannot delete Fiscal Year {0}. Fiscal Year {0} is set as default in Global Settings,Ne možete obrisati fiskalnu godinu {0}. Fiskalna {0} godina je označena kao trenutna u globalnim podešavanjima.,
You cannot delete Project Type 'External',"Не можете обрисати ""Спољни"" тип пројекта.",
You cannot edit root node.,Не можете уређивати коренски чвор.,
-You don't have enought Loyalty Points to redeem,Немате довољно Бодова Лојалности.,
+You don't have enough Loyalty Points to redeem,Немате довољно Бодова Лојалности.,
You have already assessed for the assessment criteria {}.,Већ сте оценили за критеријум оцењивања {}.,
You have already selected items from {0} {1},Већ сте изабрали ставке из {0} {1},
You have been invited to collaborate on the project: {0},Позвани сте да сарађујете на пројекту: {0},
diff --git a/erpnext/translations/sv.csv b/erpnext/translations/sv.csv
index f4ac1d5..abdbc6b 100644
--- a/erpnext/translations/sv.csv
+++ b/erpnext/translations/sv.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Du kan inte ta bort Project Type 'External',
You cannot edit root node.,Du kan inte redigera rotknutpunkt.,
You cannot restart a Subscription that is not cancelled.,Du kan inte starta om en prenumeration som inte avbryts.,
-You don't have enought Loyalty Points to redeem,Du har inte tillräckligt med lojalitetspoäng för att lösa in,
+You don't have enough Loyalty Points to redeem,Du har inte tillräckligt med lojalitetspoäng för att lösa in,
You have already assessed for the assessment criteria {}.,Du har redan bedömt för bedömningskriterierna {}.,
You have already selected items from {0} {1},Du har redan valt objekt från {0} {1},
You have been invited to collaborate on the project: {0},Du har blivit inbjuden att samarbeta i projektet: {0},
diff --git a/erpnext/translations/sw.csv b/erpnext/translations/sw.csv
index 9f2504e..5f29c3f 100644
--- a/erpnext/translations/sw.csv
+++ b/erpnext/translations/sw.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Huwezi kufuta Aina ya Mradi 'Nje',
You cannot edit root node.,Huwezi kubadilisha node ya mizizi.,
You cannot restart a Subscription that is not cancelled.,Huwezi kuanzisha upya Usajili ambao haujahairiwa.,
-You don't have enought Loyalty Points to redeem,Huna ushawishi wa Pole ya Uaminifu ili ukomboe,
+You don't have enough Loyalty Points to redeem,Huna ushawishi wa Pole ya Uaminifu ili ukomboe,
You have already assessed for the assessment criteria {}.,Tayari umehakikishia vigezo vya tathmini {}.,
You have already selected items from {0} {1},Tayari umechagua vitu kutoka {0} {1},
You have been invited to collaborate on the project: {0},Umealikwa kushirikiana kwenye mradi: {0},
diff --git a/erpnext/translations/ta.csv b/erpnext/translations/ta.csv
index cb8b83a..d36f47c 100644
--- a/erpnext/translations/ta.csv
+++ b/erpnext/translations/ta.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',நீங்கள் திட்டம் வகை 'வெளிப்புற' நீக்க முடியாது,
You cannot edit root node.,ரூட் முனையை நீங்கள் திருத்த முடியாது.,
You cannot restart a Subscription that is not cancelled.,ரத்துசெய்யப்படாத சந்தாவை மறுதொடக்கம் செய்ய முடியாது.,
-You don't have enought Loyalty Points to redeem,நீங்கள் மீட்கும் விசுவாச புள்ளிகளைப் பெறுவீர்கள்,
+You don't have enough Loyalty Points to redeem,நீங்கள் மீட்கும் விசுவாச புள்ளிகளைப் பெறுவீர்கள்,
You have already assessed for the assessment criteria {}.,ஏற்கனவே மதிப்பீட்டிற்குத் தகுதி மதிப்பீடு செய்யப்பட்டதன் {}.,
You have already selected items from {0} {1},நீங்கள் ஏற்கனவே இருந்து பொருட்களை தேர்ந்தெடுத்த {0} {1},
You have been invited to collaborate on the project: {0},நீங்கள் திட்டம் இணைந்து அழைக்கப்பட்டுள்ளனர்: {0},
diff --git a/erpnext/translations/te.csv b/erpnext/translations/te.csv
index a2f4960..83d9c8c 100644
--- a/erpnext/translations/te.csv
+++ b/erpnext/translations/te.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',మీరు ప్రాజెక్ట్ రకం 'బాహ్య' తొలగించలేరు,
You cannot edit root node.,మీరు రూట్ నోడ్ను సవరించలేరు.,
You cannot restart a Subscription that is not cancelled.,మీరు రద్దు చేయని సభ్యత్వాన్ని పునఃప్రారంభించలేరు.,
-You don't have enought Loyalty Points to redeem,మీరు విమోచన చేయడానికి లాయల్టీ పాయింట్స్ను కలిగి ఉండరు,
+You don't have enough Loyalty Points to redeem,మీరు విమోచన చేయడానికి లాయల్టీ పాయింట్స్ను కలిగి ఉండరు,
You have already assessed for the assessment criteria {}.,మీరు ఇప్పటికే అంచనా ప్రమాణం కోసం అంచనా {}.,
You have already selected items from {0} {1},మీరు ఇప్పటికే ఎంపిక నుండి అంశాలను రోజులో {0} {1},
You have been invited to collaborate on the project: {0},మీరు ప్రాజెక్ట్ సహకరించడానికి ఆహ్వానించబడ్డారు: {0},
diff --git a/erpnext/translations/th.csv b/erpnext/translations/th.csv
index af272fa..e492856 100644
--- a/erpnext/translations/th.csv
+++ b/erpnext/translations/th.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',คุณไม่สามารถลบประเภทโครงการ 'ภายนอก',
You cannot edit root node.,คุณไม่สามารถแก้ไขโหนดรากได้,
You cannot restart a Subscription that is not cancelled.,คุณไม่สามารถรีสตาร์ทการสมัครสมาชิกที่ไม่ได้ยกเลิกได้,
-You don't have enought Loyalty Points to redeem,คุณไม่มีจุดภักดีเพียงพอที่จะไถ่ถอน,
+You don't have enough Loyalty Points to redeem,คุณไม่มีจุดภักดีเพียงพอที่จะไถ่ถอน,
You have already assessed for the assessment criteria {}.,คุณได้รับการประเมินเกณฑ์การประเมินแล้ว {},
You have already selected items from {0} {1},คุณได้เลือกแล้วรายการจาก {0} {1},
You have been invited to collaborate on the project: {0},คุณได้รับเชิญที่จะทำงานร่วมกันในโครงการ: {0},
diff --git a/erpnext/translations/tr.csv b/erpnext/translations/tr.csv
index 9c8fb3f..e0034c0 100644
--- a/erpnext/translations/tr.csv
+++ b/erpnext/translations/tr.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External','Dış' Proje Türünü silemezsiniz.,
You cannot edit root node.,Kök düğümünü düzenleyemezsiniz.,
You cannot restart a Subscription that is not cancelled.,İptal edilmeyen bir Aboneliği başlatamazsınız.,
-You don't have enought Loyalty Points to redeem,Kullanılması gereken sadakat puanlarına sahip olabilirsiniz,
+You don't have enough Loyalty Points to redeem,Kullanılması gereken sadakat puanlarına sahip olabilirsiniz,
You have already assessed for the assessment criteria {}.,Zaten değerlendirme kriteri {} için değerlendirdiniz.,
You have already selected items from {0} {1},Zaten öğelerinizi seçtiniz {0} {1},
You have been invited to collaborate on the project: {0},{0} projesine davet edilmek için davet edildiniz,
diff --git a/erpnext/translations/uk.csv b/erpnext/translations/uk.csv
index 1b78f96..f4faedc 100644
--- a/erpnext/translations/uk.csv
+++ b/erpnext/translations/uk.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Ви не можете видалити тип проекту "Зовнішній",
You cannot edit root node.,Ви не можете редагувати кореневий вузол.,
You cannot restart a Subscription that is not cancelled.,"Ви не можете перезапустити підписку, яку не скасовано.",
-You don't have enought Loyalty Points to redeem,"Ви не маєте впевнених точок лояльності, щоб викупити",
+You don't have enough Loyalty Points to redeem,"Ви не маєте впевнених точок лояльності, щоб викупити",
You have already assessed for the assessment criteria {}.,Ви вже оцінили за критеріями оцінки {}.,
You have already selected items from {0} {1},Ви вже вибрали елементи з {0} {1},
You have been invited to collaborate on the project: {0},Ви були запрошені для спільної роботи над проектом: {0},
diff --git a/erpnext/translations/ur.csv b/erpnext/translations/ur.csv
index e32e594..e958e57 100644
--- a/erpnext/translations/ur.csv
+++ b/erpnext/translations/ur.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',آپ پراجیکٹ کی قسم کو خارج نہیں کرسکتے ہیں 'بیرونی',
You cannot edit root node.,آپ جڑ نوڈ میں ترمیم نہیں کر سکتے ہیں.,
You cannot restart a Subscription that is not cancelled.,آپ ایک سبسکرپشن کو دوبارہ شروع نہیں کرسکتے جو منسوخ نہیں ہوسکتا.,
-You don't have enought Loyalty Points to redeem,آپ کو بہت زیادہ وفادار پوائنٹس حاصل کرنے کے لئے نہیں ہے,
+You don't have enough Loyalty Points to redeem,آپ کو بہت زیادہ وفادار پوائنٹس حاصل کرنے کے لئے نہیں ہے,
You have already assessed for the assessment criteria {}.,آپ نے پہلے ہی تشخیص کے معیار کے تعین کی ہے {}.,
You have already selected items from {0} {1},آپ نے پہلے ہی سے اشیاء کو منتخب کیا ہے {0} {1},
You have been invited to collaborate on the project: {0},آپ کو منصوبے پر تعاون کرنے کیلئے مدعو کیا گیا ہے: {0},
diff --git a/erpnext/translations/uz.csv b/erpnext/translations/uz.csv
index 3053559..6cdb23c 100644
--- a/erpnext/translations/uz.csv
+++ b/erpnext/translations/uz.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Siz "Tashqi" loyiha turini o'chira olmaysiz,
You cannot edit root node.,Ildiz tugunni tahrirlay olmaysiz.,
You cannot restart a Subscription that is not cancelled.,Bekor qilinmagan obunani qayta boshlash mumkin emas.,
-You don't have enought Loyalty Points to redeem,Siz sotib olish uchun sodiqlik nuqtalari yo'q,
+You don't have enough Loyalty Points to redeem,Siz sotib olish uchun sodiqlik nuqtalari yo'q,
You have already assessed for the assessment criteria {}.,Siz allaqachon baholash mezonlari uchun baholagansiz {}.,
You have already selected items from {0} {1},{0} {1} dan tanlangan elementlarni tanladingiz,
You have been invited to collaborate on the project: {0},Siz loyihada hamkorlik qilish uchun taklif qilingan: {0},
diff --git a/erpnext/translations/vi.csv b/erpnext/translations/vi.csv
index 5c74694..650ac28 100644
--- a/erpnext/translations/vi.csv
+++ b/erpnext/translations/vi.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',Bạn không thể xóa Loại dự án 'Bên ngoài',
You cannot edit root node.,Bạn không thể chỉnh sửa nút gốc.,
You cannot restart a Subscription that is not cancelled.,Bạn không thể khởi động lại Đăng ký không bị hủy.,
-You don't have enought Loyalty Points to redeem,Bạn không có Điểm trung thành đủ để đổi,
+You don't have enough Loyalty Points to redeem,Bạn không có Điểm trung thành đủ để đổi,
You have already assessed for the assessment criteria {}.,Bạn đã đánh giá các tiêu chí đánh giá {}.,
You have already selected items from {0} {1},Bạn đã chọn các mục từ {0} {1},
You have been invited to collaborate on the project: {0},Bạn được lời mời cộng tác trong dự án: {0},
diff --git a/erpnext/translations/zh-TW.csv b/erpnext/translations/zh-TW.csv
index 25204f1..0209f44 100644
--- a/erpnext/translations/zh-TW.csv
+++ b/erpnext/translations/zh-TW.csv
@@ -1542,7 +1542,7 @@
Course Intro,課程介紹
MWS Auth Token,MWS Auth Token,
Stock Entry {0} created,庫存輸入{0}創建
-You don't have enought Loyalty Points to redeem,您沒有獲得忠誠度積分兌換
+You don't have enough Loyalty Points to redeem,您沒有獲得忠誠度積分兌換
Please set associated account in Tax Withholding Category {0} against Company {1},請在針對公司{1}的預扣稅分類{0}中設置關聯帳戶
Row #{0}: Rejected Qty can not be entered in Purchase Return,行#{0}:駁回採購退貨數量不能進入
Changing Customer Group for the selected Customer is not allowed.,不允許更改所選客戶的客戶組。
diff --git a/erpnext/translations/zh.csv b/erpnext/translations/zh.csv
index 9b2fbf0..d51bf6b 100644
--- a/erpnext/translations/zh.csv
+++ b/erpnext/translations/zh.csv
@@ -3094,7 +3094,7 @@
You cannot delete Project Type 'External',您不能删除“外部”类型的项目,
You cannot edit root node.,您不能编辑根节点。,
You cannot restart a Subscription that is not cancelled.,您无法重新启动未取消的订阅。,
-You don't have enought Loyalty Points to redeem,您没有获得忠诚度积分兑换,
+You don't have enough Loyalty Points to redeem,您没有获得忠诚度积分兑换,
You have already assessed for the assessment criteria {}.,您已经评估了评估标准{}。,
You have already selected items from {0} {1},您已经选择从项目{0} {1},
You have been invited to collaborate on the project: {0},您已被邀请在项目上进行合作:{0},
diff --git a/erpnext/translations/zh_tw.csv b/erpnext/translations/zh_tw.csv
index 54eb86a..75157f0 100644
--- a/erpnext/translations/zh_tw.csv
+++ b/erpnext/translations/zh_tw.csv
@@ -3127,7 +3127,7 @@
You cannot delete Project Type 'External',您不能刪除項目類型“外部”,
You cannot edit root node.,您不能編輯根節點。,
You cannot restart a Subscription that is not cancelled.,您無法重新啟動未取消的訂閱。,
-You don't have enought Loyalty Points to redeem,您沒有獲得忠誠度積分兌換,
+You don't have enough Loyalty Points to redeem,您沒有獲得忠誠度積分兌換,
You have already assessed for the assessment criteria {}.,您已經評估了評估標準{}。,
You have already selected items from {0} {1},您已經選擇從項目{0} {1},
You have been invited to collaborate on the project: {0},您已被邀請在項目上進行合作:{0},